2
2
// Use of this source code is governed by a BSD-style
3
3
// license that can be found in the LICENSE file.
4
4
5
+ // Modifications from patches written by:
6
+ // Fan Jiang <fanjiang@thoughtworks.com> and
7
+ // Sofia Celi <sceli@thoughtworks.com>
8
+
5
9
package packet
6
10
7
11
import (
@@ -10,6 +14,7 @@ import (
10
14
"crypto/cipher"
11
15
"crypto/dsa"
12
16
"crypto/ecdsa"
17
+ "crypto/rand"
13
18
"crypto/rsa"
14
19
"crypto/sha1"
15
20
"io"
@@ -34,8 +39,22 @@ type PrivateKey struct {
34
39
PrivateKey interface {} // An *{rsa|dsa|ecdsa}.PrivateKey or crypto.Signer/crypto.Decrypter (Decryptor RSA only).
35
40
sha1Checksum bool
36
41
iv []byte
42
+
43
+ // s2k related
44
+ salt []byte
45
+ s2kMode uint8
46
+ s2kConfig s2k.Config
47
+ s2kType S2KType
37
48
}
38
49
50
+ type S2KType uint8
51
+
52
+ const (
53
+ S2KNON S2KType = 0
54
+ S2KSHA1 S2KType = 254
55
+ S2KCHECKSUM S2KType = 255
56
+ )
57
+
39
58
func NewRSAPrivateKey (creationTime time.Time , priv * rsa.PrivateKey ) * PrivateKey {
40
59
pk := new (PrivateKey )
41
60
pk .PublicKey = * NewRSAPublicKey (creationTime , & priv .PublicKey )
@@ -97,24 +116,24 @@ func (pk *PrivateKey) parse(r io.Reader) (err error) {
97
116
return
98
117
}
99
118
100
- s2kType := buf [0 ]
119
+ pk . s2kType = S2KType ( buf [0 ])
101
120
102
- switch s2kType {
103
- case 0 :
121
+ switch pk . s2kType {
122
+ case S2KNON :
104
123
pk .s2k = nil
105
124
pk .Encrypted = false
106
- case 254 , 255 :
125
+ case S2KSHA1 , S2KCHECKSUM :
107
126
_ , err = readFull (r , buf [:])
108
127
if err != nil {
109
128
return
110
129
}
111
130
pk .cipher = CipherFunction (buf [0 ])
112
131
pk .Encrypted = true
113
- pk .s2k , err = s2k .Parse (r )
132
+ pk .s2k , pk . s2kMode , pk . s2kConfig . Hash , pk . salt , pk . s2kConfig . S2KCount , err = s2k .Parse2 (r )
114
133
if err != nil {
115
134
return
116
135
}
117
- if s2kType == 254 {
136
+ if pk . s2kType == S2KSHA1 {
118
137
pk .sha1Checksum = true
119
138
}
120
139
default :
@@ -153,40 +172,119 @@ func mod64kHash(d []byte) uint16 {
153
172
return h
154
173
}
155
174
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
175
+ func (pk * PrivateKey ) SerializeEncrypted (w io.Writer ) error {
176
+ privateKeyBuf := bytes .NewBuffer (nil )
177
+ encodedKeyBuf := bytes .NewBuffer (nil )
178
+ if _ , err := encodedKeyBuf .Write ([]byte {uint8 (pk .s2kType )}); err != nil {
179
+ return err
180
+ }
181
+ if _ , err := encodedKeyBuf .Write ([]byte {uint8 (pk .cipher )}); err != nil {
182
+ return err
183
+ }
184
+ if _ , err := encodedKeyBuf .Write ([]byte {pk .s2kMode }); err != nil {
185
+ return err
186
+ }
187
+ hashID , ok := s2k .HashToHashId (pk .s2kConfig .Hash )
188
+ if ! ok {
189
+ return errors .UnsupportedError ("no such hash" )
190
+ }
191
+ if _ , err := encodedKeyBuf .Write ([]byte {hashID }); err != nil {
192
+ return err
193
+ }
194
+ if _ , err := encodedKeyBuf .Write (pk .salt ); err != nil {
195
+ return err
196
+ }
197
+ if _ , err := encodedKeyBuf .Write ([]byte {pk .s2kConfig .EncodedCount ()}); err != nil {
198
+ return err
162
199
}
163
- buf .WriteByte (0 /* no encryption */ )
164
200
165
- privateKeyBuf := bytes .NewBuffer (nil )
201
+ if _ , err := privateKeyBuf .Write (pk .encryptedData ); err != nil {
202
+ return err
203
+ }
204
+
205
+ encodedKey := encodedKeyBuf .Bytes ()
206
+ privateKeyBytes := privateKeyBuf .Bytes ()
207
+
208
+ if _ , err := w .Write (encodedKey ); err != nil {
209
+ return err
210
+ }
211
+ if _ , err := w .Write (pk .iv ); err != nil {
212
+ return err
213
+ }
214
+ if _ , err := w .Write (privateKeyBytes ); err != nil {
215
+ return err
216
+ }
166
217
218
+ return nil
219
+ }
220
+
221
+ func (pk * PrivateKey ) SerializeUnEncrypted (w io.Writer ) (err error ) {
222
+ buf := bytes .NewBuffer (nil )
223
+ if _ , err := buf .Write ([]byte {uint8 (S2KNON )} /* no encryption */ ); err != nil {
224
+ return err
225
+ }
167
226
switch priv := pk .PrivateKey .(type ) {
168
227
case * rsa.PrivateKey :
169
- err = serializeRSAPrivateKey (privateKeyBuf , priv )
228
+ err = serializeRSAPrivateKey (buf , priv )
170
229
case * dsa.PrivateKey :
171
- err = serializeDSAPrivateKey (privateKeyBuf , priv )
230
+ err = serializeDSAPrivateKey (buf , priv )
172
231
case * elgamal.PrivateKey :
173
- err = serializeElGamalPrivateKey (privateKeyBuf , priv )
232
+ err = serializeElGamalPrivateKey (buf , priv )
174
233
case * ecdsa.PrivateKey :
175
- err = serializeECDSAPrivateKey (privateKeyBuf , priv )
234
+ err = serializeECDSAPrivateKey (buf , priv )
176
235
default :
177
236
err = errors .InvalidArgumentError ("unknown private key type" )
178
237
}
238
+ if err != nil {
239
+ return err
240
+ }
241
+ privateKeyBytes := buf .Bytes ()
242
+ if pk .sha1Checksum {
243
+ h := sha1 .New ()
244
+ if _ , err := h .Write (privateKeyBytes ); err != nil {
245
+ return err
246
+ }
247
+ sum := h .Sum (nil )
248
+ privateKeyBytes = append (privateKeyBytes , sum ... )
249
+ } else {
250
+ checksum := mod64kHash (privateKeyBytes )
251
+ var checksumBytes [2 ]byte
252
+ checksumBytes [0 ] = byte (checksum >> 8 )
253
+ checksumBytes [1 ] = byte (checksum )
254
+ privateKeyBytes = append (privateKeyBytes , checksumBytes [:]... )
255
+ }
256
+ if _ , err := w .Write (privateKeyBytes ); err != nil {
257
+ return err
258
+ }
259
+ return
260
+ }
261
+
262
+ func (pk * PrivateKey ) Serialize (w io.Writer ) (err error ) {
263
+ // TODO(agl): support encrypted private keys
264
+ buf := bytes .NewBuffer (nil )
265
+ err = pk .PublicKey .serializeWithoutHeaders (buf )
179
266
if err != nil {
180
267
return
181
268
}
182
269
270
+ privateKeyBuf := bytes .NewBuffer (nil )
271
+ if pk .Encrypted {
272
+ if err = pk .SerializeEncrypted (privateKeyBuf ); err != nil {
273
+ return err
274
+ }
275
+ } else {
276
+ if err = pk .SerializeUnEncrypted (privateKeyBuf ); err != nil {
277
+ return err
278
+ }
279
+ }
280
+
183
281
ptype := packetTypePrivateKey
184
282
contents := buf .Bytes ()
185
283
privateKeyBytes := privateKeyBuf .Bytes ()
186
284
if pk .IsSubkey {
187
285
ptype = packetTypePrivateSubkey
188
286
}
189
- err = serializeHeader (w , ptype , len (contents )+ len (privateKeyBytes )+ 2 )
287
+ err = serializeHeader (w , ptype , len (contents )+ len (privateKeyBytes ))
190
288
if err != nil {
191
289
return
192
290
}
@@ -198,13 +296,6 @@ func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
198
296
if err != nil {
199
297
return
200
298
}
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
299
return
209
300
}
210
301
@@ -236,6 +327,107 @@ func serializeECDSAPrivateKey(w io.Writer, priv *ecdsa.PrivateKey) error {
236
327
return writeBig (w , priv .D )
237
328
}
238
329
330
+ func (pk * PrivateKey ) Encrypt (passphrase []byte ) error {
331
+ privateKeyBuf := bytes .NewBuffer (nil )
332
+ err := pk .SerializePGPPrivate (privateKeyBuf )
333
+ if err != nil {
334
+ return err
335
+ }
336
+
337
+ //Default config of private key encryption
338
+ pk .cipher = CipherAES128
339
+ pk .s2kMode = 3 //Iterated
340
+ pk .s2kConfig = s2k.Config {
341
+ S2KCount : 65536 ,
342
+ Hash : crypto .SHA1 ,
343
+ }
344
+
345
+ privateKeyBytes := privateKeyBuf .Bytes ()
346
+ key := make ([]byte , pk .cipher .KeySize ())
347
+ pk .salt = make ([]byte , 8 )
348
+ rand .Read (pk .salt )
349
+
350
+ pk .s2k = func (out , in []byte ) {
351
+ s2k .Iterated (out , pk .s2kConfig .Hash .New (), in , pk .salt , pk .s2kConfig .S2KCount )
352
+ }
353
+ pk .s2k (key , passphrase )
354
+ block := pk .cipher .new (key )
355
+ pk .iv = make ([]byte , pk .cipher .blockSize ())
356
+ rand .Read (pk .iv )
357
+ cfb := cipher .NewCFBEncrypter (block , pk .iv )
358
+
359
+ if pk .sha1Checksum {
360
+ pk .s2kType = S2KSHA1
361
+ h := sha1 .New ()
362
+ if _ , err := h .Write (privateKeyBytes ); err != nil {
363
+ return err
364
+ }
365
+ sum := h .Sum (nil )
366
+ privateKeyBytes = append (privateKeyBytes , sum ... )
367
+ } else {
368
+ pk .s2kType = S2KCHECKSUM
369
+ var sum uint16
370
+ for i := 0 ; i < len (privateKeyBytes ); i ++ {
371
+ sum += uint16 (privateKeyBytes [i ])
372
+ }
373
+ privateKeyBytes = append (privateKeyBytes , uint8 (sum >> 8 ))
374
+ privateKeyBytes = append (privateKeyBytes , uint8 (sum ))
375
+ }
376
+
377
+ pk .encryptedData = make ([]byte , len (privateKeyBytes ))
378
+
379
+ cfb .XORKeyStream (pk .encryptedData , privateKeyBytes )
380
+
381
+ pk .Encrypted = true
382
+ return err
383
+ }
384
+
385
+ func (pk * PrivateKey ) SerializePGPPrivate (privateKeyBuf io.Writer ) error {
386
+ var err error
387
+ switch priv := pk .PrivateKey .(type ) {
388
+ case * rsa.PrivateKey :
389
+ err = serializePGPRSAPrivateKey (privateKeyBuf , priv )
390
+ case * dsa.PrivateKey :
391
+ err = serializePGPDSAPrivateKey (privateKeyBuf , priv )
392
+ case * elgamal.PrivateKey :
393
+ err = serializePGPElGamalPrivateKey (privateKeyBuf , priv )
394
+ case * ecdsa.PrivateKey :
395
+ err = serializePGPECDSAPrivateKey (privateKeyBuf , priv )
396
+ default :
397
+ err = errors .InvalidArgumentError ("unknown private key type" )
398
+ }
399
+ return err
400
+ }
401
+
402
+ func serializePGPRSAPrivateKey (w io.Writer , priv * rsa.PrivateKey ) error {
403
+ err := writeBig (w , priv .D )
404
+ if err != nil {
405
+ return err
406
+ }
407
+ err = writeBig (w , priv .Primes [0 ])
408
+ if err != nil {
409
+ return err
410
+ }
411
+ err = writeBig (w , priv .Primes [1 ])
412
+ if err != nil {
413
+ return err
414
+ }
415
+ u := new (big.Int ).ModInverse (priv .Primes [0 ], priv .Primes [1 ])
416
+ return writeBig (w , u )
417
+ }
418
+
419
+ func serializePGPDSAPrivateKey (w io.Writer , priv * dsa.PrivateKey ) error {
420
+ return writeBig (w , priv .X )
421
+ }
422
+
423
+ func serializePGPElGamalPrivateKey (w io.Writer , priv * elgamal.PrivateKey ) error {
424
+ return writeBig (w , priv .X )
425
+ }
426
+
427
+ func serializePGPECDSAPrivateKey (w io.Writer , priv * ecdsa.PrivateKey ) error {
428
+ return writeBig (w , priv .D )
429
+ }
430
+
239
431
// Decrypt decrypts an encrypted private key using a passphrase.
240
432
func (pk * PrivateKey ) Decrypt (passphrase []byte ) error {
241
433
if ! pk .Encrypted {
@@ -246,7 +438,6 @@ func (pk *PrivateKey) Decrypt(passphrase []byte) error {
246
438
pk .s2k (key , passphrase )
247
439
block := pk .cipher .new (key )
248
440
cfb := cipher .NewCFBDecrypter (block , pk .iv )
249
-
250
441
data := make ([]byte , len (pk .encryptedData ))
251
442
cfb .XORKeyStream (data , pk .encryptedData )
252
443
@@ -320,6 +511,7 @@ func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) {
320
511
return err
321
512
}
322
513
rsaPriv .Precompute ()
514
+
323
515
pk .PrivateKey = rsaPriv
324
516
pk .Encrypted = false
325
517
pk .encryptedData = nil
0 commit comments