OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / crypto / openpgp / packet / private_key.go
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 sign-only 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         switch pubkey := signer.Public().(type) {
72         case rsa.PublicKey:
73                 pk.PublicKey = *NewRSAPublicKey(currentTime, &pubkey)
74                 pk.PubKeyAlgo = PubKeyAlgoRSASignOnly
75         case ecdsa.PublicKey:
76                 pk.PublicKey = *NewECDSAPublicKey(currentTime, &pubkey)
77         default:
78                 panic("openpgp: unknown crypto.Signer type in NewSignerPrivateKey")
79         }
80         pk.PrivateKey = signer
81         return pk
82 }
83
84 func (pk *PrivateKey) parse(r io.Reader) (err error) {
85         err = (&pk.PublicKey).parse(r)
86         if err != nil {
87                 return
88         }
89         var buf [1]byte
90         _, err = readFull(r, buf[:])
91         if err != nil {
92                 return
93         }
94
95         s2kType := buf[0]
96
97         switch s2kType {
98         case 0:
99                 pk.s2k = nil
100                 pk.Encrypted = false
101         case 254, 255:
102                 _, err = readFull(r, buf[:])
103                 if err != nil {
104                         return
105                 }
106                 pk.cipher = CipherFunction(buf[0])
107                 pk.Encrypted = true
108                 pk.s2k, err = s2k.Parse(r)
109                 if err != nil {
110                         return
111                 }
112                 if s2kType == 254 {
113                         pk.sha1Checksum = true
114                 }
115         default:
116                 return errors.UnsupportedError("deprecated s2k function in private key")
117         }
118
119         if pk.Encrypted {
120                 blockSize := pk.cipher.blockSize()
121                 if blockSize == 0 {
122                         return errors.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
123                 }
124                 pk.iv = make([]byte, blockSize)
125                 _, err = readFull(r, pk.iv)
126                 if err != nil {
127                         return
128                 }
129         }
130
131         pk.encryptedData, err = ioutil.ReadAll(r)
132         if err != nil {
133                 return
134         }
135
136         if !pk.Encrypted {
137                 return pk.parsePrivateKey(pk.encryptedData)
138         }
139
140         return
141 }
142
143 func mod64kHash(d []byte) uint16 {
144         var h uint16
145         for _, b := range d {
146                 h += uint16(b)
147         }
148         return h
149 }
150
151 func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
152         // TODO(agl): support encrypted private keys
153         buf := bytes.NewBuffer(nil)
154         err = pk.PublicKey.serializeWithoutHeaders(buf)
155         if err != nil {
156                 return
157         }
158         buf.WriteByte(0 /* no encryption */)
159
160         privateKeyBuf := bytes.NewBuffer(nil)
161
162         switch priv := pk.PrivateKey.(type) {
163         case *rsa.PrivateKey:
164                 err = serializeRSAPrivateKey(privateKeyBuf, priv)
165         case *dsa.PrivateKey:
166                 err = serializeDSAPrivateKey(privateKeyBuf, priv)
167         case *elgamal.PrivateKey:
168                 err = serializeElGamalPrivateKey(privateKeyBuf, priv)
169         case *ecdsa.PrivateKey:
170                 err = serializeECDSAPrivateKey(privateKeyBuf, priv)
171         default:
172                 err = errors.InvalidArgumentError("unknown private key type")
173         }
174         if err != nil {
175                 return
176         }
177
178         ptype := packetTypePrivateKey
179         contents := buf.Bytes()
180         privateKeyBytes := privateKeyBuf.Bytes()
181         if pk.IsSubkey {
182                 ptype = packetTypePrivateSubkey
183         }
184         err = serializeHeader(w, ptype, len(contents)+len(privateKeyBytes)+2)
185         if err != nil {
186                 return
187         }
188         _, err = w.Write(contents)
189         if err != nil {
190                 return
191         }
192         _, err = w.Write(privateKeyBytes)
193         if err != nil {
194                 return
195         }
196
197         checksum := mod64kHash(privateKeyBytes)
198         var checksumBytes [2]byte
199         checksumBytes[0] = byte(checksum >> 8)
200         checksumBytes[1] = byte(checksum)
201         _, err = w.Write(checksumBytes[:])
202
203         return
204 }
205
206 func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error {
207         err := writeBig(w, priv.D)
208         if err != nil {
209                 return err
210         }
211         err = writeBig(w, priv.Primes[1])
212         if err != nil {
213                 return err
214         }
215         err = writeBig(w, priv.Primes[0])
216         if err != nil {
217                 return err
218         }
219         return writeBig(w, priv.Precomputed.Qinv)
220 }
221
222 func serializeDSAPrivateKey(w io.Writer, priv *dsa.PrivateKey) error {
223         return writeBig(w, priv.X)
224 }
225
226 func serializeElGamalPrivateKey(w io.Writer, priv *elgamal.PrivateKey) error {
227         return writeBig(w, priv.X)
228 }
229
230 func serializeECDSAPrivateKey(w io.Writer, priv *ecdsa.PrivateKey) error {
231         return writeBig(w, priv.D)
232 }
233
234 // Decrypt decrypts an encrypted private key using a passphrase.
235 func (pk *PrivateKey) Decrypt(passphrase []byte) error {
236         if !pk.Encrypted {
237                 return nil
238         }
239
240         key := make([]byte, pk.cipher.KeySize())
241         pk.s2k(key, passphrase)
242         block := pk.cipher.new(key)
243         cfb := cipher.NewCFBDecrypter(block, pk.iv)
244
245         data := make([]byte, len(pk.encryptedData))
246         cfb.XORKeyStream(data, pk.encryptedData)
247
248         if pk.sha1Checksum {
249                 if len(data) < sha1.Size {
250                         return errors.StructuralError("truncated private key data")
251                 }
252                 h := sha1.New()
253                 h.Write(data[:len(data)-sha1.Size])
254                 sum := h.Sum(nil)
255                 if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
256                         return errors.StructuralError("private key checksum failure")
257                 }
258                 data = data[:len(data)-sha1.Size]
259         } else {
260                 if len(data) < 2 {
261                         return errors.StructuralError("truncated private key data")
262                 }
263                 var sum uint16
264                 for i := 0; i < len(data)-2; i++ {
265                         sum += uint16(data[i])
266                 }
267                 if data[len(data)-2] != uint8(sum>>8) ||
268                         data[len(data)-1] != uint8(sum) {
269                         return errors.StructuralError("private key checksum failure")
270                 }
271                 data = data[:len(data)-2]
272         }
273
274         return pk.parsePrivateKey(data)
275 }
276
277 func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) {
278         switch pk.PublicKey.PubKeyAlgo {
279         case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoRSAEncryptOnly:
280                 return pk.parseRSAPrivateKey(data)
281         case PubKeyAlgoDSA:
282                 return pk.parseDSAPrivateKey(data)
283         case PubKeyAlgoElGamal:
284                 return pk.parseElGamalPrivateKey(data)
285         case PubKeyAlgoECDSA:
286                 return pk.parseECDSAPrivateKey(data)
287         }
288         panic("impossible")
289 }
290
291 func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) {
292         rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey)
293         rsaPriv := new(rsa.PrivateKey)
294         rsaPriv.PublicKey = *rsaPub
295
296         buf := bytes.NewBuffer(data)
297         d, _, err := readMPI(buf)
298         if err != nil {
299                 return
300         }
301         p, _, err := readMPI(buf)
302         if err != nil {
303                 return
304         }
305         q, _, err := readMPI(buf)
306         if err != nil {
307                 return
308         }
309
310         rsaPriv.D = new(big.Int).SetBytes(d)
311         rsaPriv.Primes = make([]*big.Int, 2)
312         rsaPriv.Primes[0] = new(big.Int).SetBytes(p)
313         rsaPriv.Primes[1] = new(big.Int).SetBytes(q)
314         if err := rsaPriv.Validate(); err != nil {
315                 return err
316         }
317         rsaPriv.Precompute()
318         pk.PrivateKey = rsaPriv
319         pk.Encrypted = false
320         pk.encryptedData = nil
321
322         return nil
323 }
324
325 func (pk *PrivateKey) parseDSAPrivateKey(data []byte) (err error) {
326         dsaPub := pk.PublicKey.PublicKey.(*dsa.PublicKey)
327         dsaPriv := new(dsa.PrivateKey)
328         dsaPriv.PublicKey = *dsaPub
329
330         buf := bytes.NewBuffer(data)
331         x, _, err := readMPI(buf)
332         if err != nil {
333                 return
334         }
335
336         dsaPriv.X = new(big.Int).SetBytes(x)
337         pk.PrivateKey = dsaPriv
338         pk.Encrypted = false
339         pk.encryptedData = nil
340
341         return nil
342 }
343
344 func (pk *PrivateKey) parseElGamalPrivateKey(data []byte) (err error) {
345         pub := pk.PublicKey.PublicKey.(*elgamal.PublicKey)
346         priv := new(elgamal.PrivateKey)
347         priv.PublicKey = *pub
348
349         buf := bytes.NewBuffer(data)
350         x, _, err := readMPI(buf)
351         if err != nil {
352                 return
353         }
354
355         priv.X = new(big.Int).SetBytes(x)
356         pk.PrivateKey = priv
357         pk.Encrypted = false
358         pk.encryptedData = nil
359
360         return nil
361 }
362
363 func (pk *PrivateKey) parseECDSAPrivateKey(data []byte) (err error) {
364         ecdsaPub := pk.PublicKey.PublicKey.(*ecdsa.PublicKey)
365
366         buf := bytes.NewBuffer(data)
367         d, _, err := readMPI(buf)
368         if err != nil {
369                 return
370         }
371
372         pk.PrivateKey = &ecdsa.PrivateKey{
373                 PublicKey: *ecdsaPub,
374                 D:         new(big.Int).SetBytes(d),
375         }
376         pk.Encrypted = false
377         pk.encryptedData = nil
378
379         return nil
380 }