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/sha1"
14	_ "crypto/sha256"
15	_ "crypto/sha512"
16	"encoding/binary"
17	"fmt"
18	"hash"
19	"io"
20	"math/big"
21	"strconv"
22	"time"
23
24	"github.com/keybase/go-crypto/brainpool"
25	"github.com/keybase/go-crypto/curve25519"
26	"github.com/keybase/go-crypto/ed25519"
27	"github.com/keybase/go-crypto/openpgp/ecdh"
28	"github.com/keybase/go-crypto/openpgp/elgamal"
29	"github.com/keybase/go-crypto/openpgp/errors"
30	"github.com/keybase/go-crypto/openpgp/s2k"
31	"github.com/keybase/go-crypto/rsa"
32)
33
34var (
35	// NIST curve P-224
36	oidCurveP224 []byte = []byte{0x2B, 0x81, 0x04, 0x00, 0x21}
37	// NIST curve P-256
38	oidCurveP256 []byte = []byte{0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07}
39	// NIST curve P-384
40	oidCurveP384 []byte = []byte{0x2B, 0x81, 0x04, 0x00, 0x22}
41	// NIST curve P-521
42	oidCurveP521 []byte = []byte{0x2B, 0x81, 0x04, 0x00, 0x23}
43	// Brainpool curve P-256r1
44	oidCurveP256r1 []byte = []byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07}
45	// Brainpool curve P-384r1
46	oidCurveP384r1 []byte = []byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B}
47	// Brainpool curve P-512r1
48	oidCurveP512r1 []byte = []byte{0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D}
49	// EdDSA
50	oidEdDSA []byte = []byte{0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01}
51	// cv25519
52	oidCurve25519 []byte = []byte{0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01}
53)
54
55const maxOIDLength = 10
56
57// ecdsaKey stores the algorithm-specific fields for ECDSA keys.
58// as defined in RFC 6637, Section 9.
59type ecdsaKey struct {
60	// oid contains the OID byte sequence identifying the elliptic curve used
61	oid []byte
62	// p contains the elliptic curve point that represents the public key
63	p parsedMPI
64}
65
66type edDSAkey struct {
67	ecdsaKey
68}
69
70func copyFrontFill(dst, src []byte, length int) int {
71	if srcLen := len(src); srcLen < length {
72		return copy(dst[length-srcLen:], src[:])
73	} else {
74		return copy(dst[:], src[:])
75	}
76}
77
78func (e *edDSAkey) Verify(payload []byte, r parsedMPI, s parsedMPI) bool {
79	const halfSigSize = ed25519.SignatureSize / 2
80	var sig [ed25519.SignatureSize]byte
81
82	// NOTE: The first byte is 0x40 - MPI header
83	// TODO: Maybe clean the code up and use 0x40 as a header when
84	// reading and keep only actual number in p field. Find out how
85	// other MPIs are stored.
86	key := e.p.bytes[1:]
87
88	// Note: it may happen that R + S do not form 64-byte signature buffer that
89	// ed25519 expects, but because we copy it over to an array of exact size,
90	// we will always pass correctly sized slice to Verify. Slice too short
91	// would make ed25519 panic().
92	copyFrontFill(sig[:halfSigSize], r.bytes, halfSigSize)
93	copyFrontFill(sig[halfSigSize:], s.bytes, halfSigSize)
94
95	return ed25519.Verify(key, payload, sig[:])
96}
97
98// parseOID reads the OID for the curve as defined in RFC 6637, Section 9.
99func parseOID(r io.Reader) (oid []byte, err error) {
100	buf := make([]byte, maxOIDLength)
101	if _, err = readFull(r, buf[:1]); err != nil {
102		return
103	}
104	oidLen := buf[0]
105	if int(oidLen) > len(buf) {
106		err = errors.UnsupportedError("invalid oid length: " + strconv.Itoa(int(oidLen)))
107		return
108	}
109	oid = buf[:oidLen]
110	_, err = readFull(r, oid)
111	return
112}
113
114func (f *ecdsaKey) parse(r io.Reader) (err error) {
115	if f.oid, err = parseOID(r); err != nil {
116		return err
117	}
118	f.p.bytes, f.p.bitLength, err = readMPI(r)
119	return err
120}
121
122func (f *ecdsaKey) serialize(w io.Writer) (err error) {
123	buf := make([]byte, maxOIDLength+1)
124	buf[0] = byte(len(f.oid))
125	copy(buf[1:], f.oid)
126	if _, err = w.Write(buf[:len(f.oid)+1]); err != nil {
127		return
128	}
129	return writeMPIs(w, f.p)
130}
131
132func getCurveByOid(oid []byte) elliptic.Curve {
133	switch {
134	case bytes.Equal(oid, oidCurveP224):
135		return elliptic.P224()
136	case bytes.Equal(oid, oidCurveP256):
137		return elliptic.P256()
138	case bytes.Equal(oid, oidCurveP384):
139		return elliptic.P384()
140	case bytes.Equal(oid, oidCurveP521):
141		return elliptic.P521()
142	case bytes.Equal(oid, oidCurveP256r1):
143		return brainpool.P256r1()
144	case bytes.Equal(oid, oidCurveP384r1):
145		return brainpool.P384r1()
146	case bytes.Equal(oid, oidCurveP512r1):
147		return brainpool.P512r1()
148	case bytes.Equal(oid, oidCurve25519):
149		return curve25519.Cv25519()
150	default:
151		return nil
152	}
153}
154
155func (f *ecdsaKey) newECDSA() (*ecdsa.PublicKey, error) {
156	var c = getCurveByOid(f.oid)
157	// Curve25519 should not be used in ECDSA.
158	if c == nil || bytes.Equal(f.oid, oidCurve25519) {
159		return nil, errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", f.oid))
160	}
161	// Note: Unmarshal already checks if point is on curve.
162	x, y := elliptic.Unmarshal(c, f.p.bytes)
163	if x == nil {
164		return nil, errors.UnsupportedError("failed to parse EC point")
165	}
166	return &ecdsa.PublicKey{Curve: c, X: x, Y: y}, nil
167}
168
169func (f *ecdsaKey) newECDH() (*ecdh.PublicKey, error) {
170	var c = getCurveByOid(f.oid)
171	if c == nil {
172		return nil, errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", f.oid))
173	}
174	// ecdh.Unmarshal handles unmarshaling for all curve types. It
175	// also checks if point is on curve.
176	x, y := ecdh.Unmarshal(c, f.p.bytes)
177	if x == nil {
178		return nil, errors.UnsupportedError("failed to parse EC point")
179	}
180	return &ecdh.PublicKey{Curve: c, X: x, Y: y}, nil
181}
182
183func (f *ecdsaKey) byteLen() int {
184	return 1 + len(f.oid) + 2 + len(f.p.bytes)
185}
186
187type kdfHashFunction byte
188type kdfAlgorithm byte
189
190// ecdhKdf stores key derivation function parameters
191// used for ECDH encryption. See RFC 6637, Section 9.
192type ecdhKdf struct {
193	KdfHash kdfHashFunction
194	KdfAlgo kdfAlgorithm
195}
196
197func (f *ecdhKdf) parse(r io.Reader) (err error) {
198	buf := make([]byte, 1)
199	if _, err = readFull(r, buf); err != nil {
200		return
201	}
202	kdfLen := int(buf[0])
203	if kdfLen < 3 {
204		return errors.UnsupportedError("Unsupported ECDH KDF length: " + strconv.Itoa(kdfLen))
205	}
206	buf = make([]byte, kdfLen)
207	if _, err = readFull(r, buf); err != nil {
208		return
209	}
210	reserved := int(buf[0])
211	f.KdfHash = kdfHashFunction(buf[1])
212	f.KdfAlgo = kdfAlgorithm(buf[2])
213	if reserved != 0x01 {
214		return errors.UnsupportedError("Unsupported KDF reserved field: " + strconv.Itoa(reserved))
215	}
216	return
217}
218
219func (f *ecdhKdf) serialize(w io.Writer) (err error) {
220	buf := make([]byte, 4)
221	// See RFC 6637, Section 9, Algorithm-Specific Fields for ECDH keys.
222	buf[0] = byte(0x03) // Length of the following fields
223	buf[1] = byte(0x01) // Reserved for future extensions, must be 1 for now
224	buf[2] = byte(f.KdfHash)
225	buf[3] = byte(f.KdfAlgo)
226	_, err = w.Write(buf[:])
227	return
228}
229
230func (f *ecdhKdf) byteLen() int {
231	return 4
232}
233
234// PublicKey represents an OpenPGP public key. See RFC 4880, section 5.5.2.
235type PublicKey struct {
236	CreationTime time.Time
237	PubKeyAlgo   PublicKeyAlgorithm
238	PublicKey    interface{} // *rsa.PublicKey, *dsa.PublicKey or *ecdsa.PublicKey
239	Fingerprint  [20]byte
240	KeyId        uint64
241	IsSubkey     bool
242
243	n, e, p, q, g, y parsedMPI
244
245	// RFC 6637 fields
246	ec   *ecdsaKey
247	ecdh *ecdhKdf
248
249	// EdDSA fields (no RFC available), uses ecdsa scaffolding
250	edk *edDSAkey
251}
252
253// signingKey provides a convenient abstraction over signature verification
254// for v3 and v4 public keys.
255type signingKey interface {
256	SerializeSignaturePrefix(io.Writer)
257	serializeWithoutHeaders(io.Writer) error
258}
259
260func FromBig(n *big.Int) parsedMPI {
261	return parsedMPI{
262		bytes:     n.Bytes(),
263		bitLength: uint16(n.BitLen()),
264	}
265}
266
267func FromBytes(bytes []byte) parsedMPI {
268	return parsedMPI{
269		bytes:     bytes,
270		bitLength: uint16(8 * len(bytes)),
271	}
272}
273
274// NewRSAPublicKey returns a PublicKey that wraps the given rsa.PublicKey.
275func NewRSAPublicKey(creationTime time.Time, pub *rsa.PublicKey) *PublicKey {
276	pk := &PublicKey{
277		CreationTime: creationTime,
278		PubKeyAlgo:   PubKeyAlgoRSA,
279		PublicKey:    pub,
280		n:            FromBig(pub.N),
281		e:            FromBig(big.NewInt(int64(pub.E))),
282	}
283
284	pk.setFingerPrintAndKeyId()
285	return pk
286}
287
288// NewDSAPublicKey returns a PublicKey that wraps the given dsa.PublicKey.
289func NewDSAPublicKey(creationTime time.Time, pub *dsa.PublicKey) *PublicKey {
290	pk := &PublicKey{
291		CreationTime: creationTime,
292		PubKeyAlgo:   PubKeyAlgoDSA,
293		PublicKey:    pub,
294		p:            FromBig(pub.P),
295		q:            FromBig(pub.Q),
296		g:            FromBig(pub.G),
297		y:            FromBig(pub.Y),
298	}
299
300	pk.setFingerPrintAndKeyId()
301	return pk
302}
303
304// check EdDSA public key material.
305// There is currently no RFC for it, but it doesn't mean it's not
306// implemented or in use.
307func (e *edDSAkey) check() error {
308	if !bytes.Equal(e.oid, oidEdDSA) {
309		return errors.UnsupportedError(fmt.Sprintf("Bad OID for EdDSA key: %v", e.oid))
310	}
311	if bLen := len(e.p.bytes); bLen != 33 { // 32 bytes for ed25519 key and 1 byte for 0x40 header
312		return errors.UnsupportedError(fmt.Sprintf("Unexpected EdDSA public key length: %d", bLen))
313	}
314	return nil
315}
316
317// NewElGamalPublicKey returns a PublicKey that wraps the given elgamal.PublicKey.
318func NewElGamalPublicKey(creationTime time.Time, pub *elgamal.PublicKey) *PublicKey {
319	pk := &PublicKey{
320		CreationTime: creationTime,
321		PubKeyAlgo:   PubKeyAlgoElGamal,
322		PublicKey:    pub,
323		p:            FromBig(pub.P),
324		g:            FromBig(pub.G),
325		y:            FromBig(pub.Y),
326	}
327
328	pk.setFingerPrintAndKeyId()
329	return pk
330}
331
332func getCurveOid(curve elliptic.Curve) (res []byte, err error) {
333	switch curve {
334	case elliptic.P224():
335		res = oidCurveP224
336	case elliptic.P256():
337		res = oidCurveP256
338	case elliptic.P384():
339		res = oidCurveP384
340	case elliptic.P521():
341		res = oidCurveP521
342	case brainpool.P256r1():
343		res = oidCurveP256r1
344	case brainpool.P384r1():
345		res = oidCurveP384r1
346	case brainpool.P512r1():
347		res = oidCurveP512r1
348	case curve25519.Cv25519():
349		res = oidCurve25519
350	default:
351		err = errors.UnsupportedError("unknown curve")
352	}
353	return
354}
355
356func NewECDSAPublicKey(creationTime time.Time, pub *ecdsa.PublicKey) *PublicKey {
357	pk := &PublicKey{
358		CreationTime: creationTime,
359		PubKeyAlgo:   PubKeyAlgoECDSA,
360		PublicKey:    pub,
361		ec:           new(ecdsaKey),
362	}
363	oid, _ := getCurveOid(pub.Curve)
364	pk.ec.oid = oid
365	bs, bitLen := ecdh.Marshal(pub.Curve, pub.X, pub.Y)
366	pk.ec.p.bytes = bs
367	pk.ec.p.bitLength = uint16(bitLen)
368
369	pk.setFingerPrintAndKeyId()
370	return pk
371}
372
373func NewECDHPublicKey(creationTime time.Time, pub *ecdh.PublicKey) *PublicKey {
374	pk := &PublicKey{
375		CreationTime: creationTime,
376		PubKeyAlgo:   PubKeyAlgoECDH,
377		PublicKey:    pub,
378		ec:           new(ecdsaKey),
379	}
380	oid, _ := getCurveOid(pub.Curve)
381	pk.ec.oid = oid
382	bs, bitLen := ecdh.Marshal(pub.Curve, pub.X, pub.Y)
383	pk.ec.p.bytes = bs
384	pk.ec.p.bitLength = uint16(bitLen)
385
386	hashbyte, _ := s2k.HashToHashId(crypto.SHA512)
387	pk.ecdh = &ecdhKdf{
388		KdfHash: kdfHashFunction(hashbyte),
389		KdfAlgo: kdfAlgorithm(CipherAES256),
390	}
391
392	pk.setFingerPrintAndKeyId()
393	return pk
394}
395
396func (pk *PublicKey) parse(r io.Reader) (err error) {
397	// RFC 4880, section 5.5.2
398	var buf [6]byte
399	_, err = readFull(r, buf[:])
400	if err != nil {
401		return
402	}
403	if buf[0] != 4 {
404		return errors.UnsupportedError("public key version")
405	}
406	pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0)
407	pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5])
408	switch pk.PubKeyAlgo {
409	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
410		err = pk.parseRSA(r)
411	case PubKeyAlgoDSA:
412		err = pk.parseDSA(r)
413	case PubKeyAlgoElGamal:
414		err = pk.parseElGamal(r)
415	case PubKeyAlgoEdDSA:
416		pk.edk = new(edDSAkey)
417		if err = pk.edk.parse(r); err != nil {
418			return err
419		}
420		err = pk.edk.check()
421		if err == nil {
422			pk.PublicKey = ed25519.PublicKey(pk.edk.p.bytes[1:])
423		}
424	case PubKeyAlgoECDSA:
425		pk.ec = new(ecdsaKey)
426		if err = pk.ec.parse(r); err != nil {
427			return err
428		}
429		pk.PublicKey, err = pk.ec.newECDSA()
430	case PubKeyAlgoECDH:
431		pk.ec = new(ecdsaKey)
432		if err = pk.ec.parse(r); err != nil {
433			return
434		}
435		pk.ecdh = new(ecdhKdf)
436		if err = pk.ecdh.parse(r); err != nil {
437			return
438		}
439		pk.PublicKey, err = pk.ec.newECDH()
440	case PubKeyAlgoBadElGamal:
441		// Key has ElGamal format but nil-implementation - it will
442		// load but it's not possible to do any operations using this
443		// key.
444		err = pk.parseElGamal(r)
445		if err != nil {
446			pk.PublicKey = nil
447		}
448	default:
449		err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
450	}
451	if err != nil {
452		return
453	}
454
455	pk.setFingerPrintAndKeyId()
456	return
457}
458
459func (pk *PublicKey) setFingerPrintAndKeyId() {
460	// RFC 4880, section 12.2
461	fingerPrint := sha1.New()
462	pk.SerializeSignaturePrefix(fingerPrint)
463	pk.serializeWithoutHeaders(fingerPrint)
464	copy(pk.Fingerprint[:], fingerPrint.Sum(nil))
465	pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20])
466}
467
468// parseRSA parses RSA public key material from the given Reader. See RFC 4880,
469// section 5.5.2.
470func (pk *PublicKey) parseRSA(r io.Reader) (err error) {
471	pk.n.bytes, pk.n.bitLength, err = readMPI(r)
472	if err != nil {
473		return
474	}
475	pk.e.bytes, pk.e.bitLength, err = readMPI(r)
476	if err != nil {
477		return
478	}
479
480	if len(pk.e.bytes) > 7 {
481		err = errors.UnsupportedError("large public exponent")
482		return
483	}
484	rsa := &rsa.PublicKey{
485		N: new(big.Int).SetBytes(pk.n.bytes),
486		E: 0,
487	}
488	// Warning: incompatibility with crypto/rsa: keybase fork uses
489	// int64 public exponents instead of int32.
490	for i := 0; i < len(pk.e.bytes); i++ {
491		rsa.E <<= 8
492		rsa.E |= int64(pk.e.bytes[i])
493	}
494	pk.PublicKey = rsa
495	return
496}
497
498// parseDSA parses DSA public key material from the given Reader. See RFC 4880,
499// section 5.5.2.
500func (pk *PublicKey) parseDSA(r io.Reader) (err error) {
501	pk.p.bytes, pk.p.bitLength, err = readMPI(r)
502	if err != nil {
503		return
504	}
505	pk.q.bytes, pk.q.bitLength, err = readMPI(r)
506	if err != nil {
507		return
508	}
509	pk.g.bytes, pk.g.bitLength, err = readMPI(r)
510	if err != nil {
511		return
512	}
513	pk.y.bytes, pk.y.bitLength, err = readMPI(r)
514	if err != nil {
515		return
516	}
517
518	dsa := new(dsa.PublicKey)
519	dsa.P = new(big.Int).SetBytes(pk.p.bytes)
520	dsa.Q = new(big.Int).SetBytes(pk.q.bytes)
521	dsa.G = new(big.Int).SetBytes(pk.g.bytes)
522	dsa.Y = new(big.Int).SetBytes(pk.y.bytes)
523	pk.PublicKey = dsa
524	return
525}
526
527// parseElGamal parses ElGamal public key material from the given Reader. See
528// RFC 4880, section 5.5.2.
529func (pk *PublicKey) parseElGamal(r io.Reader) (err error) {
530	pk.p.bytes, pk.p.bitLength, err = readMPI(r)
531	if err != nil {
532		return
533	}
534	pk.g.bytes, pk.g.bitLength, err = readMPI(r)
535	if err != nil {
536		return
537	}
538	pk.y.bytes, pk.y.bitLength, err = readMPI(r)
539	if err != nil {
540		return
541	}
542
543	elgamal := new(elgamal.PublicKey)
544	elgamal.P = new(big.Int).SetBytes(pk.p.bytes)
545	elgamal.G = new(big.Int).SetBytes(pk.g.bytes)
546	elgamal.Y = new(big.Int).SetBytes(pk.y.bytes)
547	pk.PublicKey = elgamal
548	return
549}
550
551// SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
552// The prefix is used when calculating a signature over this public key. See
553// RFC 4880, section 5.2.4.
554func (pk *PublicKey) SerializeSignaturePrefix(h io.Writer) {
555	var pLength uint16
556	switch pk.PubKeyAlgo {
557	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
558		pLength += 2 + uint16(len(pk.n.bytes))
559		pLength += 2 + uint16(len(pk.e.bytes))
560	case PubKeyAlgoDSA:
561		pLength += 2 + uint16(len(pk.p.bytes))
562		pLength += 2 + uint16(len(pk.q.bytes))
563		pLength += 2 + uint16(len(pk.g.bytes))
564		pLength += 2 + uint16(len(pk.y.bytes))
565	case PubKeyAlgoElGamal, PubKeyAlgoBadElGamal:
566		pLength += 2 + uint16(len(pk.p.bytes))
567		pLength += 2 + uint16(len(pk.g.bytes))
568		pLength += 2 + uint16(len(pk.y.bytes))
569	case PubKeyAlgoECDSA:
570		pLength += uint16(pk.ec.byteLen())
571	case PubKeyAlgoECDH:
572		pLength += uint16(pk.ec.byteLen())
573		pLength += uint16(pk.ecdh.byteLen())
574	case PubKeyAlgoEdDSA:
575		pLength += uint16(pk.edk.byteLen())
576	default:
577		panic("unknown public key algorithm")
578	}
579	pLength += 6
580	h.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
581	return
582}
583
584func (pk *PublicKey) Serialize(w io.Writer) (err error) {
585	length := 6 // 6 byte header
586
587	switch pk.PubKeyAlgo {
588	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
589		length += 2 + len(pk.n.bytes)
590		length += 2 + len(pk.e.bytes)
591	case PubKeyAlgoDSA:
592		length += 2 + len(pk.p.bytes)
593		length += 2 + len(pk.q.bytes)
594		length += 2 + len(pk.g.bytes)
595		length += 2 + len(pk.y.bytes)
596	case PubKeyAlgoElGamal, PubKeyAlgoBadElGamal:
597		length += 2 + len(pk.p.bytes)
598		length += 2 + len(pk.g.bytes)
599		length += 2 + len(pk.y.bytes)
600	case PubKeyAlgoECDSA:
601		length += pk.ec.byteLen()
602	case PubKeyAlgoECDH:
603		length += pk.ec.byteLen()
604		length += pk.ecdh.byteLen()
605	case PubKeyAlgoEdDSA:
606		length += pk.edk.byteLen()
607	default:
608		panic("unknown public key algorithm")
609	}
610
611	packetType := packetTypePublicKey
612	if pk.IsSubkey {
613		packetType = packetTypePublicSubkey
614	}
615	err = serializeHeader(w, packetType, length)
616	if err != nil {
617		return
618	}
619	return pk.serializeWithoutHeaders(w)
620}
621
622// serializeWithoutHeaders marshals the PublicKey to w in the form of an
623// OpenPGP public key packet, not including the packet header.
624func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) {
625	var buf [6]byte
626	buf[0] = 4
627	t := uint32(pk.CreationTime.Unix())
628	buf[1] = byte(t >> 24)
629	buf[2] = byte(t >> 16)
630	buf[3] = byte(t >> 8)
631	buf[4] = byte(t)
632	buf[5] = byte(pk.PubKeyAlgo)
633
634	_, err = w.Write(buf[:])
635	if err != nil {
636		return
637	}
638
639	switch pk.PubKeyAlgo {
640	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
641		return writeMPIs(w, pk.n, pk.e)
642	case PubKeyAlgoDSA:
643		return writeMPIs(w, pk.p, pk.q, pk.g, pk.y)
644	case PubKeyAlgoElGamal, PubKeyAlgoBadElGamal:
645		return writeMPIs(w, pk.p, pk.g, pk.y)
646	case PubKeyAlgoECDSA:
647		return pk.ec.serialize(w)
648	case PubKeyAlgoEdDSA:
649		return pk.edk.serialize(w)
650	case PubKeyAlgoECDH:
651		if err = pk.ec.serialize(w); err != nil {
652			return
653		}
654		return pk.ecdh.serialize(w)
655	}
656	return errors.InvalidArgumentError("bad public-key algorithm")
657}
658
659// CanSign returns true iff this public key can generate signatures
660func (pk *PublicKey) CanSign() bool {
661	return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly && pk.PubKeyAlgo != PubKeyAlgoElGamal
662}
663
664// VerifySignature returns nil iff sig is a valid signature, made by this
665// public key, of the data hashed into signed. signed is mutated by this call.
666func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err error) {
667	if !pk.CanSign() {
668		return errors.InvalidArgumentError("public key cannot generate signatures")
669	}
670
671	signed.Write(sig.HashSuffix)
672	hashBytes := signed.Sum(nil)
673
674	// NOTE(maxtaco) 2016-08-22
675	//
676	// We used to do this:
677	//
678	// if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
679	//	  return errors.SignatureError("hash tag doesn't match")
680	// }
681	//
682	// But don't do anything in this case. Some GPGs generate bad
683	// 2-byte hash prefixes, but GPG also doesn't seem to care on
684	// import. See BrentMaxwell's key. I think it's safe to disable
685	// this check!
686
687	if pk.PubKeyAlgo != sig.PubKeyAlgo {
688		return errors.InvalidArgumentError("public key and signature use different algorithms")
689	}
690
691	switch pk.PubKeyAlgo {
692	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
693		rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey)
694		err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, padToKeySize(rsaPublicKey, sig.RSASignature.bytes))
695		if err != nil {
696			return errors.SignatureError("RSA verification failure")
697		}
698		return nil
699	case PubKeyAlgoDSA:
700		dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey)
701		// Need to truncate hashBytes to match FIPS 186-3 section 4.6.
702		subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
703		if len(hashBytes) > subgroupSize {
704			hashBytes = hashBytes[:subgroupSize]
705		}
706		if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) {
707			return errors.SignatureError("DSA verification failure")
708		}
709		return nil
710	case PubKeyAlgoECDSA:
711		ecdsaPublicKey := pk.PublicKey.(*ecdsa.PublicKey)
712		if !ecdsa.Verify(ecdsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.ECDSASigR.bytes), new(big.Int).SetBytes(sig.ECDSASigS.bytes)) {
713			return errors.SignatureError("ECDSA verification failure")
714		}
715		return nil
716	case PubKeyAlgoEdDSA:
717		if !pk.edk.Verify(hashBytes, sig.EdDSASigR, sig.EdDSASigS) {
718			return errors.SignatureError("EdDSA verification failure")
719		}
720		return nil
721	default:
722		return errors.SignatureError("Unsupported public key algorithm used in signature")
723	}
724	panic("unreachable")
725}
726
727// VerifySignatureV3 returns nil iff sig is a valid signature, made by this
728// public key, of the data hashed into signed. signed is mutated by this call.
729func (pk *PublicKey) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) {
730	if !pk.CanSign() {
731		return errors.InvalidArgumentError("public key cannot generate signatures")
732	}
733
734	suffix := make([]byte, 5)
735	suffix[0] = byte(sig.SigType)
736	binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix()))
737	signed.Write(suffix)
738	hashBytes := signed.Sum(nil)
739
740	if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
741		return errors.SignatureError("hash tag doesn't match")
742	}
743
744	if pk.PubKeyAlgo != sig.PubKeyAlgo {
745		return errors.InvalidArgumentError("public key and signature use different algorithms")
746	}
747
748	switch pk.PubKeyAlgo {
749	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
750		rsaPublicKey := pk.PublicKey.(*rsa.PublicKey)
751		if err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, padToKeySize(rsaPublicKey, sig.RSASignature.bytes)); err != nil {
752			return errors.SignatureError("RSA verification failure")
753		}
754		return
755	case PubKeyAlgoDSA:
756		dsaPublicKey := pk.PublicKey.(*dsa.PublicKey)
757		// Need to truncate hashBytes to match FIPS 186-3 section 4.6.
758		subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8
759		if len(hashBytes) > subgroupSize {
760			hashBytes = hashBytes[:subgroupSize]
761		}
762		if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) {
763			return errors.SignatureError("DSA verification failure")
764		}
765		return nil
766	default:
767		panic("shouldn't happen")
768	}
769	panic("unreachable")
770}
771
772// keySignatureHash returns a Hash of the message that needs to be signed for
773// pk to assert a subkey relationship to signed.
774func keySignatureHash(pk, signed signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
775	if !hashFunc.Available() {
776		return nil, errors.UnsupportedError("hash function")
777	}
778	h = hashFunc.New()
779
780	updateKeySignatureHash(pk, signed, h)
781
782	return
783}
784
785// updateKeySignatureHash does the actual hash updates for keySignatureHash.
786func updateKeySignatureHash(pk, signed signingKey, h hash.Hash) {
787	// RFC 4880, section 5.2.4
788	pk.SerializeSignaturePrefix(h)
789	pk.serializeWithoutHeaders(h)
790	signed.SerializeSignaturePrefix(h)
791	signed.serializeWithoutHeaders(h)
792}
793
794// VerifyKeySignature returns nil iff sig is a valid signature, made by this
795// public key, of signed.
796func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) error {
797	h, err := keySignatureHash(pk, signed, sig.Hash)
798	if err != nil {
799		return err
800	}
801	if err = pk.VerifySignature(h, sig); err != nil {
802		return err
803	}
804
805	if sig.FlagSign {
806
807		// BUG(maxtaco)
808		//
809		// We should check for more than FlagsSign here, because if
810		// you read keys.go, we can sometimes use signing subkeys even if they're
811		// not explicitly flagged as such. However, so doing fails lots of currently
812		// working tests, so I'm not going to do much here.
813		//
814		// In other words, we should have this disjunction in the condition above:
815		//
816		//    || (!sig.FlagsValid && pk.PubKeyAlgo.CanSign()) {
817		//
818
819		// Signing subkeys must be cross-signed. See
820		// https://www.gnupg.org/faq/subkey-cross-certify.html.
821		if sig.EmbeddedSignature == nil {
822			return errors.StructuralError("signing subkey is missing cross-signature")
823		}
824		// Verify the cross-signature. This is calculated over the same
825		// data as the main signature, so we cannot just recursively
826		// call signed.VerifyKeySignature(...)
827		if h, err = keySignatureHash(pk, signed, sig.EmbeddedSignature.Hash); err != nil {
828			return errors.StructuralError("error while hashing for cross-signature: " + err.Error())
829		}
830		if err := signed.VerifySignature(h, sig.EmbeddedSignature); err != nil {
831			return errors.StructuralError("error while verifying cross-signature: " + err.Error())
832		}
833	}
834
835	return nil
836}
837
838func keyRevocationHash(pk signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
839	if !hashFunc.Available() {
840		return nil, errors.UnsupportedError("hash function")
841	}
842	h = hashFunc.New()
843
844	// RFC 4880, section 5.2.4
845	pk.SerializeSignaturePrefix(h)
846	pk.serializeWithoutHeaders(h)
847
848	return
849}
850
851// VerifyRevocationSignature returns nil iff sig is a valid signature, made by this
852// public key.
853func (pk *PublicKey) VerifyRevocationSignature(revokedKey *PublicKey, sig *Signature) (err error) {
854	h, err := keyRevocationHash(revokedKey, sig.Hash)
855	if err != nil {
856		return err
857	}
858	return pk.VerifySignature(h, sig)
859}
860
861type teeHash struct {
862	h hash.Hash
863}
864
865func (t teeHash) Write(b []byte) (n int, err error) {
866	fmt.Printf("hash -> %s %+v\n", string(b), b)
867	return t.h.Write(b)
868}
869func (t teeHash) Sum(b []byte) []byte { return t.h.Sum(b) }
870func (t teeHash) Reset()              { t.h.Reset() }
871func (t teeHash) Size() int           { return t.h.Size() }
872func (t teeHash) BlockSize() int      { return t.h.BlockSize() }
873
874// userIdSignatureHash returns a Hash of the message that needs to be signed
875// to assert that pk is a valid key for id.
876func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
877	if !hashFunc.Available() {
878		return nil, errors.UnsupportedError("hash function")
879	}
880	h = hashFunc.New()
881
882	updateUserIdSignatureHash(id, pk, h)
883
884	return
885}
886
887// updateUserIdSignatureHash does the actual hash updates for
888// userIdSignatureHash.
889func updateUserIdSignatureHash(id string, pk *PublicKey, h hash.Hash) {
890	// RFC 4880, section 5.2.4
891	pk.SerializeSignaturePrefix(h)
892	pk.serializeWithoutHeaders(h)
893
894	var buf [5]byte
895	buf[0] = 0xb4
896	buf[1] = byte(len(id) >> 24)
897	buf[2] = byte(len(id) >> 16)
898	buf[3] = byte(len(id) >> 8)
899	buf[4] = byte(len(id))
900	h.Write(buf[:])
901	h.Write([]byte(id))
902
903	return
904}
905
906// VerifyUserIdSignature returns nil iff sig is a valid signature, made by this
907// public key, that id is the identity of pub.
908func (pk *PublicKey) VerifyUserIdSignature(id string, pub *PublicKey, sig *Signature) (err error) {
909	h, err := userIdSignatureHash(id, pub, sig.Hash)
910	if err != nil {
911		return err
912	}
913	return pk.VerifySignature(h, sig)
914}
915
916// VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this
917// public key, that id is the identity of pub.
918func (pk *PublicKey) VerifyUserIdSignatureV3(id string, pub *PublicKey, sig *SignatureV3) (err error) {
919	h, err := userIdSignatureV3Hash(id, pub, sig.Hash)
920	if err != nil {
921		return err
922	}
923	return pk.VerifySignatureV3(h, sig)
924}
925
926// KeyIdString returns the public key's fingerprint in capital hex
927// (e.g. "6C7EE1B8621CC013").
928func (pk *PublicKey) KeyIdString() string {
929	return fmt.Sprintf("%X", pk.Fingerprint[12:20])
930}
931
932// KeyIdShortString returns the short form of public key's fingerprint
933// in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
934func (pk *PublicKey) KeyIdShortString() string {
935	return fmt.Sprintf("%X", pk.Fingerprint[16:20])
936}
937
938// A parsedMPI is used to store the contents of a big integer, along with the
939// bit length that was specified in the original input. This allows the MPI to
940// be reserialized exactly.
941type parsedMPI struct {
942	bytes     []byte
943	bitLength uint16
944}
945
946// writeMPIs is a utility function for serializing several big integers to the
947// given Writer.
948func writeMPIs(w io.Writer, mpis ...parsedMPI) (err error) {
949	for _, mpi := range mpis {
950		err = writeMPI(w, mpi.bitLength, mpi.bytes)
951		if err != nil {
952			return
953		}
954	}
955	return
956}
957
958// BitLength returns the bit length for the given public key. Used for
959// displaying key information, actual buffers and BigInts inside may
960// have non-matching different size if the key is invalid.
961func (pk *PublicKey) BitLength() (bitLength uint16, err error) {
962	switch pk.PubKeyAlgo {
963	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
964		bitLength = pk.n.bitLength
965	case PubKeyAlgoDSA:
966		bitLength = pk.p.bitLength
967	case PubKeyAlgoElGamal, PubKeyAlgoBadElGamal:
968		bitLength = pk.p.bitLength
969	case PubKeyAlgoECDH:
970		ecdhPublicKey := pk.PublicKey.(*ecdh.PublicKey)
971		bitLength = uint16(ecdhPublicKey.Curve.Params().BitSize)
972	case PubKeyAlgoECDSA:
973		ecdsaPublicKey := pk.PublicKey.(*ecdsa.PublicKey)
974		bitLength = uint16(ecdsaPublicKey.Curve.Params().BitSize)
975	case PubKeyAlgoEdDSA:
976		// EdDSA only support ed25519 curves right now, just return
977		// the length. Also, we don't have any PublicKey.Curve object
978		// to look the size up from.
979		bitLength = 256
980	default:
981		err = errors.InvalidArgumentError("bad public-key algorithm")
982	}
983	return
984}
985
986func (pk *PublicKey) ErrorIfDeprecated() error {
987	switch pk.PubKeyAlgo {
988	case PubKeyAlgoBadElGamal:
989		return errors.DeprecatedKeyError("ElGamal Encrypt or Sign (algo 20) is deprecated")
990	default:
991		return nil
992	}
993}
994