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"
19 // PrivateKeyType is the armor type for a PGP private key.
20 var PrivateKeyType = "PGP PRIVATE KEY BLOCK"
22 // An Entity represents the components of an OpenPGP key: a primary public key
23 // (which must be a signing key), one or more identities claimed by that key,
24 // and zero or more subkeys, which may be encryption keys.
26 PrimaryKey *packet.PublicKey
27 PrivateKey *packet.PrivateKey
28 Identities map[string]*Identity // indexed by Identity.Name
32 // An Identity represents an identity claimed by an Entity and zero or more
33 // assertions by other entities about that claim.
34 type Identity struct {
35 Name string // by convention, has the form "Full Name (comment) <email@example.com>"
37 SelfSignature *packet.Signature
38 Signatures []*packet.Signature
41 // A Subkey is an additional public key in an Entity. Subkeys can be used for
44 PublicKey *packet.PublicKey
45 PrivateKey *packet.PrivateKey
49 // A Key identifies a specific public key in an Entity. This is either the
50 // Entity's primary key or a subkey.
53 PublicKey *packet.PublicKey
54 PrivateKey *packet.PrivateKey
55 SelfSignature *packet.Signature
58 // A KeyRing provides access to public and private keys.
59 type KeyRing interface {
60 // KeysById returns the set of keys that have the given key id.
61 KeysById(id uint64) []Key
62 // DecryptionKeys returns all private keys that are valid for
64 DecryptionKeys() []Key
67 // primaryIdentity returns the Identity marked as primary or the first identity
68 // if none are so marked.
69 func (e *Entity) primaryIdentity() *Identity {
70 var firstIdentity *Identity
71 for _, ident := range e.Identities {
72 if firstIdentity == nil {
75 if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
82 // encryptionKey returns the best candidate Key for encrypting a message to the
84 func (e *Entity) encryptionKey() Key {
87 for i, subkey := range e.Subkeys {
88 if subkey.Sig.FlagsValid && subkey.Sig.FlagEncryptCommunications && subkey.PublicKey.PubKeyAlgo.CanEncrypt() {
94 i := e.primaryIdentity()
96 if e.PrimaryKey.PubKeyAlgo.CanEncrypt() {
97 // If we don't have any candidate subkeys for encryption and
98 // the primary key doesn't have any usage metadata then we
99 // assume that the primary key is ok. Or, if the primary key is
100 // marked as ok to encrypt to, then we can obviously use it.
101 if candidateSubkey == -1 && !i.SelfSignature.FlagsValid || i.SelfSignature.FlagEncryptCommunications && i.SelfSignature.FlagsValid {
102 return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}
106 if candidateSubkey != -1 {
107 subkey := e.Subkeys[candidateSubkey]
108 return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}
111 // This Entity appears to be signing only.
115 // signingKey return the best candidate Key for signing a message with this
117 func (e *Entity) signingKey() Key {
118 candidateSubkey := -1
120 for i, subkey := range e.Subkeys {
121 if subkey.Sig.FlagsValid && subkey.Sig.FlagSign && subkey.PublicKey.PubKeyAlgo.CanSign() {
127 i := e.primaryIdentity()
129 // If we have no candidate subkey then we assume that it's ok to sign
130 // with the primary key.
131 if candidateSubkey == -1 || i.SelfSignature.FlagsValid && i.SelfSignature.FlagSign {
132 return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}
135 subkey := e.Subkeys[candidateSubkey]
136 return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}
139 // An EntityList contains one or more Entities.
140 type EntityList []*Entity
142 // KeysById returns the set of keys that have the given key id.
143 func (el EntityList) KeysById(id uint64) (keys []Key) {
144 for _, e := range el {
145 if e.PrimaryKey.KeyId == id {
146 var selfSig *packet.Signature
147 for _, ident := range e.Identities {
149 selfSig = ident.SelfSignature
150 } else if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
151 selfSig = ident.SelfSignature
155 keys = append(keys, Key{e, e.PrimaryKey, e.PrivateKey, selfSig})
158 for _, subKey := range e.Subkeys {
159 if subKey.PublicKey.KeyId == id {
160 keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig})
167 // DecryptionKeys returns all private keys that are valid for decryption.
168 func (el EntityList) DecryptionKeys() (keys []Key) {
169 for _, e := range el {
170 for _, subKey := range e.Subkeys {
171 if subKey.PrivateKey != nil && (!subKey.Sig.FlagsValid || subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications) {
172 keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig})
179 // ReadArmoredKeyRing reads one or more public/private keys from an armor keyring file.
180 func ReadArmoredKeyRing(r io.Reader) (EntityList, error) {
181 block, err := armor.Decode(r)
183 return nil, error_.InvalidArgumentError("no armored data found")
188 if block.Type != PublicKeyType && block.Type != PrivateKeyType {
189 return nil, error_.InvalidArgumentError("expected public or private key block, got: " + block.Type)
192 return ReadKeyRing(block.Body)
195 // ReadKeyRing reads one or more public/private keys. Unsupported keys are
196 // ignored as long as at least a single valid key is found.
197 func ReadKeyRing(r io.Reader) (el EntityList, err error) {
198 packets := packet.NewReader(r)
199 var lastUnsupportedError error
203 e, err = readEntity(packets)
205 if _, ok := err.(error_.UnsupportedError); ok {
206 lastUnsupportedError = err
207 err = readToNextPublicKey(packets)
222 if len(el) == 0 && err == nil {
223 err = lastUnsupportedError
228 // readToNextPublicKey reads packets until the start of the entity and leaves
229 // the first packet of the new entity in the Reader.
230 func readToNextPublicKey(packets *packet.Reader) (err error) {
233 p, err = packets.Next()
236 } else if err != nil {
237 if _, ok := err.(error_.UnsupportedError); ok {
244 if pk, ok := p.(*packet.PublicKey); ok && !pk.IsSubkey {
253 // readEntity reads an entity (public key, identities, subkeys etc) from the
255 func readEntity(packets *packet.Reader) (*Entity, error) {
257 e.Identities = make(map[string]*Identity)
259 p, err := packets.Next()
265 if e.PrimaryKey, ok = p.(*packet.PublicKey); !ok {
266 if e.PrivateKey, ok = p.(*packet.PrivateKey); !ok {
268 return nil, error_.StructuralError("first packet was not a public/private key")
270 e.PrimaryKey = &e.PrivateKey.PublicKey
274 if !e.PrimaryKey.PubKeyAlgo.CanSign() {
275 return nil, error_.StructuralError("primary key cannot be used for signatures")
278 var current *Identity
281 p, err := packets.Next()
284 } else if err != nil {
288 switch pkt := p.(type) {
290 current = new(Identity)
291 current.Name = pkt.Id
293 e.Identities[pkt.Id] = current
296 p, err = packets.Next()
298 return nil, io.ErrUnexpectedEOF
299 } else if err != nil {
303 sig, ok := p.(*packet.Signature)
305 return nil, error_.StructuralError("user ID packet not followed by self-signature")
308 if (sig.SigType == packet.SigTypePositiveCert || sig.SigType == packet.SigTypeGenericCert) && sig.IssuerKeyId != nil && *sig.IssuerKeyId == e.PrimaryKey.KeyId {
309 if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, sig); err != nil {
310 return nil, error_.StructuralError("user ID self-signature invalid: " + err.Error())
312 current.SelfSignature = sig
315 current.Signatures = append(current.Signatures, sig)
317 case *packet.Signature:
319 return nil, error_.StructuralError("signature packet found before user id packet")
321 current.Signatures = append(current.Signatures, pkt)
322 case *packet.PrivateKey:
323 if pkt.IsSubkey == false {
327 err = addSubkey(e, packets, &pkt.PublicKey, pkt)
331 case *packet.PublicKey:
332 if pkt.IsSubkey == false {
336 err = addSubkey(e, packets, pkt, nil)
341 // we ignore unknown packets
345 if len(e.Identities) == 0 {
346 return nil, error_.StructuralError("entity without any identities")
352 func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) error {
354 subKey.PublicKey = pub
355 subKey.PrivateKey = priv
356 p, err := packets.Next()
358 return io.ErrUnexpectedEOF
361 return error_.StructuralError("subkey signature invalid: " + err.Error())
364 subKey.Sig, ok = p.(*packet.Signature)
366 return error_.StructuralError("subkey packet not followed by signature")
368 if subKey.Sig.SigType != packet.SigTypeSubkeyBinding {
369 return error_.StructuralError("subkey signature with wrong type")
371 err = e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, subKey.Sig)
373 return error_.StructuralError("subkey signature invalid: " + err.Error())
375 e.Subkeys = append(e.Subkeys, subKey)
379 const defaultRSAKeyBits = 2048
381 // NewEntity returns an Entity that contains a fresh RSA/RSA keypair with a
382 // single identity composed of the given full name, comment and email, any of
383 // which may be empty but must not contain any of "()<>\x00".
384 func NewEntity(rand io.Reader, currentTime time.Time, name, comment, email string) (*Entity, error) {
385 uid := packet.NewUserId(name, comment, email)
387 return nil, error_.InvalidArgumentError("user id field contained invalid characters")
389 signingPriv, err := rsa.GenerateKey(rand, defaultRSAKeyBits)
393 encryptingPriv, err := rsa.GenerateKey(rand, defaultRSAKeyBits)
399 PrimaryKey: packet.NewRSAPublicKey(currentTime, &signingPriv.PublicKey, false /* not a subkey */ ),
400 PrivateKey: packet.NewRSAPrivateKey(currentTime, signingPriv, false /* not a subkey */ ),
401 Identities: make(map[string]*Identity),
404 e.Identities[uid.Id] = &Identity{
407 SelfSignature: &packet.Signature{
408 CreationTime: currentTime,
409 SigType: packet.SigTypePositiveCert,
410 PubKeyAlgo: packet.PubKeyAlgoRSA,
412 IsPrimaryId: &isPrimaryId,
416 IssuerKeyId: &e.PrimaryKey.KeyId,
420 e.Subkeys = make([]Subkey, 1)
421 e.Subkeys[0] = Subkey{
422 PublicKey: packet.NewRSAPublicKey(currentTime, &encryptingPriv.PublicKey, true /* is a subkey */ ),
423 PrivateKey: packet.NewRSAPrivateKey(currentTime, encryptingPriv, true /* is a subkey */ ),
424 Sig: &packet.Signature{
425 CreationTime: currentTime,
426 SigType: packet.SigTypeSubkeyBinding,
427 PubKeyAlgo: packet.PubKeyAlgoRSA,
430 FlagEncryptStorage: true,
431 FlagEncryptCommunications: true,
432 IssuerKeyId: &e.PrimaryKey.KeyId,
439 // SerializePrivate serializes an Entity, including private key material, to
440 // the given Writer. For now, it must only be used on an Entity returned from
442 func (e *Entity) SerializePrivate(w io.Writer) (err error) {
443 err = e.PrivateKey.Serialize(w)
447 for _, ident := range e.Identities {
448 err = ident.UserId.Serialize(w)
452 err = ident.SelfSignature.SignUserId(ident.UserId.Id, e.PrimaryKey, e.PrivateKey)
456 err = ident.SelfSignature.Serialize(w)
461 for _, subkey := range e.Subkeys {
462 err = subkey.PrivateKey.Serialize(w)
466 err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey)
470 err = subkey.Sig.Serialize(w)
478 // Serialize writes the public part of the given Entity to w. (No private
479 // key material will be output).
480 func (e *Entity) Serialize(w io.Writer) error {
481 err := e.PrimaryKey.Serialize(w)
485 for _, ident := range e.Identities {
486 err = ident.UserId.Serialize(w)
490 err = ident.SelfSignature.Serialize(w)
494 for _, sig := range ident.Signatures {
495 err = sig.Serialize(w)
501 for _, subkey := range e.Subkeys {
502 err = subkey.PublicKey.Serialize(w)
506 err = subkey.Sig.Serialize(w)
514 // SignIdentity adds a signature to e, from signer, attesting that identity is
515 // associated with e. The provided identity must already be an element of
516 // e.Identities and the private key of signer must have been decrypted if
518 func (e *Entity) SignIdentity(identity string, signer *Entity) error {
519 if signer.PrivateKey == nil {
520 return error_.InvalidArgumentError("signing Entity must have a private key")
522 if signer.PrivateKey.Encrypted {
523 return error_.InvalidArgumentError("signing Entity's private key must be decrypted")
525 ident, ok := e.Identities[identity]
527 return error_.InvalidArgumentError("given identity string not found in Entity")
530 sig := &packet.Signature{
531 SigType: packet.SigTypeGenericCert,
532 PubKeyAlgo: signer.PrivateKey.PubKeyAlgo,
534 CreationTime: time.Now(),
535 IssuerKeyId: &signer.PrivateKey.KeyId,
537 if err := sig.SignKey(e.PrimaryKey, signer.PrivateKey); err != nil {
540 ident.Signatures = append(ident.Signatures, sig)