1
2
3
4
5
6
7
8
9
10
11
12 package openpgp
13
14 import (
15 "crypto"
16 _ "crypto/sha256"
17 "hash"
18 "io"
19 "strconv"
20
21 "golang.org/x/crypto/openpgp/armor"
22 "golang.org/x/crypto/openpgp/errors"
23 "golang.org/x/crypto/openpgp/packet"
24 )
25
26
27 var SignatureType = "PGP SIGNATURE"
28
29
30 func readArmored(r io.Reader, expectedType string) (body io.Reader, err error) {
31 block, err := armor.Decode(r)
32 if err != nil {
33 return
34 }
35
36 if block.Type != expectedType {
37 return nil, errors.InvalidArgumentError("expected '" + expectedType + "', got: " + block.Type)
38 }
39
40 return block.Body, nil
41 }
42
43
44
45 type MessageDetails struct {
46 IsEncrypted bool
47 EncryptedToKeyIds []uint64
48 IsSymmetricallyEncrypted bool
49 DecryptedWith Key
50 IsSigned bool
51 SignedByKeyId uint64
52 SignedBy *Key
53 LiteralData *packet.LiteralData
54 UnverifiedBody io.Reader
55
56
57
58
59
60
61
62
63
64
65 SignatureError error
66 Signature *packet.Signature
67 SignatureV3 *packet.SignatureV3
68
69 decrypted io.ReadCloser
70 }
71
72
73
74
75
76
77
78
79 type PromptFunction func(keys []Key, symmetric bool) ([]byte, error)
80
81
82
83 type keyEnvelopePair struct {
84 key Key
85 encryptedKey *packet.EncryptedKey
86 }
87
88
89
90
91
92 func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction, config *packet.Config) (md *MessageDetails, err error) {
93 var p packet.Packet
94
95 var symKeys []*packet.SymmetricKeyEncrypted
96 var pubKeys []keyEnvelopePair
97 var se *packet.SymmetricallyEncrypted
98
99 packets := packet.NewReader(r)
100 md = new(MessageDetails)
101 md.IsEncrypted = true
102
103
104
105
106
107 ParsePackets:
108 for {
109 p, err = packets.Next()
110 if err != nil {
111 return nil, err
112 }
113 switch p := p.(type) {
114 case *packet.SymmetricKeyEncrypted:
115
116 md.IsSymmetricallyEncrypted = true
117 symKeys = append(symKeys, p)
118 case *packet.EncryptedKey:
119
120 md.EncryptedToKeyIds = append(md.EncryptedToKeyIds, p.KeyId)
121 switch p.Algo {
122 case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal:
123 break
124 default:
125 continue
126 }
127 var keys []Key
128 if p.KeyId == 0 {
129 keys = keyring.DecryptionKeys()
130 } else {
131 keys = keyring.KeysById(p.KeyId)
132 }
133 for _, k := range keys {
134 pubKeys = append(pubKeys, keyEnvelopePair{k, p})
135 }
136 case *packet.SymmetricallyEncrypted:
137 se = p
138 break ParsePackets
139 case *packet.Compressed, *packet.LiteralData, *packet.OnePassSignature:
140
141 if len(symKeys) != 0 || len(pubKeys) != 0 {
142 return nil, errors.StructuralError("key material not followed by encrypted message")
143 }
144 packets.Unread(p)
145 return readSignedMessage(packets, nil, keyring)
146 }
147 }
148
149 var candidates []Key
150 var decrypted io.ReadCloser
151
152
153
154
155 FindKey:
156 for {
157
158 candidates = candidates[:0]
159 candidateFingerprints := make(map[string]bool)
160
161 for _, pk := range pubKeys {
162 if pk.key.PrivateKey == nil {
163 continue
164 }
165 if !pk.key.PrivateKey.Encrypted {
166 if len(pk.encryptedKey.Key) == 0 {
167 pk.encryptedKey.Decrypt(pk.key.PrivateKey, config)
168 }
169 if len(pk.encryptedKey.Key) == 0 {
170 continue
171 }
172 decrypted, err = se.Decrypt(pk.encryptedKey.CipherFunc, pk.encryptedKey.Key)
173 if err != nil && err != errors.ErrKeyIncorrect {
174 return nil, err
175 }
176 if decrypted != nil {
177 md.DecryptedWith = pk.key
178 break FindKey
179 }
180 } else {
181 fpr := string(pk.key.PublicKey.Fingerprint[:])
182 if v := candidateFingerprints[fpr]; v {
183 continue
184 }
185 candidates = append(candidates, pk.key)
186 candidateFingerprints[fpr] = true
187 }
188 }
189
190 if len(candidates) == 0 && len(symKeys) == 0 {
191 return nil, errors.ErrKeyIncorrect
192 }
193
194 if prompt == nil {
195 return nil, errors.ErrKeyIncorrect
196 }
197
198 passphrase, err := prompt(candidates, len(symKeys) != 0)
199 if err != nil {
200 return nil, err
201 }
202
203
204 if len(symKeys) != 0 && passphrase != nil {
205 for _, s := range symKeys {
206 key, cipherFunc, err := s.Decrypt(passphrase)
207 if err == nil {
208 decrypted, err = se.Decrypt(cipherFunc, key)
209 if err != nil && err != errors.ErrKeyIncorrect {
210 return nil, err
211 }
212 if decrypted != nil {
213 break FindKey
214 }
215 }
216
217 }
218 }
219 }
220
221 md.decrypted = decrypted
222 if err := packets.Push(decrypted); err != nil {
223 return nil, err
224 }
225 return readSignedMessage(packets, md, keyring)
226 }
227
228
229
230
231 func readSignedMessage(packets *packet.Reader, mdin *MessageDetails, keyring KeyRing) (md *MessageDetails, err error) {
232 if mdin == nil {
233 mdin = new(MessageDetails)
234 }
235 md = mdin
236
237 var p packet.Packet
238 var h hash.Hash
239 var wrappedHash hash.Hash
240 FindLiteralData:
241 for {
242 p, err = packets.Next()
243 if err != nil {
244 return nil, err
245 }
246 switch p := p.(type) {
247 case *packet.Compressed:
248 if err := packets.Push(p.Body); err != nil {
249 return nil, err
250 }
251 case *packet.OnePassSignature:
252 if !p.IsLast {
253 return nil, errors.UnsupportedError("nested signatures")
254 }
255
256 h, wrappedHash, err = hashForSignature(p.Hash, p.SigType)
257 if err != nil {
258 md = nil
259 return
260 }
261
262 md.IsSigned = true
263 md.SignedByKeyId = p.KeyId
264 keys := keyring.KeysByIdUsage(p.KeyId, packet.KeyFlagSign)
265 if len(keys) > 0 {
266 md.SignedBy = &keys[0]
267 }
268 case *packet.LiteralData:
269 md.LiteralData = p
270 break FindLiteralData
271 }
272 }
273
274 if md.SignedBy != nil {
275 md.UnverifiedBody = &signatureCheckReader{packets, h, wrappedHash, md}
276 } else if md.decrypted != nil {
277 md.UnverifiedBody = checkReader{md}
278 } else {
279 md.UnverifiedBody = md.LiteralData.Body
280 }
281
282 return md, nil
283 }
284
285
286
287
288
289
290 func hashForSignature(hashId crypto.Hash, sigType packet.SignatureType) (hash.Hash, hash.Hash, error) {
291 if !hashId.Available() {
292 return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashId)))
293 }
294 h := hashId.New()
295
296 switch sigType {
297 case packet.SigTypeBinary:
298 return h, h, nil
299 case packet.SigTypeText:
300 return h, NewCanonicalTextHash(h), nil
301 }
302
303 return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType)))
304 }
305
306
307
308
309 type checkReader struct {
310 md *MessageDetails
311 }
312
313 func (cr checkReader) Read(buf []byte) (n int, err error) {
314 n, err = cr.md.LiteralData.Body.Read(buf)
315 if err == io.EOF {
316 mdcErr := cr.md.decrypted.Close()
317 if mdcErr != nil {
318 err = mdcErr
319 }
320 }
321 return
322 }
323
324
325
326
327 type signatureCheckReader struct {
328 packets *packet.Reader
329 h, wrappedHash hash.Hash
330 md *MessageDetails
331 }
332
333 func (scr *signatureCheckReader) Read(buf []byte) (n int, err error) {
334 n, err = scr.md.LiteralData.Body.Read(buf)
335 scr.wrappedHash.Write(buf[:n])
336 if err == io.EOF {
337 var p packet.Packet
338 p, scr.md.SignatureError = scr.packets.Next()
339 if scr.md.SignatureError != nil {
340 return
341 }
342
343 var ok bool
344 if scr.md.Signature, ok = p.(*packet.Signature); ok {
345 scr.md.SignatureError = scr.md.SignedBy.PublicKey.VerifySignature(scr.h, scr.md.Signature)
346 } else if scr.md.SignatureV3, ok = p.(*packet.SignatureV3); ok {
347 scr.md.SignatureError = scr.md.SignedBy.PublicKey.VerifySignatureV3(scr.h, scr.md.SignatureV3)
348 } else {
349 scr.md.SignatureError = errors.StructuralError("LiteralData not followed by Signature")
350 return
351 }
352
353
354
355
356 if scr.md.decrypted != nil {
357 mdcErr := scr.md.decrypted.Close()
358 if mdcErr != nil {
359 err = mdcErr
360 }
361 }
362 }
363 return
364 }
365
366
367
368
369 func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
370 var issuerKeyId uint64
371 var hashFunc crypto.Hash
372 var sigType packet.SignatureType
373 var keys []Key
374 var p packet.Packet
375
376 packets := packet.NewReader(signature)
377 for {
378 p, err = packets.Next()
379 if err == io.EOF {
380 return nil, errors.ErrUnknownIssuer
381 }
382 if err != nil {
383 return nil, err
384 }
385
386 switch sig := p.(type) {
387 case *packet.Signature:
388 if sig.IssuerKeyId == nil {
389 return nil, errors.StructuralError("signature doesn't have an issuer")
390 }
391 issuerKeyId = *sig.IssuerKeyId
392 hashFunc = sig.Hash
393 sigType = sig.SigType
394 case *packet.SignatureV3:
395 issuerKeyId = sig.IssuerKeyId
396 hashFunc = sig.Hash
397 sigType = sig.SigType
398 default:
399 return nil, errors.StructuralError("non signature packet found")
400 }
401
402 keys = keyring.KeysByIdUsage(issuerKeyId, packet.KeyFlagSign)
403 if len(keys) > 0 {
404 break
405 }
406 }
407
408 if len(keys) == 0 {
409 panic("unreachable")
410 }
411
412 h, wrappedHash, err := hashForSignature(hashFunc, sigType)
413 if err != nil {
414 return nil, err
415 }
416
417 if _, err := io.Copy(wrappedHash, signed); err != nil && err != io.EOF {
418 return nil, err
419 }
420
421 for _, key := range keys {
422 switch sig := p.(type) {
423 case *packet.Signature:
424 err = key.PublicKey.VerifySignature(h, sig)
425 case *packet.SignatureV3:
426 err = key.PublicKey.VerifySignatureV3(h, sig)
427 default:
428 panic("unreachable")
429 }
430
431 if err == nil {
432 return key.Entity, nil
433 }
434 }
435
436 return nil, err
437 }
438
439
440
441 func CheckArmoredDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
442 body, err := readArmored(signature, SignatureType)
443 if err != nil {
444 return
445 }
446
447 return CheckDetachedSignature(keyring, signed, body)
448 }
449
View as plain text