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