main
Raw Download raw file
  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.
  4
  5package openpgp
  6
  7import (
  8	goerrors "errors"
  9	"fmt"
 10	"io"
 11	"time"
 12
 13	"github.com/ProtonMail/go-crypto/openpgp/armor"
 14	"github.com/ProtonMail/go-crypto/openpgp/errors"
 15	"github.com/ProtonMail/go-crypto/openpgp/packet"
 16)
 17
 18// PublicKeyType is the armor type for a PGP public key.
 19var PublicKeyType = "PGP PUBLIC KEY BLOCK"
 20
 21// PrivateKeyType is the armor type for a PGP private key.
 22var PrivateKeyType = "PGP PRIVATE KEY BLOCK"
 23
 24// An Entity represents the components of an OpenPGP key: a primary public key
 25// (which must be a signing key), one or more identities claimed by that key,
 26// and zero or more subkeys, which may be encryption keys.
 27type Entity struct {
 28	PrimaryKey    *packet.PublicKey
 29	PrivateKey    *packet.PrivateKey
 30	Identities    map[string]*Identity // indexed by Identity.Name
 31	Revocations   []*packet.Signature
 32	Subkeys       []Subkey
 33	SelfSignature *packet.Signature   // Direct-key self signature of the PrimaryKey (contains primary key properties in v6)
 34	Signatures    []*packet.Signature // all (potentially unverified) self-signatures, revocations, and third-party signatures
 35}
 36
 37// An Identity represents an identity claimed by an Entity and zero or more
 38// assertions by other entities about that claim.
 39type Identity struct {
 40	Name          string // by convention, has the form "Full Name (comment) <email@example.com>"
 41	UserId        *packet.UserId
 42	SelfSignature *packet.Signature
 43	Revocations   []*packet.Signature
 44	Signatures    []*packet.Signature // all (potentially unverified) self-signatures, revocations, and third-party signatures
 45}
 46
 47// A Subkey is an additional public key in an Entity. Subkeys can be used for
 48// encryption.
 49type Subkey struct {
 50	PublicKey   *packet.PublicKey
 51	PrivateKey  *packet.PrivateKey
 52	Sig         *packet.Signature
 53	Revocations []*packet.Signature
 54}
 55
 56// A Key identifies a specific public key in an Entity. This is either the
 57// Entity's primary key or a subkey.
 58type Key struct {
 59	Entity        *Entity
 60	PublicKey     *packet.PublicKey
 61	PrivateKey    *packet.PrivateKey
 62	SelfSignature *packet.Signature
 63	Revocations   []*packet.Signature
 64}
 65
 66// A KeyRing provides access to public and private keys.
 67type KeyRing interface {
 68	// KeysById returns the set of keys that have the given key id.
 69	KeysById(id uint64) []Key
 70	// KeysByIdAndUsage returns the set of keys with the given id
 71	// that also meet the key usage given by requiredUsage.
 72	// The requiredUsage is expressed as the bitwise-OR of
 73	// packet.KeyFlag* values.
 74	KeysByIdUsage(id uint64, requiredUsage byte) []Key
 75	// DecryptionKeys returns all private keys that are valid for
 76	// decryption.
 77	DecryptionKeys() []Key
 78}
 79
 80// PrimaryIdentity returns an Identity, preferring non-revoked identities,
 81// identities marked as primary, or the latest-created identity, in that order.
 82func (e *Entity) PrimaryIdentity() *Identity {
 83	var primaryIdentity *Identity
 84	for _, ident := range e.Identities {
 85		if shouldPreferIdentity(primaryIdentity, ident) {
 86			primaryIdentity = ident
 87		}
 88	}
 89	return primaryIdentity
 90}
 91
 92func shouldPreferIdentity(existingId, potentialNewId *Identity) bool {
 93	if existingId == nil {
 94		return true
 95	}
 96
 97	if len(existingId.Revocations) > len(potentialNewId.Revocations) {
 98		return true
 99	}
100
101	if len(existingId.Revocations) < len(potentialNewId.Revocations) {
102		return false
103	}
104
105	if existingId.SelfSignature == nil {
106		return true
107	}
108
109	if existingId.SelfSignature.IsPrimaryId != nil && *existingId.SelfSignature.IsPrimaryId &&
110		!(potentialNewId.SelfSignature.IsPrimaryId != nil && *potentialNewId.SelfSignature.IsPrimaryId) {
111		return false
112	}
113
114	if !(existingId.SelfSignature.IsPrimaryId != nil && *existingId.SelfSignature.IsPrimaryId) &&
115		potentialNewId.SelfSignature.IsPrimaryId != nil && *potentialNewId.SelfSignature.IsPrimaryId {
116		return true
117	}
118
119	return potentialNewId.SelfSignature.CreationTime.After(existingId.SelfSignature.CreationTime)
120}
121
122// EncryptionKey returns the best candidate Key for encrypting a message to the
123// given Entity.
124func (e *Entity) EncryptionKey(now time.Time) (Key, bool) {
125	// Fail to find any encryption key if the...
126	primarySelfSignature, primaryIdentity := e.PrimarySelfSignature()
127	if primarySelfSignature == nil || // no self-signature found
128		e.PrimaryKey.KeyExpired(primarySelfSignature, now) || // primary key has expired
129		e.Revoked(now) || // primary key has been revoked
130		primarySelfSignature.SigExpired(now) || // user ID or or direct self-signature has expired
131		(primaryIdentity != nil && primaryIdentity.Revoked(now)) { // user ID has been revoked (for v4 keys)
132		return Key{}, false
133	}
134
135	// Iterate the keys to find the newest, unexpired one
136	candidateSubkey := -1
137	var maxTime time.Time
138	for i, subkey := range e.Subkeys {
139		if subkey.Sig.FlagsValid &&
140			subkey.Sig.FlagEncryptCommunications &&
141			subkey.PublicKey.PubKeyAlgo.CanEncrypt() &&
142			!subkey.PublicKey.KeyExpired(subkey.Sig, now) &&
143			!subkey.Sig.SigExpired(now) &&
144			!subkey.Revoked(now) &&
145			(maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) {
146			candidateSubkey = i
147			maxTime = subkey.Sig.CreationTime
148		}
149	}
150
151	if candidateSubkey != -1 {
152		subkey := e.Subkeys[candidateSubkey]
153		return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig, subkey.Revocations}, true
154	}
155
156	// If we don't have any subkeys for encryption and the primary key
157	// is marked as OK to encrypt with, then we can use it.
158	if primarySelfSignature.FlagsValid && primarySelfSignature.FlagEncryptCommunications &&
159		e.PrimaryKey.PubKeyAlgo.CanEncrypt() {
160		return Key{e, e.PrimaryKey, e.PrivateKey, primarySelfSignature, e.Revocations}, true
161	}
162
163	return Key{}, false
164}
165
166// CertificationKey return the best candidate Key for certifying a key with this
167// Entity.
168func (e *Entity) CertificationKey(now time.Time) (Key, bool) {
169	return e.CertificationKeyById(now, 0)
170}
171
172// CertificationKeyById return the Key for key certification with this
173// Entity and keyID.
174func (e *Entity) CertificationKeyById(now time.Time, id uint64) (Key, bool) {
175	return e.signingKeyByIdUsage(now, id, packet.KeyFlagCertify)
176}
177
178// SigningKey return the best candidate Key for signing a message with this
179// Entity.
180func (e *Entity) SigningKey(now time.Time) (Key, bool) {
181	return e.SigningKeyById(now, 0)
182}
183
184// SigningKeyById return the Key for signing a message with this
185// Entity and keyID.
186func (e *Entity) SigningKeyById(now time.Time, id uint64) (Key, bool) {
187	return e.signingKeyByIdUsage(now, id, packet.KeyFlagSign)
188}
189
190func (e *Entity) signingKeyByIdUsage(now time.Time, id uint64, flags int) (Key, bool) {
191	// Fail to find any signing key if the...
192	primarySelfSignature, primaryIdentity := e.PrimarySelfSignature()
193	if primarySelfSignature == nil || // no self-signature found
194		e.PrimaryKey.KeyExpired(primarySelfSignature, now) || // primary key has expired
195		e.Revoked(now) || // primary key has been revoked
196		primarySelfSignature.SigExpired(now) || // user ID or direct self-signature has expired
197		(primaryIdentity != nil && primaryIdentity.Revoked(now)) { // user ID has been revoked (for v4 keys)
198		return Key{}, false
199	}
200
201	// Iterate the keys to find the newest, unexpired one
202	candidateSubkey := -1
203	var maxTime time.Time
204	for idx, subkey := range e.Subkeys {
205		if subkey.Sig.FlagsValid &&
206			(flags&packet.KeyFlagCertify == 0 || subkey.Sig.FlagCertify) &&
207			(flags&packet.KeyFlagSign == 0 || subkey.Sig.FlagSign) &&
208			subkey.PublicKey.PubKeyAlgo.CanSign() &&
209			!subkey.PublicKey.KeyExpired(subkey.Sig, now) &&
210			!subkey.Sig.SigExpired(now) &&
211			!subkey.Revoked(now) &&
212			(maxTime.IsZero() || subkey.Sig.CreationTime.After(maxTime)) &&
213			(id == 0 || subkey.PublicKey.KeyId == id) {
214			candidateSubkey = idx
215			maxTime = subkey.Sig.CreationTime
216		}
217	}
218
219	if candidateSubkey != -1 {
220		subkey := e.Subkeys[candidateSubkey]
221		return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig, subkey.Revocations}, true
222	}
223
224	// If we don't have any subkeys for signing and the primary key
225	// is marked as OK to sign with, then we can use it.
226	if primarySelfSignature.FlagsValid &&
227		(flags&packet.KeyFlagCertify == 0 || primarySelfSignature.FlagCertify) &&
228		(flags&packet.KeyFlagSign == 0 || primarySelfSignature.FlagSign) &&
229		e.PrimaryKey.PubKeyAlgo.CanSign() &&
230		(id == 0 || e.PrimaryKey.KeyId == id) {
231		return Key{e, e.PrimaryKey, e.PrivateKey, primarySelfSignature, e.Revocations}, true
232	}
233
234	// No keys with a valid Signing Flag or no keys matched the id passed in
235	return Key{}, false
236}
237
238func revoked(revocations []*packet.Signature, now time.Time) bool {
239	for _, revocation := range revocations {
240		if revocation.RevocationReason != nil && *revocation.RevocationReason == packet.KeyCompromised {
241			// If the key is compromised, the key is considered revoked even before the revocation date.
242			return true
243		}
244		if !revocation.SigExpired(now) {
245			return true
246		}
247	}
248	return false
249}
250
251// Revoked returns whether the entity has any direct key revocation signatures.
252// Note that third-party revocation signatures are not supported.
253// Note also that Identity and Subkey revocation should be checked separately.
254func (e *Entity) Revoked(now time.Time) bool {
255	return revoked(e.Revocations, now)
256}
257
258// EncryptPrivateKeys encrypts all non-encrypted keys in the entity with the same key
259// derived from the provided passphrase. Public keys and dummy keys are ignored,
260// and don't cause an error to be returned.
261func (e *Entity) EncryptPrivateKeys(passphrase []byte, config *packet.Config) error {
262	var keysToEncrypt []*packet.PrivateKey
263	// Add entity private key to encrypt.
264	if e.PrivateKey != nil && !e.PrivateKey.Dummy() && !e.PrivateKey.Encrypted {
265		keysToEncrypt = append(keysToEncrypt, e.PrivateKey)
266	}
267
268	// Add subkeys to encrypt.
269	for _, sub := range e.Subkeys {
270		if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() && !sub.PrivateKey.Encrypted {
271			keysToEncrypt = append(keysToEncrypt, sub.PrivateKey)
272		}
273	}
274	return packet.EncryptPrivateKeys(keysToEncrypt, passphrase, config)
275}
276
277// DecryptPrivateKeys decrypts all encrypted keys in the entity with the given passphrase.
278// Avoids recomputation of similar s2k key derivations. Public keys and dummy keys are ignored,
279// and don't cause an error to be returned.
280func (e *Entity) DecryptPrivateKeys(passphrase []byte) error {
281	var keysToDecrypt []*packet.PrivateKey
282	// Add entity private key to decrypt.
283	if e.PrivateKey != nil && !e.PrivateKey.Dummy() && e.PrivateKey.Encrypted {
284		keysToDecrypt = append(keysToDecrypt, e.PrivateKey)
285	}
286
287	// Add subkeys to decrypt.
288	for _, sub := range e.Subkeys {
289		if sub.PrivateKey != nil && !sub.PrivateKey.Dummy() && sub.PrivateKey.Encrypted {
290			keysToDecrypt = append(keysToDecrypt, sub.PrivateKey)
291		}
292	}
293	return packet.DecryptPrivateKeys(keysToDecrypt, passphrase)
294}
295
296// Revoked returns whether the identity has been revoked by a self-signature.
297// Note that third-party revocation signatures are not supported.
298func (i *Identity) Revoked(now time.Time) bool {
299	return revoked(i.Revocations, now)
300}
301
302// Revoked returns whether the subkey has been revoked by a self-signature.
303// Note that third-party revocation signatures are not supported.
304func (s *Subkey) Revoked(now time.Time) bool {
305	return revoked(s.Revocations, now)
306}
307
308// Revoked returns whether the key or subkey has been revoked by a self-signature.
309// Note that third-party revocation signatures are not supported.
310// Note also that Identity revocation should be checked separately.
311// Normally, it's not necessary to call this function, except on keys returned by
312// KeysById or KeysByIdUsage.
313func (key *Key) Revoked(now time.Time) bool {
314	return revoked(key.Revocations, now)
315}
316
317// An EntityList contains one or more Entities.
318type EntityList []*Entity
319
320// KeysById returns the set of keys that have the given key id.
321func (el EntityList) KeysById(id uint64) (keys []Key) {
322	for _, e := range el {
323		if e.PrimaryKey.KeyId == id {
324			selfSig, _ := e.PrimarySelfSignature()
325			keys = append(keys, Key{e, e.PrimaryKey, e.PrivateKey, selfSig, e.Revocations})
326		}
327
328		for _, subKey := range e.Subkeys {
329			if subKey.PublicKey.KeyId == id {
330				keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig, subKey.Revocations})
331			}
332		}
333	}
334	return
335}
336
337// KeysByIdAndUsage returns the set of keys with the given id that also meet
338// the key usage given by requiredUsage.  The requiredUsage is expressed as
339// the bitwise-OR of packet.KeyFlag* values.
340func (el EntityList) KeysByIdUsage(id uint64, requiredUsage byte) (keys []Key) {
341	for _, key := range el.KeysById(id) {
342		if requiredUsage != 0 {
343			if key.SelfSignature == nil || !key.SelfSignature.FlagsValid {
344				continue
345			}
346
347			var usage byte
348			if key.SelfSignature.FlagCertify {
349				usage |= packet.KeyFlagCertify
350			}
351			if key.SelfSignature.FlagSign {
352				usage |= packet.KeyFlagSign
353			}
354			if key.SelfSignature.FlagEncryptCommunications {
355				usage |= packet.KeyFlagEncryptCommunications
356			}
357			if key.SelfSignature.FlagEncryptStorage {
358				usage |= packet.KeyFlagEncryptStorage
359			}
360			if usage&requiredUsage != requiredUsage {
361				continue
362			}
363		}
364
365		keys = append(keys, key)
366	}
367	return
368}
369
370// DecryptionKeys returns all private keys that are valid for decryption.
371func (el EntityList) DecryptionKeys() (keys []Key) {
372	for _, e := range el {
373		for _, subKey := range e.Subkeys {
374			if subKey.PrivateKey != nil && subKey.Sig.FlagsValid && (subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications) {
375				keys = append(keys, Key{e, subKey.PublicKey, subKey.PrivateKey, subKey.Sig, subKey.Revocations})
376			}
377		}
378	}
379	return
380}
381
382// ReadArmoredKeyRing reads one or more public/private keys from an armor keyring file.
383func ReadArmoredKeyRing(r io.Reader) (EntityList, error) {
384	block, err := armor.Decode(r)
385	if err == io.EOF {
386		return nil, errors.InvalidArgumentError("no armored data found")
387	}
388	if err != nil {
389		return nil, err
390	}
391	if block.Type != PublicKeyType && block.Type != PrivateKeyType {
392		return nil, errors.InvalidArgumentError("expected public or private key block, got: " + block.Type)
393	}
394
395	return ReadKeyRing(block.Body)
396}
397
398// ReadKeyRing reads one or more public/private keys. Unsupported keys are
399// ignored as long as at least a single valid key is found.
400func ReadKeyRing(r io.Reader) (el EntityList, err error) {
401	packets := packet.NewReader(r)
402	var lastUnsupportedError error
403
404	for {
405		var e *Entity
406		e, err = ReadEntity(packets)
407		if err != nil {
408			// TODO: warn about skipped unsupported/unreadable keys
409			if _, ok := err.(errors.UnsupportedError); ok {
410				lastUnsupportedError = err
411				err = readToNextPublicKey(packets)
412			} else if _, ok := err.(errors.StructuralError); ok {
413				// Skip unreadable, badly-formatted keys
414				lastUnsupportedError = err
415				err = readToNextPublicKey(packets)
416			}
417			if err == io.EOF {
418				err = nil
419				break
420			}
421			if err != nil {
422				el = nil
423				break
424			}
425		} else {
426			el = append(el, e)
427		}
428	}
429
430	if len(el) == 0 && err == nil {
431		err = lastUnsupportedError
432	}
433	return
434}
435
436// readToNextPublicKey reads packets until the start of the entity and leaves
437// the first packet of the new entity in the Reader.
438func readToNextPublicKey(packets *packet.Reader) (err error) {
439	var p packet.Packet
440	for {
441		p, err = packets.Next()
442		if err == io.EOF {
443			return
444		} else if err != nil {
445			if _, ok := err.(errors.UnsupportedError); ok {
446				continue
447			}
448			return
449		}
450
451		if pk, ok := p.(*packet.PublicKey); ok && !pk.IsSubkey {
452			packets.Unread(p)
453			return
454		}
455	}
456}
457
458// ReadEntity reads an entity (public key, identities, subkeys etc) from the
459// given Reader.
460func ReadEntity(packets *packet.Reader) (*Entity, error) {
461	e := new(Entity)
462	e.Identities = make(map[string]*Identity)
463
464	p, err := packets.Next()
465	if err != nil {
466		return nil, err
467	}
468
469	var ok bool
470	if e.PrimaryKey, ok = p.(*packet.PublicKey); !ok {
471		if e.PrivateKey, ok = p.(*packet.PrivateKey); !ok {
472			packets.Unread(p)
473			return nil, errors.StructuralError("first packet was not a public/private key")
474		}
475		e.PrimaryKey = &e.PrivateKey.PublicKey
476	}
477
478	if !e.PrimaryKey.PubKeyAlgo.CanSign() {
479		return nil, errors.StructuralError("primary key cannot be used for signatures")
480	}
481
482	var revocations []*packet.Signature
483	var directSignatures []*packet.Signature
484EachPacket:
485	for {
486		p, err := packets.Next()
487		if err == io.EOF {
488			break
489		} else if err != nil {
490			return nil, err
491		}
492
493		switch pkt := p.(type) {
494		case *packet.UserId:
495			if err := addUserID(e, packets, pkt); err != nil {
496				return nil, err
497			}
498		case *packet.Signature:
499			if pkt.SigType == packet.SigTypeKeyRevocation {
500				revocations = append(revocations, pkt)
501			} else if pkt.SigType == packet.SigTypeDirectSignature {
502				directSignatures = append(directSignatures, pkt)
503			}
504			// Else, ignoring the signature as it does not follow anything
505			// we would know to attach it to.
506		case *packet.PrivateKey:
507			if !pkt.IsSubkey {
508				packets.Unread(p)
509				break EachPacket
510			}
511			err = addSubkey(e, packets, &pkt.PublicKey, pkt)
512			if err != nil {
513				return nil, err
514			}
515		case *packet.PublicKey:
516			if !pkt.IsSubkey {
517				packets.Unread(p)
518				break EachPacket
519			}
520			err = addSubkey(e, packets, pkt, nil)
521			if err != nil {
522				return nil, err
523			}
524		default:
525			// we ignore unknown packets.
526		}
527	}
528
529	if len(e.Identities) == 0 && e.PrimaryKey.Version < 6 {
530		return nil, errors.StructuralError(fmt.Sprintf("v%d entity without any identities", e.PrimaryKey.Version))
531	}
532
533	// An implementation MUST ensure that a valid direct-key signature is present before using a v6 key.
534	if e.PrimaryKey.Version == 6 {
535		if len(directSignatures) == 0 {
536			return nil, errors.StructuralError("v6 entity without a valid direct-key signature")
537		}
538		// Select main direct key signature.
539		var mainDirectKeySelfSignature *packet.Signature
540		for _, directSignature := range directSignatures {
541			if directSignature.SigType == packet.SigTypeDirectSignature &&
542				directSignature.CheckKeyIdOrFingerprint(e.PrimaryKey) &&
543				(mainDirectKeySelfSignature == nil ||
544					directSignature.CreationTime.After(mainDirectKeySelfSignature.CreationTime)) {
545				mainDirectKeySelfSignature = directSignature
546			}
547		}
548		if mainDirectKeySelfSignature == nil {
549			return nil, errors.StructuralError("no valid direct-key self-signature for v6 primary key found")
550		}
551		// Check that the main self-signature is valid.
552		err = e.PrimaryKey.VerifyDirectKeySignature(mainDirectKeySelfSignature)
553		if err != nil {
554			return nil, errors.StructuralError("invalid direct-key self-signature for v6 primary key")
555		}
556		e.SelfSignature = mainDirectKeySelfSignature
557		e.Signatures = directSignatures
558	}
559
560	for _, revocation := range revocations {
561		err = e.PrimaryKey.VerifyRevocationSignature(revocation)
562		if err == nil {
563			e.Revocations = append(e.Revocations, revocation)
564		} else {
565			// TODO: RFC 4880 5.2.3.15 defines revocation keys.
566			return nil, errors.StructuralError("revocation signature signed by alternate key")
567		}
568	}
569
570	return e, nil
571}
572
573func addUserID(e *Entity, packets *packet.Reader, pkt *packet.UserId) error {
574	// Make a new Identity object, that we might wind up throwing away.
575	// We'll only add it if we get a valid self-signature over this
576	// userID.
577	identity := new(Identity)
578	identity.Name = pkt.Id
579	identity.UserId = pkt
580
581	for {
582		p, err := packets.Next()
583		if err == io.EOF {
584			break
585		} else if err != nil {
586			return err
587		}
588
589		sig, ok := p.(*packet.Signature)
590		if !ok {
591			packets.Unread(p)
592			break
593		}
594
595		if sig.SigType != packet.SigTypeGenericCert &&
596			sig.SigType != packet.SigTypePersonaCert &&
597			sig.SigType != packet.SigTypeCasualCert &&
598			sig.SigType != packet.SigTypePositiveCert &&
599			sig.SigType != packet.SigTypeCertificationRevocation {
600			return errors.StructuralError("user ID signature with wrong type")
601		}
602
603		if sig.CheckKeyIdOrFingerprint(e.PrimaryKey) {
604			if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, e.PrimaryKey, sig); err != nil {
605				return errors.StructuralError("user ID self-signature invalid: " + err.Error())
606			}
607			if sig.SigType == packet.SigTypeCertificationRevocation {
608				identity.Revocations = append(identity.Revocations, sig)
609			} else if identity.SelfSignature == nil || sig.CreationTime.After(identity.SelfSignature.CreationTime) {
610				identity.SelfSignature = sig
611			}
612			identity.Signatures = append(identity.Signatures, sig)
613			e.Identities[pkt.Id] = identity
614		} else {
615			identity.Signatures = append(identity.Signatures, sig)
616		}
617	}
618
619	return nil
620}
621
622func addSubkey(e *Entity, packets *packet.Reader, pub *packet.PublicKey, priv *packet.PrivateKey) error {
623	var subKey Subkey
624	subKey.PublicKey = pub
625	subKey.PrivateKey = priv
626
627	for {
628		p, err := packets.Next()
629		if err == io.EOF {
630			break
631		} else if err != nil {
632			return errors.StructuralError("subkey signature invalid: " + err.Error())
633		}
634
635		sig, ok := p.(*packet.Signature)
636		if !ok {
637			packets.Unread(p)
638			break
639		}
640
641		if sig.SigType != packet.SigTypeSubkeyBinding && sig.SigType != packet.SigTypeSubkeyRevocation {
642			return errors.StructuralError("subkey signature with wrong type")
643		}
644
645		if err := e.PrimaryKey.VerifyKeySignature(subKey.PublicKey, sig); err != nil {
646			return errors.StructuralError("subkey signature invalid: " + err.Error())
647		}
648
649		switch sig.SigType {
650		case packet.SigTypeSubkeyRevocation:
651			subKey.Revocations = append(subKey.Revocations, sig)
652		case packet.SigTypeSubkeyBinding:
653			if subKey.Sig == nil || sig.CreationTime.After(subKey.Sig.CreationTime) {
654				subKey.Sig = sig
655			}
656		}
657	}
658
659	if subKey.Sig == nil {
660		return errors.StructuralError("subkey packet not followed by signature")
661	}
662
663	e.Subkeys = append(e.Subkeys, subKey)
664
665	return nil
666}
667
668// SerializePrivate serializes an Entity, including private key material, but
669// excluding signatures from other entities, to the given Writer.
670// Identities and subkeys are re-signed in case they changed since NewEntry.
671// If config is nil, sensible defaults will be used.
672func (e *Entity) SerializePrivate(w io.Writer, config *packet.Config) (err error) {
673	if e.PrivateKey.Dummy() {
674		return errors.ErrDummyPrivateKey("dummy private key cannot re-sign identities")
675	}
676	return e.serializePrivate(w, config, true)
677}
678
679// SerializePrivateWithoutSigning serializes an Entity, including private key
680// material, but excluding signatures from other entities, to the given Writer.
681// Self-signatures of identities and subkeys are not re-signed. This is useful
682// when serializing GNU dummy keys, among other things.
683// If config is nil, sensible defaults will be used.
684func (e *Entity) SerializePrivateWithoutSigning(w io.Writer, config *packet.Config) (err error) {
685	return e.serializePrivate(w, config, false)
686}
687
688func (e *Entity) serializePrivate(w io.Writer, config *packet.Config, reSign bool) (err error) {
689	if e.PrivateKey == nil {
690		return goerrors.New("openpgp: private key is missing")
691	}
692	err = e.PrivateKey.Serialize(w)
693	if err != nil {
694		return
695	}
696	for _, revocation := range e.Revocations {
697		err := revocation.Serialize(w)
698		if err != nil {
699			return err
700		}
701	}
702	for _, directSignature := range e.Signatures {
703		err := directSignature.Serialize(w)
704		if err != nil {
705			return err
706		}
707	}
708	for _, ident := range e.Identities {
709		err = ident.UserId.Serialize(w)
710		if err != nil {
711			return
712		}
713		if reSign {
714			if ident.SelfSignature == nil {
715				return goerrors.New("openpgp: can't re-sign identity without valid self-signature")
716			}
717			err = ident.SelfSignature.SignUserId(ident.UserId.Id, e.PrimaryKey, e.PrivateKey, config)
718			if err != nil {
719				return
720			}
721		}
722		for _, sig := range ident.Signatures {
723			err = sig.Serialize(w)
724			if err != nil {
725				return err
726			}
727		}
728	}
729	for _, subkey := range e.Subkeys {
730		err = subkey.PrivateKey.Serialize(w)
731		if err != nil {
732			return
733		}
734		if reSign {
735			err = subkey.Sig.SignKey(subkey.PublicKey, e.PrivateKey, config)
736			if err != nil {
737				return
738			}
739			if subkey.Sig.EmbeddedSignature != nil {
740				err = subkey.Sig.EmbeddedSignature.CrossSignKey(subkey.PublicKey, e.PrimaryKey,
741					subkey.PrivateKey, config)
742				if err != nil {
743					return
744				}
745			}
746		}
747		for _, revocation := range subkey.Revocations {
748			err := revocation.Serialize(w)
749			if err != nil {
750				return err
751			}
752		}
753		err = subkey.Sig.Serialize(w)
754		if err != nil {
755			return
756		}
757	}
758	return nil
759}
760
761// Serialize writes the public part of the given Entity to w, including
762// signatures from other entities. No private key material will be output.
763func (e *Entity) Serialize(w io.Writer) error {
764	err := e.PrimaryKey.Serialize(w)
765	if err != nil {
766		return err
767	}
768	for _, revocation := range e.Revocations {
769		err := revocation.Serialize(w)
770		if err != nil {
771			return err
772		}
773	}
774	for _, directSignature := range e.Signatures {
775		err := directSignature.Serialize(w)
776		if err != nil {
777			return err
778		}
779	}
780	for _, ident := range e.Identities {
781		err = ident.UserId.Serialize(w)
782		if err != nil {
783			return err
784		}
785		for _, sig := range ident.Signatures {
786			err = sig.Serialize(w)
787			if err != nil {
788				return err
789			}
790		}
791	}
792	for _, subkey := range e.Subkeys {
793		err = subkey.PublicKey.Serialize(w)
794		if err != nil {
795			return err
796		}
797		for _, revocation := range subkey.Revocations {
798			err := revocation.Serialize(w)
799			if err != nil {
800				return err
801			}
802		}
803		err = subkey.Sig.Serialize(w)
804		if err != nil {
805			return err
806		}
807	}
808	return nil
809}
810
811// SignIdentity adds a signature to e, from signer, attesting that identity is
812// associated with e. The provided identity must already be an element of
813// e.Identities and the private key of signer must have been decrypted if
814// necessary.
815// If config is nil, sensible defaults will be used.
816func (e *Entity) SignIdentity(identity string, signer *Entity, config *packet.Config) error {
817	certificationKey, ok := signer.CertificationKey(config.Now())
818	if !ok {
819		return errors.InvalidArgumentError("no valid certification key found")
820	}
821
822	if certificationKey.PrivateKey.Encrypted {
823		return errors.InvalidArgumentError("signing Entity's private key must be decrypted")
824	}
825
826	ident, ok := e.Identities[identity]
827	if !ok {
828		return errors.InvalidArgumentError("given identity string not found in Entity")
829	}
830
831	sig := createSignaturePacket(certificationKey.PublicKey, packet.SigTypeGenericCert, config)
832
833	signingUserID := config.SigningUserId()
834	if signingUserID != "" {
835		if _, ok := signer.Identities[signingUserID]; !ok {
836			return errors.InvalidArgumentError("signer identity string not found in signer Entity")
837		}
838		sig.SignerUserId = &signingUserID
839	}
840
841	if err := sig.SignUserId(identity, e.PrimaryKey, certificationKey.PrivateKey, config); err != nil {
842		return err
843	}
844	ident.Signatures = append(ident.Signatures, sig)
845	return nil
846}
847
848// RevokeKey generates a key revocation signature (packet.SigTypeKeyRevocation) with the
849// specified reason code and text (RFC4880 section-5.2.3.23).
850// If config is nil, sensible defaults will be used.
851func (e *Entity) RevokeKey(reason packet.ReasonForRevocation, reasonText string, config *packet.Config) error {
852	revSig := createSignaturePacket(e.PrimaryKey, packet.SigTypeKeyRevocation, config)
853	revSig.RevocationReason = &reason
854	revSig.RevocationReasonText = reasonText
855
856	if err := revSig.RevokeKey(e.PrimaryKey, e.PrivateKey, config); err != nil {
857		return err
858	}
859	e.Revocations = append(e.Revocations, revSig)
860	return nil
861}
862
863// RevokeSubkey generates a subkey revocation signature (packet.SigTypeSubkeyRevocation) for
864// a subkey with the specified reason code and text (RFC4880 section-5.2.3.23).
865// If config is nil, sensible defaults will be used.
866func (e *Entity) RevokeSubkey(sk *Subkey, reason packet.ReasonForRevocation, reasonText string, config *packet.Config) error {
867	if err := e.PrimaryKey.VerifyKeySignature(sk.PublicKey, sk.Sig); err != nil {
868		return errors.InvalidArgumentError("given subkey is not associated with this key")
869	}
870
871	revSig := createSignaturePacket(e.PrimaryKey, packet.SigTypeSubkeyRevocation, config)
872	revSig.RevocationReason = &reason
873	revSig.RevocationReasonText = reasonText
874
875	if err := revSig.RevokeSubkey(sk.PublicKey, e.PrivateKey, config); err != nil {
876		return err
877	}
878
879	sk.Revocations = append(sk.Revocations, revSig)
880	return nil
881}
882
883func (e *Entity) primaryDirectSignature() *packet.Signature {
884	return e.SelfSignature
885}
886
887// PrimarySelfSignature searches the entity for the self-signature that stores key preferences.
888// For V4 keys, returns the self-signature of the primary identity, and the identity.
889// For V6 keys, returns the latest valid direct-key self-signature, and no identity (nil).
890// This self-signature is to be used to check the key expiration,
891// algorithm preferences, and so on.
892func (e *Entity) PrimarySelfSignature() (*packet.Signature, *Identity) {
893	if e.PrimaryKey.Version == 6 {
894		return e.primaryDirectSignature(), nil
895	}
896	primaryIdentity := e.PrimaryIdentity()
897	if primaryIdentity == nil {
898		return nil, nil
899	}
900	return primaryIdentity.SelfSignature, primaryIdentity
901}