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.
21 "golang.org/x/crypto/openpgp/elgamal"
22 "golang.org/x/crypto/openpgp/errors"
23 "golang.org/x/crypto/openpgp/s2k"
26 // PrivateKey represents a possibly encrypted private key. See RFC 4880,
28 type PrivateKey struct {
30 Encrypted bool // if true then the private key is unavailable until Decrypt has been called.
33 s2k func(out, in []byte)
34 PrivateKey interface{} // An *{rsa|dsa|ecdsa}.PrivateKey or a crypto.Signer.
39 func NewRSAPrivateKey(creationTime time.Time, priv *rsa.PrivateKey) *PrivateKey {
41 pk.PublicKey = *NewRSAPublicKey(creationTime, &priv.PublicKey)
46 func NewDSAPrivateKey(creationTime time.Time, priv *dsa.PrivateKey) *PrivateKey {
48 pk.PublicKey = *NewDSAPublicKey(creationTime, &priv.PublicKey)
53 func NewElGamalPrivateKey(creationTime time.Time, priv *elgamal.PrivateKey) *PrivateKey {
55 pk.PublicKey = *NewElGamalPublicKey(creationTime, &priv.PublicKey)
60 func NewECDSAPrivateKey(creationTime time.Time, priv *ecdsa.PrivateKey) *PrivateKey {
62 pk.PublicKey = *NewECDSAPublicKey(creationTime, &priv.PublicKey)
67 // NewSignerPrivateKey creates a PrivateKey from a crypto.Signer that
68 // implements RSA or ECDSA.
69 func NewSignerPrivateKey(creationTime time.Time, signer crypto.Signer) *PrivateKey {
71 // In general, the public Keys should be used as pointers. We still
72 // type-switch on the values, for backwards-compatibility.
73 switch pubkey := signer.Public().(type) {
75 pk.PublicKey = *NewRSAPublicKey(creationTime, pubkey)
77 pk.PublicKey = *NewRSAPublicKey(creationTime, &pubkey)
78 case *ecdsa.PublicKey:
79 pk.PublicKey = *NewECDSAPublicKey(creationTime, pubkey)
81 pk.PublicKey = *NewECDSAPublicKey(creationTime, &pubkey)
83 panic("openpgp: unknown crypto.Signer type in NewSignerPrivateKey")
85 pk.PrivateKey = signer
89 func (pk *PrivateKey) parse(r io.Reader) (err error) {
90 err = (&pk.PublicKey).parse(r)
95 _, err = readFull(r, buf[:])
107 _, err = readFull(r, buf[:])
111 pk.cipher = CipherFunction(buf[0])
113 pk.s2k, err = s2k.Parse(r)
118 pk.sha1Checksum = true
121 return errors.UnsupportedError("deprecated s2k function in private key")
125 blockSize := pk.cipher.blockSize()
127 return errors.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
129 pk.iv = make([]byte, blockSize)
130 _, err = readFull(r, pk.iv)
136 pk.encryptedData, err = ioutil.ReadAll(r)
142 return pk.parsePrivateKey(pk.encryptedData)
148 func mod64kHash(d []byte) uint16 {
150 for _, b := range d {
156 func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
157 // TODO(agl): support encrypted private keys
158 buf := bytes.NewBuffer(nil)
159 err = pk.PublicKey.serializeWithoutHeaders(buf)
163 buf.WriteByte(0 /* no encryption */)
165 privateKeyBuf := bytes.NewBuffer(nil)
167 switch priv := pk.PrivateKey.(type) {
168 case *rsa.PrivateKey:
169 err = serializeRSAPrivateKey(privateKeyBuf, priv)
170 case *dsa.PrivateKey:
171 err = serializeDSAPrivateKey(privateKeyBuf, priv)
172 case *elgamal.PrivateKey:
173 err = serializeElGamalPrivateKey(privateKeyBuf, priv)
174 case *ecdsa.PrivateKey:
175 err = serializeECDSAPrivateKey(privateKeyBuf, priv)
177 err = errors.InvalidArgumentError("unknown private key type")
183 ptype := packetTypePrivateKey
184 contents := buf.Bytes()
185 privateKeyBytes := privateKeyBuf.Bytes()
187 ptype = packetTypePrivateSubkey
189 err = serializeHeader(w, ptype, len(contents)+len(privateKeyBytes)+2)
193 _, err = w.Write(contents)
197 _, err = w.Write(privateKeyBytes)
202 checksum := mod64kHash(privateKeyBytes)
203 var checksumBytes [2]byte
204 checksumBytes[0] = byte(checksum >> 8)
205 checksumBytes[1] = byte(checksum)
206 _, err = w.Write(checksumBytes[:])
211 func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error {
212 err := writeBig(w, priv.D)
216 err = writeBig(w, priv.Primes[1])
220 err = writeBig(w, priv.Primes[0])
224 return writeBig(w, priv.Precomputed.Qinv)
227 func serializeDSAPrivateKey(w io.Writer, priv *dsa.PrivateKey) error {
228 return writeBig(w, priv.X)
231 func serializeElGamalPrivateKey(w io.Writer, priv *elgamal.PrivateKey) error {
232 return writeBig(w, priv.X)
235 func serializeECDSAPrivateKey(w io.Writer, priv *ecdsa.PrivateKey) error {
236 return writeBig(w, priv.D)
239 // Decrypt decrypts an encrypted private key using a passphrase.
240 func (pk *PrivateKey) Decrypt(passphrase []byte) error {
245 key := make([]byte, pk.cipher.KeySize())
246 pk.s2k(key, passphrase)
247 block := pk.cipher.new(key)
248 cfb := cipher.NewCFBDecrypter(block, pk.iv)
250 data := make([]byte, len(pk.encryptedData))
251 cfb.XORKeyStream(data, pk.encryptedData)
254 if len(data) < sha1.Size {
255 return errors.StructuralError("truncated private key data")
258 h.Write(data[:len(data)-sha1.Size])
260 if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
261 return errors.StructuralError("private key checksum failure")
263 data = data[:len(data)-sha1.Size]
266 return errors.StructuralError("truncated private key data")
269 for i := 0; i < len(data)-2; i++ {
270 sum += uint16(data[i])
272 if data[len(data)-2] != uint8(sum>>8) ||
273 data[len(data)-1] != uint8(sum) {
274 return errors.StructuralError("private key checksum failure")
276 data = data[:len(data)-2]
279 return pk.parsePrivateKey(data)
282 func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) {
283 switch pk.PublicKey.PubKeyAlgo {
284 case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoRSAEncryptOnly:
285 return pk.parseRSAPrivateKey(data)
287 return pk.parseDSAPrivateKey(data)
288 case PubKeyAlgoElGamal:
289 return pk.parseElGamalPrivateKey(data)
290 case PubKeyAlgoECDSA:
291 return pk.parseECDSAPrivateKey(data)
296 func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) {
297 rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey)
298 rsaPriv := new(rsa.PrivateKey)
299 rsaPriv.PublicKey = *rsaPub
301 buf := bytes.NewBuffer(data)
302 d, _, err := readMPI(buf)
306 p, _, err := readMPI(buf)
310 q, _, err := readMPI(buf)
315 rsaPriv.D = new(big.Int).SetBytes(d)
316 rsaPriv.Primes = make([]*big.Int, 2)
317 rsaPriv.Primes[0] = new(big.Int).SetBytes(p)
318 rsaPriv.Primes[1] = new(big.Int).SetBytes(q)
319 if err := rsaPriv.Validate(); err != nil {
323 pk.PrivateKey = rsaPriv
325 pk.encryptedData = nil
330 func (pk *PrivateKey) parseDSAPrivateKey(data []byte) (err error) {
331 dsaPub := pk.PublicKey.PublicKey.(*dsa.PublicKey)
332 dsaPriv := new(dsa.PrivateKey)
333 dsaPriv.PublicKey = *dsaPub
335 buf := bytes.NewBuffer(data)
336 x, _, err := readMPI(buf)
341 dsaPriv.X = new(big.Int).SetBytes(x)
342 pk.PrivateKey = dsaPriv
344 pk.encryptedData = nil
349 func (pk *PrivateKey) parseElGamalPrivateKey(data []byte) (err error) {
350 pub := pk.PublicKey.PublicKey.(*elgamal.PublicKey)
351 priv := new(elgamal.PrivateKey)
352 priv.PublicKey = *pub
354 buf := bytes.NewBuffer(data)
355 x, _, err := readMPI(buf)
360 priv.X = new(big.Int).SetBytes(x)
363 pk.encryptedData = nil
368 func (pk *PrivateKey) parseECDSAPrivateKey(data []byte) (err error) {
369 ecdsaPub := pk.PublicKey.PublicKey.(*ecdsa.PublicKey)
371 buf := bytes.NewBuffer(data)
372 d, _, err := readMPI(buf)
377 pk.PrivateKey = &ecdsa.PrivateKey{
378 PublicKey: *ecdsaPub,
379 D: new(big.Int).SetBytes(d),
382 pk.encryptedData = nil