...

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

View as plain text