main
Raw Download raw file
  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.
  6package openpgp // import "github.com/ProtonMail/go-crypto/openpgp"
  7
  8import (
  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// SignatureType is the armor type for a PGP signature.
 24var SignatureType = "PGP SIGNATURE"
 25
 26// readArmored reads an armored block with the given type.
 27func 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// MessageDetails contains the result of parsing an OpenPGP encrypted and/or
 41// signed message.
 42type MessageDetails struct {
 43	IsEncrypted              bool                // true if the message was encrypted.
 44	EncryptedToKeyIds        []uint64            // the list of recipient key ids.
 45	IsSymmetricallyEncrypted bool                // true if a passphrase could have decrypted the message.
 46	DecryptedWith            Key                 // the private key used to decrypt the message, if any.
 47	IsSigned                 bool                // true if the message is signed.
 48	SignedByKeyId            uint64              // the key id of the signer, if any.
 49	SignedByFingerprint      []byte              // the key fingerprint of the signer, if any.
 50	SignedBy                 *Key                // the key of the signer, if available.
 51	LiteralData              *packet.LiteralData // the metadata of the contents
 52	UnverifiedBody           io.Reader           // the contents of the message.
 53
 54	// If IsSigned is true and SignedBy is non-zero then the signature will
 55	// be verified as UnverifiedBody is read. The signature cannot be
 56	// checked until the whole of UnverifiedBody is read so UnverifiedBody
 57	// must be consumed until EOF before the data can be trusted. Even if a
 58	// message isn't signed (or the signer is unknown) the data may contain
 59	// an authentication code that is only checked once UnverifiedBody has
 60	// been consumed. Once EOF has been seen, the following fields are
 61	// valid. (An authentication code failure is reported as a
 62	// SignatureError error when reading from UnverifiedBody.)
 63	Signature            *packet.Signature   // the signature packet itself.
 64	SignatureError       error               // nil if the signature is good.
 65	UnverifiedSignatures []*packet.Signature // all other unverified signature packets.
 66
 67	decrypted io.ReadCloser
 68}
 69
 70// A PromptFunction is used as a callback by functions that may need to decrypt
 71// a private key, or prompt for a passphrase. It is called with a list of
 72// acceptable, encrypted private keys and a boolean that indicates whether a
 73// passphrase is usable. It should either decrypt a private key or return a
 74// passphrase to try. If the decrypted private key or given passphrase isn't
 75// correct, the function will be called again, forever. Any error returned will
 76// be passed up.
 77type PromptFunction func(keys []Key, symmetric bool) ([]byte, error)
 78
 79// A keyEnvelopePair is used to store a private key with the envelope that
 80// contains a symmetric key, encrypted with that key.
 81type keyEnvelopePair struct {
 82	key          Key
 83	encryptedKey *packet.EncryptedKey
 84}
 85
 86// ReadMessage parses an OpenPGP message that may be signed and/or encrypted.
 87// The given KeyRing should contain both public keys (for signature
 88// verification) and, possibly encrypted, private keys for decrypting.
 89// If config is nil, sensible defaults will be used.
 90func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction, config *packet.Config) (md *MessageDetails, err error) {
 91	var p packet.Packet
 92
 93	var symKeys []*packet.SymmetricKeyEncrypted
 94	var pubKeys []keyEnvelopePair
 95	// Integrity protected encrypted packet: SymmetricallyEncrypted or AEADEncrypted
 96	var edp packet.EncryptedDataPacket
 97
 98	packets := packet.NewReader(r)
 99	md = new(MessageDetails)
100	md.IsEncrypted = true
101
102	// The message, if encrypted, starts with a number of packets
103	// containing an encrypted decryption key. The decryption key is either
104	// encrypted to a public key, or with a passphrase. This loop
105	// collects these packets.
106ParsePackets:
107	for {
108		p, err = packets.Next()
109		if err != nil {
110			return nil, err
111		}
112		switch p := p.(type) {
113		case *packet.SymmetricKeyEncrypted:
114			// This packet contains the decryption key encrypted with a passphrase.
115			md.IsSymmetricallyEncrypted = true
116			symKeys = append(symKeys, p)
117		case *packet.EncryptedKey:
118			// This packet contains the decryption key encrypted to a public key.
119			md.EncryptedToKeyIds = append(md.EncryptedToKeyIds, p.KeyId)
120			switch p.Algo {
121			case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal, packet.PubKeyAlgoECDH, packet.PubKeyAlgoX25519, packet.PubKeyAlgoX448:
122				break
123			default:
124				continue
125			}
126			if keyring != nil {
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			}
137		case *packet.SymmetricallyEncrypted:
138			if !p.IntegrityProtected && !config.AllowUnauthenticatedMessages() {
139				return nil, errors.UnsupportedError("message is not integrity protected")
140			}
141			edp = p
142			break ParsePackets
143		case *packet.AEADEncrypted:
144			edp = p
145			break ParsePackets
146		case *packet.Compressed, *packet.LiteralData, *packet.OnePassSignature:
147			// This message isn't encrypted.
148			if len(symKeys) != 0 || len(pubKeys) != 0 {
149				return nil, errors.StructuralError("key material not followed by encrypted message")
150			}
151			packets.Unread(p)
152			return readSignedMessage(packets, nil, keyring, config)
153		}
154	}
155
156	var candidates []Key
157	var decrypted io.ReadCloser
158
159	// Now that we have the list of encrypted keys we need to decrypt at
160	// least one of them or, if we cannot, we need to call the prompt
161	// function so that it can decrypt a key or give us a passphrase.
162FindKey:
163	for {
164		// See if any of the keys already have a private key available
165		candidates = candidates[:0]
166		candidateFingerprints := make(map[string]bool)
167
168		for _, pk := range pubKeys {
169			if pk.key.PrivateKey == nil {
170				continue
171			}
172			if !pk.key.PrivateKey.Encrypted {
173				if len(pk.encryptedKey.Key) == 0 {
174					errDec := pk.encryptedKey.Decrypt(pk.key.PrivateKey, config)
175					if errDec != nil {
176						continue
177					}
178				}
179				// Try to decrypt symmetrically encrypted
180				decrypted, err = edp.Decrypt(pk.encryptedKey.CipherFunc, pk.encryptedKey.Key)
181				if err != nil && err != errors.ErrKeyIncorrect {
182					return nil, err
183				}
184				if decrypted != nil {
185					md.DecryptedWith = pk.key
186					break FindKey
187				}
188			} else {
189				fpr := string(pk.key.PublicKey.Fingerprint[:])
190				if v := candidateFingerprints[fpr]; v {
191					continue
192				}
193				candidates = append(candidates, pk.key)
194				candidateFingerprints[fpr] = true
195			}
196		}
197
198		if len(candidates) == 0 && len(symKeys) == 0 {
199			return nil, errors.ErrKeyIncorrect
200		}
201
202		if prompt == nil {
203			return nil, errors.ErrKeyIncorrect
204		}
205
206		passphrase, err := prompt(candidates, len(symKeys) != 0)
207		if err != nil {
208			return nil, err
209		}
210
211		// Try the symmetric passphrase first
212		if len(symKeys) != 0 && passphrase != nil {
213			for _, s := range symKeys {
214				key, cipherFunc, err := s.Decrypt(passphrase)
215				// In v4, on wrong passphrase, session key decryption is very likely to result in an invalid cipherFunc:
216				// only for < 5% of cases we will proceed to decrypt the data
217				if err == nil {
218					decrypted, err = edp.Decrypt(cipherFunc, key)
219					if err != nil {
220						return nil, err
221					}
222					if decrypted != nil {
223						break FindKey
224					}
225				}
226			}
227		}
228	}
229
230	md.decrypted = decrypted
231	if err := packets.Push(decrypted); err != nil {
232		return nil, err
233	}
234	mdFinal, sensitiveParsingErr := readSignedMessage(packets, md, keyring, config)
235	if sensitiveParsingErr != nil {
236		return nil, errors.HandleSensitiveParsingError(sensitiveParsingErr, md.decrypted != nil)
237	}
238	return mdFinal, nil
239}
240
241// readSignedMessage reads a possibly signed message if mdin is non-zero then
242// that structure is updated and returned. Otherwise a fresh MessageDetails is
243// used.
244func readSignedMessage(packets *packet.Reader, mdin *MessageDetails, keyring KeyRing, config *packet.Config) (md *MessageDetails, err error) {
245	if mdin == nil {
246		mdin = new(MessageDetails)
247	}
248	md = mdin
249
250	var p packet.Packet
251	var h hash.Hash
252	var wrappedHash hash.Hash
253	var prevLast bool
254FindLiteralData:
255	for {
256		p, err = packets.Next()
257		if err != nil {
258			return nil, err
259		}
260		switch p := p.(type) {
261		case *packet.Compressed:
262			if err := packets.Push(p.Body); err != nil {
263				return nil, err
264			}
265		case *packet.OnePassSignature:
266			if prevLast {
267				return nil, errors.UnsupportedError("nested signature packets")
268			}
269
270			if p.IsLast {
271				prevLast = true
272			}
273
274			h, wrappedHash, err = hashForSignature(p.Hash, p.SigType, p.Salt)
275			if err != nil {
276				md.SignatureError = err
277			}
278
279			md.IsSigned = true
280			if p.Version == 6 {
281				md.SignedByFingerprint = p.KeyFingerprint
282			}
283			md.SignedByKeyId = p.KeyId
284
285			if keyring != nil {
286				keys := keyring.KeysByIdUsage(p.KeyId, packet.KeyFlagSign)
287				if len(keys) > 0 {
288					md.SignedBy = &keys[0]
289				}
290			}
291		case *packet.LiteralData:
292			md.LiteralData = p
293			break FindLiteralData
294		}
295	}
296
297	if md.IsSigned && md.SignatureError == nil {
298		md.UnverifiedBody = &signatureCheckReader{packets, h, wrappedHash, md, config}
299	} else if md.decrypted != nil {
300		md.UnverifiedBody = &checkReader{md, false}
301	} else {
302		md.UnverifiedBody = md.LiteralData.Body
303	}
304
305	return md, nil
306}
307
308func wrapHashForSignature(hashFunc hash.Hash, sigType packet.SignatureType) (hash.Hash, error) {
309	switch sigType {
310	case packet.SigTypeBinary:
311		return hashFunc, nil
312	case packet.SigTypeText:
313		return NewCanonicalTextHash(hashFunc), nil
314	}
315	return nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType)))
316}
317
318// hashForSignature returns a pair of hashes that can be used to verify a
319// signature. The signature may specify that the contents of the signed message
320// should be preprocessed (i.e. to normalize line endings). Thus this function
321// returns two hashes. The second should be used to hash the message itself and
322// performs any needed preprocessing.
323func hashForSignature(hashFunc crypto.Hash, sigType packet.SignatureType, sigSalt []byte) (hash.Hash, hash.Hash, error) {
324	if _, ok := algorithm.HashToHashIdWithSha1(hashFunc); !ok {
325		return nil, nil, errors.UnsupportedError("unsupported hash function")
326	}
327	if !hashFunc.Available() {
328		return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashFunc)))
329	}
330	h := hashFunc.New()
331	if sigSalt != nil {
332		h.Write(sigSalt)
333	}
334	wrappedHash, err := wrapHashForSignature(h, sigType)
335	if err != nil {
336		return nil, nil, err
337	}
338	switch sigType {
339	case packet.SigTypeBinary:
340		return h, wrappedHash, nil
341	case packet.SigTypeText:
342		return h, wrappedHash, nil
343	}
344	return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType)))
345}
346
347// checkReader wraps an io.Reader from a LiteralData packet. When it sees EOF
348// it closes the ReadCloser from any SymmetricallyEncrypted packet to trigger
349// MDC checks.
350type checkReader struct {
351	md      *MessageDetails
352	checked bool
353}
354
355func (cr *checkReader) Read(buf []byte) (int, error) {
356	n, sensitiveParsingError := cr.md.LiteralData.Body.Read(buf)
357	if sensitiveParsingError == io.EOF {
358		if cr.checked {
359			// Only check once
360			return n, io.EOF
361		}
362		mdcErr := cr.md.decrypted.Close()
363		if mdcErr != nil {
364			return n, mdcErr
365		}
366		cr.checked = true
367		return n, io.EOF
368	}
369
370	if sensitiveParsingError != nil {
371		return n, errors.HandleSensitiveParsingError(sensitiveParsingError, true)
372	}
373
374	return n, nil
375}
376
377// signatureCheckReader wraps an io.Reader from a LiteralData packet and hashes
378// the data as it is read. When it sees an EOF from the underlying io.Reader
379// it parses and checks a trailing Signature packet and triggers any MDC checks.
380type signatureCheckReader struct {
381	packets        *packet.Reader
382	h, wrappedHash hash.Hash
383	md             *MessageDetails
384	config         *packet.Config
385}
386
387func (scr *signatureCheckReader) Read(buf []byte) (int, error) {
388	n, sensitiveParsingError := scr.md.LiteralData.Body.Read(buf)
389
390	// Hash only if required
391	if scr.md.SignedBy != nil {
392		scr.wrappedHash.Write(buf[:n])
393	}
394
395	readsDecryptedData := scr.md.decrypted != nil
396	if sensitiveParsingError == io.EOF {
397		var p packet.Packet
398		var readError error
399		var sig *packet.Signature
400
401		p, readError = scr.packets.Next()
402		for readError == nil {
403			var ok bool
404			if sig, ok = p.(*packet.Signature); ok {
405				if sig.Version == 5 && (sig.SigType == 0x00 || sig.SigType == 0x01) {
406					sig.Metadata = scr.md.LiteralData
407				}
408
409				// If signature KeyID matches
410				if scr.md.SignedBy != nil && *sig.IssuerKeyId == scr.md.SignedByKeyId {
411					key := scr.md.SignedBy
412					signatureError := key.PublicKey.VerifySignature(scr.h, sig)
413					if signatureError == nil {
414						signatureError = checkMessageSignatureDetails(key, sig, scr.config)
415					}
416					scr.md.Signature = sig
417					scr.md.SignatureError = signatureError
418				} else {
419					scr.md.UnverifiedSignatures = append(scr.md.UnverifiedSignatures, sig)
420				}
421			}
422
423			p, readError = scr.packets.Next()
424		}
425
426		if scr.md.SignedBy != nil && scr.md.Signature == nil {
427			if scr.md.UnverifiedSignatures == nil {
428				scr.md.SignatureError = errors.StructuralError("LiteralData not followed by signature")
429			} else {
430				scr.md.SignatureError = errors.StructuralError("No matching signature found")
431			}
432		}
433
434		// The SymmetricallyEncrypted packet, if any, might have an
435		// unsigned hash of its own. In order to check this we need to
436		// close that Reader.
437		if scr.md.decrypted != nil {
438			if sensitiveParsingError := scr.md.decrypted.Close(); sensitiveParsingError != nil {
439				return n, errors.HandleSensitiveParsingError(sensitiveParsingError, true)
440			}
441		}
442		return n, io.EOF
443	}
444
445	if sensitiveParsingError != nil {
446		return n, errors.HandleSensitiveParsingError(sensitiveParsingError, readsDecryptedData)
447	}
448
449	return n, nil
450}
451
452// VerifyDetachedSignature takes a signed file and a detached signature and
453// returns the signature packet and the entity the signature was signed by,
454// if any, and a possible signature verification error.
455// If the signer isn't known, ErrUnknownIssuer is returned.
456func VerifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) {
457	return verifyDetachedSignature(keyring, signed, signature, nil, false, config)
458}
459
460// VerifyDetachedSignatureAndHash performs the same actions as
461// VerifyDetachedSignature and checks that the expected hash functions were used.
462func VerifyDetachedSignatureAndHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) {
463	return verifyDetachedSignature(keyring, signed, signature, expectedHashes, true, config)
464}
465
466// CheckDetachedSignature takes a signed file and a detached signature and
467// returns the entity the signature was signed by, if any, and a possible
468// signature verification error. If the signer isn't known,
469// ErrUnknownIssuer is returned.
470func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (signer *Entity, err error) {
471	_, signer, err = verifyDetachedSignature(keyring, signed, signature, nil, false, config)
472	return
473}
474
475// CheckDetachedSignatureAndHash performs the same actions as
476// CheckDetachedSignature and checks that the expected hash functions were used.
477func CheckDetachedSignatureAndHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (signer *Entity, err error) {
478	_, signer, err = verifyDetachedSignature(keyring, signed, signature, expectedHashes, true, config)
479	return
480}
481
482func verifyDetachedSignature(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, checkHashes bool, config *packet.Config) (sig *packet.Signature, signer *Entity, err error) {
483	var issuerKeyId uint64
484	var hashFunc crypto.Hash
485	var sigType packet.SignatureType
486	var keys []Key
487	var p packet.Packet
488
489	packets := packet.NewReader(signature)
490	for {
491		p, err = packets.Next()
492		if err == io.EOF {
493			return nil, nil, errors.ErrUnknownIssuer
494		}
495		if err != nil {
496			return nil, nil, err
497		}
498
499		var ok bool
500		sig, ok = p.(*packet.Signature)
501		if !ok {
502			return nil, nil, errors.StructuralError("non signature packet found")
503		}
504		if sig.IssuerKeyId == nil {
505			return nil, nil, errors.StructuralError("signature doesn't have an issuer")
506		}
507		issuerKeyId = *sig.IssuerKeyId
508		hashFunc = sig.Hash
509		sigType = sig.SigType
510		if checkHashes {
511			matchFound := false
512			// check for hashes
513			for _, expectedHash := range expectedHashes {
514				if hashFunc == expectedHash {
515					matchFound = true
516					break
517				}
518			}
519			if !matchFound {
520				return nil, nil, errors.StructuralError("hash algorithm or salt mismatch with cleartext message headers")
521			}
522		}
523		keys = keyring.KeysByIdUsage(issuerKeyId, packet.KeyFlagSign)
524		if len(keys) > 0 {
525			break
526		}
527	}
528
529	if len(keys) == 0 {
530		panic("unreachable")
531	}
532
533	h, err := sig.PrepareVerify()
534	if err != nil {
535		return nil, nil, err
536	}
537	wrappedHash, err := wrapHashForSignature(h, sigType)
538	if err != nil {
539		return nil, nil, err
540	}
541
542	if _, err := io.Copy(wrappedHash, signed); err != nil && err != io.EOF {
543		return nil, nil, err
544	}
545
546	for _, key := range keys {
547		err = key.PublicKey.VerifySignature(h, sig)
548		if err == nil {
549			return sig, key.Entity, checkMessageSignatureDetails(&key, sig, config)
550		}
551	}
552
553	return nil, nil, err
554}
555
556// CheckArmoredDetachedSignature performs the same actions as
557// CheckDetachedSignature but expects the signature to be armored.
558func CheckArmoredDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (signer *Entity, err error) {
559	body, err := readArmored(signature, SignatureType)
560	if err != nil {
561		return
562	}
563
564	return CheckDetachedSignature(keyring, signed, body, config)
565}
566
567// checkMessageSignatureDetails returns an error if:
568//   - The signature (or one of the binding signatures mentioned below)
569//     has a unknown critical notation data subpacket
570//   - The primary key of the signing entity is revoked
571//   - The primary identity is revoked
572//   - The signature is expired
573//   - The primary key of the signing entity is expired according to the
574//     primary identity binding signature
575//
576// ... or, if the signature was signed by a subkey and:
577//   - The signing subkey is revoked
578//   - The signing subkey is expired according to the subkey binding signature
579//   - The signing subkey binding signature is expired
580//   - The signing subkey cross-signature is expired
581//
582// NOTE: The order of these checks is important, as the caller may choose to
583// ignore ErrSignatureExpired or ErrKeyExpired errors, but should never
584// ignore any other errors.
585func checkMessageSignatureDetails(key *Key, signature *packet.Signature, config *packet.Config) error {
586	now := config.Now()
587	primarySelfSignature, primaryIdentity := key.Entity.PrimarySelfSignature()
588	signedBySubKey := key.PublicKey != key.Entity.PrimaryKey
589	sigsToCheck := []*packet.Signature{signature, primarySelfSignature}
590	if signedBySubKey {
591		sigsToCheck = append(sigsToCheck, key.SelfSignature, key.SelfSignature.EmbeddedSignature)
592	}
593	for _, sig := range sigsToCheck {
594		for _, notation := range sig.Notations {
595			if notation.IsCritical && !config.KnownNotation(notation.Name) {
596				return errors.SignatureError("unknown critical notation: " + notation.Name)
597			}
598		}
599	}
600	if key.Entity.Revoked(now) || // primary key is revoked
601		(signedBySubKey && key.Revoked(now)) || // subkey is revoked
602		(primaryIdentity != nil && primaryIdentity.Revoked(now)) { // primary identity is revoked for v4
603		return errors.ErrKeyRevoked
604	}
605	if key.Entity.PrimaryKey.KeyExpired(primarySelfSignature, now) { // primary key is expired
606		return errors.ErrKeyExpired
607	}
608	if signedBySubKey {
609		if key.PublicKey.KeyExpired(key.SelfSignature, now) { // subkey is expired
610			return errors.ErrKeyExpired
611		}
612	}
613	for _, sig := range sigsToCheck {
614		if sig.SigExpired(now) { // any of the relevant signatures are expired
615			return errors.ErrSignatureExpired
616		}
617	}
618	return nil
619}