1// Copyright 2011 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package packet
6
7import (
8	"bytes"
9	"crypto"
10	"crypto/dsa"
11	"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
29var (
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
38const maxOIDLength = 8
39
40// ecdsaKey stores the algorithm-specific fields for ECDSA keys.
41// as defined in RFC 6637, Section 9.
42type 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.
50func 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
65func (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
73func (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
83func (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
101func (f *ecdsaKey) byteLen() int {
102	return 1 + len(f.oid) + 2 + len(f.p.bytes)
103}
104
105type kdfHashFunction byte
106type kdfAlgorithm byte
107
108// ecdhKdf stores key derivation function parameters
109// used for ECDH encryption. See RFC 6637, Section 9.
110type ecdhKdf struct {
111	KdfHash kdfHashFunction
112	KdfAlgo kdfAlgorithm
113}
114
115func (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
137func (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
148func (f *ecdhKdf) byteLen() int {
149	return 4
150}
151
152// PublicKey represents an OpenPGP public key. See RFC 4880, section 5.5.2.
153type 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.
170type signingKey interface {
171	SerializeSignaturePrefix(io.Writer)
172	serializeWithoutHeaders(io.Writer) error
173}
174
175func 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.
183func 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.
197func 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.
213func 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
227func 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
248	// The bit length is 3 (for the 0x04 specifying an uncompressed key)
249	// plus two field elements (for x and y), which are rounded up to the
250	// nearest byte. See https://tools.ietf.org/html/rfc6637#section-6
251	fieldBytes := (pub.Curve.Params().BitSize + 7) & ^7
252	pk.ec.p.bitLength = uint16(3 + fieldBytes + fieldBytes)
253
254	pk.setFingerPrintAndKeyId()
255	return pk
256}
257
258func (pk *PublicKey) parse(r io.Reader) (err error) {
259	// RFC 4880, section 5.5.2
260	var buf [6]byte
261	_, err = readFull(r, buf[:])
262	if err != nil {
263		return
264	}
265	if buf[0] != 4 {
266		return errors.UnsupportedError("public key version")
267	}
268	pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0)
269	pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5])
270	switch pk.PubKeyAlgo {
271	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
272		err = pk.parseRSA(r)
273	case PubKeyAlgoDSA:
274		err = pk.parseDSA(r)
275	case PubKeyAlgoElGamal:
276		err = pk.parseElGamal(r)
277	case PubKeyAlgoECDSA:
278		pk.ec = new(ecdsaKey)
279		if err = pk.ec.parse(r); err != nil {
280			return err
281		}
282		pk.PublicKey, err = pk.ec.newECDSA()
283	case PubKeyAlgoECDH:
284		pk.ec = new(ecdsaKey)
285		if err = pk.ec.parse(r); err != nil {
286			return
287		}
288		pk.ecdh = new(ecdhKdf)
289		if err = pk.ecdh.parse(r); err != nil {
290			return
291		}
292		// The ECDH key is stored in an ecdsa.PublicKey for convenience.
293		pk.PublicKey, err = pk.ec.newECDSA()
294	default:
295		err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
296	}
297	if err != nil {
298		return
299	}
300
301	pk.setFingerPrintAndKeyId()
302	return
303}
304
305func (pk *PublicKey) setFingerPrintAndKeyId() {
306	// RFC 4880, section 12.2
307	fingerPrint := sha1.New()
308	pk.SerializeSignaturePrefix(fingerPrint)
309	pk.serializeWithoutHeaders(fingerPrint)
310	copy(pk.Fingerprint[:], fingerPrint.Sum(nil))
311	pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20])
312}
313
314// parseRSA parses RSA public key material from the given Reader. See RFC 4880,
315// section 5.5.2.
316func (pk *PublicKey) parseRSA(r io.Reader) (err error) {
317	pk.n.bytes, pk.n.bitLength, err = readMPI(r)
318	if err != nil {
319		return
320	}
321	pk.e.bytes, pk.e.bitLength, err = readMPI(r)
322	if err != nil {
323		return
324	}
325
326	if len(pk.e.bytes) > 3 {
327		err = errors.UnsupportedError("large public exponent")
328		return
329	}
330	rsa := &rsa.PublicKey{
331		N: new(big.Int).SetBytes(pk.n.bytes),
332		E: 0,
333	}
334	for i := 0; i < len(pk.e.bytes); i++ {
335		rsa.E <<= 8
336		rsa.E |= int(pk.e.bytes[i])
337	}
338	pk.PublicKey = rsa
339	return
340}
341
342// parseDSA parses DSA public key material from the given Reader. See RFC 4880,
343// section 5.5.2.
344func (pk *PublicKey) parseDSA(r io.Reader) (err error) {
345	pk.p.bytes, pk.p.bitLength, err = readMPI(r)
346	if err != nil {
347		return
348	}
349	pk.q.bytes, pk.q.bitLength, err = readMPI(r)
350	if err != nil {
351		return
352	}
353	pk.g.bytes, pk.g.bitLength, err = readMPI(r)
354	if err != nil {
355		return
356	}
357	pk.y.bytes, pk.y.bitLength, err = readMPI(r)
358	if err != nil {
359		return
360	}
361
362	dsa := new(dsa.PublicKey)
363	dsa.P = new(big.Int).SetBytes(pk.p.bytes)
364	dsa.Q = new(big.Int).SetBytes(pk.q.bytes)
365	dsa.G = new(big.Int).SetBytes(pk.g.bytes)
366	dsa.Y = new(big.Int).SetBytes(pk.y.bytes)
367	pk.PublicKey = dsa
368	return
369}
370
371// parseElGamal parses ElGamal public key material from the given Reader. See
372// RFC 4880, section 5.5.2.
373func (pk *PublicKey) parseElGamal(r io.Reader) (err error) {
374	pk.p.bytes, pk.p.bitLength, err = readMPI(r)
375	if err != nil {
376		return
377	}
378	pk.g.bytes, pk.g.bitLength, err = readMPI(r)
379	if err != nil {
380		return
381	}
382	pk.y.bytes, pk.y.bitLength, err = readMPI(r)
383	if err != nil {
384		return
385	}
386
387	elgamal := new(elgamal.PublicKey)
388	elgamal.P = new(big.Int).SetBytes(pk.p.bytes)
389	elgamal.G = new(big.Int).SetBytes(pk.g.bytes)
390	elgamal.Y = new(big.Int).SetBytes(pk.y.bytes)
391	pk.PublicKey = elgamal
392	return
393}
394
395// SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
396// The prefix is used when calculating a signature over this public key. See
397// RFC 4880, section 5.2.4.
398func (pk *PublicKey) SerializeSignaturePrefix(h io.Writer) {
399	var pLength uint16
400	switch pk.PubKeyAlgo {
401	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
402		pLength += 2 + uint16(len(pk.n.bytes))
403		pLength += 2 + uint16(len(pk.e.bytes))
404	case PubKeyAlgoDSA:
405		pLength += 2 + uint16(len(pk.p.bytes))
406		pLength += 2 + uint16(len(pk.q.bytes))
407		pLength += 2 + uint16(len(pk.g.bytes))
408		pLength += 2 + uint16(len(pk.y.bytes))
409	case PubKeyAlgoElGamal:
410		pLength += 2 + uint16(len(pk.p.bytes))
411		pLength += 2 + uint16(len(pk.g.bytes))
412		pLength += 2 + uint16(len(pk.y.bytes))
413	case PubKeyAlgoECDSA:
414		pLength += uint16(pk.ec.byteLen())
415	case PubKeyAlgoECDH:
416		pLength += uint16(pk.ec.byteLen())
417		pLength += uint16(pk.ecdh.byteLen())
418	default:
419		panic("unknown public key algorithm")
420	}
421	pLength += 6
422	h.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
423	return
424}
425
426func (pk *PublicKey) Serialize(w io.Writer) (err error) {
427	length := 6 // 6 byte header
428
429	switch pk.PubKeyAlgo {
430	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
431		length += 2 + len(pk.n.bytes)
432		length += 2 + len(pk.e.bytes)
433	case PubKeyAlgoDSA:
434		length += 2 + len(pk.p.bytes)
435		length += 2 + len(pk.q.bytes)
436		length += 2 + len(pk.g.bytes)
437		length += 2 + len(pk.y.bytes)
438	case PubKeyAlgoElGamal:
439		length += 2 + len(pk.p.bytes)
440		length += 2 + len(pk.g.bytes)
441		length += 2 + len(pk.y.bytes)
442	case PubKeyAlgoECDSA:
443		length += pk.ec.byteLen()
444	case PubKeyAlgoECDH:
445		length += pk.ec.byteLen()
446		length += pk.ecdh.byteLen()
447	default:
448		panic("unknown public key algorithm")
449	}
450
451	packetType := packetTypePublicKey
452	if pk.IsSubkey {
453		packetType = packetTypePublicSubkey
454	}
455	err = serializeHeader(w, packetType, length)
456	if err != nil {
457		return
458	}
459	return pk.serializeWithoutHeaders(w)
460}
461
462// serializeWithoutHeaders marshals the PublicKey to w in the form of an
463// OpenPGP public key packet, not including the packet header.
464func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) {
465	var buf [6]byte
466	buf[0] = 4
467	t := uint32(pk.CreationTime.Unix())
468	buf[1] = byte(t >> 24)
469	buf[2] = byte(t >> 16)
470	buf[3] = byte(t >> 8)
471	buf[4] = byte(t)
472	buf[5] = byte(pk.PubKeyAlgo)
473
474	_, err = w.Write(buf[:])
475	if err != nil {
476		return
477	}
478
479	switch pk.PubKeyAlgo {
480	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
481		return writeMPIs(w, pk.n, pk.e)
482	case PubKeyAlgoDSA:
483		return writeMPIs(w, pk.p, pk.q, pk.g, pk.y)
484	case PubKeyAlgoElGamal:
485		return writeMPIs(w, pk.p, pk.g, pk.y)
486	case PubKeyAlgoECDSA:
487		return pk.ec.serialize(w)
488	case PubKeyAlgoECDH:
489		if err = pk.ec.serialize(w); err != nil {
490			return
491		}
492		return pk.ecdh.serialize(w)
493	}
494	return errors.InvalidArgumentError("bad public-key algorithm")
495}
496
497// CanSign returns true iff this public key can generate signatures
498func (pk *PublicKey) CanSign() bool {
499	return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly && pk.PubKeyAlgo != PubKeyAlgoElGamal
500}
501
502// VerifySignature returns nil iff sig is a valid signature, made by this
503// public key, of the data hashed into signed. signed is mutated by this call.
504func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err error) {
505	if !pk.CanSign() {
506		return errors.InvalidArgumentError("public key cannot generate signatures")
507	}
508
509	signed.Write(sig.HashSuffix)
510	hashBytes := signed.Sum(nil)
511
512	if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
513		return errors.SignatureError("hash tag doesn't match")
514	}
515
516	if pk.PubKeyAlgo != sig.PubKeyAlgo {
517		return errors.InvalidArgumentError("public key and signature use different algorithms")
518	}
519
520	switch pk.PubKeyAlgo {
521	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
522		rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey)
523		err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, padToKeySize(rsaPublicKey, sig.RSASignature.bytes))
524		if err != nil {
525			return errors.SignatureError("RSA verification failure")
526		}
527		return nil
528	case PubKeyAlgoDSA:
529		dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey)
530		// Need to truncate hashBytes to match FIPS 186-3 section 4.6.
531		subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
532		if len(hashBytes) > subgroupSize {
533			hashBytes = hashBytes[:subgroupSize]
534		}
535		if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) {
536			return errors.SignatureError("DSA verification failure")
537		}
538		return nil
539	case PubKeyAlgoECDSA:
540		ecdsaPublicKey := pk.PublicKey.(*ecdsa.PublicKey)
541		if !ecdsa.Verify(ecdsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.ECDSASigR.bytes), new(big.Int).SetBytes(sig.ECDSASigS.bytes)) {
542			return errors.SignatureError("ECDSA verification failure")
543		}
544		return nil
545	default:
546		return errors.SignatureError("Unsupported public key algorithm used in signature")
547	}
548}
549
550// VerifySignatureV3 returns nil iff sig is a valid signature, made by this
551// public key, of the data hashed into signed. signed is mutated by this call.
552func (pk *PublicKey) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) {
553	if !pk.CanSign() {
554		return errors.InvalidArgumentError("public key cannot generate signatures")
555	}
556
557	suffix := make([]byte, 5)
558	suffix[0] = byte(sig.SigType)
559	binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix()))
560	signed.Write(suffix)
561	hashBytes := signed.Sum(nil)
562
563	if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
564		return errors.SignatureError("hash tag doesn't match")
565	}
566
567	if pk.PubKeyAlgo != sig.PubKeyAlgo {
568		return errors.InvalidArgumentError("public key and signature use different algorithms")
569	}
570
571	switch pk.PubKeyAlgo {
572	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
573		rsaPublicKey := pk.PublicKey.(*rsa.PublicKey)
574		if err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, padToKeySize(rsaPublicKey, sig.RSASignature.bytes)); err != nil {
575			return errors.SignatureError("RSA verification failure")
576		}
577		return
578	case PubKeyAlgoDSA:
579		dsaPublicKey := pk.PublicKey.(*dsa.PublicKey)
580		// Need to truncate hashBytes to match FIPS 186-3 section 4.6.
581		subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
582		if len(hashBytes) > subgroupSize {
583			hashBytes = hashBytes[:subgroupSize]
584		}
585		if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) {
586			return errors.SignatureError("DSA verification failure")
587		}
588		return nil
589	default:
590		panic("shouldn't happen")
591	}
592}
593
594// keySignatureHash returns a Hash of the message that needs to be signed for
595// pk to assert a subkey relationship to signed.
596func keySignatureHash(pk, signed signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
597	if !hashFunc.Available() {
598		return nil, errors.UnsupportedError("hash function")
599	}
600	h = hashFunc.New()
601
602	// RFC 4880, section 5.2.4
603	pk.SerializeSignaturePrefix(h)
604	pk.serializeWithoutHeaders(h)
605	signed.SerializeSignaturePrefix(h)
606	signed.serializeWithoutHeaders(h)
607	return
608}
609
610// VerifyKeySignature returns nil iff sig is a valid signature, made by this
611// public key, of signed.
612func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) error {
613	h, err := keySignatureHash(pk, signed, sig.Hash)
614	if err != nil {
615		return err
616	}
617	if err = pk.VerifySignature(h, sig); err != nil {
618		return err
619	}
620
621	if sig.FlagSign {
622		// Signing subkeys must be cross-signed. See
623		// https://www.gnupg.org/faq/subkey-cross-certify.html.
624		if sig.EmbeddedSignature == nil {
625			return errors.StructuralError("signing subkey is missing cross-signature")
626		}
627		// Verify the cross-signature. This is calculated over the same
628		// data as the main signature, so we cannot just recursively
629		// call signed.VerifyKeySignature(...)
630		if h, err = keySignatureHash(pk, signed, sig.EmbeddedSignature.Hash); err != nil {
631			return errors.StructuralError("error while hashing for cross-signature: " + err.Error())
632		}
633		if err := signed.VerifySignature(h, sig.EmbeddedSignature); err != nil {
634			return errors.StructuralError("error while verifying cross-signature: " + err.Error())
635		}
636	}
637
638	return nil
639}
640
641func keyRevocationHash(pk signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
642	if !hashFunc.Available() {
643		return nil, errors.UnsupportedError("hash function")
644	}
645	h = hashFunc.New()
646
647	// RFC 4880, section 5.2.4
648	pk.SerializeSignaturePrefix(h)
649	pk.serializeWithoutHeaders(h)
650
651	return
652}
653
654// VerifyRevocationSignature returns nil iff sig is a valid signature, made by this
655// public key.
656func (pk *PublicKey) VerifyRevocationSignature(sig *Signature) (err error) {
657	h, err := keyRevocationHash(pk, sig.Hash)
658	if err != nil {
659		return err
660	}
661	return pk.VerifySignature(h, sig)
662}
663
664// userIdSignatureHash returns a Hash of the message that needs to be signed
665// to assert that pk is a valid key for id.
666func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
667	if !hashFunc.Available() {
668		return nil, errors.UnsupportedError("hash function")
669	}
670	h = hashFunc.New()
671
672	// RFC 4880, section 5.2.4
673	pk.SerializeSignaturePrefix(h)
674	pk.serializeWithoutHeaders(h)
675
676	var buf [5]byte
677	buf[0] = 0xb4
678	buf[1] = byte(len(id) >> 24)
679	buf[2] = byte(len(id) >> 16)
680	buf[3] = byte(len(id) >> 8)
681	buf[4] = byte(len(id))
682	h.Write(buf[:])
683	h.Write([]byte(id))
684
685	return
686}
687
688// VerifyUserIdSignature returns nil iff sig is a valid signature, made by this
689// public key, that id is the identity of pub.
690func (pk *PublicKey) VerifyUserIdSignature(id string, pub *PublicKey, sig *Signature) (err error) {
691	h, err := userIdSignatureHash(id, pub, sig.Hash)
692	if err != nil {
693		return err
694	}
695	return pk.VerifySignature(h, sig)
696}
697
698// VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this
699// public key, that id is the identity of pub.
700func (pk *PublicKey) VerifyUserIdSignatureV3(id string, pub *PublicKey, sig *SignatureV3) (err error) {
701	h, err := userIdSignatureV3Hash(id, pub, sig.Hash)
702	if err != nil {
703		return err
704	}
705	return pk.VerifySignatureV3(h, sig)
706}
707
708// KeyIdString returns the public key's fingerprint in capital hex
709// (e.g. "6C7EE1B8621CC013").
710func (pk *PublicKey) KeyIdString() string {
711	return fmt.Sprintf("%X", pk.Fingerprint[12:20])
712}
713
714// KeyIdShortString returns the short form of public key's fingerprint
715// in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
716func (pk *PublicKey) KeyIdShortString() string {
717	return fmt.Sprintf("%X", pk.Fingerprint[16:20])
718}
719
720// A parsedMPI is used to store the contents of a big integer, along with the
721// bit length that was specified in the original input. This allows the MPI to
722// be reserialized exactly.
723type parsedMPI struct {
724	bytes     []byte
725	bitLength uint16
726}
727
728// writeMPIs is a utility function for serializing several big integers to the
729// given Writer.
730func writeMPIs(w io.Writer, mpis ...parsedMPI) (err error) {
731	for _, mpi := range mpis {
732		err = writeMPI(w, mpi.bitLength, mpi.bytes)
733		if err != nil {
734			return
735		}
736	}
737	return
738}
739
740// BitLength returns the bit length for the given public key.
741func (pk *PublicKey) BitLength() (bitLength uint16, err error) {
742	switch pk.PubKeyAlgo {
743	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
744		bitLength = pk.n.bitLength
745	case PubKeyAlgoDSA:
746		bitLength = pk.p.bitLength
747	case PubKeyAlgoElGamal:
748		bitLength = pk.p.bitLength
749	default:
750		err = errors.InvalidArgumentError("bad public-key algorithm")
751	}
752	return
753}
754