github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/crypto/openpgp/packet/private_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/cipher"
    10  	"crypto/dsa"
    11  	"crypto/rsa"
    12  	"crypto/sha1"
    13  	"golang.org/x/crypto/openpgp/elgamal"
    14  	"golang.org/x/crypto/openpgp/errors"
    15  	"golang.org/x/crypto/openpgp/s2k"
    16  	"io"
    17  	"io/ioutil"
    18  	"math/big"
    19  	"strconv"
    20  	"time"
    21  )
    22  
    23  // PrivateKey represents a possibly encrypted private key. See RFC 4880,
    24  // section 5.5.3.
    25  type PrivateKey struct {
    26  	PublicKey
    27  	Encrypted     bool // if true then the private key is unavailable until Decrypt has been called.
    28  	encryptedData []byte
    29  	cipher        CipherFunction
    30  	s2k           func(out, in []byte)
    31  	PrivateKey    interface{} // An *rsa.PrivateKey or *dsa.PrivateKey.
    32  	sha1Checksum  bool
    33  	iv            []byte
    34  }
    35  
    36  func NewRSAPrivateKey(currentTime time.Time, priv *rsa.PrivateKey) *PrivateKey {
    37  	pk := new(PrivateKey)
    38  	pk.PublicKey = *NewRSAPublicKey(currentTime, &priv.PublicKey)
    39  	pk.PrivateKey = priv
    40  	return pk
    41  }
    42  
    43  func NewDSAPrivateKey(currentTime time.Time, priv *dsa.PrivateKey) *PrivateKey {
    44  	pk := new(PrivateKey)
    45  	pk.PublicKey = *NewDSAPublicKey(currentTime, &priv.PublicKey)
    46  	pk.PrivateKey = priv
    47  	return pk
    48  }
    49  
    50  func (pk *PrivateKey) parse(r io.Reader) (err error) {
    51  	err = (&pk.PublicKey).parse(r)
    52  	if err != nil {
    53  		return
    54  	}
    55  	var buf [1]byte
    56  	_, err = readFull(r, buf[:])
    57  	if err != nil {
    58  		return
    59  	}
    60  
    61  	s2kType := buf[0]
    62  
    63  	switch s2kType {
    64  	case 0:
    65  		pk.s2k = nil
    66  		pk.Encrypted = false
    67  	case 254, 255:
    68  		_, err = readFull(r, buf[:])
    69  		if err != nil {
    70  			return
    71  		}
    72  		pk.cipher = CipherFunction(buf[0])
    73  		pk.Encrypted = true
    74  		pk.s2k, err = s2k.Parse(r)
    75  		if err != nil {
    76  			return
    77  		}
    78  		if s2kType == 254 {
    79  			pk.sha1Checksum = true
    80  		}
    81  	default:
    82  		return errors.UnsupportedError("deprecated s2k function in private key")
    83  	}
    84  
    85  	if pk.Encrypted {
    86  		blockSize := pk.cipher.blockSize()
    87  		if blockSize == 0 {
    88  			return errors.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
    89  		}
    90  		pk.iv = make([]byte, blockSize)
    91  		_, err = readFull(r, pk.iv)
    92  		if err != nil {
    93  			return
    94  		}
    95  	}
    96  
    97  	pk.encryptedData, err = ioutil.ReadAll(r)
    98  	if err != nil {
    99  		return
   100  	}
   101  
   102  	if !pk.Encrypted {
   103  		return pk.parsePrivateKey(pk.encryptedData)
   104  	}
   105  
   106  	return
   107  }
   108  
   109  func mod64kHash(d []byte) uint16 {
   110  	var h uint16
   111  	for _, b := range d {
   112  		h += uint16(b)
   113  	}
   114  	return h
   115  }
   116  
   117  func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
   118  	// TODO(agl): support encrypted private keys
   119  	buf := bytes.NewBuffer(nil)
   120  	err = pk.PublicKey.serializeWithoutHeaders(buf)
   121  	if err != nil {
   122  		return
   123  	}
   124  	buf.WriteByte(0 /* no encryption */)
   125  
   126  	privateKeyBuf := bytes.NewBuffer(nil)
   127  
   128  	switch priv := pk.PrivateKey.(type) {
   129  	case *rsa.PrivateKey:
   130  		err = serializeRSAPrivateKey(privateKeyBuf, priv)
   131  	case *dsa.PrivateKey:
   132  		err = serializeDSAPrivateKey(privateKeyBuf, priv)
   133  	default:
   134  		err = errors.InvalidArgumentError("unknown private key type")
   135  	}
   136  	if err != nil {
   137  		return
   138  	}
   139  
   140  	ptype := packetTypePrivateKey
   141  	contents := buf.Bytes()
   142  	privateKeyBytes := privateKeyBuf.Bytes()
   143  	if pk.IsSubkey {
   144  		ptype = packetTypePrivateSubkey
   145  	}
   146  	err = serializeHeader(w, ptype, len(contents)+len(privateKeyBytes)+2)
   147  	if err != nil {
   148  		return
   149  	}
   150  	_, err = w.Write(contents)
   151  	if err != nil {
   152  		return
   153  	}
   154  	_, err = w.Write(privateKeyBytes)
   155  	if err != nil {
   156  		return
   157  	}
   158  
   159  	checksum := mod64kHash(privateKeyBytes)
   160  	var checksumBytes [2]byte
   161  	checksumBytes[0] = byte(checksum >> 8)
   162  	checksumBytes[1] = byte(checksum)
   163  	_, err = w.Write(checksumBytes[:])
   164  
   165  	return
   166  }
   167  
   168  func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error {
   169  	err := writeBig(w, priv.D)
   170  	if err != nil {
   171  		return err
   172  	}
   173  	err = writeBig(w, priv.Primes[1])
   174  	if err != nil {
   175  		return err
   176  	}
   177  	err = writeBig(w, priv.Primes[0])
   178  	if err != nil {
   179  		return err
   180  	}
   181  	return writeBig(w, priv.Precomputed.Qinv)
   182  }
   183  
   184  func serializeDSAPrivateKey(w io.Writer, priv *dsa.PrivateKey) error {
   185  	return writeBig(w, priv.X)
   186  }
   187  
   188  // Decrypt decrypts an encrypted private key using a passphrase.
   189  func (pk *PrivateKey) Decrypt(passphrase []byte) error {
   190  	if !pk.Encrypted {
   191  		return nil
   192  	}
   193  
   194  	key := make([]byte, pk.cipher.KeySize())
   195  	pk.s2k(key, passphrase)
   196  	block := pk.cipher.new(key)
   197  	cfb := cipher.NewCFBDecrypter(block, pk.iv)
   198  
   199  	data := make([]byte, len(pk.encryptedData))
   200  	cfb.XORKeyStream(data, pk.encryptedData)
   201  
   202  	if pk.sha1Checksum {
   203  		if len(data) < sha1.Size {
   204  			return errors.StructuralError("truncated private key data")
   205  		}
   206  		h := sha1.New()
   207  		h.Write(data[:len(data)-sha1.Size])
   208  		sum := h.Sum(nil)
   209  		if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
   210  			return errors.StructuralError("private key checksum failure")
   211  		}
   212  		data = data[:len(data)-sha1.Size]
   213  	} else {
   214  		if len(data) < 2 {
   215  			return errors.StructuralError("truncated private key data")
   216  		}
   217  		var sum uint16
   218  		for i := 0; i < len(data)-2; i++ {
   219  			sum += uint16(data[i])
   220  		}
   221  		if data[len(data)-2] != uint8(sum>>8) ||
   222  			data[len(data)-1] != uint8(sum) {
   223  			return errors.StructuralError("private key checksum failure")
   224  		}
   225  		data = data[:len(data)-2]
   226  	}
   227  
   228  	return pk.parsePrivateKey(data)
   229  }
   230  
   231  func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) {
   232  	switch pk.PublicKey.PubKeyAlgo {
   233  	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoRSAEncryptOnly:
   234  		return pk.parseRSAPrivateKey(data)
   235  	case PubKeyAlgoDSA:
   236  		return pk.parseDSAPrivateKey(data)
   237  	case PubKeyAlgoElGamal:
   238  		return pk.parseElGamalPrivateKey(data)
   239  	}
   240  	panic("impossible")
   241  }
   242  
   243  func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) {
   244  	rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey)
   245  	rsaPriv := new(rsa.PrivateKey)
   246  	rsaPriv.PublicKey = *rsaPub
   247  
   248  	buf := bytes.NewBuffer(data)
   249  	d, _, err := readMPI(buf)
   250  	if err != nil {
   251  		return
   252  	}
   253  	p, _, err := readMPI(buf)
   254  	if err != nil {
   255  		return
   256  	}
   257  	q, _, err := readMPI(buf)
   258  	if err != nil {
   259  		return
   260  	}
   261  
   262  	rsaPriv.D = new(big.Int).SetBytes(d)
   263  	rsaPriv.Primes = make([]*big.Int, 2)
   264  	rsaPriv.Primes[0] = new(big.Int).SetBytes(p)
   265  	rsaPriv.Primes[1] = new(big.Int).SetBytes(q)
   266  	if err := rsaPriv.Validate(); err != nil {
   267  		return err
   268  	}
   269  	rsaPriv.Precompute()
   270  	pk.PrivateKey = rsaPriv
   271  	pk.Encrypted = false
   272  	pk.encryptedData = nil
   273  
   274  	return nil
   275  }
   276  
   277  func (pk *PrivateKey) parseDSAPrivateKey(data []byte) (err error) {
   278  	dsaPub := pk.PublicKey.PublicKey.(*dsa.PublicKey)
   279  	dsaPriv := new(dsa.PrivateKey)
   280  	dsaPriv.PublicKey = *dsaPub
   281  
   282  	buf := bytes.NewBuffer(data)
   283  	x, _, err := readMPI(buf)
   284  	if err != nil {
   285  		return
   286  	}
   287  
   288  	dsaPriv.X = new(big.Int).SetBytes(x)
   289  	pk.PrivateKey = dsaPriv
   290  	pk.Encrypted = false
   291  	pk.encryptedData = nil
   292  
   293  	return nil
   294  }
   295  
   296  func (pk *PrivateKey) parseElGamalPrivateKey(data []byte) (err error) {
   297  	pub := pk.PublicKey.PublicKey.(*elgamal.PublicKey)
   298  	priv := new(elgamal.PrivateKey)
   299  	priv.PublicKey = *pub
   300  
   301  	buf := bytes.NewBuffer(data)
   302  	x, _, err := readMPI(buf)
   303  	if err != nil {
   304  		return
   305  	}
   306  
   307  	priv.X = new(big.Int).SetBytes(x)
   308  	pk.PrivateKey = priv
   309  	pk.Encrypted = false
   310  	pk.encryptedData = nil
   311  
   312  	return nil
   313  }