5
5
package packet
6
6
7
7
import (
8
- "math/big"
9
8
"bytes"
10
9
"crypto"
11
10
"crypto/dsa"
12
11
"encoding/asn1"
13
12
"encoding/binary"
14
13
"hash"
15
14
"io"
15
+ "math/big"
16
16
"strconv"
17
17
"time"
18
18
@@ -26,7 +26,8 @@ import (
26
26
)
27
27
28
28
const (
29
- // See RFC 4880, section 5.2.3.21 for details.
29
+ // First octet of key flags.
30
+ // See RFC 9580, section 5.2.3.29 for details.
30
31
KeyFlagCertify = 1 << iota
31
32
KeyFlagSign
32
33
KeyFlagEncryptCommunications
@@ -37,16 +38,29 @@ const (
37
38
KeyFlagGroupKey
38
39
)
39
40
41
+ const (
42
+ // First octet of keyserver preference flags.
43
+ // See RFC 9580, section 5.2.3.25 for details.
44
+ _ = 1 << iota
45
+ _
46
+ _
47
+ _
48
+ _
49
+ _
50
+ _
51
+ KeyserverPrefNoModify
52
+ )
53
+
40
54
const SaltNotationName = "[email protected] "
41
55
42
- // Signature represents a signature. See RFC 4880 , section 5.2.
56
+ // Signature represents a signature. See RFC 9580 , section 5.2.
43
57
type Signature struct {
44
58
Version int
45
59
SigType SignatureType
46
60
PubKeyAlgo PublicKeyAlgorithm
47
61
Hash crypto.Hash
48
62
// salt contains a random salt value for v6 signatures
49
- // See RFC the crypto refresh Section 5.2.3 .
63
+ // See RFC 9580 Section 5.2.4 .
50
64
salt []byte
51
65
52
66
// HashSuffix is extra data that is hashed in after the signed data.
@@ -87,27 +101,37 @@ type Signature struct {
87
101
// TrustLevel and TrustAmount can be set by the signer to assert that
88
102
// the key is not only valid but also trustworthy at the specified
89
103
// level.
90
- // See RFC 4880 , section 5.2.3.13 for details.
104
+ // See RFC 9580 , section 5.2.3.21 for details.
91
105
TrustLevel TrustLevel
92
106
TrustAmount TrustAmount
93
107
94
108
// TrustRegularExpression can be used in conjunction with trust Signature
95
109
// packets to limit the scope of the trust that is extended.
96
- // See RFC 4880 , section 5.2.3.14 for details.
110
+ // See RFC 9580 , section 5.2.3.22 for details.
97
111
TrustRegularExpression * string
98
112
113
+ // KeyserverPrefsValid is set if any keyserver preferences were given. See RFC 9580, section
114
+ // 5.2.3.25 for details.
115
+ KeyserverPrefsValid bool
116
+ KeyserverPrefNoModify bool
117
+
118
+ // PreferredKeyserver can be set to a URI where the latest version of the
119
+ // key that this signature is made over can be found. See RFC 9580, section
120
+ // 5.2.3.26 for details.
121
+ PreferredKeyserver string
122
+
99
123
// PolicyURI can be set to the URI of a document that describes the
100
- // policy under which the signature was issued. See RFC 4880 , section
101
- // 5.2.3.20 for details.
124
+ // policy under which the signature was issued. See RFC 9580 , section
125
+ // 5.2.3.28 for details.
102
126
PolicyURI string
103
127
104
- // FlagsValid is set if any flags were given. See RFC 4880 , section
105
- // 5.2.3.21 for details.
128
+ // FlagsValid is set if any flags were given. See RFC 9580 , section
129
+ // 5.2.3.29 for details.
106
130
FlagsValid bool
107
131
FlagCertify , FlagSign , FlagEncryptCommunications , FlagEncryptStorage , FlagSplitKey , FlagAuthenticate , FlagGroupKey bool
108
132
109
133
// RevocationReason is set if this signature has been revoked.
110
- // See RFC 4880 , section 5.2.3.23 for details.
134
+ // See RFC 9580 , section 5.2.3.31 for details.
111
135
RevocationReason * ReasonForRevocation
112
136
RevocationReasonText string
113
137
@@ -147,7 +171,7 @@ func (sig *Signature) Salt() []byte {
147
171
}
148
172
149
173
func (sig * Signature ) parse (r io.Reader ) (err error ) {
150
- // RFC 4880 , section 5.2.3
174
+ // RFC 9580 , section 5.2.3
151
175
var buf [7 ]byte
152
176
_ , err = readFull (r , buf [:1 ])
153
177
if err != nil {
@@ -319,7 +343,7 @@ func (sig *Signature) parse(r io.Reader) (err error) {
319
343
}
320
344
321
345
// parseSignatureSubpackets parses subpackets of the main signature packet. See
322
- // RFC 4880 , section 5.2.3.1.
346
+ // RFC 9580 , section 5.2.3.1.
323
347
func parseSignatureSubpackets (sig * Signature , subpackets []byte , isHashed bool ) (err error ) {
324
348
for len (subpackets ) > 0 {
325
349
subpackets , err = parseSignatureSubpacket (sig , subpackets , isHashed )
@@ -349,6 +373,8 @@ const (
349
373
notationDataSubpacket signatureSubpacketType = 20
350
374
prefHashAlgosSubpacket signatureSubpacketType = 21
351
375
prefCompressionSubpacket signatureSubpacketType = 22
376
+ keyserverPrefsSubpacket signatureSubpacketType = 23
377
+ prefKeyserverSubpacket signatureSubpacketType = 24
352
378
primaryUserIdSubpacket signatureSubpacketType = 25
353
379
policyUriSubpacket signatureSubpacketType = 26
354
380
keyFlagsSubpacket signatureSubpacketType = 27
@@ -363,7 +389,7 @@ const (
363
389
364
390
// parseSignatureSubpacket parses a single subpacket. len(subpacket) is >= 1.
365
391
func parseSignatureSubpacket (sig * Signature , subpacket []byte , isHashed bool ) (rest []byte , err error ) {
366
- // RFC 4880 , section 5.2.3.1
392
+ // RFC 9580 , section 5.2.3.7
367
393
var (
368
394
length uint32
369
395
packetType signatureSubpacketType
@@ -421,7 +447,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
421
447
t := binary .BigEndian .Uint32 (subpacket )
422
448
sig .CreationTime = time .Unix (int64 (t ), 0 )
423
449
case signatureExpirationSubpacket :
424
- // Signature expiration time, section 5.2.3.10
450
+ // Signature expiration time, section 5.2.3.18
425
451
if len (subpacket ) != 4 {
426
452
err = errors .StructuralError ("expiration subpacket with bad length" )
427
453
return
@@ -438,15 +464,15 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
438
464
err = errors .StructuralError ("trust subpacket with bad length" )
439
465
return
440
466
}
441
- // Trust level and amount, section 5.2.3.13
467
+ // Trust level and amount, section 5.2.3.21
442
468
sig .TrustLevel = TrustLevel (subpacket [0 ])
443
469
sig .TrustAmount = TrustAmount (subpacket [1 ])
444
470
case regularExpressionSubpacket :
445
471
if len (subpacket ) == 0 {
446
472
err = errors .StructuralError ("regexp subpacket with bad length" )
447
473
return
448
474
}
449
- // Trust regular expression, section 5.2.3.14
475
+ // Trust regular expression, section 5.2.3.22
450
476
// RFC specifies the string should be null-terminated; remove a null byte from the end
451
477
if subpacket [len (subpacket )- 1 ] != 0x00 {
452
478
err = errors .StructuralError ("expected regular expression to be null-terminated" )
@@ -455,19 +481,19 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
455
481
trustRegularExpression := string (subpacket [:len (subpacket )- 1 ])
456
482
sig .TrustRegularExpression = & trustRegularExpression
457
483
case keyExpirationSubpacket :
458
- // Key expiration time, section 5.2.3.6
484
+ // Key expiration time, section 5.2.3.13
459
485
if len (subpacket ) != 4 {
460
486
err = errors .StructuralError ("key expiration subpacket with bad length" )
461
487
return
462
488
}
463
489
sig .KeyLifetimeSecs = new (uint32 )
464
490
* sig .KeyLifetimeSecs = binary .BigEndian .Uint32 (subpacket )
465
491
case prefSymmetricAlgosSubpacket :
466
- // Preferred symmetric algorithms, section 5.2.3.7
492
+ // Preferred symmetric algorithms, section 5.2.3.14
467
493
sig .PreferredSymmetric = make ([]byte , len (subpacket ))
468
494
copy (sig .PreferredSymmetric , subpacket )
469
495
case issuerSubpacket :
470
- // Issuer, section 5.2.3.5
496
+ // Issuer, section 5.2.3.12
471
497
if sig .Version > 4 && isHashed {
472
498
err = errors .StructuralError ("issuer subpacket found in v6 key" )
473
499
return
@@ -481,7 +507,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
481
507
* sig .IssuerKeyId = binary .BigEndian .Uint64 (subpacket )
482
508
}
483
509
case notationDataSubpacket :
484
- // Notation data, section 5.2.3.16
510
+ // Notation data, section 5.2.3.24
485
511
if len (subpacket ) < 8 {
486
512
err = errors .StructuralError ("notation data subpacket with bad length" )
487
513
return
@@ -503,15 +529,27 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
503
529
504
530
sig .Notations = append (sig .Notations , & notation )
505
531
case prefHashAlgosSubpacket :
506
- // Preferred hash algorithms, section 5.2.3.8
532
+ // Preferred hash algorithms, section 5.2.3.16
507
533
sig .PreferredHash = make ([]byte , len (subpacket ))
508
534
copy (sig .PreferredHash , subpacket )
509
535
case prefCompressionSubpacket :
510
- // Preferred compression algorithms, section 5.2.3.9
536
+ // Preferred compression algorithms, section 5.2.3.17
511
537
sig .PreferredCompression = make ([]byte , len (subpacket ))
512
538
copy (sig .PreferredCompression , subpacket )
539
+ case keyserverPrefsSubpacket :
540
+ // Keyserver preferences, section 5.2.3.25
541
+ sig .KeyserverPrefsValid = true
542
+ if len (subpacket ) == 0 {
543
+ return
544
+ }
545
+ if subpacket [0 ]& KeyserverPrefNoModify != 0 {
546
+ sig .KeyserverPrefNoModify = true
547
+ }
548
+ case prefKeyserverSubpacket :
549
+ // Preferred keyserver, section 5.2.3.26
550
+ sig .PreferredKeyserver = string (subpacket )
513
551
case primaryUserIdSubpacket :
514
- // Primary User ID, section 5.2.3.19
552
+ // Primary User ID, section 5.2.3.27
515
553
if len (subpacket ) != 1 {
516
554
err = errors .StructuralError ("primary user id subpacket with bad length" )
517
555
return
@@ -521,7 +559,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
521
559
* sig .IsPrimaryId = true
522
560
}
523
561
case keyFlagsSubpacket :
524
- // Key flags, section 5.2.3.21
562
+ // Key flags, section 5.2.3.29
525
563
sig .FlagsValid = true
526
564
if len (subpacket ) == 0 {
527
565
return
@@ -551,7 +589,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
551
589
userId := string (subpacket )
552
590
sig .SignerUserId = & userId
553
591
case reasonForRevocationSubpacket :
554
- // Reason For Revocation, section 5.2.3.23
592
+ // Reason For Revocation, section 5.2.3.31
555
593
if len (subpacket ) == 0 {
556
594
err = errors .StructuralError ("empty revocation reason subpacket" )
557
595
return
@@ -560,7 +598,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
560
598
* sig .RevocationReason = NewReasonForRevocation (subpacket [0 ])
561
599
sig .RevocationReasonText = string (subpacket [1 :])
562
600
case featuresSubpacket :
563
- // Features subpacket, section 5.2.3.24 specifies a very general
601
+ // Features subpacket, section 5.2.3.32 specifies a very general
564
602
// mechanism for OpenPGP implementations to signal support for new
565
603
// features.
566
604
if len (subpacket ) > 0 {
@@ -574,24 +612,21 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
574
612
}
575
613
case embeddedSignatureSubpacket :
576
614
// Only usage is in signatures that cross-certify
577
- // signing subkeys. section 5.2.3.26 describes the
615
+ // signing subkeys. section 5.2.3.34 describes the
578
616
// format, with its usage described in section 11.1
579
617
if sig .EmbeddedSignature != nil {
580
618
err = errors .StructuralError ("Cannot have multiple embedded signatures" )
581
619
return
582
620
}
583
621
sig .EmbeddedSignature = new (Signature )
584
- // Embedded signatures are required to be v4 signatures see
585
- // section 12.1. However, we only parse v4 signatures in this
586
- // file anyway.
587
622
if err := sig .EmbeddedSignature .parse (bytes .NewBuffer (subpacket )); err != nil {
588
623
return nil , err
589
624
}
590
625
if sigType := sig .EmbeddedSignature .SigType ; sigType != SigTypePrimaryKeyBinding {
591
626
return nil , errors .StructuralError ("cross-signature has unexpected type " + strconv .Itoa (int (sigType )))
592
627
}
593
628
case policyUriSubpacket :
594
- // Policy URI, section 5.2.3.20
629
+ // Policy URI, section 5.2.3.28
595
630
sig .PolicyURI = string (subpacket )
596
631
case issuerFingerprintSubpacket :
597
632
if len (subpacket ) == 0 {
@@ -611,8 +646,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
611
646
* sig .IssuerKeyId = binary .BigEndian .Uint64 (subpacket [13 :21 ])
612
647
}
613
648
case intendedRecipientSubpacket :
614
- // Intended Recipient Fingerprint
615
- // https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#name-intended-recipient-fingerpr
649
+ // Intended Recipient Fingerprint, section 5.2.3.36
616
650
if len (subpacket ) < 1 {
617
651
return nil , errors .StructuralError ("invalid intended recipient fingerpring length" )
618
652
}
@@ -624,8 +658,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r
624
658
copy (fingerprint , subpacket [1 :])
625
659
sig .IntendedRecipients = append (sig .IntendedRecipients , & Recipient {int (version ), fingerprint })
626
660
case prefCipherSuitesSubpacket :
627
- // Preferred AEAD cipher suites
628
- // See https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-07.html#name-preferred-aead-ciphersuites
661
+ // Preferred AEAD cipher suites, section 5.2.3.15
629
662
if len (subpacket )% 2 != 0 {
630
663
err = errors .StructuralError ("invalid aead cipher suite length" )
631
664
return
@@ -676,7 +709,7 @@ func (sig *Signature) CheckKeyIdOrFingerprintExplicit(fingerprint []byte, keyId
676
709
677
710
// serializeSubpacketLength marshals the given length into to.
678
711
func serializeSubpacketLength (to []byte , length int ) int {
679
- // RFC 4880 , Section 4.2.2 .
712
+ // RFC 9580 , Section 4.2.1 .
680
713
if length < 192 {
681
714
to [0 ] = byte (length )
682
715
return 1
@@ -819,7 +852,7 @@ func (sig *Signature) signPrepareHash(h hash.Hash) (digest []byte, err error) {
819
852
// The created hash object initially hashes a randomly generated salt
820
853
// as required by v6 signatures. The generated salt is stored in sig. If the signature is not v6,
821
854
// the method returns an empty hash object.
822
- // See RFC the crypto refresh Section 3 .2.4.
855
+ // See RFC 9580 Section 5 .2.4.
823
856
func (sig * Signature ) PrepareSign (config * Config ) (hash.Hash , error ) {
824
857
if ! sig .Hash .Available () {
825
858
return nil , errors .UnsupportedError ("hash function" )
@@ -843,7 +876,7 @@ func (sig *Signature) PrepareSign(config *Config) (hash.Hash, error) {
843
876
// If the signature is not v6, the method ignores the salt.
844
877
// Use PrepareSign whenever possible instead of generating and
845
878
// hashing the salt externally.
846
- // See RFC the crypto refresh Section 3 .2.4.
879
+ // See RFC 9580 Section 5 .2.4.
847
880
func (sig * Signature ) SetSalt (salt []byte ) error {
848
881
if sig .Version == 6 {
849
882
expectedSaltLength , err := SaltLengthForHash (sig .Hash )
@@ -861,7 +894,7 @@ func (sig *Signature) SetSalt(salt []byte) error {
861
894
// PrepareVerify must be called to create a hash object before verifying v6 signatures.
862
895
// The created hash object initially hashes the internally stored salt.
863
896
// If the signature is not v6, the method returns an empty hash object.
864
- // See crypto refresh Section 3 .2.4.
897
+ // See RFC 9580 Section 5 .2.4.
865
898
func (sig * Signature ) PrepareVerify () (hash.Hash , error ) {
866
899
if ! sig .Hash .Available () {
867
900
return nil , errors .UnsupportedError ("hash function" )
@@ -1276,6 +1309,19 @@ func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubp
1276
1309
if len (sig .PreferredCompression ) > 0 {
1277
1310
subpackets = append (subpackets , outputSubpacket {true , prefCompressionSubpacket , false , sig .PreferredCompression })
1278
1311
}
1312
+ // Keyserver Preferences
1313
+ // Keyserver preferences may only appear in self-signatures or certification signatures.
1314
+ if sig .KeyserverPrefsValid {
1315
+ var prefs byte
1316
+ if sig .KeyserverPrefNoModify {
1317
+ prefs |= KeyserverPrefNoModify
1318
+ }
1319
+ subpackets = append (subpackets , outputSubpacket {true , keyserverPrefsSubpacket , false , []byte {prefs }})
1320
+ }
1321
+ // Preferred Keyserver
1322
+ if len (sig .PreferredKeyserver ) > 0 {
1323
+ subpackets = append (subpackets , outputSubpacket {true , prefKeyserverSubpacket , false , []uint8 (sig .PreferredKeyserver )})
1324
+ }
1279
1325
// Primary User ID
1280
1326
if sig .IsPrimaryId != nil && * sig .IsPrimaryId {
1281
1327
subpackets = append (subpackets , outputSubpacket {true , primaryUserIdSubpacket , false , []byte {1 }})
@@ -1316,7 +1362,7 @@ func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubp
1316
1362
subpackets = append (subpackets , outputSubpacket {true , signerUserIdSubpacket , false , []byte (* sig .SignerUserId )})
1317
1363
}
1318
1364
// Reason for Revocation
1319
- // Revocation reason appears only in revocation signatures and is serialized as per section 5.2.3.23 .
1365
+ // Revocation reason appears only in revocation signatures and is serialized as per section 5.2.3.31 .
1320
1366
if sig .RevocationReason != nil {
1321
1367
subpackets = append (subpackets , outputSubpacket {true , reasonForRevocationSubpacket , true ,
1322
1368
append ([]uint8 {uint8 (* sig .RevocationReason )}, []uint8 (sig .RevocationReasonText )... )})
@@ -1333,7 +1379,7 @@ func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubp
1333
1379
subpackets = append (subpackets , outputSubpacket {true , featuresSubpacket , false , []byte {features }})
1334
1380
}
1335
1381
// Embedded Signature
1336
- // EmbeddedSignature appears only in subkeys capable of signing and is serialized as per section 5.2.3.26 .
1382
+ // EmbeddedSignature appears only in subkeys capable of signing and is serialized as per section 5.2.3.34 .
1337
1383
if sig .EmbeddedSignature != nil {
1338
1384
var buf bytes.Buffer
1339
1385
err = sig .EmbeddedSignature .serializeBody (& buf )
@@ -1418,7 +1464,7 @@ func (sig *Signature) AddMetadataToHashSuffix() {
1418
1464
1419
1465
// SaltLengthForHash selects the required salt length for the given hash algorithm,
1420
1466
// as per Table 23 (Hash algorithm registry) of the crypto refresh.
1421
- // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#section-9.5|Crypto Refresh Section 9.5.
1467
+ // See RFC 9580 Section 9.5.
1422
1468
func SaltLengthForHash (hash crypto.Hash ) (int , error ) {
1423
1469
switch hash {
1424
1470
case crypto .SHA256 , crypto .SHA224 , crypto .SHA3_256 :
@@ -1434,7 +1480,7 @@ func SaltLengthForHash(hash crypto.Hash) (int, error) {
1434
1480
1435
1481
// SignatureSaltForHash generates a random signature salt
1436
1482
// with the length for the given hash algorithm.
1437
- // See https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#section-9.5|Crypto Refresh Section 9.5.
1483
+ // See RFC 9580 Section 9.5.
1438
1484
func SignatureSaltForHash (hash crypto.Hash , randReader io.Reader ) ([]byte , error ) {
1439
1485
saltLength , err := SaltLengthForHash (hash )
1440
1486
if err != nil {
0 commit comments