launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/environs/simplestreams/decode.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package simplestreams
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"io"
    10  	"io/ioutil"
    11  
    12  	"code.google.com/p/go.crypto/openpgp"
    13  	"code.google.com/p/go.crypto/openpgp/clearsign"
    14  )
    15  
    16  // DecodeCheckSignature parses the inline signed PGP text, checks the signature,
    17  // and returns plain text if the signature matches.
    18  func DecodeCheckSignature(r io.Reader, armoredPublicKey string) ([]byte, error) {
    19  	data, err := ioutil.ReadAll(r)
    20  	if err != nil {
    21  		return nil, err
    22  	}
    23  	b, _ := clearsign.Decode(data)
    24  	if b == nil {
    25  		return nil, &NotPGPSignedError{}
    26  	}
    27  	keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(armoredPublicKey))
    28  	if err != nil {
    29  		return nil, fmt.Errorf("failed to parse public key: %v", err)
    30  	}
    31  
    32  	_, err = openpgp.CheckDetachedSignature(keyring, bytes.NewBuffer(b.Bytes), b.ArmoredSignature.Body)
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  	return b.Plaintext, nil
    37  }
    38  
    39  // NotPGPSignedError is used when PGP text does not contain an inline signature.
    40  type NotPGPSignedError struct{}
    41  
    42  func (*NotPGPSignedError) Error() string {
    43  	return "no PGP signature embedded in plain text data"
    44  }