1
2
3
4
5 package packet
6
7 import (
8 "bytes"
9 "crypto"
10 "crypto/dsa"
11 "encoding/binary"
12 "hash"
13 "io"
14 "strconv"
15 "time"
16
17 "github.com/ProtonMail/go-crypto/openpgp/ecdsa"
18 "github.com/ProtonMail/go-crypto/openpgp/eddsa"
19 "github.com/ProtonMail/go-crypto/openpgp/errors"
20 "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
21 "github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
22 )
23
24 const (
25
26 KeyFlagCertify = 1 << iota
27 KeyFlagSign
28 KeyFlagEncryptCommunications
29 KeyFlagEncryptStorage
30 KeyFlagSplitKey
31 KeyFlagAuthenticate
32 _
33 KeyFlagGroupKey
34 )
35
36
37 type Signature struct {
38 Version int
39 SigType SignatureType
40 PubKeyAlgo PublicKeyAlgorithm
41 Hash crypto.Hash
42
43
44 HashSuffix []byte
45
46
47 HashTag [2]byte
48
49
50
51
52 Metadata *LiteralData
53
54 CreationTime time.Time
55
56 RSASignature encoding.Field
57 DSASigR, DSASigS encoding.Field
58 ECDSASigR, ECDSASigS encoding.Field
59 EdDSASigR, EdDSASigS encoding.Field
60
61
62 rawSubpackets []outputSubpacket
63
64
65
66
67 SigLifetimeSecs, KeyLifetimeSecs *uint32
68 PreferredSymmetric, PreferredHash, PreferredCompression []uint8
69 PreferredCipherSuites [][2]uint8
70 IssuerKeyId *uint64
71 IssuerFingerprint []byte
72 SignerUserId *string
73 IsPrimaryId *bool
74 Notations []*Notation
75
76
77
78
79
80 TrustLevel TrustLevel
81 TrustAmount TrustAmount
82
83
84
85
86 TrustRegularExpression *string
87
88
89
90
91 PolicyURI string
92
93
94
95 FlagsValid bool
96 FlagCertify, FlagSign, FlagEncryptCommunications, FlagEncryptStorage, FlagSplitKey, FlagAuthenticate, FlagGroupKey bool
97
98
99
100 RevocationReason *ReasonForRevocation
101 RevocationReasonText string
102
103
104
105
106 SEIPDv1, SEIPDv2 bool
107
108
109
110
111 EmbeddedSignature *Signature
112
113 outSubpackets []outputSubpacket
114 }
115
116 func (sig *Signature) parse(r io.Reader) (err error) {
117
118 var buf [5]byte
119 _, err = readFull(r, buf[:1])
120 if err != nil {
121 return
122 }
123 if buf[0] != 4 && buf[0] != 5 {
124 err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0])))
125 return
126 }
127 sig.Version = int(buf[0])
128 _, err = readFull(r, buf[:5])
129 if err != nil {
130 return
131 }
132 sig.SigType = SignatureType(buf[0])
133 sig.PubKeyAlgo = PublicKeyAlgorithm(buf[1])
134 switch sig.PubKeyAlgo {
135 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA, PubKeyAlgoEdDSA:
136 default:
137 err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo)))
138 return
139 }
140
141 var ok bool
142
143 if sig.Version < 5 {
144 sig.Hash, ok = algorithm.HashIdToHashWithSha1(buf[2])
145 } else {
146 sig.Hash, ok = algorithm.HashIdToHash(buf[2])
147 }
148
149 if !ok {
150 return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2])))
151 }
152
153 hashedSubpacketsLength := int(buf[3])<<8 | int(buf[4])
154 hashedSubpackets := make([]byte, hashedSubpacketsLength)
155 _, err = readFull(r, hashedSubpackets)
156 if err != nil {
157 return
158 }
159 err = sig.buildHashSuffix(hashedSubpackets)
160 if err != nil {
161 return
162 }
163
164 err = parseSignatureSubpackets(sig, hashedSubpackets, true)
165 if err != nil {
166 return
167 }
168
169 _, err = readFull(r, buf[:2])
170 if err != nil {
171 return
172 }
173 unhashedSubpacketsLength := int(buf[0])<<8 | int(buf[1])
174 unhashedSubpackets := make([]byte, unhashedSubpacketsLength)
175 _, err = readFull(r, unhashedSubpackets)
176 if err != nil {
177 return
178 }
179 err = parseSignatureSubpackets(sig, unhashedSubpackets, false)
180 if err != nil {
181 return
182 }
183
184 _, err = readFull(r, sig.HashTag[:2])
185 if err != nil {
186 return
187 }
188
189 switch sig.PubKeyAlgo {
190 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
191 sig.RSASignature = new(encoding.MPI)
192 _, err = sig.RSASignature.ReadFrom(r)
193 case PubKeyAlgoDSA:
194 sig.DSASigR = new(encoding.MPI)
195 if _, err = sig.DSASigR.ReadFrom(r); err != nil {
196 return
197 }
198
199 sig.DSASigS = new(encoding.MPI)
200 _, err = sig.DSASigS.ReadFrom(r)
201 case PubKeyAlgoECDSA:
202 sig.ECDSASigR = new(encoding.MPI)
203 if _, err = sig.ECDSASigR.ReadFrom(r); err != nil {
204 return
205 }
206
207 sig.ECDSASigS = new(encoding.MPI)
208 _, err = sig.ECDSASigS.ReadFrom(r)
209 case PubKeyAlgoEdDSA:
210 sig.EdDSASigR = new(encoding.MPI)
211 if _, err = sig.EdDSASigR.ReadFrom(r); err != nil {
212 return
213 }
214
215 sig.EdDSASigS = new(encoding.MPI)
216 if _, err = sig.EdDSASigS.ReadFrom(r); err != nil {
217 return
218 }
219 default:
220 panic("unreachable")
221 }
222 return
223 }
224
225
226
227 func parseSignatureSubpackets(sig *Signature, subpackets []byte, isHashed bool) (err error) {
228 for len(subpackets) > 0 {
229 subpackets, err = parseSignatureSubpacket(sig, subpackets, isHashed)
230 if err != nil {
231 return
232 }
233 }
234
235 if sig.CreationTime.IsZero() {
236 err = errors.StructuralError("no creation time in signature")
237 }
238
239 return
240 }
241
242 type signatureSubpacketType uint8
243
244 const (
245 creationTimeSubpacket signatureSubpacketType = 2
246 signatureExpirationSubpacket signatureSubpacketType = 3
247 trustSubpacket signatureSubpacketType = 5
248 regularExpressionSubpacket signatureSubpacketType = 6
249 keyExpirationSubpacket signatureSubpacketType = 9
250 prefSymmetricAlgosSubpacket signatureSubpacketType = 11
251 issuerSubpacket signatureSubpacketType = 16
252 notationDataSubpacket signatureSubpacketType = 20
253 prefHashAlgosSubpacket signatureSubpacketType = 21
254 prefCompressionSubpacket signatureSubpacketType = 22
255 primaryUserIdSubpacket signatureSubpacketType = 25
256 policyUriSubpacket signatureSubpacketType = 26
257 keyFlagsSubpacket signatureSubpacketType = 27
258 signerUserIdSubpacket signatureSubpacketType = 28
259 reasonForRevocationSubpacket signatureSubpacketType = 29
260 featuresSubpacket signatureSubpacketType = 30
261 embeddedSignatureSubpacket signatureSubpacketType = 32
262 issuerFingerprintSubpacket signatureSubpacketType = 33
263 prefCipherSuitesSubpacket signatureSubpacketType = 39
264 )
265
266
267 func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (rest []byte, err error) {
268
269 var (
270 length uint32
271 packetType signatureSubpacketType
272 isCritical bool
273 )
274 if len(subpacket) == 0 {
275 err = errors.StructuralError("zero length signature subpacket")
276 return
277 }
278 switch {
279 case subpacket[0] < 192:
280 length = uint32(subpacket[0])
281 subpacket = subpacket[1:]
282 case subpacket[0] < 255:
283 if len(subpacket) < 2 {
284 goto Truncated
285 }
286 length = uint32(subpacket[0]-192)<<8 + uint32(subpacket[1]) + 192
287 subpacket = subpacket[2:]
288 default:
289 if len(subpacket) < 5 {
290 goto Truncated
291 }
292 length = uint32(subpacket[1])<<24 |
293 uint32(subpacket[2])<<16 |
294 uint32(subpacket[3])<<8 |
295 uint32(subpacket[4])
296 subpacket = subpacket[5:]
297 }
298 if length > uint32(len(subpacket)) {
299 goto Truncated
300 }
301 rest = subpacket[length:]
302 subpacket = subpacket[:length]
303 if len(subpacket) == 0 {
304 err = errors.StructuralError("zero length signature subpacket")
305 return
306 }
307 packetType = signatureSubpacketType(subpacket[0] & 0x7f)
308 isCritical = subpacket[0]&0x80 == 0x80
309 subpacket = subpacket[1:]
310 sig.rawSubpackets = append(sig.rawSubpackets, outputSubpacket{isHashed, packetType, isCritical, subpacket})
311 if !isHashed &&
312 packetType != issuerSubpacket &&
313 packetType != issuerFingerprintSubpacket &&
314 packetType != embeddedSignatureSubpacket {
315 return
316 }
317 switch packetType {
318 case creationTimeSubpacket:
319 if len(subpacket) != 4 {
320 err = errors.StructuralError("signature creation time not four bytes")
321 return
322 }
323 t := binary.BigEndian.Uint32(subpacket)
324 sig.CreationTime = time.Unix(int64(t), 0)
325 case signatureExpirationSubpacket:
326
327 if len(subpacket) != 4 {
328 err = errors.StructuralError("expiration subpacket with bad length")
329 return
330 }
331 sig.SigLifetimeSecs = new(uint32)
332 *sig.SigLifetimeSecs = binary.BigEndian.Uint32(subpacket)
333 case trustSubpacket:
334 if len(subpacket) != 2 {
335 err = errors.StructuralError("trust subpacket with bad length")
336 return
337 }
338
339 sig.TrustLevel = TrustLevel(subpacket[0])
340 sig.TrustAmount = TrustAmount(subpacket[1])
341 case regularExpressionSubpacket:
342 if len(subpacket) == 0 {
343 err = errors.StructuralError("regexp subpacket with bad length")
344 return
345 }
346
347
348 if subpacket[len(subpacket)-1] != 0x00 {
349 err = errors.StructuralError("expected regular expression to be null-terminated")
350 return
351 }
352 trustRegularExpression := string(subpacket[:len(subpacket)-1])
353 sig.TrustRegularExpression = &trustRegularExpression
354 case keyExpirationSubpacket:
355
356 if len(subpacket) != 4 {
357 err = errors.StructuralError("key expiration subpacket with bad length")
358 return
359 }
360 sig.KeyLifetimeSecs = new(uint32)
361 *sig.KeyLifetimeSecs = binary.BigEndian.Uint32(subpacket)
362 case prefSymmetricAlgosSubpacket:
363
364 sig.PreferredSymmetric = make([]byte, len(subpacket))
365 copy(sig.PreferredSymmetric, subpacket)
366 case issuerSubpacket:
367
368 if sig.Version > 4 {
369 err = errors.StructuralError("issuer subpacket found in v5 key")
370 return
371 }
372 if len(subpacket) != 8 {
373 err = errors.StructuralError("issuer subpacket with bad length")
374 return
375 }
376 sig.IssuerKeyId = new(uint64)
377 *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket)
378 case notationDataSubpacket:
379
380 if len(subpacket) < 8 {
381 err = errors.StructuralError("notation data subpacket with bad length")
382 return
383 }
384
385 nameLength := uint32(subpacket[4])<<8 | uint32(subpacket[5])
386 valueLength := uint32(subpacket[6])<<8 | uint32(subpacket[7])
387 if len(subpacket) != int(nameLength)+int(valueLength)+8 {
388 err = errors.StructuralError("notation data subpacket with bad length")
389 return
390 }
391
392 notation := Notation{
393 IsHumanReadable: (subpacket[0] & 0x80) == 0x80,
394 Name: string(subpacket[8:(nameLength + 8)]),
395 Value: subpacket[(nameLength + 8):(valueLength + nameLength + 8)],
396 IsCritical: isCritical,
397 }
398
399 sig.Notations = append(sig.Notations, ¬ation)
400 case prefHashAlgosSubpacket:
401
402 sig.PreferredHash = make([]byte, len(subpacket))
403 copy(sig.PreferredHash, subpacket)
404 case prefCompressionSubpacket:
405
406 sig.PreferredCompression = make([]byte, len(subpacket))
407 copy(sig.PreferredCompression, subpacket)
408 case primaryUserIdSubpacket:
409
410 if len(subpacket) != 1 {
411 err = errors.StructuralError("primary user id subpacket with bad length")
412 return
413 }
414 sig.IsPrimaryId = new(bool)
415 if subpacket[0] > 0 {
416 *sig.IsPrimaryId = true
417 }
418 case keyFlagsSubpacket:
419
420 if len(subpacket) == 0 {
421 err = errors.StructuralError("empty key flags subpacket")
422 return
423 }
424 sig.FlagsValid = true
425 if subpacket[0]&KeyFlagCertify != 0 {
426 sig.FlagCertify = true
427 }
428 if subpacket[0]&KeyFlagSign != 0 {
429 sig.FlagSign = true
430 }
431 if subpacket[0]&KeyFlagEncryptCommunications != 0 {
432 sig.FlagEncryptCommunications = true
433 }
434 if subpacket[0]&KeyFlagEncryptStorage != 0 {
435 sig.FlagEncryptStorage = true
436 }
437 if subpacket[0]&KeyFlagSplitKey != 0 {
438 sig.FlagSplitKey = true
439 }
440 if subpacket[0]&KeyFlagAuthenticate != 0 {
441 sig.FlagAuthenticate = true
442 }
443 if subpacket[0]&KeyFlagGroupKey != 0 {
444 sig.FlagGroupKey = true
445 }
446 case signerUserIdSubpacket:
447 userId := string(subpacket)
448 sig.SignerUserId = &userId
449 case reasonForRevocationSubpacket:
450
451 if len(subpacket) == 0 {
452 err = errors.StructuralError("empty revocation reason subpacket")
453 return
454 }
455 sig.RevocationReason = new(ReasonForRevocation)
456 *sig.RevocationReason = ReasonForRevocation(subpacket[0])
457 sig.RevocationReasonText = string(subpacket[1:])
458 case featuresSubpacket:
459
460
461
462 if len(subpacket) > 0 {
463 if subpacket[0]&0x01 != 0 {
464 sig.SEIPDv1 = true
465 }
466
467 if subpacket[0]&0x08 != 0 {
468 sig.SEIPDv2 = true
469 }
470 }
471 case embeddedSignatureSubpacket:
472
473
474
475 if sig.EmbeddedSignature != nil {
476 err = errors.StructuralError("Cannot have multiple embedded signatures")
477 return
478 }
479 sig.EmbeddedSignature = new(Signature)
480
481
482
483 if err := sig.EmbeddedSignature.parse(bytes.NewBuffer(subpacket)); err != nil {
484 return nil, err
485 }
486 if sigType := sig.EmbeddedSignature.SigType; sigType != SigTypePrimaryKeyBinding {
487 return nil, errors.StructuralError("cross-signature has unexpected type " + strconv.Itoa(int(sigType)))
488 }
489 case policyUriSubpacket:
490
491 sig.PolicyURI = string(subpacket)
492 case issuerFingerprintSubpacket:
493 if len(subpacket) == 0 {
494 err = errors.StructuralError("empty issuer fingerprint subpacket")
495 return
496 }
497 v, l := subpacket[0], len(subpacket[1:])
498 if v == 5 && l != 32 || v != 5 && l != 20 {
499 return nil, errors.StructuralError("bad fingerprint length")
500 }
501 sig.IssuerFingerprint = make([]byte, l)
502 copy(sig.IssuerFingerprint, subpacket[1:])
503 sig.IssuerKeyId = new(uint64)
504 if v == 5 {
505 *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket[1:9])
506 } else {
507 *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket[13:21])
508 }
509 case prefCipherSuitesSubpacket:
510
511
512 if len(subpacket)%2 != 0 {
513 err = errors.StructuralError("invalid aead cipher suite length")
514 return
515 }
516
517 sig.PreferredCipherSuites = make([][2]byte, len(subpacket)/2)
518
519 for i := 0; i < len(subpacket)/2; i++ {
520 sig.PreferredCipherSuites[i] = [2]uint8{subpacket[2*i], subpacket[2*i+1]}
521 }
522 default:
523 if isCritical {
524 err = errors.UnsupportedError("unknown critical signature subpacket type " + strconv.Itoa(int(packetType)))
525 return
526 }
527 }
528 return
529
530 Truncated:
531 err = errors.StructuralError("signature subpacket truncated")
532 return
533 }
534
535
536 func subpacketLengthLength(length int) int {
537 if length < 192 {
538 return 1
539 }
540 if length < 16320 {
541 return 2
542 }
543 return 5
544 }
545
546 func (sig *Signature) CheckKeyIdOrFingerprint(pk *PublicKey) bool {
547 if sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) >= 20 {
548 return bytes.Equal(sig.IssuerFingerprint, pk.Fingerprint)
549 }
550 return sig.IssuerKeyId != nil && *sig.IssuerKeyId == pk.KeyId
551 }
552
553
554 func serializeSubpacketLength(to []byte, length int) int {
555
556 if length < 192 {
557 to[0] = byte(length)
558 return 1
559 }
560 if length < 16320 {
561 length -= 192
562 to[0] = byte((length >> 8) + 192)
563 to[1] = byte(length)
564 return 2
565 }
566 to[0] = 255
567 to[1] = byte(length >> 24)
568 to[2] = byte(length >> 16)
569 to[3] = byte(length >> 8)
570 to[4] = byte(length)
571 return 5
572 }
573
574
575
576 func subpacketsLength(subpackets []outputSubpacket, hashed bool) (length int) {
577 for _, subpacket := range subpackets {
578 if subpacket.hashed == hashed {
579 length += subpacketLengthLength(len(subpacket.contents) + 1)
580 length += 1
581 length += len(subpacket.contents)
582 }
583 }
584 return
585 }
586
587
588 func serializeSubpackets(to []byte, subpackets []outputSubpacket, hashed bool) {
589 for _, subpacket := range subpackets {
590 if subpacket.hashed == hashed {
591 n := serializeSubpacketLength(to, len(subpacket.contents)+1)
592 to[n] = byte(subpacket.subpacketType)
593 if subpacket.isCritical {
594 to[n] |= 0x80
595 }
596 to = to[1+n:]
597 n = copy(to, subpacket.contents)
598 to = to[n:]
599 }
600 }
601 return
602 }
603
604
605
606 func (sig *Signature) SigExpired(currentTime time.Time) bool {
607 if sig.CreationTime.After(currentTime) {
608 return true
609 }
610 if sig.SigLifetimeSecs == nil || *sig.SigLifetimeSecs == 0 {
611 return false
612 }
613 expiry := sig.CreationTime.Add(time.Duration(*sig.SigLifetimeSecs) * time.Second)
614 return currentTime.After(expiry)
615 }
616
617
618 func (sig *Signature) buildHashSuffix(hashedSubpackets []byte) (err error) {
619 var hashId byte
620 var ok bool
621
622 if sig.Version < 5 {
623 hashId, ok = algorithm.HashToHashIdWithSha1(sig.Hash)
624 } else {
625 hashId, ok = algorithm.HashToHashId(sig.Hash)
626 }
627
628 if !ok {
629 sig.HashSuffix = nil
630 return errors.InvalidArgumentError("hash cannot be represented in OpenPGP: " + strconv.Itoa(int(sig.Hash)))
631 }
632
633 hashedFields := bytes.NewBuffer([]byte{
634 uint8(sig.Version),
635 uint8(sig.SigType),
636 uint8(sig.PubKeyAlgo),
637 uint8(hashId),
638 uint8(len(hashedSubpackets) >> 8),
639 uint8(len(hashedSubpackets)),
640 })
641 hashedFields.Write(hashedSubpackets)
642
643 var l uint64 = uint64(6 + len(hashedSubpackets))
644 if sig.Version == 5 {
645 hashedFields.Write([]byte{0x05, 0xff})
646 hashedFields.Write([]byte{
647 uint8(l >> 56), uint8(l >> 48), uint8(l >> 40), uint8(l >> 32),
648 uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
649 })
650 } else {
651 hashedFields.Write([]byte{0x04, 0xff})
652 hashedFields.Write([]byte{
653 uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
654 })
655 }
656 sig.HashSuffix = make([]byte, hashedFields.Len())
657 copy(sig.HashSuffix, hashedFields.Bytes())
658 return
659 }
660
661 func (sig *Signature) signPrepareHash(h hash.Hash) (digest []byte, err error) {
662 hashedSubpacketsLen := subpacketsLength(sig.outSubpackets, true)
663 hashedSubpackets := make([]byte, hashedSubpacketsLen)
664 serializeSubpackets(hashedSubpackets, sig.outSubpackets, true)
665 err = sig.buildHashSuffix(hashedSubpackets)
666 if err != nil {
667 return
668 }
669 if sig.Version == 5 && (sig.SigType == 0x00 || sig.SigType == 0x01) {
670 sig.AddMetadataToHashSuffix()
671 }
672
673 h.Write(sig.HashSuffix)
674 digest = h.Sum(nil)
675 copy(sig.HashTag[:], digest)
676 return
677 }
678
679
680
681
682
683 func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err error) {
684 if priv.Dummy() {
685 return errors.ErrDummyPrivateKey("dummy key found")
686 }
687 sig.Version = priv.PublicKey.Version
688 sig.IssuerFingerprint = priv.PublicKey.Fingerprint
689 sig.outSubpackets, err = sig.buildSubpackets(priv.PublicKey)
690 if err != nil {
691 return err
692 }
693 digest, err := sig.signPrepareHash(h)
694 if err != nil {
695 return
696 }
697 switch priv.PubKeyAlgo {
698 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
699
700 sigdata, err := priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, sig.Hash)
701 if err == nil {
702 sig.RSASignature = encoding.NewMPI(sigdata)
703 }
704 case PubKeyAlgoDSA:
705 dsaPriv := priv.PrivateKey.(*dsa.PrivateKey)
706
707
708 subgroupSize := (dsaPriv.Q.BitLen() + 7) / 8
709 if len(digest) > subgroupSize {
710 digest = digest[:subgroupSize]
711 }
712 r, s, err := dsa.Sign(config.Random(), dsaPriv, digest)
713 if err == nil {
714 sig.DSASigR = new(encoding.MPI).SetBig(r)
715 sig.DSASigS = new(encoding.MPI).SetBig(s)
716 }
717 case PubKeyAlgoECDSA:
718 sk := priv.PrivateKey.(*ecdsa.PrivateKey)
719 r, s, err := ecdsa.Sign(config.Random(), sk, digest)
720
721 if err == nil {
722 sig.ECDSASigR = new(encoding.MPI).SetBig(r)
723 sig.ECDSASigS = new(encoding.MPI).SetBig(s)
724 }
725 case PubKeyAlgoEdDSA:
726 sk := priv.PrivateKey.(*eddsa.PrivateKey)
727 r, s, err := eddsa.Sign(sk, digest)
728 if err == nil {
729 sig.EdDSASigR = encoding.NewMPI(r)
730 sig.EdDSASigS = encoding.NewMPI(s)
731 }
732 default:
733 err = errors.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo)))
734 }
735
736 return
737 }
738
739
740
741
742
743 func (sig *Signature) SignUserId(id string, pub *PublicKey, priv *PrivateKey, config *Config) error {
744 if priv.Dummy() {
745 return errors.ErrDummyPrivateKey("dummy key found")
746 }
747 h, err := userIdSignatureHash(id, pub, sig.Hash)
748 if err != nil {
749 return err
750 }
751 return sig.Sign(h, priv, config)
752 }
753
754
755
756
757 func (sig *Signature) CrossSignKey(pub *PublicKey, hashKey *PublicKey, signingKey *PrivateKey,
758 config *Config) error {
759 h, err := keySignatureHash(hashKey, pub, sig.Hash)
760 if err != nil {
761 return err
762 }
763 return sig.Sign(h, signingKey, config)
764 }
765
766
767
768
769 func (sig *Signature) SignKey(pub *PublicKey, priv *PrivateKey, config *Config) error {
770 if priv.Dummy() {
771 return errors.ErrDummyPrivateKey("dummy key found")
772 }
773 h, err := keySignatureHash(&priv.PublicKey, pub, sig.Hash)
774 if err != nil {
775 return err
776 }
777 return sig.Sign(h, priv, config)
778 }
779
780
781
782
783 func (sig *Signature) RevokeKey(pub *PublicKey, priv *PrivateKey, config *Config) error {
784 h, err := keyRevocationHash(pub, sig.Hash)
785 if err != nil {
786 return err
787 }
788 return sig.Sign(h, priv, config)
789 }
790
791
792
793
794 func (sig *Signature) RevokeSubkey(pub *PublicKey, priv *PrivateKey, config *Config) error {
795
796 return sig.SignKey(pub, priv, config)
797 }
798
799
800
801 func (sig *Signature) Serialize(w io.Writer) (err error) {
802 if len(sig.outSubpackets) == 0 {
803 sig.outSubpackets = sig.rawSubpackets
804 }
805 if sig.RSASignature == nil && sig.DSASigR == nil && sig.ECDSASigR == nil && sig.EdDSASigR == nil {
806 return errors.InvalidArgumentError("Signature: need to call Sign, SignUserId or SignKey before Serialize")
807 }
808
809 sigLength := 0
810 switch sig.PubKeyAlgo {
811 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
812 sigLength = int(sig.RSASignature.EncodedLength())
813 case PubKeyAlgoDSA:
814 sigLength = int(sig.DSASigR.EncodedLength())
815 sigLength += int(sig.DSASigS.EncodedLength())
816 case PubKeyAlgoECDSA:
817 sigLength = int(sig.ECDSASigR.EncodedLength())
818 sigLength += int(sig.ECDSASigS.EncodedLength())
819 case PubKeyAlgoEdDSA:
820 sigLength = int(sig.EdDSASigR.EncodedLength())
821 sigLength += int(sig.EdDSASigS.EncodedLength())
822 default:
823 panic("impossible")
824 }
825
826 unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false)
827 length := len(sig.HashSuffix) - 6 +
828 2 + unhashedSubpacketsLen +
829 2 + sigLength
830 if sig.Version == 5 {
831 length -= 4
832 }
833 err = serializeHeader(w, packetTypeSignature, length)
834 if err != nil {
835 return
836 }
837 err = sig.serializeBody(w)
838 if err != nil {
839 return err
840 }
841 return
842 }
843
844 func (sig *Signature) serializeBody(w io.Writer) (err error) {
845 hashedSubpacketsLen := uint16(uint16(sig.HashSuffix[4])<<8) | uint16(sig.HashSuffix[5])
846 fields := sig.HashSuffix[:6+hashedSubpacketsLen]
847 _, err = w.Write(fields)
848 if err != nil {
849 return
850 }
851
852 unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false)
853 unhashedSubpackets := make([]byte, 2+unhashedSubpacketsLen)
854 unhashedSubpackets[0] = byte(unhashedSubpacketsLen >> 8)
855 unhashedSubpackets[1] = byte(unhashedSubpacketsLen)
856 serializeSubpackets(unhashedSubpackets[2:], sig.outSubpackets, false)
857
858 _, err = w.Write(unhashedSubpackets)
859 if err != nil {
860 return
861 }
862 _, err = w.Write(sig.HashTag[:])
863 if err != nil {
864 return
865 }
866
867 switch sig.PubKeyAlgo {
868 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
869 _, err = w.Write(sig.RSASignature.EncodedBytes())
870 case PubKeyAlgoDSA:
871 if _, err = w.Write(sig.DSASigR.EncodedBytes()); err != nil {
872 return
873 }
874 _, err = w.Write(sig.DSASigS.EncodedBytes())
875 case PubKeyAlgoECDSA:
876 if _, err = w.Write(sig.ECDSASigR.EncodedBytes()); err != nil {
877 return
878 }
879 _, err = w.Write(sig.ECDSASigS.EncodedBytes())
880 case PubKeyAlgoEdDSA:
881 if _, err = w.Write(sig.EdDSASigR.EncodedBytes()); err != nil {
882 return
883 }
884 _, err = w.Write(sig.EdDSASigS.EncodedBytes())
885 default:
886 panic("impossible")
887 }
888 return
889 }
890
891
892 type outputSubpacket struct {
893 hashed bool
894 subpacketType signatureSubpacketType
895 isCritical bool
896 contents []byte
897 }
898
899 func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubpacket, err error) {
900 creationTime := make([]byte, 4)
901 binary.BigEndian.PutUint32(creationTime, uint32(sig.CreationTime.Unix()))
902 subpackets = append(subpackets, outputSubpacket{true, creationTimeSubpacket, false, creationTime})
903
904 if sig.IssuerKeyId != nil && sig.Version == 4 {
905 keyId := make([]byte, 8)
906 binary.BigEndian.PutUint64(keyId, *sig.IssuerKeyId)
907 subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, false, keyId})
908 }
909 if sig.IssuerFingerprint != nil {
910 contents := append([]uint8{uint8(issuer.Version)}, sig.IssuerFingerprint...)
911 subpackets = append(subpackets, outputSubpacket{true, issuerFingerprintSubpacket, sig.Version == 5, contents})
912 }
913 if sig.SignerUserId != nil {
914 subpackets = append(subpackets, outputSubpacket{true, signerUserIdSubpacket, false, []byte(*sig.SignerUserId)})
915 }
916 if sig.SigLifetimeSecs != nil && *sig.SigLifetimeSecs != 0 {
917 sigLifetime := make([]byte, 4)
918 binary.BigEndian.PutUint32(sigLifetime, *sig.SigLifetimeSecs)
919 subpackets = append(subpackets, outputSubpacket{true, signatureExpirationSubpacket, true, sigLifetime})
920 }
921
922
923
924 if sig.FlagsValid {
925 var flags byte
926 if sig.FlagCertify {
927 flags |= KeyFlagCertify
928 }
929 if sig.FlagSign {
930 flags |= KeyFlagSign
931 }
932 if sig.FlagEncryptCommunications {
933 flags |= KeyFlagEncryptCommunications
934 }
935 if sig.FlagEncryptStorage {
936 flags |= KeyFlagEncryptStorage
937 }
938 if sig.FlagSplitKey {
939 flags |= KeyFlagSplitKey
940 }
941 if sig.FlagAuthenticate {
942 flags |= KeyFlagAuthenticate
943 }
944 if sig.FlagGroupKey {
945 flags |= KeyFlagGroupKey
946 }
947 subpackets = append(subpackets, outputSubpacket{true, keyFlagsSubpacket, false, []byte{flags}})
948 }
949
950 for _, notation := range sig.Notations {
951 subpackets = append(
952 subpackets,
953 outputSubpacket{
954 true,
955 notationDataSubpacket,
956 notation.IsCritical,
957 notation.getData(),
958 })
959 }
960
961
962
963 var features = byte(0x00)
964 if sig.SEIPDv1 {
965 features |= 0x01
966 }
967 if sig.SEIPDv2 {
968 features |= 0x08
969 }
970
971 if features != 0x00 {
972 subpackets = append(subpackets, outputSubpacket{true, featuresSubpacket, false, []byte{features}})
973 }
974
975 if sig.TrustLevel != 0 {
976 subpackets = append(subpackets, outputSubpacket{true, trustSubpacket, true, []byte{byte(sig.TrustLevel), byte(sig.TrustAmount)}})
977 }
978
979 if sig.TrustRegularExpression != nil {
980
981 subpackets = append(subpackets, outputSubpacket{true, regularExpressionSubpacket, true, []byte(*sig.TrustRegularExpression + "\000")})
982 }
983
984 if sig.KeyLifetimeSecs != nil && *sig.KeyLifetimeSecs != 0 {
985 keyLifetime := make([]byte, 4)
986 binary.BigEndian.PutUint32(keyLifetime, *sig.KeyLifetimeSecs)
987 subpackets = append(subpackets, outputSubpacket{true, keyExpirationSubpacket, true, keyLifetime})
988 }
989
990 if sig.IsPrimaryId != nil && *sig.IsPrimaryId {
991 subpackets = append(subpackets, outputSubpacket{true, primaryUserIdSubpacket, false, []byte{1}})
992 }
993
994 if len(sig.PreferredSymmetric) > 0 {
995 subpackets = append(subpackets, outputSubpacket{true, prefSymmetricAlgosSubpacket, false, sig.PreferredSymmetric})
996 }
997
998 if len(sig.PreferredHash) > 0 {
999 subpackets = append(subpackets, outputSubpacket{true, prefHashAlgosSubpacket, false, sig.PreferredHash})
1000 }
1001
1002 if len(sig.PreferredCompression) > 0 {
1003 subpackets = append(subpackets, outputSubpacket{true, prefCompressionSubpacket, false, sig.PreferredCompression})
1004 }
1005
1006 if len(sig.PolicyURI) > 0 {
1007 subpackets = append(subpackets, outputSubpacket{true, policyUriSubpacket, false, []uint8(sig.PolicyURI)})
1008 }
1009
1010 if len(sig.PreferredCipherSuites) > 0 {
1011 serialized := make([]byte, len(sig.PreferredCipherSuites)*2)
1012 for i, cipherSuite := range sig.PreferredCipherSuites {
1013 serialized[2*i] = cipherSuite[0]
1014 serialized[2*i+1] = cipherSuite[1]
1015 }
1016 subpackets = append(subpackets, outputSubpacket{true, prefCipherSuitesSubpacket, false, serialized})
1017 }
1018
1019
1020 if sig.RevocationReason != nil {
1021 subpackets = append(subpackets, outputSubpacket{true, reasonForRevocationSubpacket, true,
1022 append([]uint8{uint8(*sig.RevocationReason)}, []uint8(sig.RevocationReasonText)...)})
1023 }
1024
1025
1026 if sig.EmbeddedSignature != nil {
1027 var buf bytes.Buffer
1028 err = sig.EmbeddedSignature.serializeBody(&buf)
1029 if err != nil {
1030 return
1031 }
1032 subpackets = append(subpackets, outputSubpacket{true, embeddedSignatureSubpacket, true, buf.Bytes()})
1033 }
1034
1035 return
1036 }
1037
1038
1039
1040
1041 func (sig *Signature) AddMetadataToHashSuffix() {
1042 if sig == nil || sig.Version != 5 {
1043 return
1044 }
1045 if sig.SigType != 0x00 && sig.SigType != 0x01 {
1046 return
1047 }
1048 lit := sig.Metadata
1049 if lit == nil {
1050
1051 lit = &LiteralData{}
1052 }
1053
1054
1055 n := sig.HashSuffix[len(sig.HashSuffix)-8:]
1056 l := uint64(
1057 uint64(n[0])<<56 | uint64(n[1])<<48 | uint64(n[2])<<40 | uint64(n[3])<<32 |
1058 uint64(n[4])<<24 | uint64(n[5])<<16 | uint64(n[6])<<8 | uint64(n[7]))
1059
1060 suffix := bytes.NewBuffer(nil)
1061 suffix.Write(sig.HashSuffix[:l])
1062
1063
1064 var buf [4]byte
1065 buf[0] = lit.Format
1066 fileName := lit.FileName
1067 if len(lit.FileName) > 255 {
1068 fileName = fileName[:255]
1069 }
1070 buf[1] = byte(len(fileName))
1071 suffix.Write(buf[:2])
1072 suffix.Write([]byte(lit.FileName))
1073 binary.BigEndian.PutUint32(buf[:], lit.Time)
1074 suffix.Write(buf[:])
1075
1076
1077 l = uint64(suffix.Len())
1078 suffix.Write([]byte{0x05, 0xff})
1079 suffix.Write([]byte{
1080 uint8(l >> 56), uint8(l >> 48), uint8(l >> 40), uint8(l >> 32),
1081 uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
1082 })
1083 sig.HashSuffix = suffix.Bytes()
1084 }
1085
View as plain text