]>
Commit | Line | Data |
---|---|---|
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 | "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. | |
28 | type 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 a crypto.Signer. | |
35 | sha1Checksum bool | |
36 | iv []byte | |
37 | } | |
38 | ||
39 | func NewRSAPrivateKey(currentTime time.Time, priv *rsa.PrivateKey) *PrivateKey { | |
40 | pk := new(PrivateKey) | |
41 | pk.PublicKey = *NewRSAPublicKey(currentTime, &priv.PublicKey) | |
42 | pk.PrivateKey = priv | |
43 | return pk | |
44 | } | |
45 | ||
46 | func NewDSAPrivateKey(currentTime time.Time, priv *dsa.PrivateKey) *PrivateKey { | |
47 | pk := new(PrivateKey) | |
48 | pk.PublicKey = *NewDSAPublicKey(currentTime, &priv.PublicKey) | |
49 | pk.PrivateKey = priv | |
50 | return pk | |
51 | } | |
52 | ||
53 | func NewElGamalPrivateKey(currentTime time.Time, priv *elgamal.PrivateKey) *PrivateKey { | |
54 | pk := new(PrivateKey) | |
55 | pk.PublicKey = *NewElGamalPublicKey(currentTime, &priv.PublicKey) | |
56 | pk.PrivateKey = priv | |
57 | return pk | |
58 | } | |
59 | ||
60 | func NewECDSAPrivateKey(currentTime time.Time, priv *ecdsa.PrivateKey) *PrivateKey { | |
61 | pk := new(PrivateKey) | |
62 | pk.PublicKey = *NewECDSAPublicKey(currentTime, &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. | |
69 | func NewSignerPrivateKey(currentTime 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(currentTime, pubkey) | |
76 | case rsa.PublicKey: | |
77 | pk.PublicKey = *NewRSAPublicKey(currentTime, &pubkey) | |
78 | case *ecdsa.PublicKey: | |
79 | pk.PublicKey = *NewECDSAPublicKey(currentTime, pubkey) | |
80 | case ecdsa.PublicKey: | |
81 | pk.PublicKey = *NewECDSAPublicKey(currentTime, &pubkey) | |
82 | default: | |
83 | panic("openpgp: unknown crypto.Signer type in NewSignerPrivateKey") | |
84 | } | |
85 | pk.PrivateKey = signer | |
86 | return pk | |
87 | } | |
88 | ||
89 | func (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 | ||
148 | func mod64kHash(d []byte) uint16 { | |
149 | var h uint16 | |
150 | for _, b := range d { | |
151 | h += uint16(b) | |
152 | } | |
153 | return h | |
154 | } | |
155 | ||
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) | |
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 | ||
211 | func 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 | ||
227 | func serializeDSAPrivateKey(w io.Writer, priv *dsa.PrivateKey) error { | |
228 | return writeBig(w, priv.X) | |
229 | } | |
230 | ||
231 | func serializeElGamalPrivateKey(w io.Writer, priv *elgamal.PrivateKey) error { | |
232 | return writeBig(w, priv.X) | |
233 | } | |
234 | ||
235 | func 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. | |
240 | func (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 | ||
282 | func (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 | ||
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 | |
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 | ||
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 | |
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 | ||
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 | |
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 | ||
368 | func (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 | } |