// 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 }
// 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 }