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