1
2
3
4
5 package packet
6
7 import (
8 "crypto"
9 "crypto/dsa"
10 "crypto/rsa"
11 "crypto/sha1"
12 "crypto/sha256"
13 _ "crypto/sha512"
14 "encoding/binary"
15 "fmt"
16 "hash"
17 "io"
18 "math/big"
19 "strconv"
20 "time"
21
22 "github.com/ProtonMail/go-crypto/openpgp/ecdh"
23 "github.com/ProtonMail/go-crypto/openpgp/ecdsa"
24 "github.com/ProtonMail/go-crypto/openpgp/eddsa"
25 "github.com/ProtonMail/go-crypto/openpgp/elgamal"
26 "github.com/ProtonMail/go-crypto/openpgp/errors"
27 "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
28 "github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
29 "github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
30 )
31
32 type kdfHashFunction byte
33 type kdfAlgorithm byte
34
35
36 type PublicKey struct {
37 Version int
38 CreationTime time.Time
39 PubKeyAlgo PublicKeyAlgorithm
40 PublicKey interface{}
41 Fingerprint []byte
42 KeyId uint64
43 IsSubkey bool
44
45
46 n, e, p, q, g, y encoding.Field
47
48
49
50 oid encoding.Field
51
52
53
54 kdf encoding.Field
55 }
56
57
58
59 func (pk *PublicKey) UpgradeToV5() {
60 pk.Version = 5
61 pk.setFingerprintAndKeyId()
62 }
63
64
65
66 type signingKey interface {
67 SerializeForHash(io.Writer) error
68 SerializeSignaturePrefix(io.Writer)
69 serializeWithoutHeaders(io.Writer) error
70 }
71
72
73 func NewRSAPublicKey(creationTime time.Time, pub *rsa.PublicKey) *PublicKey {
74 pk := &PublicKey{
75 Version: 4,
76 CreationTime: creationTime,
77 PubKeyAlgo: PubKeyAlgoRSA,
78 PublicKey: pub,
79 n: new(encoding.MPI).SetBig(pub.N),
80 e: new(encoding.MPI).SetBig(big.NewInt(int64(pub.E))),
81 }
82
83 pk.setFingerprintAndKeyId()
84 return pk
85 }
86
87
88 func NewDSAPublicKey(creationTime time.Time, pub *dsa.PublicKey) *PublicKey {
89 pk := &PublicKey{
90 Version: 4,
91 CreationTime: creationTime,
92 PubKeyAlgo: PubKeyAlgoDSA,
93 PublicKey: pub,
94 p: new(encoding.MPI).SetBig(pub.P),
95 q: new(encoding.MPI).SetBig(pub.Q),
96 g: new(encoding.MPI).SetBig(pub.G),
97 y: new(encoding.MPI).SetBig(pub.Y),
98 }
99
100 pk.setFingerprintAndKeyId()
101 return pk
102 }
103
104
105 func NewElGamalPublicKey(creationTime time.Time, pub *elgamal.PublicKey) *PublicKey {
106 pk := &PublicKey{
107 Version: 4,
108 CreationTime: creationTime,
109 PubKeyAlgo: PubKeyAlgoElGamal,
110 PublicKey: pub,
111 p: new(encoding.MPI).SetBig(pub.P),
112 g: new(encoding.MPI).SetBig(pub.G),
113 y: new(encoding.MPI).SetBig(pub.Y),
114 }
115
116 pk.setFingerprintAndKeyId()
117 return pk
118 }
119
120 func NewECDSAPublicKey(creationTime time.Time, pub *ecdsa.PublicKey) *PublicKey {
121 pk := &PublicKey{
122 Version: 4,
123 CreationTime: creationTime,
124 PubKeyAlgo: PubKeyAlgoECDSA,
125 PublicKey: pub,
126 p: encoding.NewMPI(pub.MarshalPoint()),
127 }
128
129 curveInfo := ecc.FindByCurve(pub.GetCurve())
130 if curveInfo == nil {
131 panic("unknown elliptic curve")
132 }
133 pk.oid = curveInfo.Oid
134 pk.setFingerprintAndKeyId()
135 return pk
136 }
137
138 func NewECDHPublicKey(creationTime time.Time, pub *ecdh.PublicKey) *PublicKey {
139 var pk *PublicKey
140 var kdf = encoding.NewOID([]byte{0x1, pub.Hash.Id(), pub.Cipher.Id()})
141 pk = &PublicKey{
142 Version: 4,
143 CreationTime: creationTime,
144 PubKeyAlgo: PubKeyAlgoECDH,
145 PublicKey: pub,
146 p: encoding.NewMPI(pub.MarshalPoint()),
147 kdf: kdf,
148 }
149
150 curveInfo := ecc.FindByCurve(pub.GetCurve())
151
152 if curveInfo == nil {
153 panic("unknown elliptic curve")
154 }
155
156 pk.oid = curveInfo.Oid
157 pk.setFingerprintAndKeyId()
158 return pk
159 }
160
161 func NewEdDSAPublicKey(creationTime time.Time, pub *eddsa.PublicKey) *PublicKey {
162 curveInfo := ecc.FindByCurve(pub.GetCurve())
163 pk := &PublicKey{
164 Version: 4,
165 CreationTime: creationTime,
166 PubKeyAlgo: PubKeyAlgoEdDSA,
167 PublicKey: pub,
168 oid: curveInfo.Oid,
169
170 p: encoding.NewMPI(pub.MarshalPoint()),
171 }
172
173 pk.setFingerprintAndKeyId()
174 return pk
175 }
176
177 func (pk *PublicKey) parse(r io.Reader) (err error) {
178
179 var buf [6]byte
180 _, err = readFull(r, buf[:])
181 if err != nil {
182 return
183 }
184 if buf[0] != 4 && buf[0] != 5 {
185 return errors.UnsupportedError("public key version " + strconv.Itoa(int(buf[0])))
186 }
187
188 pk.Version = int(buf[0])
189 if pk.Version == 5 {
190 var n [4]byte
191 _, err = readFull(r, n[:])
192 if err != nil {
193 return
194 }
195 }
196 pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0)
197 pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5])
198 switch pk.PubKeyAlgo {
199 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
200 err = pk.parseRSA(r)
201 case PubKeyAlgoDSA:
202 err = pk.parseDSA(r)
203 case PubKeyAlgoElGamal:
204 err = pk.parseElGamal(r)
205 case PubKeyAlgoECDSA:
206 err = pk.parseECDSA(r)
207 case PubKeyAlgoECDH:
208 err = pk.parseECDH(r)
209 case PubKeyAlgoEdDSA:
210 err = pk.parseEdDSA(r)
211 default:
212 err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
213 }
214 if err != nil {
215 return
216 }
217
218 pk.setFingerprintAndKeyId()
219 return
220 }
221
222 func (pk *PublicKey) setFingerprintAndKeyId() {
223
224 if pk.Version == 5 {
225 fingerprint := sha256.New()
226 pk.SerializeForHash(fingerprint)
227 pk.Fingerprint = make([]byte, 32)
228 copy(pk.Fingerprint, fingerprint.Sum(nil))
229 pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[:8])
230 } else {
231 fingerprint := sha1.New()
232 pk.SerializeForHash(fingerprint)
233 pk.Fingerprint = make([]byte, 20)
234 copy(pk.Fingerprint, fingerprint.Sum(nil))
235 pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20])
236 }
237 }
238
239
240
241 func (pk *PublicKey) parseRSA(r io.Reader) (err error) {
242 pk.n = new(encoding.MPI)
243 if _, err = pk.n.ReadFrom(r); err != nil {
244 return
245 }
246 pk.e = new(encoding.MPI)
247 if _, err = pk.e.ReadFrom(r); err != nil {
248 return
249 }
250
251 if len(pk.e.Bytes()) > 3 {
252 err = errors.UnsupportedError("large public exponent")
253 return
254 }
255 rsa := &rsa.PublicKey{
256 N: new(big.Int).SetBytes(pk.n.Bytes()),
257 E: 0,
258 }
259 for i := 0; i < len(pk.e.Bytes()); i++ {
260 rsa.E <<= 8
261 rsa.E |= int(pk.e.Bytes()[i])
262 }
263 pk.PublicKey = rsa
264 return
265 }
266
267
268
269 func (pk *PublicKey) parseDSA(r io.Reader) (err error) {
270 pk.p = new(encoding.MPI)
271 if _, err = pk.p.ReadFrom(r); err != nil {
272 return
273 }
274 pk.q = new(encoding.MPI)
275 if _, err = pk.q.ReadFrom(r); err != nil {
276 return
277 }
278 pk.g = new(encoding.MPI)
279 if _, err = pk.g.ReadFrom(r); err != nil {
280 return
281 }
282 pk.y = new(encoding.MPI)
283 if _, err = pk.y.ReadFrom(r); err != nil {
284 return
285 }
286
287 dsa := new(dsa.PublicKey)
288 dsa.P = new(big.Int).SetBytes(pk.p.Bytes())
289 dsa.Q = new(big.Int).SetBytes(pk.q.Bytes())
290 dsa.G = new(big.Int).SetBytes(pk.g.Bytes())
291 dsa.Y = new(big.Int).SetBytes(pk.y.Bytes())
292 pk.PublicKey = dsa
293 return
294 }
295
296
297
298 func (pk *PublicKey) parseElGamal(r io.Reader) (err error) {
299 pk.p = new(encoding.MPI)
300 if _, err = pk.p.ReadFrom(r); err != nil {
301 return
302 }
303 pk.g = new(encoding.MPI)
304 if _, err = pk.g.ReadFrom(r); err != nil {
305 return
306 }
307 pk.y = new(encoding.MPI)
308 if _, err = pk.y.ReadFrom(r); err != nil {
309 return
310 }
311
312 elgamal := new(elgamal.PublicKey)
313 elgamal.P = new(big.Int).SetBytes(pk.p.Bytes())
314 elgamal.G = new(big.Int).SetBytes(pk.g.Bytes())
315 elgamal.Y = new(big.Int).SetBytes(pk.y.Bytes())
316 pk.PublicKey = elgamal
317 return
318 }
319
320
321
322 func (pk *PublicKey) parseECDSA(r io.Reader) (err error) {
323 pk.oid = new(encoding.OID)
324 if _, err = pk.oid.ReadFrom(r); err != nil {
325 return
326 }
327 pk.p = new(encoding.MPI)
328 if _, err = pk.p.ReadFrom(r); err != nil {
329 return
330 }
331
332 curveInfo := ecc.FindByOid(pk.oid)
333 if curveInfo == nil {
334 return errors.UnsupportedError(fmt.Sprintf("unknown oid: %x", pk.oid))
335 }
336
337 c, ok := curveInfo.Curve.(ecc.ECDSACurve)
338 if !ok {
339 return errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", pk.oid))
340 }
341
342 ecdsaKey := ecdsa.NewPublicKey(c)
343 err = ecdsaKey.UnmarshalPoint(pk.p.Bytes())
344 pk.PublicKey = ecdsaKey
345
346 return
347 }
348
349
350
351 func (pk *PublicKey) parseECDH(r io.Reader) (err error) {
352 pk.oid = new(encoding.OID)
353 if _, err = pk.oid.ReadFrom(r); err != nil {
354 return
355 }
356 pk.p = new(encoding.MPI)
357 if _, err = pk.p.ReadFrom(r); err != nil {
358 return
359 }
360 pk.kdf = new(encoding.OID)
361 if _, err = pk.kdf.ReadFrom(r); err != nil {
362 return
363 }
364
365 curveInfo := ecc.FindByOid(pk.oid)
366
367 if curveInfo == nil {
368 return errors.UnsupportedError(fmt.Sprintf("unknown oid: %x", pk.oid))
369 }
370
371 c, ok := curveInfo.Curve.(ecc.ECDHCurve)
372 if !ok {
373 return errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", pk.oid))
374 }
375
376 if kdfLen := len(pk.kdf.Bytes()); kdfLen < 3 {
377 return errors.UnsupportedError("unsupported ECDH KDF length: " + strconv.Itoa(kdfLen))
378 }
379 if reserved := pk.kdf.Bytes()[0]; reserved != 0x01 {
380 return errors.UnsupportedError("unsupported KDF reserved field: " + strconv.Itoa(int(reserved)))
381 }
382 kdfHash, ok := algorithm.HashById[pk.kdf.Bytes()[1]]
383 if !ok {
384 return errors.UnsupportedError("unsupported ECDH KDF hash: " + strconv.Itoa(int(pk.kdf.Bytes()[1])))
385 }
386 kdfCipher, ok := algorithm.CipherById[pk.kdf.Bytes()[2]]
387 if !ok {
388 return errors.UnsupportedError("unsupported ECDH KDF cipher: " + strconv.Itoa(int(pk.kdf.Bytes()[2])))
389 }
390
391 ecdhKey := ecdh.NewPublicKey(c, kdfHash, kdfCipher)
392 err = ecdhKey.UnmarshalPoint(pk.p.Bytes())
393 pk.PublicKey = ecdhKey
394
395 return
396 }
397
398 func (pk *PublicKey) parseEdDSA(r io.Reader) (err error) {
399 pk.oid = new(encoding.OID)
400 if _, err = pk.oid.ReadFrom(r); err != nil {
401 return
402 }
403 curveInfo := ecc.FindByOid(pk.oid)
404 if curveInfo == nil {
405 return errors.UnsupportedError(fmt.Sprintf("unknown oid: %x", pk.oid))
406 }
407
408 c, ok := curveInfo.Curve.(ecc.EdDSACurve)
409 if !ok {
410 return errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", pk.oid))
411 }
412
413 pk.p = new(encoding.MPI)
414 if _, err = pk.p.ReadFrom(r); err != nil {
415 return
416 }
417
418 if len(pk.p.Bytes()) == 0 {
419 return errors.StructuralError("empty EdDSA public key")
420 }
421
422 pub := eddsa.NewPublicKey(c)
423
424 switch flag := pk.p.Bytes()[0]; flag {
425 case 0x04:
426
427 return errors.UnsupportedError("unsupported EdDSA compression: " + strconv.Itoa(int(flag)))
428 case 0x40:
429 err = pub.UnmarshalPoint(pk.p.Bytes())
430 default:
431 return errors.UnsupportedError("unsupported EdDSA compression: " + strconv.Itoa(int(flag)))
432 }
433
434 pk.PublicKey = pub
435 return
436 }
437
438
439
440 func (pk *PublicKey) SerializeForHash(w io.Writer) error {
441 pk.SerializeSignaturePrefix(w)
442 return pk.serializeWithoutHeaders(w)
443 }
444
445
446
447
448 func (pk *PublicKey) SerializeSignaturePrefix(w io.Writer) {
449 var pLength = pk.algorithmSpecificByteCount()
450 if pk.Version == 5 {
451 pLength += 10
452 w.Write([]byte{
453 0x9A,
454 byte(pLength >> 24),
455 byte(pLength >> 16),
456 byte(pLength >> 8),
457 byte(pLength),
458 })
459 return
460 }
461 pLength += 6
462 w.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
463 }
464
465 func (pk *PublicKey) Serialize(w io.Writer) (err error) {
466 length := 6
467 length += pk.algorithmSpecificByteCount()
468 if pk.Version == 5 {
469 length += 4
470 }
471 packetType := packetTypePublicKey
472 if pk.IsSubkey {
473 packetType = packetTypePublicSubkey
474 }
475 err = serializeHeader(w, packetType, length)
476 if err != nil {
477 return
478 }
479 return pk.serializeWithoutHeaders(w)
480 }
481
482 func (pk *PublicKey) algorithmSpecificByteCount() int {
483 length := 0
484 switch pk.PubKeyAlgo {
485 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
486 length += int(pk.n.EncodedLength())
487 length += int(pk.e.EncodedLength())
488 case PubKeyAlgoDSA:
489 length += int(pk.p.EncodedLength())
490 length += int(pk.q.EncodedLength())
491 length += int(pk.g.EncodedLength())
492 length += int(pk.y.EncodedLength())
493 case PubKeyAlgoElGamal:
494 length += int(pk.p.EncodedLength())
495 length += int(pk.g.EncodedLength())
496 length += int(pk.y.EncodedLength())
497 case PubKeyAlgoECDSA:
498 length += int(pk.oid.EncodedLength())
499 length += int(pk.p.EncodedLength())
500 case PubKeyAlgoECDH:
501 length += int(pk.oid.EncodedLength())
502 length += int(pk.p.EncodedLength())
503 length += int(pk.kdf.EncodedLength())
504 case PubKeyAlgoEdDSA:
505 length += int(pk.oid.EncodedLength())
506 length += int(pk.p.EncodedLength())
507 default:
508 panic("unknown public key algorithm")
509 }
510 return length
511 }
512
513
514
515 func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) {
516 t := uint32(pk.CreationTime.Unix())
517 if _, err = w.Write([]byte{
518 byte(pk.Version),
519 byte(t >> 24), byte(t >> 16), byte(t >> 8), byte(t),
520 byte(pk.PubKeyAlgo),
521 }); err != nil {
522 return
523 }
524
525 if pk.Version == 5 {
526 n := pk.algorithmSpecificByteCount()
527 if _, err = w.Write([]byte{
528 byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n),
529 }); err != nil {
530 return
531 }
532 }
533
534 switch pk.PubKeyAlgo {
535 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
536 if _, err = w.Write(pk.n.EncodedBytes()); err != nil {
537 return
538 }
539 _, err = w.Write(pk.e.EncodedBytes())
540 return
541 case PubKeyAlgoDSA:
542 if _, err = w.Write(pk.p.EncodedBytes()); err != nil {
543 return
544 }
545 if _, err = w.Write(pk.q.EncodedBytes()); err != nil {
546 return
547 }
548 if _, err = w.Write(pk.g.EncodedBytes()); err != nil {
549 return
550 }
551 _, err = w.Write(pk.y.EncodedBytes())
552 return
553 case PubKeyAlgoElGamal:
554 if _, err = w.Write(pk.p.EncodedBytes()); err != nil {
555 return
556 }
557 if _, err = w.Write(pk.g.EncodedBytes()); err != nil {
558 return
559 }
560 _, err = w.Write(pk.y.EncodedBytes())
561 return
562 case PubKeyAlgoECDSA:
563 if _, err = w.Write(pk.oid.EncodedBytes()); err != nil {
564 return
565 }
566 _, err = w.Write(pk.p.EncodedBytes())
567 return
568 case PubKeyAlgoECDH:
569 if _, err = w.Write(pk.oid.EncodedBytes()); err != nil {
570 return
571 }
572 if _, err = w.Write(pk.p.EncodedBytes()); err != nil {
573 return
574 }
575 _, err = w.Write(pk.kdf.EncodedBytes())
576 return
577 case PubKeyAlgoEdDSA:
578 if _, err = w.Write(pk.oid.EncodedBytes()); err != nil {
579 return
580 }
581 _, err = w.Write(pk.p.EncodedBytes())
582 return
583 }
584 return errors.InvalidArgumentError("bad public-key algorithm")
585 }
586
587
588 func (pk *PublicKey) CanSign() bool {
589 return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly && pk.PubKeyAlgo != PubKeyAlgoElGamal && pk.PubKeyAlgo != PubKeyAlgoECDH
590 }
591
592
593
594 func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err error) {
595 if !pk.CanSign() {
596 return errors.InvalidArgumentError("public key cannot generate signatures")
597 }
598 if sig.Version == 5 && (sig.SigType == 0x00 || sig.SigType == 0x01) {
599 sig.AddMetadataToHashSuffix()
600 }
601 signed.Write(sig.HashSuffix)
602 hashBytes := signed.Sum(nil)
603 if sig.Version == 5 && (hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1]) {
604 return errors.SignatureError("hash tag doesn't match")
605 }
606
607 if pk.PubKeyAlgo != sig.PubKeyAlgo {
608 return errors.InvalidArgumentError("public key and signature use different algorithms")
609 }
610
611 switch pk.PubKeyAlgo {
612 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
613 rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey)
614 err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, padToKeySize(rsaPublicKey, sig.RSASignature.Bytes()))
615 if err != nil {
616 return errors.SignatureError("RSA verification failure")
617 }
618 return nil
619 case PubKeyAlgoDSA:
620 dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey)
621
622 subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
623 if len(hashBytes) > subgroupSize {
624 hashBytes = hashBytes[:subgroupSize]
625 }
626 if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.Bytes()), new(big.Int).SetBytes(sig.DSASigS.Bytes())) {
627 return errors.SignatureError("DSA verification failure")
628 }
629 return nil
630 case PubKeyAlgoECDSA:
631 ecdsaPublicKey := pk.PublicKey.(*ecdsa.PublicKey)
632 if !ecdsa.Verify(ecdsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.ECDSASigR.Bytes()), new(big.Int).SetBytes(sig.ECDSASigS.Bytes())) {
633 return errors.SignatureError("ECDSA verification failure")
634 }
635 return nil
636 case PubKeyAlgoEdDSA:
637 eddsaPublicKey := pk.PublicKey.(*eddsa.PublicKey)
638 if !eddsa.Verify(eddsaPublicKey, hashBytes, sig.EdDSASigR.Bytes(), sig.EdDSASigS.Bytes()) {
639 return errors.SignatureError("EdDSA verification failure")
640 }
641 return nil
642 default:
643 return errors.SignatureError("Unsupported public key algorithm used in signature")
644 }
645 }
646
647
648
649 func keySignatureHash(pk, signed signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
650 if !hashFunc.Available() {
651 return nil, errors.UnsupportedError("hash function")
652 }
653 h = hashFunc.New()
654
655
656 err = pk.SerializeForHash(h)
657 if err != nil {
658 return nil, err
659 }
660
661 err = signed.SerializeForHash(h)
662 return
663 }
664
665
666
667 func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) error {
668 h, err := keySignatureHash(pk, signed, sig.Hash)
669 if err != nil {
670 return err
671 }
672 if err = pk.VerifySignature(h, sig); err != nil {
673 return err
674 }
675
676 if sig.FlagSign {
677
678
679 if sig.EmbeddedSignature == nil {
680 return errors.StructuralError("signing subkey is missing cross-signature")
681 }
682
683
684
685 if h, err = keySignatureHash(pk, signed, sig.EmbeddedSignature.Hash); err != nil {
686 return errors.StructuralError("error while hashing for cross-signature: " + err.Error())
687 }
688 if err := signed.VerifySignature(h, sig.EmbeddedSignature); err != nil {
689 return errors.StructuralError("error while verifying cross-signature: " + err.Error())
690 }
691 }
692
693 return nil
694 }
695
696 func keyRevocationHash(pk signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
697 if !hashFunc.Available() {
698 return nil, errors.UnsupportedError("hash function")
699 }
700 h = hashFunc.New()
701
702
703 err = pk.SerializeForHash(h)
704
705 return
706 }
707
708
709
710 func (pk *PublicKey) VerifyRevocationSignature(sig *Signature) (err error) {
711 h, err := keyRevocationHash(pk, sig.Hash)
712 if err != nil {
713 return err
714 }
715 return pk.VerifySignature(h, sig)
716 }
717
718
719
720 func (pk *PublicKey) VerifySubkeyRevocationSignature(sig *Signature, signed *PublicKey) (err error) {
721 h, err := keySignatureHash(pk, signed, sig.Hash)
722 if err != nil {
723 return err
724 }
725 return pk.VerifySignature(h, sig)
726 }
727
728
729
730 func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
731 if !hashFunc.Available() {
732 return nil, errors.UnsupportedError("hash function")
733 }
734 h = hashFunc.New()
735
736
737 pk.SerializeSignaturePrefix(h)
738 pk.serializeWithoutHeaders(h)
739
740 var buf [5]byte
741 buf[0] = 0xb4
742 buf[1] = byte(len(id) >> 24)
743 buf[2] = byte(len(id) >> 16)
744 buf[3] = byte(len(id) >> 8)
745 buf[4] = byte(len(id))
746 h.Write(buf[:])
747 h.Write([]byte(id))
748
749 return
750 }
751
752
753
754 func (pk *PublicKey) VerifyUserIdSignature(id string, pub *PublicKey, sig *Signature) (err error) {
755 h, err := userIdSignatureHash(id, pub, sig.Hash)
756 if err != nil {
757 return err
758 }
759 return pk.VerifySignature(h, sig)
760 }
761
762
763
764 func (pk *PublicKey) KeyIdString() string {
765 return fmt.Sprintf("%X", pk.Fingerprint[12:20])
766 }
767
768
769
770 func (pk *PublicKey) KeyIdShortString() string {
771 return fmt.Sprintf("%X", pk.Fingerprint[16:20])
772 }
773
774
775 func (pk *PublicKey) BitLength() (bitLength uint16, err error) {
776 switch pk.PubKeyAlgo {
777 case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
778 bitLength = pk.n.BitLength()
779 case PubKeyAlgoDSA:
780 bitLength = pk.p.BitLength()
781 case PubKeyAlgoElGamal:
782 bitLength = pk.p.BitLength()
783 case PubKeyAlgoECDSA:
784 bitLength = pk.p.BitLength()
785 case PubKeyAlgoECDH:
786 bitLength = pk.p.BitLength()
787 case PubKeyAlgoEdDSA:
788 bitLength = pk.p.BitLength()
789 default:
790 err = errors.InvalidArgumentError("bad public-key algorithm")
791 }
792 return
793 }
794
795
796
797 func (pk *PublicKey) KeyExpired(sig *Signature, currentTime time.Time) bool {
798 if pk.CreationTime.After(currentTime) {
799 return true
800 }
801 if sig.KeyLifetimeSecs == nil || *sig.KeyLifetimeSecs == 0 {
802 return false
803 }
804 expiry := pk.CreationTime.Add(time.Duration(*sig.KeyLifetimeSecs) * time.Second)
805 return currentTime.After(expiry)
806 }
807
View as plain text