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