github.com/olivere/camlistore@v0.0.0-20140121221811-1b7ac2da0199/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  func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction) (md *MessageDetails, err error) {
    84  	var p packet.Packet
    85  
    86  	var symKeys []*packet.SymmetricKeyEncrypted
    87  	var pubKeys []keyEnvelopePair
    88  	var se *packet.SymmetricallyEncrypted
    89  
    90  	packets := packet.NewReader(r)
    91  	md = new(MessageDetails)
    92  	md.IsEncrypted = true
    93  
    94  	// The message, if encrypted, starts with a number of packets
    95  	// containing an encrypted decryption key. The decryption key is either
    96  	// encrypted to a public key, or with a passphrase. This loop
    97  	// collects these packets.
    98  ParsePackets:
    99  	for {
   100  		p, err = packets.Next()
   101  		if err != nil {
   102  			return nil, err
   103  		}
   104  		switch p := p.(type) {
   105  		case *packet.SymmetricKeyEncrypted:
   106  			// This packet contains the decryption key encrypted with a passphrase.
   107  			md.IsSymmetricallyEncrypted = true
   108  			symKeys = append(symKeys, p)
   109  		case *packet.EncryptedKey:
   110  			// This packet contains the decryption key encrypted to a public key.
   111  			md.EncryptedToKeyIds = append(md.EncryptedToKeyIds, p.KeyId)
   112  			switch p.Algo {
   113  			case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal:
   114  				break
   115  			default:
   116  				continue
   117  			}
   118  			var keys []Key
   119  			if p.KeyId == 0 {
   120  				keys = keyring.DecryptionKeys()
   121  			} else {
   122  				keys = keyring.KeysById(p.KeyId)
   123  			}
   124  			for _, k := range keys {
   125  				pubKeys = append(pubKeys, keyEnvelopePair{k, p})
   126  			}
   127  		case *packet.SymmetricallyEncrypted:
   128  			se = p
   129  			break ParsePackets
   130  		case *packet.Compressed, *packet.LiteralData, *packet.OnePassSignature:
   131  			// This message isn't encrypted.
   132  			if len(symKeys) != 0 || len(pubKeys) != 0 {
   133  				return nil, errors.StructuralError("key material not followed by encrypted message")
   134  			}
   135  			packets.Unread(p)
   136  			return readSignedMessage(packets, nil, keyring)
   137  		}
   138  	}
   139  
   140  	var candidates []Key
   141  	var decrypted io.ReadCloser
   142  
   143  	// Now that we have the list of encrypted keys we need to decrypt at
   144  	// least one of them or, if we cannot, we need to call the prompt
   145  	// function so that it can decrypt a key or give us a passphrase.
   146  FindKey:
   147  	for {
   148  		// See if any of the keys already have a private key available
   149  		candidates = candidates[:0]
   150  		candidateFingerprints := make(map[string]bool)
   151  
   152  		for _, pk := range pubKeys {
   153  			if pk.key.PrivateKey == nil {
   154  				continue
   155  			}
   156  			if !pk.key.PrivateKey.Encrypted {
   157  				if len(pk.encryptedKey.Key) == 0 {
   158  					pk.encryptedKey.Decrypt(pk.key.PrivateKey)
   159  				}
   160  				if len(pk.encryptedKey.Key) == 0 {
   161  					continue
   162  				}
   163  				decrypted, err = se.Decrypt(pk.encryptedKey.CipherFunc, pk.encryptedKey.Key)
   164  				if err != nil && err != errors.ErrKeyIncorrect {
   165  					return nil, err
   166  				}
   167  				if decrypted != nil {
   168  					md.DecryptedWith = pk.key
   169  					break FindKey
   170  				}
   171  			} else {
   172  				fpr := string(pk.key.PublicKey.Fingerprint[:])
   173  				if v := candidateFingerprints[fpr]; v {
   174  					continue
   175  				}
   176  				candidates = append(candidates, pk.key)
   177  				candidateFingerprints[fpr] = true
   178  			}
   179  		}
   180  
   181  		if len(candidates) == 0 && len(symKeys) == 0 {
   182  			return nil, errors.ErrKeyIncorrect
   183  		}
   184  
   185  		if prompt == nil {
   186  			return nil, errors.ErrKeyIncorrect
   187  		}
   188  
   189  		passphrase, err := prompt(candidates, len(symKeys) != 0)
   190  		if err != nil {
   191  			return nil, err
   192  		}
   193  
   194  		// Try the symmetric passphrase first
   195  		if len(symKeys) != 0 && passphrase != nil {
   196  			for _, s := range symKeys {
   197  				err = s.Decrypt(passphrase)
   198  				if err == nil && !s.Encrypted {
   199  					decrypted, err = se.Decrypt(s.CipherFunc, s.Key)
   200  					if err != nil && err != errors.ErrKeyIncorrect {
   201  						return nil, err
   202  					}
   203  					if decrypted != nil {
   204  						break FindKey
   205  					}
   206  				}
   207  
   208  			}
   209  		}
   210  	}
   211  
   212  	md.decrypted = decrypted
   213  	packets.Push(decrypted)
   214  	return readSignedMessage(packets, md, keyring)
   215  }
   216  
   217  // readSignedMessage reads a possibly signed message if mdin is non-zero then
   218  // that structure is updated and returned. Otherwise a fresh MessageDetails is
   219  // used.
   220  func readSignedMessage(packets *packet.Reader, mdin *MessageDetails, keyring KeyRing) (md *MessageDetails, err error) {
   221  	if mdin == nil {
   222  		mdin = new(MessageDetails)
   223  	}
   224  	md = mdin
   225  
   226  	var p packet.Packet
   227  	var h hash.Hash
   228  	var wrappedHash hash.Hash
   229  FindLiteralData:
   230  	for {
   231  		p, err = packets.Next()
   232  		if err != nil {
   233  			return nil, err
   234  		}
   235  		switch p := p.(type) {
   236  		case *packet.Compressed:
   237  			packets.Push(p.Body)
   238  		case *packet.OnePassSignature:
   239  			if !p.IsLast {
   240  				return nil, errors.UnsupportedError("nested signatures")
   241  			}
   242  
   243  			h, wrappedHash, err = hashForSignature(p.Hash, p.SigType)
   244  			if err != nil {
   245  				md = nil
   246  				return
   247  			}
   248  
   249  			md.IsSigned = true
   250  			md.SignedByKeyId = p.KeyId
   251  			keys := keyring.KeysById(p.KeyId)
   252  			for i, key := range keys {
   253  				if key.SelfSignature.FlagsValid && !key.SelfSignature.FlagSign {
   254  					continue
   255  				}
   256  				md.SignedBy = &keys[i]
   257  				break
   258  			}
   259  		case *packet.LiteralData:
   260  			md.LiteralData = p
   261  			break FindLiteralData
   262  		}
   263  	}
   264  
   265  	if md.SignedBy != nil {
   266  		md.UnverifiedBody = &signatureCheckReader{packets, h, wrappedHash, md}
   267  	} else if md.decrypted != nil {
   268  		md.UnverifiedBody = checkReader{md}
   269  	} else {
   270  		md.UnverifiedBody = md.LiteralData.Body
   271  	}
   272  
   273  	return md, nil
   274  }
   275  
   276  // hashForSignature returns a pair of hashes that can be used to verify a
   277  // signature. The signature may specify that the contents of the signed message
   278  // should be preprocessed (i.e. to normalize line endings). Thus this function
   279  // returns two hashes. The second should be used to hash the message itself and
   280  // performs any needed preprocessing.
   281  func hashForSignature(hashId crypto.Hash, sigType packet.SignatureType) (hash.Hash, hash.Hash, error) {
   282  	h := hashId.New()
   283  	if h == nil {
   284  		return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashId)))
   285  	}
   286  
   287  	switch sigType {
   288  	case packet.SigTypeBinary:
   289  		return h, h, nil
   290  	case packet.SigTypeText:
   291  		return h, NewCanonicalTextHash(h), nil
   292  	}
   293  
   294  	return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType)))
   295  }
   296  
   297  // checkReader wraps an io.Reader from a LiteralData packet. When it sees EOF
   298  // it closes the ReadCloser from any SymmetricallyEncrypted packet to trigger
   299  // MDC checks.
   300  type checkReader struct {
   301  	md *MessageDetails
   302  }
   303  
   304  func (cr checkReader) Read(buf []byte) (n int, err error) {
   305  	n, err = cr.md.LiteralData.Body.Read(buf)
   306  	if err == io.EOF {
   307  		mdcErr := cr.md.decrypted.Close()
   308  		if mdcErr != nil {
   309  			err = mdcErr
   310  		}
   311  	}
   312  	return
   313  }
   314  
   315  // signatureCheckReader wraps an io.Reader from a LiteralData packet and hashes
   316  // the data as it is read. When it sees an EOF from the underlying io.Reader
   317  // it parses and checks a trailing Signature packet and triggers any MDC checks.
   318  type signatureCheckReader struct {
   319  	packets        *packet.Reader
   320  	h, wrappedHash hash.Hash
   321  	md             *MessageDetails
   322  }
   323  
   324  func (scr *signatureCheckReader) Read(buf []byte) (n int, err error) {
   325  	n, err = scr.md.LiteralData.Body.Read(buf)
   326  	scr.wrappedHash.Write(buf[:n])
   327  	if err == io.EOF {
   328  		var p packet.Packet
   329  		p, scr.md.SignatureError = scr.packets.Next()
   330  		if scr.md.SignatureError != nil {
   331  			return
   332  		}
   333  
   334  		var ok bool
   335  		if scr.md.Signature, ok = p.(*packet.Signature); !ok {
   336  			scr.md.SignatureError = errors.StructuralError("LiteralData not followed by Signature")
   337  			return
   338  		}
   339  
   340  		scr.md.SignatureError = scr.md.SignedBy.PublicKey.VerifySignature(scr.h, scr.md.Signature)
   341  
   342  		// The SymmetricallyEncrypted packet, if any, might have an
   343  		// unsigned hash of its own. In order to check this we need to
   344  		// close that Reader.
   345  		if scr.md.decrypted != nil {
   346  			mdcErr := scr.md.decrypted.Close()
   347  			if mdcErr != nil {
   348  				err = mdcErr
   349  			}
   350  		}
   351  	}
   352  	return
   353  }
   354  
   355  // CheckDetachedSignature takes a signed file and a detached signature and
   356  // returns the signer if the signature is valid. If the signer isn't known,
   357  // ErrUnknownIssuer is returned.
   358  func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
   359  	p, err := packet.Read(signature)
   360  	if err != nil {
   361  		return
   362  	}
   363  
   364  	sig, ok := p.(*packet.Signature)
   365  	if !ok {
   366  		return nil, errors.StructuralError("non signature packet found")
   367  	}
   368  
   369  	if sig.IssuerKeyId == nil {
   370  		return nil, errors.StructuralError("signature doesn't have an issuer")
   371  	}
   372  
   373  	keys := keyring.KeysById(*sig.IssuerKeyId)
   374  	if len(keys) == 0 {
   375  		return nil, errors.ErrUnknownIssuer
   376  	}
   377  
   378  	h, wrappedHash, err := hashForSignature(sig.Hash, sig.SigType)
   379  	if err != nil {
   380  		return
   381  	}
   382  
   383  	_, err = io.Copy(wrappedHash, signed)
   384  	if err != nil && err != io.EOF {
   385  		return
   386  	}
   387  
   388  	for _, key := range keys {
   389  		if key.SelfSignature.FlagsValid && !key.SelfSignature.FlagSign {
   390  			continue
   391  		}
   392  		err = key.PublicKey.VerifySignature(h, sig)
   393  		if err == nil {
   394  			return key.Entity, nil
   395  		}
   396  	}
   397  
   398  	if err != nil {
   399  		return
   400  	}
   401  
   402  	return nil, errors.ErrUnknownIssuer
   403  }
   404  
   405  // CheckArmoredDetachedSignature performs the same actions as
   406  // CheckDetachedSignature but expects the signature to be armored.
   407  func CheckArmoredDetachedSignature(keyring KeyRing, signed, signature io.Reader) (signer *Entity, err error) {
   408  	body, err := readArmored(signature, SignatureType)
   409  	if err != nil {
   410  		return
   411  	}
   412  
   413  	return CheckDetachedSignature(keyring, signed, body)
   414  }