Exemplo n.º 1
0
// NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a
// single identity composed of the given full name, comment and email, any of
// which may be empty but must not contain any of "()<>\x00".
// If config is nil, sensible defaults will be used.
//
// Modification of: https://code.google.com/p/go/source/browse/openpgp/keys.go?repo=crypto&r=8fec09c61d5d66f460d227fd1df3473d7e015bc6#456
//  From golang.com/x/crypto/openpgp/keys.go
func GeneratePGPKeyBundle(arg PGPGenArg, logUI LogUI) (*PGPKeyBundle, error) {
	currentTime := arg.Config.Now()

	if len(arg.Ids) == 0 {
		return nil, errors.InvalidArgumentError("No Ids in PGPArg")
	}
	uids, err := arg.PGPUserIDs()
	if err != nil {
		return nil, err
	}
	for i, id := range arg.Ids {
		extra := ""
		if i == 0 {
			extra = "[primary]"
		}
		if logUI != nil {
			logUI.Info("PGP User ID: %s %s", id, extra)
		}
	}

	if logUI != nil {
		logUI.Info("Generating primary key (%d bits)", arg.PrimaryBits)
	}
	masterPriv, err := rsa.GenerateKey(arg.Config.Random(), arg.PrimaryBits)
	if err != nil {
		return nil, err
	}

	if logUI != nil {
		logUI.Info("Generating encryption subkey (%d bits)", arg.SubkeyBits)
	}
	encryptingPriv, err := rsa.GenerateKey(arg.Config.Random(), arg.SubkeyBits)
	if err != nil {
		return nil, err
	}

	e := &openpgp.Entity{
		PrimaryKey: packet.NewRSAPublicKey(currentTime, &masterPriv.PublicKey),
		PrivateKey: packet.NewRSAPrivateKey(currentTime, masterPriv),
		Identities: make(map[string]*openpgp.Identity),
	}

	for i, uid := range uids {
		isPrimaryID := true
		if i > 0 {
			isPrimaryID = false
		}
		id := &openpgp.Identity{
			Name:   uid.Name,
			UserId: uid,
			SelfSignature: &packet.Signature{
				CreationTime:         currentTime,
				SigType:              packet.SigTypePositiveCert,
				PubKeyAlgo:           packet.PubKeyAlgoRSA,
				Hash:                 arg.Config.Hash(),
				IsPrimaryId:          &isPrimaryID,
				FlagsValid:           true,
				FlagSign:             true,
				FlagCertify:          true,
				IssuerKeyId:          &e.PrimaryKey.KeyId,
				PreferredSymmetric:   arg.PreferredSymmetric(),
				PreferredHash:        arg.PreferredHash(),
				PreferredCompression: arg.PreferredCompression(),
			},
		}
		id.SelfSignature.KeyLifetimeSecs = ui32p(arg.PrimaryLifetime)
		e.Identities[uid.Id] = id
	}

	e.Subkeys = make([]openpgp.Subkey, 1)
	e.Subkeys[0] = openpgp.Subkey{
		PublicKey:  packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey),
		PrivateKey: packet.NewRSAPrivateKey(currentTime, encryptingPriv),
		Sig: &packet.Signature{
			CreationTime:              currentTime,
			SigType:                   packet.SigTypeSubkeyBinding,
			PubKeyAlgo:                packet.PubKeyAlgoRSA,
			Hash:                      arg.Config.Hash(),
			FlagsValid:                true,
			FlagEncryptStorage:        true,
			FlagEncryptCommunications: true,
			IssuerKeyId:               &e.PrimaryKey.KeyId,
			PreferredSymmetric:        arg.PreferredSymmetric(),
			PreferredHash:             arg.PreferredHash(),
			PreferredCompression:      arg.PreferredCompression(),
		},
	}
	e.Subkeys[0].PublicKey.IsSubkey = true
	e.Subkeys[0].PrivateKey.IsSubkey = true
	e.Subkeys[0].Sig.KeyLifetimeSecs = ui32p(arg.SubkeyLifetime)

	return NewGeneratedPGPKeyBundle(e), nil
}
Exemplo n.º 2
0
// NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a
// single identity composed of the given full name, comment and email, any of
// which may be empty but must not contain any of "()<>\x00".
// If config is nil, sensible defaults will be used.
func NewEntity(name, comment, email string, config *packet.Config) (*Entity, error) {
	currentTime := config.Now()

	bits := defaultRSAKeyBits
	if config != nil && config.RSABits != 0 {
		bits = config.RSABits
	}

	uid := packet.NewUserId(name, comment, email)
	if uid == nil {
		return nil, errors.InvalidArgumentError("user id field contained invalid characters")
	}
	signingPriv, err := rsa.GenerateKey(config.Random(), bits)
	if err != nil {
		return nil, err
	}
	encryptingPriv, err := rsa.GenerateKey(config.Random(), bits)
	if err != nil {
		return nil, err
	}

	e := &Entity{
		PrimaryKey: packet.NewRSAPublicKey(currentTime, &signingPriv.PublicKey),
		PrivateKey: packet.NewRSAPrivateKey(currentTime, signingPriv),
		Identities: make(map[string]*Identity),
	}
	isPrimaryId := true
	e.Identities[uid.Id] = &Identity{
		Name:   uid.Name,
		UserId: uid,
		SelfSignature: &packet.Signature{
			CreationTime: currentTime,
			SigType:      packet.SigTypePositiveCert,
			PubKeyAlgo:   packet.PubKeyAlgoRSA,
			Hash:         config.Hash(),
			IsPrimaryId:  &isPrimaryId,
			FlagsValid:   true,
			FlagSign:     true,
			FlagCertify:  true,
			IssuerKeyId:  &e.PrimaryKey.KeyId,
		},
	}

	e.Subkeys = make([]Subkey, 1)
	e.Subkeys[0] = Subkey{
		PublicKey:  packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey),
		PrivateKey: packet.NewRSAPrivateKey(currentTime, encryptingPriv),
		Sig: &packet.Signature{
			CreationTime:              currentTime,
			SigType:                   packet.SigTypeSubkeyBinding,
			PubKeyAlgo:                packet.PubKeyAlgoRSA,
			Hash:                      config.Hash(),
			FlagsValid:                true,
			FlagEncryptStorage:        true,
			FlagEncryptCommunications: true,
			IssuerKeyId:               &e.PrimaryKey.KeyId,
		},
	}
	e.Subkeys[0].PublicKey.IsSubkey = true
	e.Subkeys[0].PrivateKey.IsSubkey = true

	return e, nil
}