OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / crypto / openpgp / packet / public_key.go
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
5 package packet
6
7 import (
8         "bytes"
9         "crypto"
10         "crypto/dsa"
11         "crypto/ecdsa"
12         "crypto/elliptic"
13         "crypto/rsa"
14         "crypto/sha1"
15         _ "crypto/sha256"
16         _ "crypto/sha512"
17         "encoding/binary"
18         "fmt"
19         "hash"
20         "io"
21         "math/big"
22         "strconv"
23         "time"
24
25         "golang.org/x/crypto/openpgp/elgamal"
26         "golang.org/x/crypto/openpgp/errors"
27 )
28
29 var (
30         // NIST curve P-256
31         oidCurveP256 []byte = []byte{0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07}
32         // NIST curve P-384
33         oidCurveP384 []byte = []byte{0x2B, 0x81, 0x04, 0x00, 0x22}
34         // NIST curve P-521
35         oidCurveP521 []byte = []byte{0x2B, 0x81, 0x04, 0x00, 0x23}
36 )
37
38 const maxOIDLength = 8
39
40 // ecdsaKey stores the algorithm-specific fields for ECDSA keys.
41 // as defined in RFC 6637, Section 9.
42 type ecdsaKey struct {
43         // oid contains the OID byte sequence identifying the elliptic curve used
44         oid []byte
45         // p contains the elliptic curve point that represents the public key
46         p parsedMPI
47 }
48
49 // parseOID reads the OID for the curve as defined in RFC 6637, Section 9.
50 func parseOID(r io.Reader) (oid []byte, err error) {
51         buf := make([]byte, maxOIDLength)
52         if _, err = readFull(r, buf[:1]); err != nil {
53                 return
54         }
55         oidLen := buf[0]
56         if int(oidLen) > len(buf) {
57                 err = errors.UnsupportedError("invalid oid length: " + strconv.Itoa(int(oidLen)))
58                 return
59         }
60         oid = buf[:oidLen]
61         _, err = readFull(r, oid)
62         return
63 }
64
65 func (f *ecdsaKey) parse(r io.Reader) (err error) {
66         if f.oid, err = parseOID(r); err != nil {
67                 return err
68         }
69         f.p.bytes, f.p.bitLength, err = readMPI(r)
70         return
71 }
72
73 func (f *ecdsaKey) serialize(w io.Writer) (err error) {
74         buf := make([]byte, maxOIDLength+1)
75         buf[0] = byte(len(f.oid))
76         copy(buf[1:], f.oid)
77         if _, err = w.Write(buf[:len(f.oid)+1]); err != nil {
78                 return
79         }
80         return writeMPIs(w, f.p)
81 }
82
83 func (f *ecdsaKey) newECDSA() (*ecdsa.PublicKey, error) {
84         var c elliptic.Curve
85         if bytes.Equal(f.oid, oidCurveP256) {
86                 c = elliptic.P256()
87         } else if bytes.Equal(f.oid, oidCurveP384) {
88                 c = elliptic.P384()
89         } else if bytes.Equal(f.oid, oidCurveP521) {
90                 c = elliptic.P521()
91         } else {
92                 return nil, errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", f.oid))
93         }
94         x, y := elliptic.Unmarshal(c, f.p.bytes)
95         if x == nil {
96                 return nil, errors.UnsupportedError("failed to parse EC point")
97         }
98         return &ecdsa.PublicKey{Curve: c, X: x, Y: y}, nil
99 }
100
101 func (f *ecdsaKey) byteLen() int {
102         return 1 + len(f.oid) + 2 + len(f.p.bytes)
103 }
104
105 type kdfHashFunction byte
106 type kdfAlgorithm byte
107
108 // ecdhKdf stores key derivation function parameters
109 // used for ECDH encryption. See RFC 6637, Section 9.
110 type ecdhKdf struct {
111         KdfHash kdfHashFunction
112         KdfAlgo kdfAlgorithm
113 }
114
115 func (f *ecdhKdf) parse(r io.Reader) (err error) {
116         buf := make([]byte, 1)
117         if _, err = readFull(r, buf); err != nil {
118                 return
119         }
120         kdfLen := int(buf[0])
121         if kdfLen < 3 {
122                 return errors.UnsupportedError("Unsupported ECDH KDF length: " + strconv.Itoa(kdfLen))
123         }
124         buf = make([]byte, kdfLen)
125         if _, err = readFull(r, buf); err != nil {
126                 return
127         }
128         reserved := int(buf[0])
129         f.KdfHash = kdfHashFunction(buf[1])
130         f.KdfAlgo = kdfAlgorithm(buf[2])
131         if reserved != 0x01 {
132                 return errors.UnsupportedError("Unsupported KDF reserved field: " + strconv.Itoa(reserved))
133         }
134         return
135 }
136
137 func (f *ecdhKdf) serialize(w io.Writer) (err error) {
138         buf := make([]byte, 4)
139         // See RFC 6637, Section 9, Algorithm-Specific Fields for ECDH keys.
140         buf[0] = byte(0x03) // Length of the following fields
141         buf[1] = byte(0x01) // Reserved for future extensions, must be 1 for now
142         buf[2] = byte(f.KdfHash)
143         buf[3] = byte(f.KdfAlgo)
144         _, err = w.Write(buf[:])
145         return
146 }
147
148 func (f *ecdhKdf) byteLen() int {
149         return 4
150 }
151
152 // PublicKey represents an OpenPGP public key. See RFC 4880, section 5.5.2.
153 type PublicKey struct {
154         CreationTime time.Time
155         PubKeyAlgo   PublicKeyAlgorithm
156         PublicKey    interface{} // *rsa.PublicKey, *dsa.PublicKey or *ecdsa.PublicKey
157         Fingerprint  [20]byte
158         KeyId        uint64
159         IsSubkey     bool
160
161         n, e, p, q, g, y parsedMPI
162
163         // RFC 6637 fields
164         ec   *ecdsaKey
165         ecdh *ecdhKdf
166 }
167
168 // signingKey provides a convenient abstraction over signature verification
169 // for v3 and v4 public keys.
170 type signingKey interface {
171         SerializeSignaturePrefix(io.Writer)
172         serializeWithoutHeaders(io.Writer) error
173 }
174
175 func fromBig(n *big.Int) parsedMPI {
176         return parsedMPI{
177                 bytes:     n.Bytes(),
178                 bitLength: uint16(n.BitLen()),
179         }
180 }
181
182 // NewRSAPublicKey returns a PublicKey that wraps the given rsa.PublicKey.
183 func NewRSAPublicKey(creationTime time.Time, pub *rsa.PublicKey) *PublicKey {
184         pk := &PublicKey{
185                 CreationTime: creationTime,
186                 PubKeyAlgo:   PubKeyAlgoRSA,
187                 PublicKey:    pub,
188                 n:            fromBig(pub.N),
189                 e:            fromBig(big.NewInt(int64(pub.E))),
190         }
191
192         pk.setFingerPrintAndKeyId()
193         return pk
194 }
195
196 // NewDSAPublicKey returns a PublicKey that wraps the given dsa.PublicKey.
197 func NewDSAPublicKey(creationTime time.Time, pub *dsa.PublicKey) *PublicKey {
198         pk := &PublicKey{
199                 CreationTime: creationTime,
200                 PubKeyAlgo:   PubKeyAlgoDSA,
201                 PublicKey:    pub,
202                 p:            fromBig(pub.P),
203                 q:            fromBig(pub.Q),
204                 g:            fromBig(pub.G),
205                 y:            fromBig(pub.Y),
206         }
207
208         pk.setFingerPrintAndKeyId()
209         return pk
210 }
211
212 // NewElGamalPublicKey returns a PublicKey that wraps the given elgamal.PublicKey.
213 func NewElGamalPublicKey(creationTime time.Time, pub *elgamal.PublicKey) *PublicKey {
214         pk := &PublicKey{
215                 CreationTime: creationTime,
216                 PubKeyAlgo:   PubKeyAlgoElGamal,
217                 PublicKey:    pub,
218                 p:            fromBig(pub.P),
219                 g:            fromBig(pub.G),
220                 y:            fromBig(pub.Y),
221         }
222
223         pk.setFingerPrintAndKeyId()
224         return pk
225 }
226
227 func NewECDSAPublicKey(creationTime time.Time, pub *ecdsa.PublicKey) *PublicKey {
228         pk := &PublicKey{
229                 CreationTime: creationTime,
230                 PubKeyAlgo:   PubKeyAlgoECDSA,
231                 PublicKey:    pub,
232                 ec:           new(ecdsaKey),
233         }
234
235         switch pub.Curve {
236         case elliptic.P256():
237                 pk.ec.oid = oidCurveP256
238         case elliptic.P384():
239                 pk.ec.oid = oidCurveP384
240         case elliptic.P521():
241                 pk.ec.oid = oidCurveP521
242         default:
243                 panic("unknown elliptic curve")
244         }
245
246         pk.ec.p.bytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y)
247         pk.ec.p.bitLength = uint16(8 * len(pk.ec.p.bytes))
248
249         pk.setFingerPrintAndKeyId()
250         return pk
251 }
252
253 func (pk *PublicKey) parse(r io.Reader) (err error) {
254         // RFC 4880, section 5.5.2
255         var buf [6]byte
256         _, err = readFull(r, buf[:])
257         if err != nil {
258                 return
259         }
260         if buf[0] != 4 {
261                 return errors.UnsupportedError("public key version")
262         }
263         pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0)
264         pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5])
265         switch pk.PubKeyAlgo {
266         case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
267                 err = pk.parseRSA(r)
268         case PubKeyAlgoDSA:
269                 err = pk.parseDSA(r)
270         case PubKeyAlgoElGamal:
271                 err = pk.parseElGamal(r)
272         case PubKeyAlgoECDSA:
273                 pk.ec = new(ecdsaKey)
274                 if err = pk.ec.parse(r); err != nil {
275                         return err
276                 }
277                 pk.PublicKey, err = pk.ec.newECDSA()
278         case PubKeyAlgoECDH:
279                 pk.ec = new(ecdsaKey)
280                 if err = pk.ec.parse(r); err != nil {
281                         return
282                 }
283                 pk.ecdh = new(ecdhKdf)
284                 if err = pk.ecdh.parse(r); err != nil {
285                         return
286                 }
287                 // The ECDH key is stored in an ecdsa.PublicKey for convenience.
288                 pk.PublicKey, err = pk.ec.newECDSA()
289         default:
290                 err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
291         }
292         if err != nil {
293                 return
294         }
295
296         pk.setFingerPrintAndKeyId()
297         return
298 }
299
300 func (pk *PublicKey) setFingerPrintAndKeyId() {
301         // RFC 4880, section 12.2
302         fingerPrint := sha1.New()
303         pk.SerializeSignaturePrefix(fingerPrint)
304         pk.serializeWithoutHeaders(fingerPrint)
305         copy(pk.Fingerprint[:], fingerPrint.Sum(nil))
306         pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20])
307 }
308
309 // parseRSA parses RSA public key material from the given Reader. See RFC 4880,
310 // section 5.5.2.
311 func (pk *PublicKey) parseRSA(r io.Reader) (err error) {
312         pk.n.bytes, pk.n.bitLength, err = readMPI(r)
313         if err != nil {
314                 return
315         }
316         pk.e.bytes, pk.e.bitLength, err = readMPI(r)
317         if err != nil {
318                 return
319         }
320
321         if len(pk.e.bytes) > 3 {
322                 err = errors.UnsupportedError("large public exponent")
323                 return
324         }
325         rsa := &rsa.PublicKey{
326                 N: new(big.Int).SetBytes(pk.n.bytes),
327                 E: 0,
328         }
329         for i := 0; i < len(pk.e.bytes); i++ {
330                 rsa.E <<= 8
331                 rsa.E |= int(pk.e.bytes[i])
332         }
333         pk.PublicKey = rsa
334         return
335 }
336
337 // parseDSA parses DSA public key material from the given Reader. See RFC 4880,
338 // section 5.5.2.
339 func (pk *PublicKey) parseDSA(r io.Reader) (err error) {
340         pk.p.bytes, pk.p.bitLength, err = readMPI(r)
341         if err != nil {
342                 return
343         }
344         pk.q.bytes, pk.q.bitLength, err = readMPI(r)
345         if err != nil {
346                 return
347         }
348         pk.g.bytes, pk.g.bitLength, err = readMPI(r)
349         if err != nil {
350                 return
351         }
352         pk.y.bytes, pk.y.bitLength, err = readMPI(r)
353         if err != nil {
354                 return
355         }
356
357         dsa := new(dsa.PublicKey)
358         dsa.P = new(big.Int).SetBytes(pk.p.bytes)
359         dsa.Q = new(big.Int).SetBytes(pk.q.bytes)
360         dsa.G = new(big.Int).SetBytes(pk.g.bytes)
361         dsa.Y = new(big.Int).SetBytes(pk.y.bytes)
362         pk.PublicKey = dsa
363         return
364 }
365
366 // parseElGamal parses ElGamal public key material from the given Reader. See
367 // RFC 4880, section 5.5.2.
368 func (pk *PublicKey) parseElGamal(r io.Reader) (err error) {
369         pk.p.bytes, pk.p.bitLength, err = readMPI(r)
370         if err != nil {
371                 return
372         }
373         pk.g.bytes, pk.g.bitLength, err = readMPI(r)
374         if err != nil {
375                 return
376         }
377         pk.y.bytes, pk.y.bitLength, err = readMPI(r)
378         if err != nil {
379                 return
380         }
381
382         elgamal := new(elgamal.PublicKey)
383         elgamal.P = new(big.Int).SetBytes(pk.p.bytes)
384         elgamal.G = new(big.Int).SetBytes(pk.g.bytes)
385         elgamal.Y = new(big.Int).SetBytes(pk.y.bytes)
386         pk.PublicKey = elgamal
387         return
388 }
389
390 // SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
391 // The prefix is used when calculating a signature over this public key. See
392 // RFC 4880, section 5.2.4.
393 func (pk *PublicKey) SerializeSignaturePrefix(h io.Writer) {
394         var pLength uint16
395         switch pk.PubKeyAlgo {
396         case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
397                 pLength += 2 + uint16(len(pk.n.bytes))
398                 pLength += 2 + uint16(len(pk.e.bytes))
399         case PubKeyAlgoDSA:
400                 pLength += 2 + uint16(len(pk.p.bytes))
401                 pLength += 2 + uint16(len(pk.q.bytes))
402                 pLength += 2 + uint16(len(pk.g.bytes))
403                 pLength += 2 + uint16(len(pk.y.bytes))
404         case PubKeyAlgoElGamal:
405                 pLength += 2 + uint16(len(pk.p.bytes))
406                 pLength += 2 + uint16(len(pk.g.bytes))
407                 pLength += 2 + uint16(len(pk.y.bytes))
408         case PubKeyAlgoECDSA:
409                 pLength += uint16(pk.ec.byteLen())
410         case PubKeyAlgoECDH:
411                 pLength += uint16(pk.ec.byteLen())
412                 pLength += uint16(pk.ecdh.byteLen())
413         default:
414                 panic("unknown public key algorithm")
415         }
416         pLength += 6
417         h.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
418         return
419 }
420
421 func (pk *PublicKey) Serialize(w io.Writer) (err error) {
422         length := 6 // 6 byte header
423
424         switch pk.PubKeyAlgo {
425         case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
426                 length += 2 + len(pk.n.bytes)
427                 length += 2 + len(pk.e.bytes)
428         case PubKeyAlgoDSA:
429                 length += 2 + len(pk.p.bytes)
430                 length += 2 + len(pk.q.bytes)
431                 length += 2 + len(pk.g.bytes)
432                 length += 2 + len(pk.y.bytes)
433         case PubKeyAlgoElGamal:
434                 length += 2 + len(pk.p.bytes)
435                 length += 2 + len(pk.g.bytes)
436                 length += 2 + len(pk.y.bytes)
437         case PubKeyAlgoECDSA:
438                 length += pk.ec.byteLen()
439         case PubKeyAlgoECDH:
440                 length += pk.ec.byteLen()
441                 length += pk.ecdh.byteLen()
442         default:
443                 panic("unknown public key algorithm")
444         }
445
446         packetType := packetTypePublicKey
447         if pk.IsSubkey {
448                 packetType = packetTypePublicSubkey
449         }
450         err = serializeHeader(w, packetType, length)
451         if err != nil {
452                 return
453         }
454         return pk.serializeWithoutHeaders(w)
455 }
456
457 // serializeWithoutHeaders marshals the PublicKey to w in the form of an
458 // OpenPGP public key packet, not including the packet header.
459 func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) {
460         var buf [6]byte
461         buf[0] = 4
462         t := uint32(pk.CreationTime.Unix())
463         buf[1] = byte(t >> 24)
464         buf[2] = byte(t >> 16)
465         buf[3] = byte(t >> 8)
466         buf[4] = byte(t)
467         buf[5] = byte(pk.PubKeyAlgo)
468
469         _, err = w.Write(buf[:])
470         if err != nil {
471                 return
472         }
473
474         switch pk.PubKeyAlgo {
475         case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
476                 return writeMPIs(w, pk.n, pk.e)
477         case PubKeyAlgoDSA:
478                 return writeMPIs(w, pk.p, pk.q, pk.g, pk.y)
479         case PubKeyAlgoElGamal:
480                 return writeMPIs(w, pk.p, pk.g, pk.y)
481         case PubKeyAlgoECDSA:
482                 return pk.ec.serialize(w)
483         case PubKeyAlgoECDH:
484                 if err = pk.ec.serialize(w); err != nil {
485                         return
486                 }
487                 return pk.ecdh.serialize(w)
488         }
489         return errors.InvalidArgumentError("bad public-key algorithm")
490 }
491
492 // CanSign returns true iff this public key can generate signatures
493 func (pk *PublicKey) CanSign() bool {
494         return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly && pk.PubKeyAlgo != PubKeyAlgoElGamal
495 }
496
497 // VerifySignature returns nil iff sig is a valid signature, made by this
498 // public key, of the data hashed into signed. signed is mutated by this call.
499 func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err error) {
500         if !pk.CanSign() {
501                 return errors.InvalidArgumentError("public key cannot generate signatures")
502         }
503
504         signed.Write(sig.HashSuffix)
505         hashBytes := signed.Sum(nil)
506
507         if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
508                 return errors.SignatureError("hash tag doesn't match")
509         }
510
511         if pk.PubKeyAlgo != sig.PubKeyAlgo {
512                 return errors.InvalidArgumentError("public key and signature use different algorithms")
513         }
514
515         switch pk.PubKeyAlgo {
516         case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
517                 rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey)
518                 err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes)
519                 if err != nil {
520                         return errors.SignatureError("RSA verification failure")
521                 }
522                 return nil
523         case PubKeyAlgoDSA:
524                 dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey)
525                 // Need to truncate hashBytes to match FIPS 186-3 section 4.6.
526                 subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
527                 if len(hashBytes) > subgroupSize {
528                         hashBytes = hashBytes[:subgroupSize]
529                 }
530                 if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) {
531                         return errors.SignatureError("DSA verification failure")
532                 }
533                 return nil
534         case PubKeyAlgoECDSA:
535                 ecdsaPublicKey := pk.PublicKey.(*ecdsa.PublicKey)
536                 if !ecdsa.Verify(ecdsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.ECDSASigR.bytes), new(big.Int).SetBytes(sig.ECDSASigS.bytes)) {
537                         return errors.SignatureError("ECDSA verification failure")
538                 }
539                 return nil
540         default:
541                 return errors.SignatureError("Unsupported public key algorithm used in signature")
542         }
543 }
544
545 // VerifySignatureV3 returns nil iff sig is a valid signature, made by this
546 // public key, of the data hashed into signed. signed is mutated by this call.
547 func (pk *PublicKey) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) {
548         if !pk.CanSign() {
549                 return errors.InvalidArgumentError("public key cannot generate signatures")
550         }
551
552         suffix := make([]byte, 5)
553         suffix[0] = byte(sig.SigType)
554         binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix()))
555         signed.Write(suffix)
556         hashBytes := signed.Sum(nil)
557
558         if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
559                 return errors.SignatureError("hash tag doesn't match")
560         }
561
562         if pk.PubKeyAlgo != sig.PubKeyAlgo {
563                 return errors.InvalidArgumentError("public key and signature use different algorithms")
564         }
565
566         switch pk.PubKeyAlgo {
567         case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
568                 rsaPublicKey := pk.PublicKey.(*rsa.PublicKey)
569                 if err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil {
570                         return errors.SignatureError("RSA verification failure")
571                 }
572                 return
573         case PubKeyAlgoDSA:
574                 dsaPublicKey := pk.PublicKey.(*dsa.PublicKey)
575                 // Need to truncate hashBytes to match FIPS 186-3 section 4.6.
576                 subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
577                 if len(hashBytes) > subgroupSize {
578                         hashBytes = hashBytes[:subgroupSize]
579                 }
580                 if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) {
581                         return errors.SignatureError("DSA verification failure")
582                 }
583                 return nil
584         default:
585                 panic("shouldn't happen")
586         }
587 }
588
589 // keySignatureHash returns a Hash of the message that needs to be signed for
590 // pk to assert a subkey relationship to signed.
591 func keySignatureHash(pk, signed signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
592         if !hashFunc.Available() {
593                 return nil, errors.UnsupportedError("hash function")
594         }
595         h = hashFunc.New()
596
597         // RFC 4880, section 5.2.4
598         pk.SerializeSignaturePrefix(h)
599         pk.serializeWithoutHeaders(h)
600         signed.SerializeSignaturePrefix(h)
601         signed.serializeWithoutHeaders(h)
602         return
603 }
604
605 // VerifyKeySignature returns nil iff sig is a valid signature, made by this
606 // public key, of signed.
607 func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) error {
608         h, err := keySignatureHash(pk, signed, sig.Hash)
609         if err != nil {
610                 return err
611         }
612         if err = pk.VerifySignature(h, sig); err != nil {
613                 return err
614         }
615
616         if sig.FlagSign {
617                 // Signing subkeys must be cross-signed. See
618                 // https://www.gnupg.org/faq/subkey-cross-certify.html.
619                 if sig.EmbeddedSignature == nil {
620                         return errors.StructuralError("signing subkey is missing cross-signature")
621                 }
622                 // Verify the cross-signature. This is calculated over the same
623                 // data as the main signature, so we cannot just recursively
624                 // call signed.VerifyKeySignature(...)
625                 if h, err = keySignatureHash(pk, signed, sig.EmbeddedSignature.Hash); err != nil {
626                         return errors.StructuralError("error while hashing for cross-signature: " + err.Error())
627                 }
628                 if err := signed.VerifySignature(h, sig.EmbeddedSignature); err != nil {
629                         return errors.StructuralError("error while verifying cross-signature: " + err.Error())
630                 }
631         }
632
633         return nil
634 }
635
636 func keyRevocationHash(pk signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
637         if !hashFunc.Available() {
638                 return nil, errors.UnsupportedError("hash function")
639         }
640         h = hashFunc.New()
641
642         // RFC 4880, section 5.2.4
643         pk.SerializeSignaturePrefix(h)
644         pk.serializeWithoutHeaders(h)
645
646         return
647 }
648
649 // VerifyRevocationSignature returns nil iff sig is a valid signature, made by this
650 // public key.
651 func (pk *PublicKey) VerifyRevocationSignature(sig *Signature) (err error) {
652         h, err := keyRevocationHash(pk, sig.Hash)
653         if err != nil {
654                 return err
655         }
656         return pk.VerifySignature(h, sig)
657 }
658
659 // userIdSignatureHash returns a Hash of the message that needs to be signed
660 // to assert that pk is a valid key for id.
661 func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
662         if !hashFunc.Available() {
663                 return nil, errors.UnsupportedError("hash function")
664         }
665         h = hashFunc.New()
666
667         // RFC 4880, section 5.2.4
668         pk.SerializeSignaturePrefix(h)
669         pk.serializeWithoutHeaders(h)
670
671         var buf [5]byte
672         buf[0] = 0xb4
673         buf[1] = byte(len(id) >> 24)
674         buf[2] = byte(len(id) >> 16)
675         buf[3] = byte(len(id) >> 8)
676         buf[4] = byte(len(id))
677         h.Write(buf[:])
678         h.Write([]byte(id))
679
680         return
681 }
682
683 // VerifyUserIdSignature returns nil iff sig is a valid signature, made by this
684 // public key, that id is the identity of pub.
685 func (pk *PublicKey) VerifyUserIdSignature(id string, pub *PublicKey, sig *Signature) (err error) {
686         h, err := userIdSignatureHash(id, pub, sig.Hash)
687         if err != nil {
688                 return err
689         }
690         return pk.VerifySignature(h, sig)
691 }
692
693 // VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this
694 // public key, that id is the identity of pub.
695 func (pk *PublicKey) VerifyUserIdSignatureV3(id string, pub *PublicKey, sig *SignatureV3) (err error) {
696         h, err := userIdSignatureV3Hash(id, pub, sig.Hash)
697         if err != nil {
698                 return err
699         }
700         return pk.VerifySignatureV3(h, sig)
701 }
702
703 // KeyIdString returns the public key's fingerprint in capital hex
704 // (e.g. "6C7EE1B8621CC013").
705 func (pk *PublicKey) KeyIdString() string {
706         return fmt.Sprintf("%X", pk.Fingerprint[12:20])
707 }
708
709 // KeyIdShortString returns the short form of public key's fingerprint
710 // in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
711 func (pk *PublicKey) KeyIdShortString() string {
712         return fmt.Sprintf("%X", pk.Fingerprint[16:20])
713 }
714
715 // A parsedMPI is used to store the contents of a big integer, along with the
716 // bit length that was specified in the original input. This allows the MPI to
717 // be reserialized exactly.
718 type parsedMPI struct {
719         bytes     []byte
720         bitLength uint16
721 }
722
723 // writeMPIs is a utility function for serializing several big integers to the
724 // given Writer.
725 func writeMPIs(w io.Writer, mpis ...parsedMPI) (err error) {
726         for _, mpi := range mpis {
727                 err = writeMPI(w, mpi.bitLength, mpi.bytes)
728                 if err != nil {
729                         return
730                 }
731         }
732         return
733 }
734
735 // BitLength returns the bit length for the given public key.
736 func (pk *PublicKey) BitLength() (bitLength uint16, err error) {
737         switch pk.PubKeyAlgo {
738         case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
739                 bitLength = pk.n.bitLength
740         case PubKeyAlgoDSA:
741                 bitLength = pk.p.bitLength
742         case PubKeyAlgoElGamal:
743                 bitLength = pk.p.bitLength
744         default:
745                 err = errors.InvalidArgumentError("bad public-key algorithm")
746         }
747         return
748 }