1
2
3
4
5
6 package openpgp
7
8 import (
9 "crypto"
10 _ "crypto/sha256"
11 _ "crypto/sha512"
12 "hash"
13 "io"
14 "strconv"
15
16 "github.com/ProtonMail/go-crypto/openpgp/armor"
17 "github.com/ProtonMail/go-crypto/openpgp/errors"
18 "github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
19 "github.com/ProtonMail/go-crypto/openpgp/packet"
20 _ "golang.org/x/crypto/sha3"
21 )
22
23
24 var SignatureType = "PGP SIGNATURE"
25
26
27 func readArmored(r io.Reader, expectedType string) (body io.Reader, err error) {
28 block, err := armor.Decode(r)
29 if err != nil {
30 return
31 }
32
33 if block.Type != expectedType {
34 return nil, errors.InvalidArgumentError("expected '" + expectedType + "', got: " + block.Type)
35 }
36
37 return block.Body, nil
38 }
39
40
41
42 type MessageDetails struct {
43 IsEncrypted bool
44 EncryptedToKeyIds []uint64
45 IsSymmetricallyEncrypted bool
46 DecryptedWith Key
47 IsSigned bool
48 SignedByKeyId uint64
49 SignedBy *Key
50 LiteralData *packet.LiteralData
51 UnverifiedBody io.Reader
52
53
54
55
56
57
58
59
60
61
62 Signature *packet.Signature
63 SignatureError error
64 UnverifiedSignatures []*packet.Signature
65
66 decrypted io.ReadCloser
67 }
68
69
70
71
72
73
74
75
76 type PromptFunction func(keys []Key, symmetric bool) ([]byte, error)
77
78
79
80 type keyEnvelopePair struct {
81 key Key
82 encryptedKey *packet.EncryptedKey
83 }
84
85
86
87
88
89 func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction, config *packet.Config) (md *MessageDetails, err error) {
90 var p packet.Packet
91
92 var symKeys []*packet.SymmetricKeyEncrypted
93 var pubKeys []keyEnvelopePair
94
95 var edp packet.EncryptedDataPacket
96
97 packets := packet.NewReader(r)
98 md = new(MessageDetails)
99 md.IsEncrypted = true
100
101
102
103
104
105 ParsePackets:
106 for {
107 p, err = packets.Next()
108 if err != nil {
109 return nil, err
110 }
111 switch p := p.(type) {
112 case *packet.SymmetricKeyEncrypted:
113
114 md.IsSymmetricallyEncrypted = true
115 symKeys = append(symKeys, p)
116 case *packet.EncryptedKey:
117
118 md.EncryptedToKeyIds = append(md.EncryptedToKeyIds, p.KeyId)
119 switch p.Algo {
120 case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal, packet.PubKeyAlgoECDH:
121 break
122 default:
123 continue
124 }
125 if keyring != nil {
126 var keys []Key
127 if p.KeyId == 0 {
128 keys = keyring.DecryptionKeys()
129 } else {
130 keys = keyring.KeysById(p.KeyId)
131 }
132 for _, k := range keys {
133 pubKeys = append(pubKeys, keyEnvelopePair{k, p})
134 }
135 }
136 case *packet.SymmetricallyEncrypted:
137 if !p.IntegrityProtected && !config.AllowUnauthenticatedMessages() {
138 return nil, errors.UnsupportedError("message is not integrity protected")
139 }
140 edp = p
141 break ParsePackets
142 case *packet.AEADEncrypted:
143 edp = p
144 break ParsePackets
145 case *packet.Compressed, *packet.LiteralData, *packet.OnePassSignature:
146
147 if len(symKeys) != 0 || len(pubKeys) != 0 {
148 return nil, errors.StructuralError("key material not followed by encrypted message")
149 }
150 packets.Unread(p)
151 return readSignedMessage(packets, nil, keyring, config)
152 }
153 }
154
155 var candidates []Key
156 var decrypted io.ReadCloser
157
158
159
160
161 FindKey:
162 for {
163
164 candidates = candidates[:0]
165 candidateFingerprints := make(map[string]bool)
166
167 for _, pk := range pubKeys {
168 if pk.key.PrivateKey == nil {
169 continue
170 }
171 if !pk.key.PrivateKey.Encrypted {
172 if len(pk.encryptedKey.Key) == 0 {
173 errDec := pk.encryptedKey.Decrypt(pk.key.PrivateKey, config)
174 if errDec != nil {
175 continue
176 }
177 }
178
179 decrypted, err = edp.Decrypt(pk.encryptedKey.CipherFunc, pk.encryptedKey.Key)
180 if err != nil && err != errors.ErrKeyIncorrect {
181 return nil, err
182 }
183 if decrypted != nil {
184 md.DecryptedWith = pk.key
185 break FindKey
186 }
187 } else {
188 fpr := string(pk.key.PublicKey.Fingerprint[:])
189 if v := candidateFingerprints[fpr]; v {
190 continue
191 }
192 candidates = append(candidates, pk.key)
193 candidateFingerprints[fpr] = true
194 }
195 }
196
197 if len(candidates) == 0 && len(symKeys) == 0 {
198 return nil, errors.ErrKeyIncorrect
199 }
200
201 if prompt == nil {
202 return nil, errors.ErrKeyIncorrect
203 }
204
205 passphrase, err := prompt(candidates, len(symKeys) != 0)
206 if err != nil {
207 return nil, err
208 }
209
210
211 if len(symKeys) != 0 && passphrase != nil {
212 for _, s := range symKeys {
213 key, cipherFunc, err := s.Decrypt(passphrase)
214
215
216 if err == nil {
217 decrypted, err = edp.Decrypt(cipherFunc, key)
218 if err != nil {
219 return nil, err
220 }
221 if decrypted != nil {
222 break FindKey
223 }
224 }
225 }
226 }
227 }
228
229 md.decrypted = decrypted
230 if err := packets.Push(decrypted); err != nil {
231 return nil, err
232 }
233 mdFinal, sensitiveParsingErr := readSignedMessage(packets, md, keyring, config)
234 if sensitiveParsingErr != nil {
235 return nil, errors.StructuralError("parsing error")
236 }
237 return mdFinal, nil
238 }
239
240
241
242
243 func readSignedMessage(packets *packet.Reader, mdin *MessageDetails, keyring KeyRing, config *packet.Config) (md *MessageDetails, err error) {
244 if mdin == nil {
245 mdin = new(MessageDetails)
246 }
247 md = mdin
248
249 var p packet.Packet
250 var h hash.Hash
251 var wrappedHash hash.Hash
252 var prevLast bool
253 FindLiteralData:
254 for {
255 p, err = packets.Next()
256 if err != nil {
257 return nil, err
258 }
259 switch p := p.(type) {
260 case *packet.Compressed:
261 if err := packets.Push(p.Body); err != nil {
262 return nil, err
263 }
264 case *packet.OnePassSignature:
265 if prevLast {
266 return nil, errors.UnsupportedError("nested signature packets")
267 }
268
269 if p.IsLast {
270 prevLast = true
271 }
272
273 h, wrappedHash, err = hashForSignature(p.Hash, p.SigType)
274 if err != nil {
275 md.SignatureError = err
276 }
277
278 md.IsSigned = true
279 md.SignedByKeyId = p.KeyId
280 if keyring != nil {
281 keys := keyring.KeysByIdUsage(p.KeyId, packet.KeyFlagSign)
282 if len(keys) > 0 {
283 md.SignedBy = &keys[0]
284 }
285 }
286 case *packet.LiteralData:
287 md.LiteralData = p
288 break FindLiteralData
289 }
290 }
291
292 if md.IsSigned && md.SignatureError == nil {
293 md.UnverifiedBody = &signatureCheckReader{packets, h, wrappedHash, md, config}
294 } else if md.decrypted != nil {
295 md.UnverifiedBody = checkReader{md}
296 } else {
297 md.UnverifiedBody = md.LiteralData.Body
298 }
299
300 return md, nil
301 }
302
303
304
305
306
307
308 func hashForSignature(hashFunc crypto.Hash, sigType packet.SignatureType) (hash.Hash, hash.Hash, error) {
309 if _, ok := algorithm.HashToHashIdWithSha1(hashFunc); !ok {
310 return nil, nil, errors.UnsupportedError("unsupported hash function")
311 }
312 if !hashFunc.Available() {
313 return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashFunc)))
314 }
315 h := hashFunc.New()
316
317 switch sigType {
318 case packet.SigTypeBinary:
319 return h, h, nil
320 case packet.SigTypeText:
321 return h, NewCanonicalTextHash(h), nil
322 }
323
324 return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType)))
325 }
326
327
328
329
330 type checkReader struct {
331 md *MessageDetails
332 }
333
334 func (cr checkReader) Read(buf []byte) (int, error) {
335 n, sensitiveParsingError := cr.md.LiteralData.Body.Read(buf)
336 if sensitiveParsingError == io.EOF {
337 mdcErr := cr.md.decrypted.Close()
338 if mdcErr != nil {
339 return n, mdcErr
340 }
341 return n, io.EOF
342 }
343
344 if sensitiveParsingError != nil {
345 return n, errors.StructuralError("parsing error")
346 }
347
348 return n, nil
349 }
350
351
352
353
354 type signatureCheckReader struct {
355 packets *packet.Reader
356 h, wrappedHash hash.Hash
357 md *MessageDetails
358 config *packet.Config
359 }
360
361 func (scr *signatureCheckReader) Read(buf []byte) (int, error) {
362 n, sensitiveParsingError := scr.md.LiteralData.Body.Read(buf)
363
364
365 if scr.md.SignedBy != nil {
366 scr.wrappedHash.Write(buf[:n])
367 }
368
369 if sensitiveParsingError == io.EOF {
370 var p packet.Packet
371 var readError error
372 var sig *packet.Signature
373
374 p, readError = scr.packets.Next()
375 for readError == nil {
376 var ok bool
377 if sig, ok = p.(*packet.Signature); ok {
378 if sig.Version == 5 && (sig.SigType == 0x00 || sig.SigType == 0x01) {
379 sig.Metadata = scr.md.LiteralData
380 }
381
382
383 if scr.md.SignedBy != nil && *sig.IssuerKeyId == scr.md.SignedByKeyId {
384 key := scr.md.SignedBy
385 signatureError := key.PublicKey.VerifySignature(scr.h, sig)
386 if signatureError == nil {
387 signatureError = checkSignatureDetails(key, sig, scr.config)
388 }
389 scr.md.Signature = sig
390 scr.md.SignatureError = signatureError
391 } else {
392 scr.md.UnverifiedSignatures = append(scr.md.UnverifiedSignatures, sig)
393 }
394 }
395
396 p, readError = scr.packets.Next()
397 }
398
399 if scr.md.SignedBy != nil && scr.md.Signature == nil {
400 if scr.md.UnverifiedSignatures == nil {
401 scr.md.SignatureError = errors.StructuralError("LiteralData not followed by signature")
402 } else {
403 scr.md.SignatureError = errors.StructuralError("No matching signature found")
404 }
405 }
406
407
408
409
410 if scr.md.decrypted != nil {
411 mdcErr := scr.md.decrypted.Close()
412 if mdcErr != nil {
413 return n, mdcErr
414 }
415 }
416 return n, io.EOF
417 }
418
419 if sensitiveParsingError != nil {
420 return n, errors.StructuralError("parsing error")
421 }
422
423 return n, nil
424 }
425
426
427
428
429
430 func VerifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) {
431 var expectedHashes []crypto.Hash
432 return verifyDetachedSignature(keyring, signed, signature, expectedHashes, config)
433 }
434
435
436
437 func VerifyDetachedSignatureAndHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) {
438 return verifyDetachedSignature(keyring, signed, signature, expectedHashes, config)
439 }
440
441
442
443
444
445 func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (signer *Entity, err error) {
446 var expectedHashes []crypto.Hash
447 return CheckDetachedSignatureAndHash(keyring, signed, signature, expectedHashes, config)
448 }
449
450
451
452 func CheckDetachedSignatureAndHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (signer *Entity, err error) {
453 _, signer, err = verifyDetachedSignature(keyring, signed, signature, expectedHashes, config)
454 return
455 }
456
457 func verifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) {
458 var issuerKeyId uint64
459 var hashFunc crypto.Hash
460 var sigType packet.SignatureType
461 var keys []Key
462 var p packet.Packet
463
464 expectedHashesLen := len(expectedHashes)
465 packets := packet.NewReader(signature)
466 for {
467 p, err = packets.Next()
468 if err == io.EOF {
469 return nil, nil, errors.ErrUnknownIssuer
470 }
471 if err != nil {
472 return nil, nil, err
473 }
474
475 var ok bool
476 sig, ok = p.(*packet.Signature)
477 if !ok {
478 return nil, nil, errors.StructuralError("non signature packet found")
479 }
480 if sig.IssuerKeyId == nil {
481 return nil, nil, errors.StructuralError("signature doesn't have an issuer")
482 }
483 issuerKeyId = *sig.IssuerKeyId
484 hashFunc = sig.Hash
485 sigType = sig.SigType
486
487 for i, expectedHash := range expectedHashes {
488 if hashFunc == expectedHash {
489 break
490 }
491 if i+1 == expectedHashesLen {
492 return nil, nil, errors.StructuralError("hash algorithm mismatch with cleartext message headers")
493 }
494 }
495
496 keys = keyring.KeysByIdUsage(issuerKeyId, packet.KeyFlagSign)
497 if len(keys) > 0 {
498 break
499 }
500 }
501
502 if len(keys) == 0 {
503 panic("unreachable")
504 }
505
506 h, wrappedHash, err := hashForSignature(hashFunc, sigType)
507 if err != nil {
508 return nil, nil, err
509 }
510
511 if _, err := io.Copy(wrappedHash, signed); err != nil && err != io.EOF {
512 return nil, nil, err
513 }
514
515 for _, key := range keys {
516 err = key.PublicKey.VerifySignature(h, sig)
517 if err == nil {
518 return sig, key.Entity, checkSignatureDetails(&key, sig, config)
519 }
520 }
521
522 return nil, nil, err
523 }
524
525
526
527 func CheckArmoredDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (signer *Entity, err error) {
528 body, err := readArmored(signature, SignatureType)
529 if err != nil {
530 return
531 }
532
533 return CheckDetachedSignature(keyring, signed, body, config)
534 }
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558 func checkSignatureDetails(key *Key, signature *packet.Signature, config *packet.Config) error {
559 now := config.Now()
560 primaryIdentity := key.Entity.PrimaryIdentity()
561 signedBySubKey := key.PublicKey != key.Entity.PrimaryKey
562 sigsToCheck := []*packet.Signature{signature, primaryIdentity.SelfSignature}
563 if signedBySubKey {
564 sigsToCheck = append(sigsToCheck, key.SelfSignature, key.SelfSignature.EmbeddedSignature)
565 }
566 for _, sig := range sigsToCheck {
567 for _, notation := range sig.Notations {
568 if notation.IsCritical && !config.KnownNotation(notation.Name) {
569 return errors.SignatureError("unknown critical notation: " + notation.Name)
570 }
571 }
572 }
573 if key.Entity.Revoked(now) ||
574 (signedBySubKey && key.Revoked(now)) ||
575 primaryIdentity.Revoked(now) {
576 return errors.ErrKeyRevoked
577 }
578 if key.Entity.PrimaryKey.KeyExpired(primaryIdentity.SelfSignature, now) {
579 return errors.ErrKeyExpired
580 }
581 if signedBySubKey {
582 if key.PublicKey.KeyExpired(key.SelfSignature, now) {
583 return errors.ErrKeyExpired
584 }
585 }
586 for _, sig := range sigsToCheck {
587 if sig.SigExpired(now) {
588 return errors.ErrSignatureExpired
589 }
590 }
591 return nil
592 }
593
View as plain text