...

Source file src/golang.org/x/crypto/openpgp/read.go

Documentation: golang.org/x/crypto/openpgp

     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  //
     7  // Deprecated: this package is unmaintained except for security fixes. New
     8  // applications should consider a more focused, modern alternative to OpenPGP
     9  // for their specific task. If you are required to interoperate with OpenPGP
    10  // systems and need a maintained package, consider a community fork.
    11  // See https://golang.org/issue/44226.
    12  package openpgp // import "golang.org/x/crypto/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  // SignatureType is the armor type for a PGP signature.
    27  var SignatureType = "PGP SIGNATURE"
    28  
    29  // readArmored reads an armored block with the given type.
    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  // MessageDetails contains the result of parsing an OpenPGP encrypted and/or
    44  // signed message.
    45  type MessageDetails struct {
    46  	IsEncrypted              bool                // true if the message was encrypted.
    47  	EncryptedToKeyIds        []uint64            // the list of recipient key ids.
    48  	IsSymmetricallyEncrypted bool                // true if a passphrase could have decrypted the message.
    49  	DecryptedWith            Key                 // the private key used to decrypt the message, if any.
    50  	IsSigned                 bool                // true if the message is signed.
    51  	SignedByKeyId            uint64              // the key id of the signer, if any.
    52  	SignedBy                 *Key                // the key of the signer, if available.
    53  	LiteralData              *packet.LiteralData // the metadata of the contents
    54  	UnverifiedBody           io.Reader           // the contents of the message.
    55  
    56  	// If IsSigned is true and SignedBy is non-zero then the signature will
    57  	// be verified as UnverifiedBody is read. The signature cannot be
    58  	// checked until the whole of UnverifiedBody is read so UnverifiedBody
    59  	// must be consumed until EOF before the data can be trusted. Even if a
    60  	// message isn't signed (or the signer is unknown) the data may contain
    61  	// an authentication code that is only checked once UnverifiedBody has
    62  	// been consumed. Once EOF has been seen, the following fields are
    63  	// valid. (An authentication code failure is reported as a
    64  	// SignatureError error when reading from UnverifiedBody.)
    65  	SignatureError error               // nil if the signature is good.
    66  	Signature      *packet.Signature   // the signature packet itself, if v4 (default)
    67  	SignatureV3    *packet.SignatureV3 // the signature packet if it is a v2 or v3 signature
    68  
    69  	decrypted io.ReadCloser
    70  }
    71  
    72  // A PromptFunction is used as a callback by functions that may need to decrypt
    73  // a private key, or prompt for a passphrase. It is called with a list of
    74  // acceptable, encrypted private keys and a boolean that indicates whether a
    75  // passphrase is usable. It should either decrypt a private key or return a
    76  // passphrase to try. If the decrypted private key or given passphrase isn't
    77  // correct, the function will be called again, forever. Any error returned will
    78  // be passed up.
    79  type PromptFunction func(keys []Key, symmetric bool) ([]byte, error)
    80  
    81  // A keyEnvelopePair is used to store a private key with the envelope that
    82  // contains a symmetric key, encrypted with that key.
    83  type keyEnvelopePair struct {
    84  	key          Key
    85  	encryptedKey *packet.EncryptedKey
    86  }
    87  
    88  // ReadMessage parses an OpenPGP message that may be signed and/or encrypted.
    89  // The given KeyRing should contain both public keys (for signature
    90  // verification) and, possibly encrypted, private keys for decrypting.
    91  // If config is nil, sensible defaults will be used.
    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  	// The message, if encrypted, starts with a number of packets
   104  	// containing an encrypted decryption key. The decryption key is either
   105  	// encrypted to a public key, or with a passphrase. This loop
   106  	// collects these packets.
   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  			// This packet contains the decryption key encrypted with a passphrase.
   116  			md.IsSymmetricallyEncrypted = true
   117  			symKeys = append(symKeys, p)
   118  		case *packet.EncryptedKey:
   119  			// This packet contains the decryption key encrypted to a public key.
   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  			// This message isn't encrypted.
   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  	// Now that we have the list of encrypted keys we need to decrypt at
   153  	// least one of them or, if we cannot, we need to call the prompt
   154  	// function so that it can decrypt a key or give us a passphrase.
   155  FindKey:
   156  	for {
   157  		// See if any of the keys already have a private key available
   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  		// Try the symmetric passphrase first
   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  // readSignedMessage reads a possibly signed message if mdin is non-zero then
   229  // that structure is updated and returned. Otherwise a fresh MessageDetails is
   230  // used.
   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  // hashForSignature returns a pair of hashes that can be used to verify a
   286  // signature. The signature may specify that the contents of the signed message
   287  // should be preprocessed (i.e. to normalize line endings). Thus this function
   288  // returns two hashes. The second should be used to hash the message itself and
   289  // performs any needed preprocessing.
   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  // checkReader wraps an io.Reader from a LiteralData packet. When it sees EOF
   307  // it closes the ReadCloser from any SymmetricallyEncrypted packet to trigger
   308  // MDC checks.
   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  // signatureCheckReader wraps an io.Reader from a LiteralData packet and hashes
   325  // the data as it is read. When it sees an EOF from the underlying io.Reader
   326  // it parses and checks a trailing Signature packet and triggers any MDC checks.
   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  		// The SymmetricallyEncrypted packet, if any, might have an
   354  		// unsigned hash of its own. In order to check this we need to
   355  		// close that Reader.
   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  // CheckDetachedSignature takes a signed file and a detached signature and
   367  // returns the signer if the signature is valid. If the signer isn't known,
   368  // ErrUnknownIssuer is returned.
   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  // CheckArmoredDetachedSignature performs the same actions as
   440  // CheckDetachedSignature but expects the signature to be armored.
   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