]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/golang.org/x/crypto/openpgp/packet/private_key.go
vendor: github.com/hashicorp/terraform/...@v0.10.0
[github/fretlink/terraform-provider-statuscake.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 }