]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/golang.org/x/crypto/openpgp/packet/public_key.go
Merge pull request #3 from terraform-providers/vendor-tf-0.10
[github/fretlink/terraform-provider-statuscake.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 }