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 "golang.org/x/crypto/openpgp"
7
8import (
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.
21var SignatureType = "PGP SIGNATURE"
22
23// readArmored reads an armored block with the given type.
24func 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.
39type 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.
73type 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.
77type 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.
86func 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.
101ParsePackets:
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.
149FindKey:
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.
225func 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
234FindLiteralData:
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.
284func 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.
303type checkReader struct {
304	md *MessageDetails
305}
306
307func (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.
321type signatureCheckReader struct {
322	packets        *packet.Reader
323	h, wrappedHash hash.Hash
324	md             *MessageDetails
325}
326
327func (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.
363func 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.
435func 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}
443