OSDN Git Service

d67e968861758a183fa60784b05ff4cb2a18f87e
[pf3gnuchains/gcc-fork.git] / libgo / go / 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/cipher"
10         "crypto/dsa"
11         "crypto/openpgp/elgamal"
12         error_ "crypto/openpgp/error"
13         "crypto/openpgp/s2k"
14         "crypto/rsa"
15         "crypto/sha1"
16         "io"
17         "io/ioutil"
18         "math/big"
19         "strconv"
20         "time"
21 )
22
23 // PrivateKey represents a possibly encrypted private key. See RFC 4880,
24 // section 5.5.3.
25 type PrivateKey struct {
26         PublicKey
27         Encrypted     bool // if true then the private key is unavailable until Decrypt has been called.
28         encryptedData []byte
29         cipher        CipherFunction
30         s2k           func(out, in []byte)
31         PrivateKey    interface{} // An *rsa.PrivateKey.
32         sha1Checksum  bool
33         iv            []byte
34 }
35
36 func NewRSAPrivateKey(currentTime time.Time, priv *rsa.PrivateKey, isSubkey bool) *PrivateKey {
37         pk := new(PrivateKey)
38         pk.PublicKey = *NewRSAPublicKey(currentTime, &priv.PublicKey, isSubkey)
39         pk.PrivateKey = priv
40         return pk
41 }
42
43 func (pk *PrivateKey) parse(r io.Reader) (err error) {
44         err = (&pk.PublicKey).parse(r)
45         if err != nil {
46                 return
47         }
48         var buf [1]byte
49         _, err = readFull(r, buf[:])
50         if err != nil {
51                 return
52         }
53
54         s2kType := buf[0]
55
56         switch s2kType {
57         case 0:
58                 pk.s2k = nil
59                 pk.Encrypted = false
60         case 254, 255:
61                 _, err = readFull(r, buf[:])
62                 if err != nil {
63                         return
64                 }
65                 pk.cipher = CipherFunction(buf[0])
66                 pk.Encrypted = true
67                 pk.s2k, err = s2k.Parse(r)
68                 if err != nil {
69                         return
70                 }
71                 if s2kType == 254 {
72                         pk.sha1Checksum = true
73                 }
74         default:
75                 return error_.UnsupportedError("deprecated s2k function in private key")
76         }
77
78         if pk.Encrypted {
79                 blockSize := pk.cipher.blockSize()
80                 if blockSize == 0 {
81                         return error_.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher)))
82                 }
83                 pk.iv = make([]byte, blockSize)
84                 _, err = readFull(r, pk.iv)
85                 if err != nil {
86                         return
87                 }
88         }
89
90         pk.encryptedData, err = ioutil.ReadAll(r)
91         if err != nil {
92                 return
93         }
94
95         if !pk.Encrypted {
96                 return pk.parsePrivateKey(pk.encryptedData)
97         }
98
99         return
100 }
101
102 func mod64kHash(d []byte) uint16 {
103         var h uint16
104         for _, b := range d {
105                 h += uint16(b)
106         }
107         return h
108 }
109
110 func (pk *PrivateKey) Serialize(w io.Writer) (err error) {
111         // TODO(agl): support encrypted private keys
112         buf := bytes.NewBuffer(nil)
113         err = pk.PublicKey.serializeWithoutHeaders(buf)
114         if err != nil {
115                 return
116         }
117         buf.WriteByte(0 /* no encryption */ )
118
119         privateKeyBuf := bytes.NewBuffer(nil)
120
121         switch priv := pk.PrivateKey.(type) {
122         case *rsa.PrivateKey:
123                 err = serializeRSAPrivateKey(privateKeyBuf, priv)
124         default:
125                 err = error_.InvalidArgumentError("non-RSA private key")
126         }
127         if err != nil {
128                 return
129         }
130
131         ptype := packetTypePrivateKey
132         contents := buf.Bytes()
133         privateKeyBytes := privateKeyBuf.Bytes()
134         if pk.IsSubkey {
135                 ptype = packetTypePrivateSubkey
136         }
137         err = serializeHeader(w, ptype, len(contents)+len(privateKeyBytes)+2)
138         if err != nil {
139                 return
140         }
141         _, err = w.Write(contents)
142         if err != nil {
143                 return
144         }
145         _, err = w.Write(privateKeyBytes)
146         if err != nil {
147                 return
148         }
149
150         checksum := mod64kHash(privateKeyBytes)
151         var checksumBytes [2]byte
152         checksumBytes[0] = byte(checksum >> 8)
153         checksumBytes[1] = byte(checksum)
154         _, err = w.Write(checksumBytes[:])
155
156         return
157 }
158
159 func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error {
160         err := writeBig(w, priv.D)
161         if err != nil {
162                 return err
163         }
164         err = writeBig(w, priv.Primes[1])
165         if err != nil {
166                 return err
167         }
168         err = writeBig(w, priv.Primes[0])
169         if err != nil {
170                 return err
171         }
172         return writeBig(w, priv.Precomputed.Qinv)
173 }
174
175 // Decrypt decrypts an encrypted private key using a passphrase.
176 func (pk *PrivateKey) Decrypt(passphrase []byte) error {
177         if !pk.Encrypted {
178                 return nil
179         }
180
181         key := make([]byte, pk.cipher.KeySize())
182         pk.s2k(key, passphrase)
183         block := pk.cipher.new(key)
184         cfb := cipher.NewCFBDecrypter(block, pk.iv)
185
186         data := pk.encryptedData
187         cfb.XORKeyStream(data, data)
188
189         if pk.sha1Checksum {
190                 if len(data) < sha1.Size {
191                         return error_.StructuralError("truncated private key data")
192                 }
193                 h := sha1.New()
194                 h.Write(data[:len(data)-sha1.Size])
195                 sum := h.Sum(nil)
196                 if !bytes.Equal(sum, data[len(data)-sha1.Size:]) {
197                         return error_.StructuralError("private key checksum failure")
198                 }
199                 data = data[:len(data)-sha1.Size]
200         } else {
201                 if len(data) < 2 {
202                         return error_.StructuralError("truncated private key data")
203                 }
204                 var sum uint16
205                 for i := 0; i < len(data)-2; i++ {
206                         sum += uint16(data[i])
207                 }
208                 if data[len(data)-2] != uint8(sum>>8) ||
209                         data[len(data)-1] != uint8(sum) {
210                         return error_.StructuralError("private key checksum failure")
211                 }
212                 data = data[:len(data)-2]
213         }
214
215         return pk.parsePrivateKey(data)
216 }
217
218 func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) {
219         switch pk.PublicKey.PubKeyAlgo {
220         case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoRSAEncryptOnly:
221                 return pk.parseRSAPrivateKey(data)
222         case PubKeyAlgoDSA:
223                 return pk.parseDSAPrivateKey(data)
224         case PubKeyAlgoElGamal:
225                 return pk.parseElGamalPrivateKey(data)
226         }
227         panic("impossible")
228 }
229
230 func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) {
231         rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey)
232         rsaPriv := new(rsa.PrivateKey)
233         rsaPriv.PublicKey = *rsaPub
234
235         buf := bytes.NewBuffer(data)
236         d, _, err := readMPI(buf)
237         if err != nil {
238                 return
239         }
240         p, _, err := readMPI(buf)
241         if err != nil {
242                 return
243         }
244         q, _, err := readMPI(buf)
245         if err != nil {
246                 return
247         }
248
249         rsaPriv.D = new(big.Int).SetBytes(d)
250         rsaPriv.Primes = make([]*big.Int, 2)
251         rsaPriv.Primes[0] = new(big.Int).SetBytes(p)
252         rsaPriv.Primes[1] = new(big.Int).SetBytes(q)
253         rsaPriv.Precompute()
254         pk.PrivateKey = rsaPriv
255         pk.Encrypted = false
256         pk.encryptedData = nil
257
258         return nil
259 }
260
261 func (pk *PrivateKey) parseDSAPrivateKey(data []byte) (err error) {
262         dsaPub := pk.PublicKey.PublicKey.(*dsa.PublicKey)
263         dsaPriv := new(dsa.PrivateKey)
264         dsaPriv.PublicKey = *dsaPub
265
266         buf := bytes.NewBuffer(data)
267         x, _, err := readMPI(buf)
268         if err != nil {
269                 return
270         }
271
272         dsaPriv.X = new(big.Int).SetBytes(x)
273         pk.PrivateKey = dsaPriv
274         pk.Encrypted = false
275         pk.encryptedData = nil
276
277         return nil
278 }
279
280 func (pk *PrivateKey) parseElGamalPrivateKey(data []byte) (err error) {
281         pub := pk.PublicKey.PublicKey.(*elgamal.PublicKey)
282         priv := new(elgamal.PrivateKey)
283         priv.PublicKey = *pub
284
285         buf := bytes.NewBuffer(data)
286         x, _, err := readMPI(buf)
287         if err != nil {
288                 return
289         }
290
291         priv.X = new(big.Int).SetBytes(x)
292         pk.PrivateKey = priv
293         pk.Encrypted = false
294         pk.encryptedData = nil
295
296         return nil
297 }