github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/crypto/openpgp/packet/public_key.go (about)

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