Skip to content

Commit e6b35e3

Browse files
cclergetDrDaveD
authored andcommitted
Applied patch with modification notice
1 parent 32db794 commit e6b35e3

File tree

2 files changed

+251
-40
lines changed

2 files changed

+251
-40
lines changed

Diff for: openpgp/packet/private_key.go

+219-27
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5+
// Modifications from patches written by:
6+
// Fan Jiang <fanjiang@thoughtworks.com> and
7+
// Sofia Celi <sceli@thoughtworks.com>
8+
59
package packet
610

711
import (
@@ -10,6 +14,7 @@ import (
1014
"crypto/cipher"
1115
"crypto/dsa"
1216
"crypto/ecdsa"
17+
"crypto/rand"
1318
"crypto/rsa"
1419
"crypto/sha1"
1520
"io"
@@ -34,8 +39,22 @@ type PrivateKey struct {
3439
PrivateKey interface{} // An *{rsa|dsa|ecdsa}.PrivateKey or crypto.Signer/crypto.Decrypter (Decryptor RSA only).
3540
sha1Checksum bool
3641
iv []byte
42+
43+
// s2k related
44+
salt []byte
45+
s2kMode uint8
46+
s2kConfig s2k.Config
47+
s2kType S2KType
3748
}
3849

50+
type S2KType uint8
51+
52+
const (
53+
S2KNON S2KType = 0
54+
S2KSHA1 S2KType = 254
55+
S2KCHECKSUM S2KType = 255
56+
)
57+
3958
func NewRSAPrivateKey(creationTime time.Time, priv *rsa.PrivateKey) *PrivateKey {
4059
pk := new(PrivateKey)
4160
pk.PublicKey = *NewRSAPublicKey(creationTime, &priv.PublicKey)
@@ -97,24 +116,24 @@ func (pk *PrivateKey) parse(r io.Reader) (err error) {
97116
return
98117
}
99118

100-
s2kType := buf[0]
119+
pk.s2kType = S2KType(buf[0])
101120

102-
switch s2kType {
103-
case 0:
121+
switch pk.s2kType {
122+
case S2KNON:
104123
pk.s2k = nil
105124
pk.Encrypted = false
106-
case 254, 255:
125+
case S2KSHA1, S2KCHECKSUM:
107126
_, err = readFull(r, buf[:])
108127
if err != nil {
109128
return
110129
}
111130
pk.cipher = CipherFunction(buf[0])
112131
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)
114133
if err != nil {
115134
return
116135
}
117-
if s2kType == 254 {
136+
if pk.s2kType == S2KSHA1 {
118137
pk.sha1Checksum = true
119138
}
120139
default:
@@ -153,40 +172,119 @@ func mod64kHash(d []byte) uint16 {
153172
return h
154173
}
155174

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
162199
}
163-
buf.WriteByte(0 /* no encryption */)
164200

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+
}
166217

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+
}
167226
switch priv := pk.PrivateKey.(type) {
168227
case *rsa.PrivateKey:
169-
err = serializeRSAPrivateKey(privateKeyBuf, priv)
228+
err = serializeRSAPrivateKey(buf, priv)
170229
case *dsa.PrivateKey:
171-
err = serializeDSAPrivateKey(privateKeyBuf, priv)
230+
err = serializeDSAPrivateKey(buf, priv)
172231
case *elgamal.PrivateKey:
173-
err = serializeElGamalPrivateKey(privateKeyBuf, priv)
232+
err = serializeElGamalPrivateKey(buf, priv)
174233
case *ecdsa.PrivateKey:
175-
err = serializeECDSAPrivateKey(privateKeyBuf, priv)
234+
err = serializeECDSAPrivateKey(buf, priv)
176235
default:
177236
err = errors.InvalidArgumentError("unknown private key type")
178237
}
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)
179266
if err != nil {
180267
return
181268
}
182269

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+
183281
ptype := packetTypePrivateKey
184282
contents := buf.Bytes()
185283
privateKeyBytes := privateKeyBuf.Bytes()
186284
if pk.IsSubkey {
187285
ptype = packetTypePrivateSubkey
188286
}
189-
err = serializeHeader(w, ptype, len(contents)+len(privateKeyBytes)+2)
287+
err = serializeHeader(w, ptype, len(contents)+len(privateKeyBytes))
190288
if err != nil {
191289
return
192290
}
@@ -198,13 +296,6 @@ func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
198296
if err != nil {
199297
return
200298
}
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-
208299
return
209300
}
210301

@@ -236,6 +327,107 @@ func serializeECDSAPrivateKey(w io.Writer, priv *ecdsa.PrivateKey) error {
236327
return writeBig(w, priv.D)
237328
}
238329

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+
239431
// Decrypt decrypts an encrypted private key using a passphrase.
240432
func (pk *PrivateKey) Decrypt(passphrase []byte) error {
241433
if !pk.Encrypted {
@@ -246,7 +438,6 @@ func (pk *PrivateKey) Decrypt(passphrase []byte) error {
246438
pk.s2k(key, passphrase)
247439
block := pk.cipher.new(key)
248440
cfb := cipher.NewCFBDecrypter(block, pk.iv)
249-
250441
data := make([]byte, len(pk.encryptedData))
251442
cfb.XORKeyStream(data, pk.encryptedData)
252443

@@ -320,6 +511,7 @@ func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) {
320511
return err
321512
}
322513
rsaPriv.Precompute()
514+
323515
pk.PrivateKey = rsaPriv
324516
pk.Encrypted = false
325517
pk.encryptedData = nil

0 commit comments

Comments
 (0)