1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
10 error_ "crypto/openpgp/error"
11 "crypto/openpgp/packet"
17 // PublicKeyType is the armor type for a PGP public key.
18 var PublicKeyType = "PGP PUBLIC KEY BLOCK"
20 // PrivateKeyType is the armor type for a PGP private key.
21 var PrivateKeyType = "PGP PRIVATE KEY BLOCK"
23 // An Entity represents the components of an OpenPGP key: a primary public key
24 // (which must be a signing key), one or more identities claimed by that key,
25 // and zero or more subkeys, which may be encryption keys.
27 PrimaryKey *packet.PublicKey
28 PrivateKey *packet.PrivateKey
29 Identities map[string]*Identity // indexed by Identity.Name
33 // An Identity represents an identity claimed by an Entity and zero or more
34 // assertions by other entities about that claim.
35 type Identity struct {
36 Name string // by convention, has the form "Full Name (comment) <email@example.com>"
38 SelfSignature *packet.Signature
39 Signatures []*packet.Signature
42 // A Subkey is an additional public key in an Entity. Subkeys can be used for
45 PublicKey *packet.PublicKey
46 PrivateKey *packet.PrivateKey
50 // A Key identifies a specific public key in an Entity. This is either the
51 // Entity's primary key or a subkey.
54 PublicKey *packet.PublicKey
55 PrivateKey *packet.PrivateKey
56 SelfSignature *packet.Signature
59 // A KeyRing provides access to public and private keys.
60 type KeyRing interface {
61 // KeysById returns the set of keys that have the given key id.
62 KeysById(id uint64) []Key
63 // DecryptionKeys returns all private keys that are valid for
65 DecryptionKeys() []Key
68 // primaryIdentity returns the Identity marked as primary or the first identity
69 // if none are so marked.
70 func (e *Entity) primaryIdentity() *Identity {
71 var firstIdentity *Identity
72 for _, ident := range e.Identities {
73 if firstIdentity == nil {
76 if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
83 // encryptionKey returns the best candidate Key for encrypting a message to the
85 func (e *Entity) encryptionKey() Key {
88 for i, subkey := range e.Subkeys {
89 if subkey.Sig.FlagsValid && subkey.Sig.FlagEncryptCommunications && subkey.PublicKey.PubKeyAlgo.CanEncrypt() {
95 i := e.primaryIdentity()
97 if e.PrimaryKey.PubKeyAlgo.CanEncrypt() {
98 // If we don't have any candidate subkeys for encryption and
99 // the primary key doesn't have any usage metadata then we
100 // assume that the primary key is ok. Or, if the primary key is
101 // marked as ok to encrypt to, then we can obviously use it.
102 if candidateSubkey == -1 && !i.SelfSignature.FlagsValid || i.SelfSignature.FlagEncryptCommunications && i.SelfSignature.FlagsValid {
103 return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}
107 if candidateSubkey != -1 {
108 subkey := e.Subkeys[candidateSubkey]
109 return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}
112 // This Entity appears to be signing only.
116 // signingKey return the best candidate Key for signing a message with this
118 func (e *Entity) signingKey() Key {
119 candidateSubkey := -1
121 for i, subkey := range e.Subkeys {
122 if subkey.Sig.FlagsValid && subkey.Sig.FlagSign && subkey.PublicKey.PubKeyAlgo.CanSign() {
128 i := e.primaryIdentity()
130 // If we have no candidate subkey then we assume that it's ok to sign
131 // with the primary key.
132 if candidateSubkey == -1 || i.SelfSignature.FlagsValid && i.SelfSignature.FlagSign {
133 return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}
136 subkey := e.Subkeys[candidateSubkey]
137 return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}
140 // An EntityList contains one or more Entities.
141 type EntityList []*Entity
143 // KeysById returns the set of keys that have the given key id.
144 func (el EntityList) KeysById(id uint64) (keys []Key) {
145 for _, e := range el {
146 if e.PrimaryKey.KeyId == id {
147 var selfSig *packet.Signature
148 for _, ident := range e.Identities {
150 selfSig = ident.SelfSignature
151 } else if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
152 selfSig = ident.SelfSignature
156 keys = append(keys, Key{e, e.PrimaryKey, e.PrivateKey, selfSig})
159 for _, subKey := range e.Subkeys {
160 if subKey.PublicKey.KeyId == id {
161 keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig})
168 // DecryptionKeys returns all private keys that are valid for decryption.
169 func (el EntityList) DecryptionKeys() (keys []Key) {
170 for _, e := range el {
171 for _, subKey := range e.Subkeys {
172 if subKey.PrivateKey != nil && (!subKey.Sig.FlagsValid || subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications) {
173 keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig})
180 // ReadArmoredKeyRing reads one or more public/private keys from an armor keyring file.
181 func ReadArmoredKeyRing(r io.Reader) (EntityList, error) {
182 block, err := armor.Decode(r)
184 return nil, error_.InvalidArgumentError("no armored data found")
189 if block.Type != PublicKeyType && block.Type != PrivateKeyType {
190 return nil, error_.InvalidArgumentError("expected public or private key block, got: " + block.Type)
193 return ReadKeyRing(block.Body)
196 // ReadKeyRing reads one or more public/private keys. Unsupported keys are
197 // ignored as long as at least a single valid key is found.
198 func ReadKeyRing(r io.Reader) (el EntityList, err error) {
199 packets := packet.NewReader(r)
200 var lastUnsupportedError error
204 e, err = readEntity(packets)
206 if _, ok := err.(error_.UnsupportedError); ok {
207 lastUnsupportedError = err
208 err = readToNextPublicKey(packets)
223 if len(el) == 0 && err == nil {
224 err = lastUnsupportedError
229 // readToNextPublicKey reads packets until the start of the entity and leaves
230 // the first packet of the new entity in the Reader.
231 func readToNextPublicKey(packets *packet.Reader) (err error) {
234 p, err = packets.Next()
237 } else if err != nil {
238 if _, ok := err.(error_.UnsupportedError); ok {
245 if pk, ok := p.(*packet.PublicKey); ok && !pk.IsSubkey {
254 // readEntity reads an entity (public key, identities, subkeys etc) from the
256 func readEntity(packets *packet.Reader) (*Entity, error) {
258 e.Identities = make(map[string]*Identity)
260 p, err := packets.Next()
266 if e.PrimaryKey, ok = p.(*packet.PublicKey); !ok {
267 if e.PrivateKey, ok = p.(*packet.PrivateKey); !ok {
269 return nil, error_.StructuralError("first packet was not a public/private key")
271 e.PrimaryKey = &e.PrivateKey.PublicKey
275 if !e.PrimaryKey.PubKeyAlgo.CanSign() {
276 return nil, error_.StructuralError("primary key cannot be used for signatures")
279 var current *Identity
282 p, err := packets.Next()
285 } else if err != nil {
289 switch pkt := p.(type) {
291 current = new(Identity)
292 current.Name = pkt.Id
294 e.Identities[pkt.Id] = current
297 p, err = packets.Next()
299 return nil, io.ErrUnexpectedEOF
300 } else if err != nil {
304 sig, ok := p.(*packet.Signature)
306 return nil, error_.StructuralError("user ID packet not followed by self-signature")
309 if (sig.SigType == packet.SigTypePositiveCert || sig.SigType == packet.SigTypeGenericCert) && sig.IssuerKeyId != nil && *sig.IssuerKeyId == e.PrimaryKey.KeyId {
310 if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, sig); err != nil {
311 return nil, error_.StructuralError("user ID self-signature invalid: " + err.Error())
313 current.SelfSignature = sig
316 current.Signatures = append(current.Signatures, sig)
318 case *packet.Signature:
320 return nil, error_.StructuralError("signature packet found before user id packet")
322 current.Signatures = append(current.Signatures, pkt)
323 case *packet.PrivateKey:
324 if pkt.IsSubkey == false {
328 err = addSubkey(e, packets, &pkt.PublicKey, pkt)
332 case *packet.PublicKey:
333 if pkt.IsSubkey == false {
337 err = addSubkey(e, packets, pkt, nil)
342 // we ignore unknown packets
346 if len(e.Identities) == 0 {
347 return nil, error_.StructuralError("entity without any identities")
353 func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) error {
355 subKey.PublicKey = pub
356 subKey.PrivateKey = priv
357 p, err := packets.Next()
359 return io.ErrUnexpectedEOF
362 return error_.StructuralError("subkey signature invalid: " + err.Error())
365 subKey.Sig, ok = p.(*packet.Signature)
367 return error_.StructuralError("subkey packet not followed by signature")
369 if subKey.Sig.SigType != packet.SigTypeSubkeyBinding {
370 return error_.StructuralError("subkey signature with wrong type")
372 err = e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, subKey.Sig)
374 return error_.StructuralError("subkey signature invalid: " + err.Error())
376 e.Subkeys = append(e.Subkeys, subKey)
380 const defaultRSAKeyBits = 2048
382 // NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a
383 // single identity composed of the given full name, comment and email, any of
384 // which may be empty but must not contain any of "()<>\x00".
385 func NewEntity(rand io.Reader, currentTime time.Time, name, comment, email string) (*Entity, error) {
386 uid := packet.NewUserId(name, comment, email)
388 return nil, error_.InvalidArgumentError("user id field contained invalid characters")
390 signingPriv, err := rsa.GenerateKey(rand, defaultRSAKeyBits)
394 encryptingPriv, err := rsa.GenerateKey(rand, defaultRSAKeyBits)
400 PrimaryKey: packet.NewRSAPublicKey(currentTime, &signingPriv.PublicKey, false /* not a subkey */ ),
401 PrivateKey: packet.NewRSAPrivateKey(currentTime, signingPriv, false /* not a subkey */ ),
402 Identities: make(map[string]*Identity),
405 e.Identities[uid.Id] = &Identity{
408 SelfSignature: &packet.Signature{
409 CreationTime: currentTime,
410 SigType: packet.SigTypePositiveCert,
411 PubKeyAlgo: packet.PubKeyAlgoRSA,
413 IsPrimaryId: &isPrimaryId,
417 IssuerKeyId: &e.PrimaryKey.KeyId,
421 e.Subkeys = make([]Subkey, 1)
422 e.Subkeys[0] = Subkey{
423 PublicKey: packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey, true /* is a subkey */ ),
424 PrivateKey: packet.NewRSAPrivateKey(currentTime, encryptingPriv, true /* is a subkey */ ),
425 Sig: &packet.Signature{
426 CreationTime: currentTime,
427 SigType: packet.SigTypeSubkeyBinding,
428 PubKeyAlgo: packet.PubKeyAlgoRSA,
431 FlagEncryptStorage: true,
432 FlagEncryptCommunications: true,
433 IssuerKeyId: &e.PrimaryKey.KeyId,
440 // SerializePrivate serializes an Entity, including private key material, to
441 // the given Writer. For now, it must only be used on an Entity returned from
443 func (e *Entity) SerializePrivate(w io.Writer) (err error) {
444 err = e.PrivateKey.Serialize(w)
448 for _, ident := range e.Identities {
449 err = ident.UserId.Serialize(w)
453 err = ident.SelfSignature.SignUserId(ident.UserId.Id, e.PrimaryKey, e.PrivateKey)
457 err = ident.SelfSignature.Serialize(w)
462 for _, subkey := range e.Subkeys {
463 err = subkey.PrivateKey.Serialize(w)
467 err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey)
471 err = subkey.Sig.Serialize(w)
479 // Serialize writes the public part of the given Entity to w. (No private
480 // key material will be output).
481 func (e *Entity) Serialize(w io.Writer) error {
482 err := e.PrimaryKey.Serialize(w)
486 for _, ident := range e.Identities {
487 err = ident.UserId.Serialize(w)
491 err = ident.SelfSignature.Serialize(w)
495 for _, sig := range ident.Signatures {
496 err = sig.Serialize(w)
502 for _, subkey := range e.Subkeys {
503 err = subkey.PublicKey.Serialize(w)
507 err = subkey.Sig.Serialize(w)
515 // SignIdentity adds a signature to e, from signer, attesting that identity is
516 // associated with e. The provided identity must already be an element of
517 // e.Identities and the private key of signer must have been decrypted if
519 func (e *Entity) SignIdentity(identity string, signer *Entity) error {
520 if signer.PrivateKey == nil {
521 return error_.InvalidArgumentError("signing Entity must have a private key")
523 if signer.PrivateKey.Encrypted {
524 return error_.InvalidArgumentError("signing Entity's private key must be decrypted")
526 ident, ok := e.Identities[identity]
528 return error_.InvalidArgumentError("given identity string not found in Entity")
531 sig := &packet.Signature{
532 SigType: packet.SigTypeGenericCert,
533 PubKeyAlgo: signer.PrivateKey.PubKeyAlgo,
535 CreationTime: time.Now(),
536 IssuerKeyId: &signer.PrivateKey.KeyId,
538 if err := sig.SignKey(e.PrimaryKey, signer.PrivateKey); err != nil {
541 ident.Signatures = append(ident.Signatures, sig)