github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/third_party/code.google.com/p/go.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  	"camlistore.org/third_party/code.google.com/p/go.crypto/openpgp/armor"
    10  	"camlistore.org/third_party/code.google.com/p/go.crypto/openpgp/errors"
    11  	"camlistore.org/third_party/code.google.com/p/go.crypto/openpgp/packet"
    12  	"crypto"
    13  	_ "crypto/sha256"
    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.KeysById(p.KeyId)
   253  			for i, key := range keys {
   254  				if key.SelfSignature.FlagsValid && !key.SelfSignature.FlagSign {
   255  					continue
   256  				}
   257  				md.SignedBy = &keys[i]
   258  				break
   259  			}
   260  		case *packet.LiteralData:
   261  			md.LiteralData = p
   262  			break FindLiteralData
   263  		}
   264  	}
   265  
   266  	if md.SignedBy != nil {
   267  		md.UnverifiedBody = &signatureCheckReader{packets, h, wrappedHash, md}
   268  	} else if md.decrypted != nil {
   269  		md.UnverifiedBody = checkReader{md}
   270  	} else {
   271  		md.UnverifiedBody = md.LiteralData.Body
   272  	}
   273  
   274  	return md, nil
   275  }
   276  
   277  // hashForSignature returns a pair of hashes that can be used to verify a
   278  // signature. The signature may specify that the contents of the signed message
   279  // should be preprocessed (i.e. to normalize line endings). Thus this function
   280  // returns two hashes. The second should be used to hash the message itself and
   281  // performs any needed preprocessing.
   282  func hashForSignature(hashId crypto.Hash, sigType packet.SignatureType) (hash.Hash, hash.Hash, error) {
   283  	h := hashId.New()
   284  	if h == nil {
   285  		return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashId)))
   286  	}
   287  
   288  	switch sigType {
   289  	case packet.SigTypeBinary:
   290  		return h, h, nil
   291  	case packet.SigTypeText:
   292  		return h, NewCanonicalTextHash(h), nil
   293  	}
   294  
   295  	return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType)))
   296  }
   297  
   298  // checkReader wraps an io.Reader from a LiteralData packet. When it sees EOF
   299  // it closes the ReadCloser from any SymmetricallyEncrypted packet to trigger
   300  // MDC checks.
   301  type checkReader struct {
   302  	md *MessageDetails
   303  }
   304  
   305  func (cr checkReader) Read(buf []byte) (n int, err error) {
   306  	n, err = cr.md.LiteralData.Body.Read(buf)
   307  	if err == io.EOF {
   308  		mdcErr := cr.md.decrypted.Close()
   309  		if mdcErr != nil {
   310  			err = mdcErr
   311  		}
   312  	}
   313  	return
   314  }
   315  
   316  // signatureCheckReader wraps an io.Reader from a LiteralData packet and hashes
   317  // the data as it is read. When it sees an EOF from the underlying io.Reader
   318  // it parses and checks a trailing Signature packet and triggers any MDC checks.
   319  type signatureCheckReader struct {
   320  	packets        *packet.Reader
   321  	h, wrappedHash hash.Hash
   322  	md             *MessageDetails
   323  }
   324  
   325  func (scr *signatureCheckReader) Read(buf []byte) (n int, err error) {
   326  	n, err = scr.md.LiteralData.Body.Read(buf)
   327  	scr.wrappedHash.Write(buf[:n])
   328  	if err == io.EOF {
   329  		var p packet.Packet
   330  		p, scr.md.SignatureError = scr.packets.Next()
   331  		if scr.md.SignatureError != nil {
   332  			return
   333  		}
   334  
   335  		var ok bool
   336  		if scr.md.Signature, ok = p.(*packet.Signature); !ok {
   337  			scr.md.SignatureError = errors.StructuralError("LiteralData not followed by Signature")
   338  			return
   339  		}
   340  
   341  		scr.md.SignatureError = scr.md.SignedBy.PublicKey.VerifySignature(scr.h, scr.md.Signature)
   342  
   343  		// The SymmetricallyEncrypted packet, if any, might have an
   344  		// unsigned hash of its own. In order to check this we need to
   345  		// close that Reader.
   346  		if scr.md.decrypted != nil {
   347  			mdcErr := scr.md.decrypted.Close()
   348  			if mdcErr != nil {
   349  				err = mdcErr
   350  			}
   351  		}
   352  	}
   353  	return
   354  }
   355  
   356  // CheckDetachedSignature takes a signed file and a detached signature and
   357  // returns the signer if the signature is valid. If the signer isn't known,
   358  // ErrUnknownIssuer is returned.
   359  func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
   360  	p, err := packet.Read(signature)
   361  	if err != nil {
   362  		return
   363  	}
   364  
   365  	var issuerKeyId uint64
   366  	var hashFunc crypto.Hash
   367  	var sigType packet.SignatureType
   368  
   369  	switch sig := p.(type) {
   370  	case *packet.Signature:
   371  		if sig.IssuerKeyId == nil {
   372  			return nil, errors.StructuralError("signature doesn't have an issuer")
   373  		}
   374  		issuerKeyId = *sig.IssuerKeyId
   375  		hashFunc = sig.Hash
   376  		sigType = sig.SigType
   377  	case *packet.SignatureV3:
   378  		issuerKeyId = sig.IssuerKeyId
   379  		hashFunc = sig.Hash
   380  		sigType = sig.SigType
   381  	default:
   382  		return nil, errors.StructuralError("non signature packet found")
   383  	}
   384  
   385  	keys := keyring.KeysById(issuerKeyId)
   386  	if len(keys) == 0 {
   387  		return nil, errors.ErrUnknownIssuer
   388  	}
   389  
   390  	h, wrappedHash, err := hashForSignature(hashFunc, sigType)
   391  	if err != nil {
   392  		return
   393  	}
   394  
   395  	_, err = io.Copy(wrappedHash, signed)
   396  	if err != nil && err != io.EOF {
   397  		return
   398  	}
   399  
   400  	for _, key := range keys {
   401  		if key.SelfSignature.FlagsValid && !key.SelfSignature.FlagSign {
   402  			continue
   403  		}
   404  		switch sig := p.(type) {
   405  		case *packet.Signature:
   406  			err = key.PublicKey.VerifySignature(h, sig)
   407  		case *packet.SignatureV3:
   408  			err = key.PublicKey.VerifySignatureV3(h, sig)
   409  		}
   410  		if err == nil {
   411  			return key.Entity, nil
   412  		}
   413  	}
   414  
   415  	if err != nil {
   416  		return
   417  	}
   418  
   419  	return nil, errors.ErrUnknownIssuer
   420  }
   421  
   422  // CheckArmoredDetachedSignature performs the same actions as
   423  // CheckDetachedSignature but expects the signature to be armored.
   424  func CheckArmoredDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
   425  	body, err := readArmored(signature, SignatureType)
   426  	if err != nil {
   427  		return
   428  	}
   429  
   430  	return CheckDetachedSignature(keyring, signed, body)
   431  }