]>
Commit | Line | Data |
---|---|---|
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 | } |