github.com/stackdocker/rkt@v0.10.1-0.20151109095037-1aa827478248/Godeps/_workspace/src/golang.org/x/crypto/openpgp/read.go (about)

     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  package openpgp
     7  
     8  import (
     9  	"crypto"
    10  	_ "crypto/sha256"
    11  	"github.com/coreos/rkt/Godeps/_workspace/src/golang.org/x/crypto/openpgp/armor"
    12  	"github.com/coreos/rkt/Godeps/_workspace/src/golang.org/x/crypto/openpgp/errors"
    13  	"github.com/coreos/rkt/Godeps/_workspace/src/golang.org/x/crypto/openpgp/packet"
    14  	"hash"
    15  	"io"
    16  	"strconv"
    17  )
    18  
    19  // SignatureType is the armor type for a PGP signature.
    20  var SignatureType = "PGP SIGNATURE"
    21  
    22  // readArmored reads an armored block with the given type.
    23  func readArmored(r io.Reader, expectedType string) (body io.Reader, err error) {
    24  	block, err := armor.Decode(r)
    25  	if err != nil {
    26  		return
    27  	}
    28  
    29  	if block.Type != expectedType {
    30  		return nil, errors.InvalidArgumentError("expected '" + expectedType + "', got: " + block.Type)
    31  	}
    32  
    33  	return block.Body, nil
    34  }
    35  
    36  // MessageDetails contains the result of parsing an OpenPGP encrypted and/or
    37  // signed message.
    38  type MessageDetails struct {
    39  	IsEncrypted              bool                // true if the message was encrypted.
    40  	EncryptedToKeyIds        []uint64            // the list of recipient key ids.
    41  	IsSymmetricallyEncrypted bool                // true if a passphrase could have decrypted the message.
    42  	DecryptedWith            Key                 // the private key used to decrypt the message, if any.
    43  	IsSigned                 bool                // true if the message is signed.
    44  	SignedByKeyId            uint64              // the key id of the signer, if any.
    45  	SignedBy                 *Key                // the key of the signer, if available.
    46  	LiteralData              *packet.LiteralData // the metadata of the contents
    47  	UnverifiedBody           io.Reader           // the contents of the message.
    48  
    49  	// If IsSigned is true and SignedBy is non-zero then the signature will
    50  	// be verified as UnverifiedBody is read. The signature cannot be
    51  	// checked until the whole of UnverifiedBody is read so UnverifiedBody
    52  	// must be consumed until EOF before the data can trusted. Even if a
    53  	// message isn't signed (or the signer is unknown) the data may contain
    54  	// an authentication code that is only checked once UnverifiedBody has
    55  	// been consumed. Once EOF has been seen, the following fields are
    56  	// valid. (An authentication code failure is reported as a
    57  	// SignatureError error when reading from UnverifiedBody.)
    58  	SignatureError error             // nil if the signature is good.
    59  	Signature      *packet.Signature // the signature packet itself.
    60  
    61  	decrypted io.ReadCloser
    62  }
    63  
    64  // A PromptFunction is used as a callback by functions that may need to decrypt
    65  // a private key, or prompt for a passphrase. It is called with a list of
    66  // acceptable, encrypted private keys and a boolean that indicates whether a
    67  // passphrase is usable. It should either decrypt a private key or return a
    68  // passphrase to try. If the decrypted private key or given passphrase isn't
    69  // correct, the function will be called again, forever. Any error returned will
    70  // be passed up.
    71  type PromptFunction func(keys []Key, symmetric bool) ([]byte, error)
    72  
    73  // A keyEnvelopePair is used to store a private key with the envelope that
    74  // contains a symmetric key, encrypted with that key.
    75  type keyEnvelopePair struct {
    76  	key          Key
    77  	encryptedKey *packet.EncryptedKey
    78  }
    79  
    80  // ReadMessage parses an OpenPGP message that may be signed and/or encrypted.
    81  // The given KeyRing should contain both public keys (for signature
    82  // verification) and, possibly encrypted, private keys for decrypting.
    83  // If config is nil, sensible defaults will be used.
    84  func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction, config *packet.Config) (md *MessageDetails, err error) {
    85  	var p packet.Packet
    86  
    87  	var symKeys []*packet.SymmetricKeyEncrypted
    88  	var pubKeys []keyEnvelopePair
    89  	var se *packet.SymmetricallyEncrypted
    90  
    91  	packets := packet.NewReader(r)
    92  	md = new(MessageDetails)
    93  	md.IsEncrypted = true
    94  
    95  	// The message, if encrypted, starts with a number of packets
    96  	// containing an encrypted decryption key. The decryption key is either
    97  	// encrypted to a public key, or with a passphrase. This loop
    98  	// collects these packets.
    99  ParsePackets:
   100  	for {
   101  		p, err = packets.Next()
   102  		if err != nil {
   103  			return nil, err
   104  		}
   105  		switch p := p.(type) {
   106  		case *packet.SymmetricKeyEncrypted:
   107  			// This packet contains the decryption key encrypted with a passphrase.
   108  			md.IsSymmetricallyEncrypted = true
   109  			symKeys = append(symKeys, p)
   110  		case *packet.EncryptedKey:
   111  			// This packet contains the decryption key encrypted to a public key.
   112  			md.EncryptedToKeyIds = append(md.EncryptedToKeyIds, p.KeyId)
   113  			switch p.Algo {
   114  			case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal:
   115  				break
   116  			default:
   117  				continue
   118  			}
   119  			var keys []Key
   120  			if p.KeyId == 0 {
   121  				keys = keyring.DecryptionKeys()
   122  			} else {
   123  				keys = keyring.KeysById(p.KeyId)
   124  			}
   125  			for _, k := range keys {
   126  				pubKeys = append(pubKeys, keyEnvelopePair{k, p})
   127  			}
   128  		case *packet.SymmetricallyEncrypted:
   129  			se = p
   130  			break ParsePackets
   131  		case *packet.Compressed, *packet.LiteralData, *packet.OnePassSignature:
   132  			// This message isn't encrypted.
   133  			if len(symKeys) != 0 || len(pubKeys) != 0 {
   134  				return nil, errors.StructuralError("key material not followed by encrypted message")
   135  			}
   136  			packets.Unread(p)
   137  			return readSignedMessage(packets, nil, keyring)
   138  		}
   139  	}
   140  
   141  	var candidates []Key
   142  	var decrypted io.ReadCloser
   143  
   144  	// Now that we have the list of encrypted keys we need to decrypt at
   145  	// least one of them or, if we cannot, we need to call the prompt
   146  	// function so that it can decrypt a key or give us a passphrase.
   147  FindKey:
   148  	for {
   149  		// See if any of the keys already have a private key available
   150  		candidates = candidates[:0]
   151  		candidateFingerprints := make(map[string]bool)
   152  
   153  		for _, pk := range pubKeys {
   154  			if pk.key.PrivateKey == nil {
   155  				continue
   156  			}
   157  			if !pk.key.PrivateKey.Encrypted {
   158  				if len(pk.encryptedKey.Key) == 0 {
   159  					pk.encryptedKey.Decrypt(pk.key.PrivateKey, config)
   160  				}
   161  				if len(pk.encryptedKey.Key) == 0 {
   162  					continue
   163  				}
   164  				decrypted, err = se.Decrypt(pk.encryptedKey.CipherFunc, pk.encryptedKey.Key)
   165  				if err != nil && err != errors.ErrKeyIncorrect {
   166  					return nil, err
   167  				}
   168  				if decrypted != nil {
   169  					md.DecryptedWith = pk.key
   170  					break FindKey
   171  				}
   172  			} else {
   173  				fpr := string(pk.key.PublicKey.Fingerprint[:])
   174  				if v := candidateFingerprints[fpr]; v {
   175  					continue
   176  				}
   177  				candidates = append(candidates, pk.key)
   178  				candidateFingerprints[fpr] = true
   179  			}
   180  		}
   181  
   182  		if len(candidates) == 0 && len(symKeys) == 0 {
   183  			return nil, errors.ErrKeyIncorrect
   184  		}
   185  
   186  		if prompt == nil {
   187  			return nil, errors.ErrKeyIncorrect
   188  		}
   189  
   190  		passphrase, err := prompt(candidates, len(symKeys) != 0)
   191  		if err != nil {
   192  			return nil, err
   193  		}
   194  
   195  		// Try the symmetric passphrase first
   196  		if len(symKeys) != 0 && passphrase != nil {
   197  			for _, s := range symKeys {
   198  				err = s.Decrypt(passphrase)
   199  				if err == nil && !s.Encrypted {
   200  					decrypted, err = se.Decrypt(s.CipherFunc, s.Key)
   201  					if err != nil && err != errors.ErrKeyIncorrect {
   202  						return nil, err
   203  					}
   204  					if decrypted != nil {
   205  						break FindKey
   206  					}
   207  				}
   208  
   209  			}
   210  		}
   211  	}
   212  
   213  	md.decrypted = decrypted
   214  	packets.Push(decrypted)
   215  	return readSignedMessage(packets, md, keyring)
   216  }
   217  
   218  // readSignedMessage reads a possibly signed message if mdin is non-zero then
   219  // that structure is updated and returned. Otherwise a fresh MessageDetails is
   220  // used.
   221  func readSignedMessage(packets *packet.Reader, mdin *MessageDetails, keyring KeyRing) (md *MessageDetails, err error) {
   222  	if mdin == nil {
   223  		mdin = new(MessageDetails)
   224  	}
   225  	md = mdin
   226  
   227  	var p packet.Packet
   228  	var h hash.Hash
   229  	var wrappedHash hash.Hash
   230  FindLiteralData:
   231  	for {
   232  		p, err = packets.Next()
   233  		if err != nil {
   234  			return nil, err
   235  		}
   236  		switch p := p.(type) {
   237  		case *packet.Compressed:
   238  			packets.Push(p.Body)
   239  		case *packet.OnePassSignature:
   240  			if !p.IsLast {
   241  				return nil, errors.UnsupportedError("nested signatures")
   242  			}
   243  
   244  			h, wrappedHash, err = hashForSignature(p.Hash, p.SigType)
   245  			if err != nil {
   246  				md = nil
   247  				return
   248  			}
   249  
   250  			md.IsSigned = true
   251  			md.SignedByKeyId = p.KeyId
   252  			keys := keyring.KeysByIdUsage(p.KeyId, packet.KeyFlagSign)
   253  			if len(keys) > 0 {
   254  				md.SignedBy = &keys[0]
   255  			}
   256  		case *packet.LiteralData:
   257  			md.LiteralData = p
   258  			break FindLiteralData
   259  		}
   260  	}
   261  
   262  	if md.SignedBy != nil {
   263  		md.UnverifiedBody = &signatureCheckReader{packets, h, wrappedHash, md}
   264  	} else if md.decrypted != nil {
   265  		md.UnverifiedBody = checkReader{md}
   266  	} else {
   267  		md.UnverifiedBody = md.LiteralData.Body
   268  	}
   269  
   270  	return md, nil
   271  }
   272  
   273  // hashForSignature returns a pair of hashes that can be used to verify a
   274  // signature. The signature may specify that the contents of the signed message
   275  // should be preprocessed (i.e. to normalize line endings). Thus this function
   276  // returns two hashes. The second should be used to hash the message itself and
   277  // performs any needed preprocessing.
   278  func hashForSignature(hashId crypto.Hash, sigType packet.SignatureType) (hash.Hash, hash.Hash, error) {
   279  	if !hashId.Available() {
   280  		return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashId)))
   281  	}
   282  	h := hashId.New()
   283  
   284  	switch sigType {
   285  	case packet.SigTypeBinary:
   286  		return h, h, nil
   287  	case packet.SigTypeText:
   288  		return h, NewCanonicalTextHash(h), nil
   289  	}
   290  
   291  	return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType)))
   292  }
   293  
   294  // checkReader wraps an io.Reader from a LiteralData packet. When it sees EOF
   295  // it closes the ReadCloser from any SymmetricallyEncrypted packet to trigger
   296  // MDC checks.
   297  type checkReader struct {
   298  	md *MessageDetails
   299  }
   300  
   301  func (cr checkReader) Read(buf []byte) (n int, err error) {
   302  	n, err = cr.md.LiteralData.Body.Read(buf)
   303  	if err == io.EOF {
   304  		mdcErr := cr.md.decrypted.Close()
   305  		if mdcErr != nil {
   306  			err = mdcErr
   307  		}
   308  	}
   309  	return
   310  }
   311  
   312  // signatureCheckReader wraps an io.Reader from a LiteralData packet and hashes
   313  // the data as it is read. When it sees an EOF from the underlying io.Reader
   314  // it parses and checks a trailing Signature packet and triggers any MDC checks.
   315  type signatureCheckReader struct {
   316  	packets        *packet.Reader
   317  	h, wrappedHash hash.Hash
   318  	md             *MessageDetails
   319  }
   320  
   321  func (scr *signatureCheckReader) Read(buf []byte) (n int, err error) {
   322  	n, err = scr.md.LiteralData.Body.Read(buf)
   323  	scr.wrappedHash.Write(buf[:n])
   324  	if err == io.EOF {
   325  		var p packet.Packet
   326  		p, scr.md.SignatureError = scr.packets.Next()
   327  		if scr.md.SignatureError != nil {
   328  			return
   329  		}
   330  
   331  		var ok bool
   332  		if scr.md.Signature, ok = p.(*packet.Signature); !ok {
   333  			scr.md.SignatureError = errors.StructuralError("LiteralData not followed by Signature")
   334  			return
   335  		}
   336  
   337  		scr.md.SignatureError = scr.md.SignedBy.PublicKey.VerifySignature(scr.h, scr.md.Signature)
   338  
   339  		// The SymmetricallyEncrypted packet, if any, might have an
   340  		// unsigned hash of its own. In order to check this we need to
   341  		// close that Reader.
   342  		if scr.md.decrypted != nil {
   343  			mdcErr := scr.md.decrypted.Close()
   344  			if mdcErr != nil {
   345  				err = mdcErr
   346  			}
   347  		}
   348  	}
   349  	return
   350  }
   351  
   352  // CheckDetachedSignature takes a signed file and a detached signature and
   353  // returns the signer if the signature is valid. If the signer isn't known,
   354  // ErrUnknownIssuer is returned.
   355  func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
   356  	p, err := packet.Read(signature)
   357  	if err != nil {
   358  		return
   359  	}
   360  
   361  	var issuerKeyId uint64
   362  	var hashFunc crypto.Hash
   363  	var sigType packet.SignatureType
   364  
   365  	switch sig := p.(type) {
   366  	case *packet.Signature:
   367  		if sig.IssuerKeyId == nil {
   368  			return nil, errors.StructuralError("signature doesn't have an issuer")
   369  		}
   370  		issuerKeyId = *sig.IssuerKeyId
   371  		hashFunc = sig.Hash
   372  		sigType = sig.SigType
   373  	case *packet.SignatureV3:
   374  		issuerKeyId = sig.IssuerKeyId
   375  		hashFunc = sig.Hash
   376  		sigType = sig.SigType
   377  	default:
   378  		return nil, errors.StructuralError("non signature packet found")
   379  	}
   380  
   381  	h, wrappedHash, err := hashForSignature(hashFunc, sigType)
   382  	if err != nil {
   383  		return
   384  	}
   385  
   386  	_, err = io.Copy(wrappedHash, signed)
   387  	if err != nil && err != io.EOF {
   388  		return
   389  	}
   390  
   391  	keys := keyring.KeysByIdUsage(issuerKeyId, packet.KeyFlagSign)
   392  	if len(keys) == 0 {
   393  		return nil, errors.ErrUnknownIssuer
   394  	}
   395  
   396  	for _, key := range keys {
   397  		switch sig := p.(type) {
   398  		case *packet.Signature:
   399  			err = key.PublicKey.VerifySignature(h, sig)
   400  		case *packet.SignatureV3:
   401  			err = key.PublicKey.VerifySignatureV3(h, sig)
   402  		}
   403  		if err == nil {
   404  			return key.Entity, nil
   405  		}
   406  	}
   407  
   408  	if err == nil {
   409  		err = errors.ErrUnknownIssuer
   410  	}
   411  	return nil, err
   412  }
   413  
   414  // CheckArmoredDetachedSignature performs the same actions as
   415  // CheckDetachedSignature but expects the signature to be armored.
   416  func CheckArmoredDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
   417  	body, err := readArmored(signature, SignatureType)
   418  	if err != nil {
   419  		return
   420  	}
   421  
   422  	return CheckDetachedSignature(keyring, signed, body)
   423  }