...

Source file src/golang.org/x/crypto/openpgp/packet/public_key.go

Documentation: golang.org/x/crypto/openpgp/packet

     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  
   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  
   258  func (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  
   305  func (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.
   316  func (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.
   344  func (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.
   373  func (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.
   398  func (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  
   426  func (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.
   464  func (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
   498  func (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.
   504  func (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.
   552  func (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.
   596  func 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.
   612  func (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  
   641  func 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.
   656  func (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.
   666  func 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.
   690  func (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.
   700  func (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").
   710  func (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").
   716  func (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.
   723  type 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.
   730  func 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.
   741  func (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  

View as plain text