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 packet
6
7import (
8 "bytes"
9 "crypto"
10 "crypto/dsa"
11 "encoding/asn1"
12 "encoding/binary"
13 "hash"
14 "io"
15 "math/big"
16 "strconv"
17 "time"
18
19 "github.com/ProtonMail/go-crypto/openpgp/ecdsa"
20 "github.com/ProtonMail/go-crypto/openpgp/ed25519"
21 "github.com/ProtonMail/go-crypto/openpgp/ed448"
22 "github.com/ProtonMail/go-crypto/openpgp/eddsa"
23 "github.com/ProtonMail/go-crypto/openpgp/errors"
24 "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
25 "github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
26)
27
28const (
29 // First octet of key flags.
30 // See RFC 9580, section 5.2.3.29 for details.
31 KeyFlagCertify = 1 << iota
32 KeyFlagSign
33 KeyFlagEncryptCommunications
34 KeyFlagEncryptStorage
35 KeyFlagSplitKey
36 KeyFlagAuthenticate
37 _
38 KeyFlagGroupKey
39)
40
41const (
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
54const SaltNotationName = "salt@notations.openpgpjs.org"
55
56// Signature represents a signature. See RFC 9580, section 5.2.
57type Signature struct {
58 Version int
59 SigType SignatureType
60 PubKeyAlgo PublicKeyAlgorithm
61 Hash crypto.Hash
62 // salt contains a random salt value for v6 signatures
63 // See RFC 9580 Section 5.2.4.
64 salt []byte
65
66 // HashSuffix is extra data that is hashed in after the signed data.
67 HashSuffix []byte
68 // HashTag contains the first two bytes of the hash for fast rejection
69 // of bad signed data.
70 HashTag [2]byte
71
72 // Metadata includes format, filename and time, and is protected by v5
73 // signatures of type 0x00 or 0x01. This metadata is included into the hash
74 // computation; if nil, six 0x00 bytes are used instead. See section 5.2.4.
75 Metadata *LiteralData
76
77 CreationTime time.Time
78
79 RSASignature encoding.Field
80 DSASigR, DSASigS encoding.Field
81 ECDSASigR, ECDSASigS encoding.Field
82 EdDSASigR, EdDSASigS encoding.Field
83 EdSig []byte
84
85 // rawSubpackets contains the unparsed subpackets, in order.
86 rawSubpackets []outputSubpacket
87
88 // The following are optional so are nil when not included in the
89 // signature.
90
91 SigLifetimeSecs, KeyLifetimeSecs *uint32
92 PreferredSymmetric, PreferredHash, PreferredCompression []uint8
93 PreferredCipherSuites [][2]uint8
94 IssuerKeyId *uint64
95 IssuerFingerprint []byte
96 SignerUserId *string
97 IsPrimaryId *bool
98 Notations []*Notation
99 IntendedRecipients []*Recipient
100
101 // TrustLevel and TrustAmount can be set by the signer to assert that
102 // the key is not only valid but also trustworthy at the specified
103 // level.
104 // See RFC 9580, section 5.2.3.21 for details.
105 TrustLevel TrustLevel
106 TrustAmount TrustAmount
107
108 // TrustRegularExpression can be used in conjunction with trust Signature
109 // packets to limit the scope of the trust that is extended.
110 // See RFC 9580, section 5.2.3.22 for details.
111 TrustRegularExpression *string
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
123 // PolicyURI can be set to the URI of a document that describes the
124 // policy under which the signature was issued. See RFC 9580, section
125 // 5.2.3.28 for details.
126 PolicyURI string
127
128 // FlagsValid is set if any flags were given. See RFC 9580, section
129 // 5.2.3.29 for details.
130 FlagsValid bool
131 FlagCertify, FlagSign, FlagEncryptCommunications, FlagEncryptStorage, FlagSplitKey, FlagAuthenticate, FlagGroupKey bool
132
133 // RevocationReason is set if this signature has been revoked.
134 // See RFC 9580, section 5.2.3.31 for details.
135 RevocationReason *ReasonForRevocation
136 RevocationReasonText string
137
138 // In a self-signature, these flags are set there is a features subpacket
139 // indicating that the issuer implementation supports these features
140 // see https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#features-subpacket
141 SEIPDv1, SEIPDv2 bool
142
143 // EmbeddedSignature, if non-nil, is a signature of the parent key, by
144 // this key. This prevents an attacker from claiming another's signing
145 // subkey as their own.
146 EmbeddedSignature *Signature
147
148 outSubpackets []outputSubpacket
149}
150
151// VerifiableSignature internally keeps state if the
152// the signature has been verified before.
153type VerifiableSignature struct {
154 Valid *bool // nil if it has not been verified yet
155 Packet *Signature
156}
157
158// NewVerifiableSig returns a struct of type VerifiableSignature referencing the input signature.
159func NewVerifiableSig(signature *Signature) *VerifiableSignature {
160 return &VerifiableSignature{
161 Packet: signature,
162 }
163}
164
165// Salt returns the signature salt for v6 signatures.
166func (sig *Signature) Salt() []byte {
167 if sig == nil {
168 return nil
169 }
170 return sig.salt
171}
172
173func (sig *Signature) parse(r io.Reader) (err error) {
174 // RFC 9580, section 5.2.3
175 var buf [7]byte
176 _, err = readFull(r, buf[:1])
177 if err != nil {
178 return
179 }
180 sig.Version = int(buf[0])
181 if sig.Version != 4 && sig.Version != 5 && sig.Version != 6 {
182 err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0])))
183 return
184 }
185
186 if V5Disabled && sig.Version == 5 {
187 return errors.UnsupportedError("support for parsing v5 entities is disabled; build with `-tags v5` if needed")
188 }
189
190 if sig.Version == 6 {
191 _, err = readFull(r, buf[:7])
192 } else {
193 _, err = readFull(r, buf[:5])
194 }
195 if err != nil {
196 return
197 }
198 sig.SigType = SignatureType(buf[0])
199 sig.PubKeyAlgo = PublicKeyAlgorithm(buf[1])
200 switch sig.PubKeyAlgo {
201 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA, PubKeyAlgoEdDSA, PubKeyAlgoEd25519, PubKeyAlgoEd448:
202 default:
203 err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo)))
204 return
205 }
206
207 var ok bool
208
209 if sig.Version < 5 {
210 sig.Hash, ok = algorithm.HashIdToHashWithSha1(buf[2])
211 } else {
212 sig.Hash, ok = algorithm.HashIdToHash(buf[2])
213 }
214
215 if !ok {
216 return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2])))
217 }
218
219 var hashedSubpacketsLength int
220 if sig.Version == 6 {
221 // For a v6 signature, a four-octet length is used.
222 hashedSubpacketsLength =
223 int(buf[3])<<24 |
224 int(buf[4])<<16 |
225 int(buf[5])<<8 |
226 int(buf[6])
227 } else {
228 hashedSubpacketsLength = int(buf[3])<<8 | int(buf[4])
229 }
230 hashedSubpackets := make([]byte, hashedSubpacketsLength)
231 _, err = readFull(r, hashedSubpackets)
232 if err != nil {
233 return
234 }
235 err = sig.buildHashSuffix(hashedSubpackets)
236 if err != nil {
237 return
238 }
239
240 err = parseSignatureSubpackets(sig, hashedSubpackets, true)
241 if err != nil {
242 return
243 }
244
245 if sig.Version == 6 {
246 _, err = readFull(r, buf[:4])
247 } else {
248 _, err = readFull(r, buf[:2])
249 }
250
251 if err != nil {
252 return
253 }
254 var unhashedSubpacketsLength uint32
255 if sig.Version == 6 {
256 unhashedSubpacketsLength = uint32(buf[0])<<24 | uint32(buf[1])<<16 | uint32(buf[2])<<8 | uint32(buf[3])
257 } else {
258 unhashedSubpacketsLength = uint32(buf[0])<<8 | uint32(buf[1])
259 }
260 unhashedSubpackets := make([]byte, unhashedSubpacketsLength)
261 _, err = readFull(r, unhashedSubpackets)
262 if err != nil {
263 return
264 }
265 err = parseSignatureSubpackets(sig, unhashedSubpackets, false)
266 if err != nil {
267 return
268 }
269
270 _, err = readFull(r, sig.HashTag[:2])
271 if err != nil {
272 return
273 }
274
275 if sig.Version == 6 {
276 // Only for v6 signatures, a variable-length field containing the salt
277 _, err = readFull(r, buf[:1])
278 if err != nil {
279 return
280 }
281 saltLength := int(buf[0])
282 var expectedSaltLength int
283 expectedSaltLength, err = SaltLengthForHash(sig.Hash)
284 if err != nil {
285 return
286 }
287 if saltLength != expectedSaltLength {
288 err = errors.StructuralError("unexpected salt size for the given hash algorithm")
289 return
290 }
291 salt := make([]byte, expectedSaltLength)
292 _, err = readFull(r, salt)
293 if err != nil {
294 return
295 }
296 sig.salt = salt
297 }
298
299 switch sig.PubKeyAlgo {
300 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
301 sig.RSASignature = new(encoding.MPI)
302 _, err = sig.RSASignature.ReadFrom(r)
303 case PubKeyAlgoDSA:
304 sig.DSASigR = new(encoding.MPI)
305 if _, err = sig.DSASigR.ReadFrom(r); err != nil {
306 return
307 }
308
309 sig.DSASigS = new(encoding.MPI)
310 _, err = sig.DSASigS.ReadFrom(r)
311 case PubKeyAlgoECDSA:
312 sig.ECDSASigR = new(encoding.MPI)
313 if _, err = sig.ECDSASigR.ReadFrom(r); err != nil {
314 return
315 }
316
317 sig.ECDSASigS = new(encoding.MPI)
318 _, err = sig.ECDSASigS.ReadFrom(r)
319 case PubKeyAlgoEdDSA:
320 sig.EdDSASigR = new(encoding.MPI)
321 if _, err = sig.EdDSASigR.ReadFrom(r); err != nil {
322 return
323 }
324
325 sig.EdDSASigS = new(encoding.MPI)
326 if _, err = sig.EdDSASigS.ReadFrom(r); err != nil {
327 return
328 }
329 case PubKeyAlgoEd25519:
330 sig.EdSig, err = ed25519.ReadSignature(r)
331 if err != nil {
332 return
333 }
334 case PubKeyAlgoEd448:
335 sig.EdSig, err = ed448.ReadSignature(r)
336 if err != nil {
337 return
338 }
339 default:
340 panic("unreachable")
341 }
342 return
343}
344
345// parseSignatureSubpackets parses subpackets of the main signature packet. See
346// RFC 9580, section 5.2.3.1.
347func parseSignatureSubpackets(sig *Signature, subpackets []byte, isHashed bool) (err error) {
348 for len(subpackets) > 0 {
349 subpackets, err = parseSignatureSubpacket(sig, subpackets, isHashed)
350 if err != nil {
351 return
352 }
353 }
354
355 if sig.CreationTime.IsZero() {
356 err = errors.StructuralError("no creation time in signature")
357 }
358
359 return
360}
361
362type signatureSubpacketType uint8
363
364const (
365 creationTimeSubpacket signatureSubpacketType = 2
366 signatureExpirationSubpacket signatureSubpacketType = 3
367 exportableCertSubpacket signatureSubpacketType = 4
368 trustSubpacket signatureSubpacketType = 5
369 regularExpressionSubpacket signatureSubpacketType = 6
370 keyExpirationSubpacket signatureSubpacketType = 9
371 prefSymmetricAlgosSubpacket signatureSubpacketType = 11
372 issuerSubpacket signatureSubpacketType = 16
373 notationDataSubpacket signatureSubpacketType = 20
374 prefHashAlgosSubpacket signatureSubpacketType = 21
375 prefCompressionSubpacket signatureSubpacketType = 22
376 keyserverPrefsSubpacket signatureSubpacketType = 23
377 prefKeyserverSubpacket signatureSubpacketType = 24
378 primaryUserIdSubpacket signatureSubpacketType = 25
379 policyUriSubpacket signatureSubpacketType = 26
380 keyFlagsSubpacket signatureSubpacketType = 27
381 signerUserIdSubpacket signatureSubpacketType = 28
382 reasonForRevocationSubpacket signatureSubpacketType = 29
383 featuresSubpacket signatureSubpacketType = 30
384 embeddedSignatureSubpacket signatureSubpacketType = 32
385 issuerFingerprintSubpacket signatureSubpacketType = 33
386 intendedRecipientSubpacket signatureSubpacketType = 35
387 prefCipherSuitesSubpacket signatureSubpacketType = 39
388)
389
390// parseSignatureSubpacket parses a single subpacket. len(subpacket) is >= 1.
391func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (rest []byte, err error) {
392 // RFC 9580, section 5.2.3.7
393 var (
394 length uint32
395 packetType signatureSubpacketType
396 isCritical bool
397 )
398 if len(subpacket) == 0 {
399 err = errors.StructuralError("zero length signature subpacket")
400 return
401 }
402 switch {
403 case subpacket[0] < 192:
404 length = uint32(subpacket[0])
405 subpacket = subpacket[1:]
406 case subpacket[0] < 255:
407 if len(subpacket) < 2 {
408 goto Truncated
409 }
410 length = uint32(subpacket[0]-192)<<8 + uint32(subpacket[1]) + 192
411 subpacket = subpacket[2:]
412 default:
413 if len(subpacket) < 5 {
414 goto Truncated
415 }
416 length = uint32(subpacket[1])<<24 |
417 uint32(subpacket[2])<<16 |
418 uint32(subpacket[3])<<8 |
419 uint32(subpacket[4])
420 subpacket = subpacket[5:]
421 }
422 if length > uint32(len(subpacket)) {
423 goto Truncated
424 }
425 rest = subpacket[length:]
426 subpacket = subpacket[:length]
427 if len(subpacket) == 0 {
428 err = errors.StructuralError("zero length signature subpacket")
429 return
430 }
431 packetType = signatureSubpacketType(subpacket[0] & 0x7f)
432 isCritical = subpacket[0]&0x80 == 0x80
433 subpacket = subpacket[1:]
434 sig.rawSubpackets = append(sig.rawSubpackets, outputSubpacket{isHashed, packetType, isCritical, subpacket})
435 if !isHashed &&
436 packetType != issuerSubpacket &&
437 packetType != issuerFingerprintSubpacket &&
438 packetType != embeddedSignatureSubpacket {
439 return
440 }
441 switch packetType {
442 case creationTimeSubpacket:
443 if len(subpacket) != 4 {
444 err = errors.StructuralError("signature creation time not four bytes")
445 return
446 }
447 t := binary.BigEndian.Uint32(subpacket)
448 sig.CreationTime = time.Unix(int64(t), 0)
449 case signatureExpirationSubpacket:
450 // Signature expiration time, section 5.2.3.18
451 if len(subpacket) != 4 {
452 err = errors.StructuralError("expiration subpacket with bad length")
453 return
454 }
455 sig.SigLifetimeSecs = new(uint32)
456 *sig.SigLifetimeSecs = binary.BigEndian.Uint32(subpacket)
457 case exportableCertSubpacket:
458 if subpacket[0] == 0 {
459 err = errors.UnsupportedError("signature with non-exportable certification")
460 return
461 }
462 case trustSubpacket:
463 if len(subpacket) != 2 {
464 err = errors.StructuralError("trust subpacket with bad length")
465 return
466 }
467 // Trust level and amount, section 5.2.3.21
468 sig.TrustLevel = TrustLevel(subpacket[0])
469 sig.TrustAmount = TrustAmount(subpacket[1])
470 case regularExpressionSubpacket:
471 if len(subpacket) == 0 {
472 err = errors.StructuralError("regexp subpacket with bad length")
473 return
474 }
475 // Trust regular expression, section 5.2.3.22
476 // RFC specifies the string should be null-terminated; remove a null byte from the end
477 if subpacket[len(subpacket)-1] != 0x00 {
478 err = errors.StructuralError("expected regular expression to be null-terminated")
479 return
480 }
481 trustRegularExpression := string(subpacket[:len(subpacket)-1])
482 sig.TrustRegularExpression = &trustRegularExpression
483 case keyExpirationSubpacket:
484 // Key expiration time, section 5.2.3.13
485 if len(subpacket) != 4 {
486 err = errors.StructuralError("key expiration subpacket with bad length")
487 return
488 }
489 sig.KeyLifetimeSecs = new(uint32)
490 *sig.KeyLifetimeSecs = binary.BigEndian.Uint32(subpacket)
491 case prefSymmetricAlgosSubpacket:
492 // Preferred symmetric algorithms, section 5.2.3.14
493 sig.PreferredSymmetric = make([]byte, len(subpacket))
494 copy(sig.PreferredSymmetric, subpacket)
495 case issuerSubpacket:
496 // Issuer, section 5.2.3.12
497 if sig.Version > 4 && isHashed {
498 err = errors.StructuralError("issuer subpacket found in v6 key")
499 return
500 }
501 if len(subpacket) != 8 {
502 err = errors.StructuralError("issuer subpacket with bad length")
503 return
504 }
505 if sig.Version <= 4 {
506 sig.IssuerKeyId = new(uint64)
507 *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket)
508 }
509 case notationDataSubpacket:
510 // Notation data, section 5.2.3.24
511 if len(subpacket) < 8 {
512 err = errors.StructuralError("notation data subpacket with bad length")
513 return
514 }
515
516 nameLength := uint32(subpacket[4])<<8 | uint32(subpacket[5])
517 valueLength := uint32(subpacket[6])<<8 | uint32(subpacket[7])
518 if len(subpacket) != int(nameLength)+int(valueLength)+8 {
519 err = errors.StructuralError("notation data subpacket with bad length")
520 return
521 }
522
523 notation := Notation{
524 IsHumanReadable: (subpacket[0] & 0x80) == 0x80,
525 Name: string(subpacket[8:(nameLength + 8)]),
526 Value: subpacket[(nameLength + 8):(valueLength + nameLength + 8)],
527 IsCritical: isCritical,
528 }
529
530 sig.Notations = append(sig.Notations, ¬ation)
531 case prefHashAlgosSubpacket:
532 // Preferred hash algorithms, section 5.2.3.16
533 sig.PreferredHash = make([]byte, len(subpacket))
534 copy(sig.PreferredHash, subpacket)
535 case prefCompressionSubpacket:
536 // Preferred compression algorithms, section 5.2.3.17
537 sig.PreferredCompression = make([]byte, len(subpacket))
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)
551 case primaryUserIdSubpacket:
552 // Primary User ID, section 5.2.3.27
553 if len(subpacket) != 1 {
554 err = errors.StructuralError("primary user id subpacket with bad length")
555 return
556 }
557 sig.IsPrimaryId = new(bool)
558 if subpacket[0] > 0 {
559 *sig.IsPrimaryId = true
560 }
561 case keyFlagsSubpacket:
562 // Key flags, section 5.2.3.29
563 sig.FlagsValid = true
564 if len(subpacket) == 0 {
565 return
566 }
567 if subpacket[0]&KeyFlagCertify != 0 {
568 sig.FlagCertify = true
569 }
570 if subpacket[0]&KeyFlagSign != 0 {
571 sig.FlagSign = true
572 }
573 if subpacket[0]&KeyFlagEncryptCommunications != 0 {
574 sig.FlagEncryptCommunications = true
575 }
576 if subpacket[0]&KeyFlagEncryptStorage != 0 {
577 sig.FlagEncryptStorage = true
578 }
579 if subpacket[0]&KeyFlagSplitKey != 0 {
580 sig.FlagSplitKey = true
581 }
582 if subpacket[0]&KeyFlagAuthenticate != 0 {
583 sig.FlagAuthenticate = true
584 }
585 if subpacket[0]&KeyFlagGroupKey != 0 {
586 sig.FlagGroupKey = true
587 }
588 case signerUserIdSubpacket:
589 userId := string(subpacket)
590 sig.SignerUserId = &userId
591 case reasonForRevocationSubpacket:
592 // Reason For Revocation, section 5.2.3.31
593 if len(subpacket) == 0 {
594 err = errors.StructuralError("empty revocation reason subpacket")
595 return
596 }
597 sig.RevocationReason = new(ReasonForRevocation)
598 *sig.RevocationReason = NewReasonForRevocation(subpacket[0])
599 sig.RevocationReasonText = string(subpacket[1:])
600 case featuresSubpacket:
601 // Features subpacket, section 5.2.3.32 specifies a very general
602 // mechanism for OpenPGP implementations to signal support for new
603 // features.
604 if len(subpacket) > 0 {
605 if subpacket[0]&0x01 != 0 {
606 sig.SEIPDv1 = true
607 }
608 // 0x02 and 0x04 are reserved
609 if subpacket[0]&0x08 != 0 {
610 sig.SEIPDv2 = true
611 }
612 }
613 case embeddedSignatureSubpacket:
614 // Only usage is in signatures that cross-certify
615 // signing subkeys. section 5.2.3.34 describes the
616 // format, with its usage described in section 11.1
617 if sig.EmbeddedSignature != nil {
618 err = errors.StructuralError("Cannot have multiple embedded signatures")
619 return
620 }
621 sig.EmbeddedSignature = new(Signature)
622 if err := sig.EmbeddedSignature.parse(bytes.NewBuffer(subpacket)); err != nil {
623 return nil, err
624 }
625 if sigType := sig.EmbeddedSignature.SigType; sigType != SigTypePrimaryKeyBinding {
626 return nil, errors.StructuralError("cross-signature has unexpected type " + strconv.Itoa(int(sigType)))
627 }
628 case policyUriSubpacket:
629 // Policy URI, section 5.2.3.28
630 sig.PolicyURI = string(subpacket)
631 case issuerFingerprintSubpacket:
632 if len(subpacket) == 0 {
633 err = errors.StructuralError("empty issuer fingerprint subpacket")
634 return
635 }
636 v, l := subpacket[0], len(subpacket[1:])
637 if v >= 5 && l != 32 || v < 5 && l != 20 {
638 return nil, errors.StructuralError("bad fingerprint length")
639 }
640 sig.IssuerFingerprint = make([]byte, l)
641 copy(sig.IssuerFingerprint, subpacket[1:])
642 sig.IssuerKeyId = new(uint64)
643 if v >= 5 {
644 *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket[1:9])
645 } else {
646 *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket[13:21])
647 }
648 case intendedRecipientSubpacket:
649 // Intended Recipient Fingerprint, section 5.2.3.36
650 if len(subpacket) < 1 {
651 return nil, errors.StructuralError("invalid intended recipient fingerpring length")
652 }
653 version, length := subpacket[0], len(subpacket[1:])
654 if version >= 5 && length != 32 || version < 5 && length != 20 {
655 return nil, errors.StructuralError("invalid fingerprint length")
656 }
657 fingerprint := make([]byte, length)
658 copy(fingerprint, subpacket[1:])
659 sig.IntendedRecipients = append(sig.IntendedRecipients, &Recipient{int(version), fingerprint})
660 case prefCipherSuitesSubpacket:
661 // Preferred AEAD cipher suites, section 5.2.3.15
662 if len(subpacket)%2 != 0 {
663 err = errors.StructuralError("invalid aead cipher suite length")
664 return
665 }
666
667 sig.PreferredCipherSuites = make([][2]byte, len(subpacket)/2)
668
669 for i := 0; i < len(subpacket)/2; i++ {
670 sig.PreferredCipherSuites[i] = [2]uint8{subpacket[2*i], subpacket[2*i+1]}
671 }
672 default:
673 if isCritical {
674 err = errors.UnsupportedError("unknown critical signature subpacket type " + strconv.Itoa(int(packetType)))
675 return
676 }
677 }
678 return
679
680Truncated:
681 err = errors.StructuralError("signature subpacket truncated")
682 return
683}
684
685// subpacketLengthLength returns the length, in bytes, of an encoded length value.
686func subpacketLengthLength(length int) int {
687 if length < 192 {
688 return 1
689 }
690 if length < 16320 {
691 return 2
692 }
693 return 5
694}
695
696func (sig *Signature) CheckKeyIdOrFingerprint(pk *PublicKey) bool {
697 if sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) >= 20 {
698 return bytes.Equal(sig.IssuerFingerprint, pk.Fingerprint)
699 }
700 return sig.IssuerKeyId != nil && *sig.IssuerKeyId == pk.KeyId
701}
702
703func (sig *Signature) CheckKeyIdOrFingerprintExplicit(fingerprint []byte, keyId uint64) bool {
704 if sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) >= 20 && fingerprint != nil {
705 return bytes.Equal(sig.IssuerFingerprint, fingerprint)
706 }
707 return sig.IssuerKeyId != nil && *sig.IssuerKeyId == keyId
708}
709
710// serializeSubpacketLength marshals the given length into to.
711func serializeSubpacketLength(to []byte, length int) int {
712 // RFC 9580, Section 4.2.1.
713 if length < 192 {
714 to[0] = byte(length)
715 return 1
716 }
717 if length < 16320 {
718 length -= 192
719 to[0] = byte((length >> 8) + 192)
720 to[1] = byte(length)
721 return 2
722 }
723 to[0] = 255
724 to[1] = byte(length >> 24)
725 to[2] = byte(length >> 16)
726 to[3] = byte(length >> 8)
727 to[4] = byte(length)
728 return 5
729}
730
731// subpacketsLength returns the serialized length, in bytes, of the given
732// subpackets.
733func subpacketsLength(subpackets []outputSubpacket, hashed bool) (length int) {
734 for _, subpacket := range subpackets {
735 if subpacket.hashed == hashed {
736 length += subpacketLengthLength(len(subpacket.contents) + 1)
737 length += 1 // type byte
738 length += len(subpacket.contents)
739 }
740 }
741 return
742}
743
744// serializeSubpackets marshals the given subpackets into to.
745func serializeSubpackets(to []byte, subpackets []outputSubpacket, hashed bool) {
746 for _, subpacket := range subpackets {
747 if subpacket.hashed == hashed {
748 n := serializeSubpacketLength(to, len(subpacket.contents)+1)
749 to[n] = byte(subpacket.subpacketType)
750 if subpacket.isCritical {
751 to[n] |= 0x80
752 }
753 to = to[1+n:]
754 n = copy(to, subpacket.contents)
755 to = to[n:]
756 }
757 }
758}
759
760// SigExpired returns whether sig is a signature that has expired or is created
761// in the future.
762func (sig *Signature) SigExpired(currentTime time.Time) bool {
763 if sig.CreationTime.Unix() > currentTime.Unix() {
764 return true
765 }
766 if sig.SigLifetimeSecs == nil || *sig.SigLifetimeSecs == 0 {
767 return false
768 }
769 expiry := sig.CreationTime.Add(time.Duration(*sig.SigLifetimeSecs) * time.Second)
770 return currentTime.Unix() > expiry.Unix()
771}
772
773// buildHashSuffix constructs the HashSuffix member of sig in preparation for signing.
774func (sig *Signature) buildHashSuffix(hashedSubpackets []byte) (err error) {
775 var hashId byte
776 var ok bool
777
778 if sig.Version < 5 {
779 hashId, ok = algorithm.HashToHashIdWithSha1(sig.Hash)
780 } else {
781 hashId, ok = algorithm.HashToHashId(sig.Hash)
782 }
783
784 if !ok {
785 sig.HashSuffix = nil
786 return errors.InvalidArgumentError("hash cannot be represented in OpenPGP: " + strconv.Itoa(int(sig.Hash)))
787 }
788
789 hashedFields := bytes.NewBuffer([]byte{
790 uint8(sig.Version),
791 uint8(sig.SigType),
792 uint8(sig.PubKeyAlgo),
793 uint8(hashId),
794 })
795 hashedSubpacketsLength := len(hashedSubpackets)
796 if sig.Version == 6 {
797 // v6 signatures store the length in 4 octets
798 hashedFields.Write([]byte{
799 uint8(hashedSubpacketsLength >> 24),
800 uint8(hashedSubpacketsLength >> 16),
801 uint8(hashedSubpacketsLength >> 8),
802 uint8(hashedSubpacketsLength),
803 })
804 } else {
805 hashedFields.Write([]byte{
806 uint8(hashedSubpacketsLength >> 8),
807 uint8(hashedSubpacketsLength),
808 })
809 }
810 lenPrefix := hashedFields.Len()
811 hashedFields.Write(hashedSubpackets)
812
813 var l uint64 = uint64(lenPrefix + len(hashedSubpackets))
814 if sig.Version == 5 {
815 // v5 case
816 hashedFields.Write([]byte{0x05, 0xff})
817 hashedFields.Write([]byte{
818 uint8(l >> 56), uint8(l >> 48), uint8(l >> 40), uint8(l >> 32),
819 uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
820 })
821 } else {
822 // v4 and v6 case
823 hashedFields.Write([]byte{byte(sig.Version), 0xff})
824 hashedFields.Write([]byte{
825 uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
826 })
827 }
828 sig.HashSuffix = make([]byte, hashedFields.Len())
829 copy(sig.HashSuffix, hashedFields.Bytes())
830 return
831}
832
833func (sig *Signature) signPrepareHash(h hash.Hash) (digest []byte, err error) {
834 hashedSubpacketsLen := subpacketsLength(sig.outSubpackets, true)
835 hashedSubpackets := make([]byte, hashedSubpacketsLen)
836 serializeSubpackets(hashedSubpackets, sig.outSubpackets, true)
837 err = sig.buildHashSuffix(hashedSubpackets)
838 if err != nil {
839 return
840 }
841 if sig.Version == 5 && (sig.SigType == 0x00 || sig.SigType == 0x01) {
842 sig.AddMetadataToHashSuffix()
843 }
844
845 h.Write(sig.HashSuffix)
846 digest = h.Sum(nil)
847 copy(sig.HashTag[:], digest)
848 return
849}
850
851// PrepareSign must be called to create a hash object before Sign for v6 signatures.
852// The created hash object initially hashes a randomly generated salt
853// as required by v6 signatures. The generated salt is stored in sig. If the signature is not v6,
854// the method returns an empty hash object.
855// See RFC 9580 Section 5.2.4.
856func (sig *Signature) PrepareSign(config *Config) (hash.Hash, error) {
857 if !sig.Hash.Available() {
858 return nil, errors.UnsupportedError("hash function")
859 }
860 hasher := sig.Hash.New()
861 if sig.Version == 6 {
862 if sig.salt == nil {
863 var err error
864 sig.salt, err = SignatureSaltForHash(sig.Hash, config.Random())
865 if err != nil {
866 return nil, err
867 }
868 }
869 hasher.Write(sig.salt)
870 }
871 return hasher, nil
872}
873
874// SetSalt sets the signature salt for v6 signatures.
875// Assumes salt is generated correctly and checks if length matches.
876// If the signature is not v6, the method ignores the salt.
877// Use PrepareSign whenever possible instead of generating and
878// hashing the salt externally.
879// See RFC 9580 Section 5.2.4.
880func (sig *Signature) SetSalt(salt []byte) error {
881 if sig.Version == 6 {
882 expectedSaltLength, err := SaltLengthForHash(sig.Hash)
883 if err != nil {
884 return err
885 }
886 if salt == nil || len(salt) != expectedSaltLength {
887 return errors.InvalidArgumentError("unexpected salt size for the given hash algorithm")
888 }
889 sig.salt = salt
890 }
891 return nil
892}
893
894// PrepareVerify must be called to create a hash object before verifying v6 signatures.
895// The created hash object initially hashes the internally stored salt.
896// If the signature is not v6, the method returns an empty hash object.
897// See RFC 9580 Section 5.2.4.
898func (sig *Signature) PrepareVerify() (hash.Hash, error) {
899 if !sig.Hash.Available() {
900 return nil, errors.UnsupportedError("hash function")
901 }
902 hasher := sig.Hash.New()
903 if sig.Version == 6 {
904 if sig.salt == nil {
905 return nil, errors.StructuralError("v6 requires a salt for the hash to be signed")
906 }
907 hasher.Write(sig.salt)
908 }
909 return hasher, nil
910}
911
912// Sign signs a message with a private key. The hash, h, must contain
913// the hash of the message to be signed and will be mutated by this function.
914// On success, the signature is stored in sig. Call Serialize to write it out.
915// If config is nil, sensible defaults will be used.
916func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err error) {
917 if priv.Dummy() {
918 return errors.ErrDummyPrivateKey("dummy key found")
919 }
920 sig.Version = priv.PublicKey.Version
921 sig.IssuerFingerprint = priv.PublicKey.Fingerprint
922 if sig.Version < 6 && config.RandomizeSignaturesViaNotation() {
923 sig.removeNotationsWithName(SaltNotationName)
924 salt, err := SignatureSaltForHash(sig.Hash, config.Random())
925 if err != nil {
926 return err
927 }
928 notation := Notation{
929 Name: SaltNotationName,
930 Value: salt,
931 IsCritical: false,
932 IsHumanReadable: false,
933 }
934 sig.Notations = append(sig.Notations, ¬ation)
935 }
936 sig.outSubpackets, err = sig.buildSubpackets(priv.PublicKey)
937 if err != nil {
938 return err
939 }
940 digest, err := sig.signPrepareHash(h)
941 if err != nil {
942 return
943 }
944 switch priv.PubKeyAlgo {
945 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
946 // supports both *rsa.PrivateKey and crypto.Signer
947 sigdata, err := priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, sig.Hash)
948 if err == nil {
949 sig.RSASignature = encoding.NewMPI(sigdata)
950 }
951 case PubKeyAlgoDSA:
952 dsaPriv := priv.PrivateKey.(*dsa.PrivateKey)
953
954 // Need to truncate hashBytes to match FIPS 186-3 section 4.6.
955 subgroupSize := (dsaPriv.Q.BitLen() + 7) / 8
956 if len(digest) > subgroupSize {
957 digest = digest[:subgroupSize]
958 }
959 r, s, err := dsa.Sign(config.Random(), dsaPriv, digest)
960 if err == nil {
961 sig.DSASigR = new(encoding.MPI).SetBig(r)
962 sig.DSASigS = new(encoding.MPI).SetBig(s)
963 }
964 case PubKeyAlgoECDSA:
965 var r, s *big.Int
966 if sk, ok := priv.PrivateKey.(*ecdsa.PrivateKey); ok {
967 r, s, err = ecdsa.Sign(config.Random(), sk, digest)
968 } else {
969 var b []byte
970 b, err = priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, sig.Hash)
971 if err == nil {
972 r, s, err = unwrapECDSASig(b)
973 }
974 }
975
976 if err == nil {
977 sig.ECDSASigR = new(encoding.MPI).SetBig(r)
978 sig.ECDSASigS = new(encoding.MPI).SetBig(s)
979 }
980 case PubKeyAlgoEdDSA:
981 sk := priv.PrivateKey.(*eddsa.PrivateKey)
982 r, s, err := eddsa.Sign(sk, digest)
983 if err == nil {
984 sig.EdDSASigR = encoding.NewMPI(r)
985 sig.EdDSASigS = encoding.NewMPI(s)
986 }
987 case PubKeyAlgoEd25519:
988 sk := priv.PrivateKey.(*ed25519.PrivateKey)
989 signature, err := ed25519.Sign(sk, digest)
990 if err == nil {
991 sig.EdSig = signature
992 }
993 case PubKeyAlgoEd448:
994 sk := priv.PrivateKey.(*ed448.PrivateKey)
995 signature, err := ed448.Sign(sk, digest)
996 if err == nil {
997 sig.EdSig = signature
998 }
999 default:
1000 err = errors.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo)))
1001 }
1002
1003 return
1004}
1005
1006// unwrapECDSASig parses the two integer components of an ASN.1-encoded ECDSA signature.
1007func unwrapECDSASig(b []byte) (r, s *big.Int, err error) {
1008 var ecsdaSig struct {
1009 R, S *big.Int
1010 }
1011 _, err = asn1.Unmarshal(b, &ecsdaSig)
1012 if err != nil {
1013 return
1014 }
1015 return ecsdaSig.R, ecsdaSig.S, nil
1016}
1017
1018// SignUserId computes a signature from priv, asserting that pub is a valid
1019// key for the identity id. On success, the signature is stored in sig. Call
1020// Serialize to write it out.
1021// If config is nil, sensible defaults will be used.
1022func (sig *Signature) SignUserId(id string, pub *PublicKey, priv *PrivateKey, config *Config) error {
1023 if priv.Dummy() {
1024 return errors.ErrDummyPrivateKey("dummy key found")
1025 }
1026 prepareHash, err := sig.PrepareSign(config)
1027 if err != nil {
1028 return err
1029 }
1030 if err := userIdSignatureHash(id, pub, prepareHash); err != nil {
1031 return err
1032 }
1033 return sig.Sign(prepareHash, priv, config)
1034}
1035
1036// SignDirectKeyBinding computes a signature from priv
1037// On success, the signature is stored in sig.
1038// Call Serialize to write it out.
1039// If config is nil, sensible defaults will be used.
1040func (sig *Signature) SignDirectKeyBinding(pub *PublicKey, priv *PrivateKey, config *Config) error {
1041 if priv.Dummy() {
1042 return errors.ErrDummyPrivateKey("dummy key found")
1043 }
1044 prepareHash, err := sig.PrepareSign(config)
1045 if err != nil {
1046 return err
1047 }
1048 if err := directKeySignatureHash(pub, prepareHash); err != nil {
1049 return err
1050 }
1051 return sig.Sign(prepareHash, priv, config)
1052}
1053
1054// CrossSignKey computes a signature from signingKey on pub hashed using hashKey. On success,
1055// the signature is stored in sig. Call Serialize to write it out.
1056// If config is nil, sensible defaults will be used.
1057func (sig *Signature) CrossSignKey(pub *PublicKey, hashKey *PublicKey, signingKey *PrivateKey,
1058 config *Config) error {
1059 prepareHash, err := sig.PrepareSign(config)
1060 if err != nil {
1061 return err
1062 }
1063 h, err := keySignatureHash(hashKey, pub, prepareHash)
1064 if err != nil {
1065 return err
1066 }
1067 return sig.Sign(h, signingKey, config)
1068}
1069
1070// SignKey computes a signature from priv, asserting that pub is a subkey. On
1071// success, the signature is stored in sig. Call Serialize to write it out.
1072// If config is nil, sensible defaults will be used.
1073func (sig *Signature) SignKey(pub *PublicKey, priv *PrivateKey, config *Config) error {
1074 if priv.Dummy() {
1075 return errors.ErrDummyPrivateKey("dummy key found")
1076 }
1077 prepareHash, err := sig.PrepareSign(config)
1078 if err != nil {
1079 return err
1080 }
1081 h, err := keySignatureHash(&priv.PublicKey, pub, prepareHash)
1082 if err != nil {
1083 return err
1084 }
1085 return sig.Sign(h, priv, config)
1086}
1087
1088// RevokeKey computes a revocation signature of pub using priv. On success, the signature is
1089// stored in sig. Call Serialize to write it out.
1090// If config is nil, sensible defaults will be used.
1091func (sig *Signature) RevokeKey(pub *PublicKey, priv *PrivateKey, config *Config) error {
1092 prepareHash, err := sig.PrepareSign(config)
1093 if err != nil {
1094 return err
1095 }
1096 if err := keyRevocationHash(pub, prepareHash); err != nil {
1097 return err
1098 }
1099 return sig.Sign(prepareHash, priv, config)
1100}
1101
1102// RevokeSubkey computes a subkey revocation signature of pub using priv.
1103// On success, the signature is stored in sig. Call Serialize to write it out.
1104// If config is nil, sensible defaults will be used.
1105func (sig *Signature) RevokeSubkey(pub *PublicKey, priv *PrivateKey, config *Config) error {
1106 // Identical to a subkey binding signature
1107 return sig.SignKey(pub, priv, config)
1108}
1109
1110// Serialize marshals sig to w. Sign, SignUserId or SignKey must have been
1111// called first.
1112func (sig *Signature) Serialize(w io.Writer) (err error) {
1113 if len(sig.outSubpackets) == 0 {
1114 sig.outSubpackets = sig.rawSubpackets
1115 }
1116 if sig.RSASignature == nil && sig.DSASigR == nil && sig.ECDSASigR == nil && sig.EdDSASigR == nil && sig.EdSig == nil {
1117 return errors.InvalidArgumentError("Signature: need to call Sign, SignUserId or SignKey before Serialize")
1118 }
1119
1120 sigLength := 0
1121 switch sig.PubKeyAlgo {
1122 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
1123 sigLength = int(sig.RSASignature.EncodedLength())
1124 case PubKeyAlgoDSA:
1125 sigLength = int(sig.DSASigR.EncodedLength())
1126 sigLength += int(sig.DSASigS.EncodedLength())
1127 case PubKeyAlgoECDSA:
1128 sigLength = int(sig.ECDSASigR.EncodedLength())
1129 sigLength += int(sig.ECDSASigS.EncodedLength())
1130 case PubKeyAlgoEdDSA:
1131 sigLength = int(sig.EdDSASigR.EncodedLength())
1132 sigLength += int(sig.EdDSASigS.EncodedLength())
1133 case PubKeyAlgoEd25519:
1134 sigLength = ed25519.SignatureSize
1135 case PubKeyAlgoEd448:
1136 sigLength = ed448.SignatureSize
1137 default:
1138 panic("impossible")
1139 }
1140
1141 hashedSubpacketsLen := subpacketsLength(sig.outSubpackets, true)
1142 unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false)
1143 length := 4 + /* length of version|signature type|public-key algorithm|hash algorithm */
1144 2 /* length of hashed subpackets */ + hashedSubpacketsLen +
1145 2 /* length of unhashed subpackets */ + unhashedSubpacketsLen +
1146 2 /* hash tag */ + sigLength
1147 if sig.Version == 6 {
1148 length += 4 + /* the two length fields are four-octet instead of two */
1149 1 + /* salt length */
1150 len(sig.salt) /* length salt */
1151 }
1152 err = serializeHeader(w, packetTypeSignature, length)
1153 if err != nil {
1154 return
1155 }
1156 err = sig.serializeBody(w)
1157 if err != nil {
1158 return err
1159 }
1160 return
1161}
1162
1163func (sig *Signature) serializeBody(w io.Writer) (err error) {
1164 var fields []byte
1165 if sig.Version == 6 {
1166 // v6 signatures use 4 octets for length
1167 hashedSubpacketsLen :=
1168 uint32(uint32(sig.HashSuffix[4])<<24) |
1169 uint32(uint32(sig.HashSuffix[5])<<16) |
1170 uint32(uint32(sig.HashSuffix[6])<<8) |
1171 uint32(sig.HashSuffix[7])
1172 fields = sig.HashSuffix[:8+hashedSubpacketsLen]
1173 } else {
1174 hashedSubpacketsLen := uint16(uint16(sig.HashSuffix[4])<<8) |
1175 uint16(sig.HashSuffix[5])
1176 fields = sig.HashSuffix[:6+hashedSubpacketsLen]
1177
1178 }
1179 _, err = w.Write(fields)
1180 if err != nil {
1181 return
1182 }
1183
1184 unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false)
1185 var unhashedSubpackets []byte
1186 if sig.Version == 6 {
1187 unhashedSubpackets = make([]byte, 4+unhashedSubpacketsLen)
1188 unhashedSubpackets[0] = byte(unhashedSubpacketsLen >> 24)
1189 unhashedSubpackets[1] = byte(unhashedSubpacketsLen >> 16)
1190 unhashedSubpackets[2] = byte(unhashedSubpacketsLen >> 8)
1191 unhashedSubpackets[3] = byte(unhashedSubpacketsLen)
1192 serializeSubpackets(unhashedSubpackets[4:], sig.outSubpackets, false)
1193 } else {
1194 unhashedSubpackets = make([]byte, 2+unhashedSubpacketsLen)
1195 unhashedSubpackets[0] = byte(unhashedSubpacketsLen >> 8)
1196 unhashedSubpackets[1] = byte(unhashedSubpacketsLen)
1197 serializeSubpackets(unhashedSubpackets[2:], sig.outSubpackets, false)
1198 }
1199
1200 _, err = w.Write(unhashedSubpackets)
1201 if err != nil {
1202 return
1203 }
1204 _, err = w.Write(sig.HashTag[:])
1205 if err != nil {
1206 return
1207 }
1208
1209 if sig.Version == 6 {
1210 // write salt for v6 signatures
1211 _, err = w.Write([]byte{uint8(len(sig.salt))})
1212 if err != nil {
1213 return
1214 }
1215 _, err = w.Write(sig.salt)
1216 if err != nil {
1217 return
1218 }
1219 }
1220
1221 switch sig.PubKeyAlgo {
1222 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
1223 _, err = w.Write(sig.RSASignature.EncodedBytes())
1224 case PubKeyAlgoDSA:
1225 if _, err = w.Write(sig.DSASigR.EncodedBytes()); err != nil {
1226 return
1227 }
1228 _, err = w.Write(sig.DSASigS.EncodedBytes())
1229 case PubKeyAlgoECDSA:
1230 if _, err = w.Write(sig.ECDSASigR.EncodedBytes()); err != nil {
1231 return
1232 }
1233 _, err = w.Write(sig.ECDSASigS.EncodedBytes())
1234 case PubKeyAlgoEdDSA:
1235 if _, err = w.Write(sig.EdDSASigR.EncodedBytes()); err != nil {
1236 return
1237 }
1238 _, err = w.Write(sig.EdDSASigS.EncodedBytes())
1239 case PubKeyAlgoEd25519:
1240 err = ed25519.WriteSignature(w, sig.EdSig)
1241 case PubKeyAlgoEd448:
1242 err = ed448.WriteSignature(w, sig.EdSig)
1243 default:
1244 panic("impossible")
1245 }
1246 return
1247}
1248
1249// outputSubpacket represents a subpacket to be marshaled.
1250type outputSubpacket struct {
1251 hashed bool // true if this subpacket is in the hashed area.
1252 subpacketType signatureSubpacketType
1253 isCritical bool
1254 contents []byte
1255}
1256
1257func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubpacket, err error) {
1258 creationTime := make([]byte, 4)
1259 binary.BigEndian.PutUint32(creationTime, uint32(sig.CreationTime.Unix()))
1260 // Signature Creation Time
1261 subpackets = append(subpackets, outputSubpacket{true, creationTimeSubpacket, true, creationTime})
1262 // Signature Expiration Time
1263 if sig.SigLifetimeSecs != nil && *sig.SigLifetimeSecs != 0 {
1264 sigLifetime := make([]byte, 4)
1265 binary.BigEndian.PutUint32(sigLifetime, *sig.SigLifetimeSecs)
1266 subpackets = append(subpackets, outputSubpacket{true, signatureExpirationSubpacket, true, sigLifetime})
1267 }
1268 // Trust Signature
1269 if sig.TrustLevel != 0 {
1270 subpackets = append(subpackets, outputSubpacket{true, trustSubpacket, true, []byte{byte(sig.TrustLevel), byte(sig.TrustAmount)}})
1271 }
1272 // Regular Expression
1273 if sig.TrustRegularExpression != nil {
1274 // RFC specifies the string should be null-terminated; add a null byte to the end
1275 subpackets = append(subpackets, outputSubpacket{true, regularExpressionSubpacket, true, []byte(*sig.TrustRegularExpression + "\000")})
1276 }
1277 // Key Expiration Time
1278 if sig.KeyLifetimeSecs != nil && *sig.KeyLifetimeSecs != 0 {
1279 keyLifetime := make([]byte, 4)
1280 binary.BigEndian.PutUint32(keyLifetime, *sig.KeyLifetimeSecs)
1281 subpackets = append(subpackets, outputSubpacket{true, keyExpirationSubpacket, true, keyLifetime})
1282 }
1283 // Preferred Symmetric Ciphers for v1 SEIPD
1284 if len(sig.PreferredSymmetric) > 0 {
1285 subpackets = append(subpackets, outputSubpacket{true, prefSymmetricAlgosSubpacket, false, sig.PreferredSymmetric})
1286 }
1287 // Issuer Key ID
1288 if sig.IssuerKeyId != nil && sig.Version == 4 {
1289 keyId := make([]byte, 8)
1290 binary.BigEndian.PutUint64(keyId, *sig.IssuerKeyId)
1291 // Note: making this critical breaks RPM <=4.16.
1292 // See: https://github.com/ProtonMail/go-crypto/issues/263
1293 subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, false, keyId})
1294 }
1295 // Notation Data
1296 for _, notation := range sig.Notations {
1297 subpackets = append(
1298 subpackets,
1299 outputSubpacket{
1300 true,
1301 notationDataSubpacket,
1302 notation.IsCritical,
1303 notation.getData(),
1304 })
1305 }
1306 // Preferred Hash Algorithms
1307 if len(sig.PreferredHash) > 0 {
1308 subpackets = append(subpackets, outputSubpacket{true, prefHashAlgosSubpacket, false, sig.PreferredHash})
1309 }
1310 // Preferred Compression Algorithms
1311 if len(sig.PreferredCompression) > 0 {
1312 subpackets = append(subpackets, outputSubpacket{true, prefCompressionSubpacket, false, sig.PreferredCompression})
1313 }
1314 // Keyserver Preferences
1315 // Keyserver preferences may only appear in self-signatures or certification signatures.
1316 if sig.KeyserverPrefsValid {
1317 var prefs byte
1318 if sig.KeyserverPrefNoModify {
1319 prefs |= KeyserverPrefNoModify
1320 }
1321 subpackets = append(subpackets, outputSubpacket{true, keyserverPrefsSubpacket, false, []byte{prefs}})
1322 }
1323 // Preferred Keyserver
1324 if len(sig.PreferredKeyserver) > 0 {
1325 subpackets = append(subpackets, outputSubpacket{true, prefKeyserverSubpacket, false, []uint8(sig.PreferredKeyserver)})
1326 }
1327 // Primary User ID
1328 if sig.IsPrimaryId != nil && *sig.IsPrimaryId {
1329 subpackets = append(subpackets, outputSubpacket{true, primaryUserIdSubpacket, false, []byte{1}})
1330 }
1331 // Policy URI
1332 if len(sig.PolicyURI) > 0 {
1333 subpackets = append(subpackets, outputSubpacket{true, policyUriSubpacket, false, []uint8(sig.PolicyURI)})
1334 }
1335 // Key Flags
1336 // Key flags may only appear in self-signatures or certification signatures.
1337 if sig.FlagsValid {
1338 var flags byte
1339 if sig.FlagCertify {
1340 flags |= KeyFlagCertify
1341 }
1342 if sig.FlagSign {
1343 flags |= KeyFlagSign
1344 }
1345 if sig.FlagEncryptCommunications {
1346 flags |= KeyFlagEncryptCommunications
1347 }
1348 if sig.FlagEncryptStorage {
1349 flags |= KeyFlagEncryptStorage
1350 }
1351 if sig.FlagSplitKey {
1352 flags |= KeyFlagSplitKey
1353 }
1354 if sig.FlagAuthenticate {
1355 flags |= KeyFlagAuthenticate
1356 }
1357 if sig.FlagGroupKey {
1358 flags |= KeyFlagGroupKey
1359 }
1360 subpackets = append(subpackets, outputSubpacket{true, keyFlagsSubpacket, true, []byte{flags}})
1361 }
1362 // Signer's User ID
1363 if sig.SignerUserId != nil {
1364 subpackets = append(subpackets, outputSubpacket{true, signerUserIdSubpacket, false, []byte(*sig.SignerUserId)})
1365 }
1366 // Reason for Revocation
1367 // Revocation reason appears only in revocation signatures and is serialized as per section 5.2.3.31.
1368 if sig.RevocationReason != nil {
1369 subpackets = append(subpackets, outputSubpacket{true, reasonForRevocationSubpacket, true,
1370 append([]uint8{uint8(*sig.RevocationReason)}, []uint8(sig.RevocationReasonText)...)})
1371 }
1372 // Features
1373 var features = byte(0x00)
1374 if sig.SEIPDv1 {
1375 features |= 0x01
1376 }
1377 if sig.SEIPDv2 {
1378 features |= 0x08
1379 }
1380 if features != 0x00 {
1381 subpackets = append(subpackets, outputSubpacket{true, featuresSubpacket, false, []byte{features}})
1382 }
1383 // Embedded Signature
1384 // EmbeddedSignature appears only in subkeys capable of signing and is serialized as per section 5.2.3.34.
1385 if sig.EmbeddedSignature != nil {
1386 var buf bytes.Buffer
1387 err = sig.EmbeddedSignature.serializeBody(&buf)
1388 if err != nil {
1389 return
1390 }
1391 subpackets = append(subpackets, outputSubpacket{true, embeddedSignatureSubpacket, true, buf.Bytes()})
1392 }
1393 // Issuer Fingerprint
1394 if sig.IssuerFingerprint != nil {
1395 contents := append([]uint8{uint8(issuer.Version)}, sig.IssuerFingerprint...)
1396 subpackets = append(subpackets, outputSubpacket{true, issuerFingerprintSubpacket, sig.Version >= 5, contents})
1397 }
1398 // Intended Recipient Fingerprint
1399 for _, recipient := range sig.IntendedRecipients {
1400 subpackets = append(
1401 subpackets,
1402 outputSubpacket{
1403 true,
1404 intendedRecipientSubpacket,
1405 false,
1406 recipient.Serialize(),
1407 })
1408 }
1409 // Preferred AEAD Ciphersuites
1410 if len(sig.PreferredCipherSuites) > 0 {
1411 serialized := make([]byte, len(sig.PreferredCipherSuites)*2)
1412 for i, cipherSuite := range sig.PreferredCipherSuites {
1413 serialized[2*i] = cipherSuite[0]
1414 serialized[2*i+1] = cipherSuite[1]
1415 }
1416 subpackets = append(subpackets, outputSubpacket{true, prefCipherSuitesSubpacket, false, serialized})
1417 }
1418 return
1419}
1420
1421// AddMetadataToHashSuffix modifies the current hash suffix to include metadata
1422// (format, filename, and time). Version 5 keys protect this data including it
1423// in the hash computation. See section 5.2.4.
1424func (sig *Signature) AddMetadataToHashSuffix() {
1425 if sig == nil || sig.Version != 5 {
1426 return
1427 }
1428 if sig.SigType != 0x00 && sig.SigType != 0x01 {
1429 return
1430 }
1431 lit := sig.Metadata
1432 if lit == nil {
1433 // This will translate into six 0x00 bytes.
1434 lit = &LiteralData{}
1435 }
1436
1437 // Extract the current byte count
1438 n := sig.HashSuffix[len(sig.HashSuffix)-8:]
1439 l := uint64(
1440 uint64(n[0])<<56 | uint64(n[1])<<48 | uint64(n[2])<<40 | uint64(n[3])<<32 |
1441 uint64(n[4])<<24 | uint64(n[5])<<16 | uint64(n[6])<<8 | uint64(n[7]))
1442
1443 suffix := bytes.NewBuffer(nil)
1444 suffix.Write(sig.HashSuffix[:l])
1445
1446 // Add the metadata
1447 var buf [4]byte
1448 buf[0] = lit.Format
1449 fileName := lit.FileName
1450 if len(lit.FileName) > 255 {
1451 fileName = fileName[:255]
1452 }
1453 buf[1] = byte(len(fileName))
1454 suffix.Write(buf[:2])
1455 suffix.Write([]byte(lit.FileName))
1456 binary.BigEndian.PutUint32(buf[:], lit.Time)
1457 suffix.Write(buf[:])
1458
1459 suffix.Write([]byte{0x05, 0xff})
1460 suffix.Write([]byte{
1461 uint8(l >> 56), uint8(l >> 48), uint8(l >> 40), uint8(l >> 32),
1462 uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
1463 })
1464 sig.HashSuffix = suffix.Bytes()
1465}
1466
1467// SaltLengthForHash selects the required salt length for the given hash algorithm,
1468// as per Table 23 (Hash algorithm registry) of the crypto refresh.
1469// See RFC 9580 Section 9.5.
1470func SaltLengthForHash(hash crypto.Hash) (int, error) {
1471 switch hash {
1472 case crypto.SHA256, crypto.SHA224, crypto.SHA3_256:
1473 return 16, nil
1474 case crypto.SHA384:
1475 return 24, nil
1476 case crypto.SHA512, crypto.SHA3_512:
1477 return 32, nil
1478 default:
1479 return 0, errors.UnsupportedError("hash function not supported for V6 signatures")
1480 }
1481}
1482
1483// SignatureSaltForHash generates a random signature salt
1484// with the length for the given hash algorithm.
1485// See RFC 9580 Section 9.5.
1486func SignatureSaltForHash(hash crypto.Hash, randReader io.Reader) ([]byte, error) {
1487 saltLength, err := SaltLengthForHash(hash)
1488 if err != nil {
1489 return nil, err
1490 }
1491 salt := make([]byte, saltLength)
1492 _, err = io.ReadFull(randReader, salt)
1493 if err != nil {
1494 return nil, err
1495 }
1496 return salt, nil
1497}
1498
1499// removeNotationsWithName removes all notations in this signature with the given name.
1500func (sig *Signature) removeNotationsWithName(name string) {
1501 if sig == nil || sig.Notations == nil {
1502 return
1503 }
1504 updatedNotations := make([]*Notation, 0, len(sig.Notations))
1505 for _, notation := range sig.Notations {
1506 if notation.Name != name {
1507 updatedNotations = append(updatedNotations, notation)
1508 }
1509 }
1510 sig.Notations = updatedNotations
1511}