diff options
Diffstat (limited to 'vendor/golang.org/x/crypto/openpgp/read.go')
-rw-r--r-- | vendor/golang.org/x/crypto/openpgp/read.go | 442 |
1 files changed, 442 insertions, 0 deletions
diff --git a/vendor/golang.org/x/crypto/openpgp/read.go b/vendor/golang.org/x/crypto/openpgp/read.go new file mode 100644 index 0000000..6ec664f --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/read.go | |||
@@ -0,0 +1,442 @@ | |||
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 openpgp implements high level operations on OpenPGP messages. | ||
6 | package openpgp // import "golang.org/x/crypto/openpgp" | ||
7 | |||
8 | import ( | ||
9 | "crypto" | ||
10 | _ "crypto/sha256" | ||
11 | "hash" | ||
12 | "io" | ||
13 | "strconv" | ||
14 | |||
15 | "golang.org/x/crypto/openpgp/armor" | ||
16 | "golang.org/x/crypto/openpgp/errors" | ||
17 | "golang.org/x/crypto/openpgp/packet" | ||
18 | ) | ||
19 | |||
20 | // SignatureType is the armor type for a PGP signature. | ||
21 | var SignatureType = "PGP SIGNATURE" | ||
22 | |||
23 | // readArmored reads an armored block with the given type. | ||
24 | func readArmored(r io.Reader, expectedType string) (body io.Reader, err error) { | ||
25 | block, err := armor.Decode(r) | ||
26 | if err != nil { | ||
27 | return | ||
28 | } | ||
29 | |||
30 | if block.Type != expectedType { | ||
31 | return nil, errors.InvalidArgumentError("expected '" + expectedType + "', got: " + block.Type) | ||
32 | } | ||
33 | |||
34 | return block.Body, nil | ||
35 | } | ||
36 | |||
37 | // MessageDetails contains the result of parsing an OpenPGP encrypted and/or | ||
38 | // signed message. | ||
39 | type MessageDetails struct { | ||
40 | IsEncrypted bool // true if the message was encrypted. | ||
41 | EncryptedToKeyIds []uint64 // the list of recipient key ids. | ||
42 | IsSymmetricallyEncrypted bool // true if a passphrase could have decrypted the message. | ||
43 | DecryptedWith Key // the private key used to decrypt the message, if any. | ||
44 | IsSigned bool // true if the message is signed. | ||
45 | SignedByKeyId uint64 // the key id of the signer, if any. | ||
46 | SignedBy *Key // the key of the signer, if available. | ||
47 | LiteralData *packet.LiteralData // the metadata of the contents | ||
48 | UnverifiedBody io.Reader // the contents of the message. | ||
49 | |||
50 | // If IsSigned is true and SignedBy is non-zero then the signature will | ||
51 | // be verified as UnverifiedBody is read. The signature cannot be | ||
52 | // checked until the whole of UnverifiedBody is read so UnverifiedBody | ||
53 | // must be consumed until EOF before the data can be trusted. Even if a | ||
54 | // message isn't signed (or the signer is unknown) the data may contain | ||
55 | // an authentication code that is only checked once UnverifiedBody has | ||
56 | // been consumed. Once EOF has been seen, the following fields are | ||
57 | // valid. (An authentication code failure is reported as a | ||
58 | // SignatureError error when reading from UnverifiedBody.) | ||
59 | SignatureError error // nil if the signature is good. | ||
60 | Signature *packet.Signature // the signature packet itself, if v4 (default) | ||
61 | SignatureV3 *packet.SignatureV3 // the signature packet if it is a v2 or v3 signature | ||
62 | |||
63 | decrypted io.ReadCloser | ||
64 | } | ||
65 | |||
66 | // A PromptFunction is used as a callback by functions that may need to decrypt | ||
67 | // a private key, or prompt for a passphrase. It is called with a list of | ||
68 | // acceptable, encrypted private keys and a boolean that indicates whether a | ||
69 | // passphrase is usable. It should either decrypt a private key or return a | ||
70 | // passphrase to try. If the decrypted private key or given passphrase isn't | ||
71 | // correct, the function will be called again, forever. Any error returned will | ||
72 | // be passed up. | ||
73 | type PromptFunction func(keys []Key, symmetric bool) ([]byte, error) | ||
74 | |||
75 | // A keyEnvelopePair is used to store a private key with the envelope that | ||
76 | // contains a symmetric key, encrypted with that key. | ||
77 | type keyEnvelopePair struct { | ||
78 | key Key | ||
79 | encryptedKey *packet.EncryptedKey | ||
80 | } | ||
81 | |||
82 | // ReadMessage parses an OpenPGP message that may be signed and/or encrypted. | ||
83 | // The given KeyRing should contain both public keys (for signature | ||
84 | // verification) and, possibly encrypted, private keys for decrypting. | ||
85 | // If config is nil, sensible defaults will be used. | ||
86 | func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction, config *packet.Config) (md *MessageDetails, err error) { | ||
87 | var p packet.Packet | ||
88 | |||
89 | var symKeys []*packet.SymmetricKeyEncrypted | ||
90 | var pubKeys []keyEnvelopePair | ||
91 | var se *packet.SymmetricallyEncrypted | ||
92 | |||
93 | packets := packet.NewReader(r) | ||
94 | md = new(MessageDetails) | ||
95 | md.IsEncrypted = true | ||
96 | |||
97 | // The message, if encrypted, starts with a number of packets | ||
98 | // containing an encrypted decryption key. The decryption key is either | ||
99 | // encrypted to a public key, or with a passphrase. This loop | ||
100 | // collects these packets. | ||
101 | ParsePackets: | ||
102 | for { | ||
103 | p, err = packets.Next() | ||
104 | if err != nil { | ||
105 | return nil, err | ||
106 | } | ||
107 | switch p := p.(type) { | ||
108 | case *packet.SymmetricKeyEncrypted: | ||
109 | // This packet contains the decryption key encrypted with a passphrase. | ||
110 | md.IsSymmetricallyEncrypted = true | ||
111 | symKeys = append(symKeys, p) | ||
112 | case *packet.EncryptedKey: | ||
113 | // This packet contains the decryption key encrypted to a public key. | ||
114 | md.EncryptedToKeyIds = append(md.EncryptedToKeyIds, p.KeyId) | ||
115 | switch p.Algo { | ||
116 | case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal: | ||
117 | break | ||
118 | default: | ||
119 | continue | ||
120 | } | ||
121 | var keys []Key | ||
122 | if p.KeyId == 0 { | ||
123 | keys = keyring.DecryptionKeys() | ||
124 | } else { | ||
125 | keys = keyring.KeysById(p.KeyId) | ||
126 | } | ||
127 | for _, k := range keys { | ||
128 | pubKeys = append(pubKeys, keyEnvelopePair{k, p}) | ||
129 | } | ||
130 | case *packet.SymmetricallyEncrypted: | ||
131 | se = p | ||
132 | break ParsePackets | ||
133 | case *packet.Compressed, *packet.LiteralData, *packet.OnePassSignature: | ||
134 | // This message isn't encrypted. | ||
135 | if len(symKeys) != 0 || len(pubKeys) != 0 { | ||
136 | return nil, errors.StructuralError("key material not followed by encrypted message") | ||
137 | } | ||
138 | packets.Unread(p) | ||
139 | return readSignedMessage(packets, nil, keyring) | ||
140 | } | ||
141 | } | ||
142 | |||
143 | var candidates []Key | ||
144 | var decrypted io.ReadCloser | ||
145 | |||
146 | // Now that we have the list of encrypted keys we need to decrypt at | ||
147 | // least one of them or, if we cannot, we need to call the prompt | ||
148 | // function so that it can decrypt a key or give us a passphrase. | ||
149 | FindKey: | ||
150 | for { | ||
151 | // See if any of the keys already have a private key available | ||
152 | candidates = candidates[:0] | ||
153 | candidateFingerprints := make(map[string]bool) | ||
154 | |||
155 | for _, pk := range pubKeys { | ||
156 | if pk.key.PrivateKey == nil { | ||
157 | continue | ||
158 | } | ||
159 | if !pk.key.PrivateKey.Encrypted { | ||
160 | if len(pk.encryptedKey.Key) == 0 { | ||
161 | pk.encryptedKey.Decrypt(pk.key.PrivateKey, config) | ||
162 | } | ||
163 | if len(pk.encryptedKey.Key) == 0 { | ||
164 | continue | ||
165 | } | ||
166 | decrypted, err = se.Decrypt(pk.encryptedKey.CipherFunc, pk.encryptedKey.Key) | ||
167 | if err != nil && err != errors.ErrKeyIncorrect { | ||
168 | return nil, err | ||
169 | } | ||
170 | if decrypted != nil { | ||
171 | md.DecryptedWith = pk.key | ||
172 | break FindKey | ||
173 | } | ||
174 | } else { | ||
175 | fpr := string(pk.key.PublicKey.Fingerprint[:]) | ||
176 | if v := candidateFingerprints[fpr]; v { | ||
177 | continue | ||
178 | } | ||
179 | candidates = append(candidates, pk.key) | ||
180 | candidateFingerprints[fpr] = true | ||
181 | } | ||
182 | } | ||
183 | |||
184 | if len(candidates) == 0 && len(symKeys) == 0 { | ||
185 | return nil, errors.ErrKeyIncorrect | ||
186 | } | ||
187 | |||
188 | if prompt == nil { | ||
189 | return nil, errors.ErrKeyIncorrect | ||
190 | } | ||
191 | |||
192 | passphrase, err := prompt(candidates, len(symKeys) != 0) | ||
193 | if err != nil { | ||
194 | return nil, err | ||
195 | } | ||
196 | |||
197 | // Try the symmetric passphrase first | ||
198 | if len(symKeys) != 0 && passphrase != nil { | ||
199 | for _, s := range symKeys { | ||
200 | key, cipherFunc, err := s.Decrypt(passphrase) | ||
201 | if err == nil { | ||
202 | decrypted, err = se.Decrypt(cipherFunc, key) | ||
203 | if err != nil && err != errors.ErrKeyIncorrect { | ||
204 | return nil, err | ||
205 | } | ||
206 | if decrypted != nil { | ||
207 | break FindKey | ||
208 | } | ||
209 | } | ||
210 | |||
211 | } | ||
212 | } | ||
213 | } | ||
214 | |||
215 | md.decrypted = decrypted | ||
216 | if err := packets.Push(decrypted); err != nil { | ||
217 | return nil, err | ||
218 | } | ||
219 | return readSignedMessage(packets, md, keyring) | ||
220 | } | ||
221 | |||
222 | // readSignedMessage reads a possibly signed message if mdin is non-zero then | ||
223 | // that structure is updated and returned. Otherwise a fresh MessageDetails is | ||
224 | // used. | ||
225 | func readSignedMessage(packets *packet.Reader, mdin *MessageDetails, keyring KeyRing) (md *MessageDetails, err error) { | ||
226 | if mdin == nil { | ||
227 | mdin = new(MessageDetails) | ||
228 | } | ||
229 | md = mdin | ||
230 | |||
231 | var p packet.Packet | ||
232 | var h hash.Hash | ||
233 | var wrappedHash hash.Hash | ||
234 | FindLiteralData: | ||
235 | for { | ||
236 | p, err = packets.Next() | ||
237 | if err != nil { | ||
238 | return nil, err | ||
239 | } | ||
240 | switch p := p.(type) { | ||
241 | case *packet.Compressed: | ||
242 | if err := packets.Push(p.Body); err != nil { | ||
243 | return nil, err | ||
244 | } | ||
245 | case *packet.OnePassSignature: | ||
246 | if !p.IsLast { | ||
247 | return nil, errors.UnsupportedError("nested signatures") | ||
248 | } | ||
249 | |||
250 | h, wrappedHash, err = hashForSignature(p.Hash, p.SigType) | ||
251 | if err != nil { | ||
252 | md = nil | ||
253 | return | ||
254 | } | ||
255 | |||
256 | md.IsSigned = true | ||
257 | md.SignedByKeyId = p.KeyId | ||
258 | keys := keyring.KeysByIdUsage(p.KeyId, packet.KeyFlagSign) | ||
259 | if len(keys) > 0 { | ||
260 | md.SignedBy = &keys[0] | ||
261 | } | ||
262 | case *packet.LiteralData: | ||
263 | md.LiteralData = p | ||
264 | break FindLiteralData | ||
265 | } | ||
266 | } | ||
267 | |||
268 | if md.SignedBy != nil { | ||
269 | md.UnverifiedBody = &signatureCheckReader{packets, h, wrappedHash, md} | ||
270 | } else if md.decrypted != nil { | ||
271 | md.UnverifiedBody = checkReader{md} | ||
272 | } else { | ||
273 | md.UnverifiedBody = md.LiteralData.Body | ||
274 | } | ||
275 | |||
276 | return md, nil | ||
277 | } | ||
278 | |||
279 | // hashForSignature returns a pair of hashes that can be used to verify a | ||
280 | // signature. The signature may specify that the contents of the signed message | ||
281 | // should be preprocessed (i.e. to normalize line endings). Thus this function | ||
282 | // returns two hashes. The second should be used to hash the message itself and | ||
283 | // performs any needed preprocessing. | ||
284 | func hashForSignature(hashId crypto.Hash, sigType packet.SignatureType) (hash.Hash, hash.Hash, error) { | ||
285 | if !hashId.Available() { | ||
286 | return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashId))) | ||
287 | } | ||
288 | h := hashId.New() | ||
289 | |||
290 | switch sigType { | ||
291 | case packet.SigTypeBinary: | ||
292 | return h, h, nil | ||
293 | case packet.SigTypeText: | ||
294 | return h, NewCanonicalTextHash(h), nil | ||
295 | } | ||
296 | |||
297 | return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType))) | ||
298 | } | ||
299 | |||
300 | // checkReader wraps an io.Reader from a LiteralData packet. When it sees EOF | ||
301 | // it closes the ReadCloser from any SymmetricallyEncrypted packet to trigger | ||
302 | // MDC checks. | ||
303 | type checkReader struct { | ||
304 | md *MessageDetails | ||
305 | } | ||
306 | |||
307 | func (cr checkReader) Read(buf []byte) (n int, err error) { | ||
308 | n, err = cr.md.LiteralData.Body.Read(buf) | ||
309 | if err == io.EOF { | ||
310 | mdcErr := cr.md.decrypted.Close() | ||
311 | if mdcErr != nil { | ||
312 | err = mdcErr | ||
313 | } | ||
314 | } | ||
315 | return | ||
316 | } | ||
317 | |||
318 | // signatureCheckReader wraps an io.Reader from a LiteralData packet and hashes | ||
319 | // the data as it is read. When it sees an EOF from the underlying io.Reader | ||
320 | // it parses and checks a trailing Signature packet and triggers any MDC checks. | ||
321 | type signatureCheckReader struct { | ||
322 | packets *packet.Reader | ||
323 | h, wrappedHash hash.Hash | ||
324 | md *MessageDetails | ||
325 | } | ||
326 | |||
327 | func (scr *signatureCheckReader) Read(buf []byte) (n int, err error) { | ||
328 | n, err = scr.md.LiteralData.Body.Read(buf) | ||
329 | scr.wrappedHash.Write(buf[:n]) | ||
330 | if err == io.EOF { | ||
331 | var p packet.Packet | ||
332 | p, scr.md.SignatureError = scr.packets.Next() | ||
333 | if scr.md.SignatureError != nil { | ||
334 | return | ||
335 | } | ||
336 | |||
337 | var ok bool | ||
338 | if scr.md.Signature, ok = p.(*packet.Signature); ok { | ||
339 | scr.md.SignatureError = scr.md.SignedBy.PublicKey.VerifySignature(scr.h, scr.md.Signature) | ||
340 | } else if scr.md.SignatureV3, ok = p.(*packet.SignatureV3); ok { | ||
341 | scr.md.SignatureError = scr.md.SignedBy.PublicKey.VerifySignatureV3(scr.h, scr.md.SignatureV3) | ||
342 | } else { | ||
343 | scr.md.SignatureError = errors.StructuralError("LiteralData not followed by Signature") | ||
344 | return | ||
345 | } | ||
346 | |||
347 | // The SymmetricallyEncrypted packet, if any, might have an | ||
348 | // unsigned hash of its own. In order to check this we need to | ||
349 | // close that Reader. | ||
350 | if scr.md.decrypted != nil { | ||
351 | mdcErr := scr.md.decrypted.Close() | ||
352 | if mdcErr != nil { | ||
353 | err = mdcErr | ||
354 | } | ||
355 | } | ||
356 | } | ||
357 | return | ||
358 | } | ||
359 | |||
360 | // CheckDetachedSignature takes a signed file and a detached signature and | ||
361 | // returns the signer if the signature is valid. If the signer isn't known, | ||
362 | // ErrUnknownIssuer is returned. | ||
363 | func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) { | ||
364 | var issuerKeyId uint64 | ||
365 | var hashFunc crypto.Hash | ||
366 | var sigType packet.SignatureType | ||
367 | var keys []Key | ||
368 | var p packet.Packet | ||
369 | |||
370 | packets := packet.NewReader(signature) | ||
371 | for { | ||
372 | p, err = packets.Next() | ||
373 | if err == io.EOF { | ||
374 | return nil, errors.ErrUnknownIssuer | ||
375 | } | ||
376 | if err != nil { | ||
377 | return nil, err | ||
378 | } | ||
379 | |||
380 | switch sig := p.(type) { | ||
381 | case *packet.Signature: | ||
382 | if sig.IssuerKeyId == nil { | ||
383 | return nil, errors.StructuralError("signature doesn't have an issuer") | ||
384 | } | ||
385 | issuerKeyId = *sig.IssuerKeyId | ||
386 | hashFunc = sig.Hash | ||
387 | sigType = sig.SigType | ||
388 | case *packet.SignatureV3: | ||
389 | issuerKeyId = sig.IssuerKeyId | ||
390 | hashFunc = sig.Hash | ||
391 | sigType = sig.SigType | ||
392 | default: | ||
393 | return nil, errors.StructuralError("non signature packet found") | ||
394 | } | ||
395 | |||
396 | keys = keyring.KeysByIdUsage(issuerKeyId, packet.KeyFlagSign) | ||
397 | if len(keys) > 0 { | ||
398 | break | ||
399 | } | ||
400 | } | ||
401 | |||
402 | if len(keys) == 0 { | ||
403 | panic("unreachable") | ||
404 | } | ||
405 | |||
406 | h, wrappedHash, err := hashForSignature(hashFunc, sigType) | ||
407 | if err != nil { | ||
408 | return nil, err | ||
409 | } | ||
410 | |||
411 | if _, err := io.Copy(wrappedHash, signed); err != nil && err != io.EOF { | ||
412 | return nil, err | ||
413 | } | ||
414 | |||
415 | for _, key := range keys { | ||
416 | switch sig := p.(type) { | ||
417 | case *packet.Signature: | ||
418 | err = key.PublicKey.VerifySignature(h, sig) | ||
419 | case *packet.SignatureV3: | ||
420 | err = key.PublicKey.VerifySignatureV3(h, sig) | ||
421 | default: | ||
422 | panic("unreachable") | ||
423 | } | ||
424 | |||
425 | if err == nil { | ||
426 | return key.Entity, nil | ||
427 | } | ||
428 | } | ||
429 | |||
430 | return nil, err | ||
431 | } | ||
432 | |||
433 | // CheckArmoredDetachedSignature performs the same actions as | ||
434 | // CheckDetachedSignature but expects the signature to be armored. | ||
435 | func CheckArmoredDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) { | ||
436 | body, err := readArmored(signature, SignatureType) | ||
437 | if err != nil { | ||
438 | return | ||
439 | } | ||
440 | |||
441 | return CheckDetachedSignature(keyring, signed, body) | ||
442 | } | ||