github.com/xmidt-org/webpa-common@v1.11.9/secure/key/parser.go (about)

     1  package key
     2  
     3  import (
     4  	"crypto/rsa"
     5  	"crypto/x509"
     6  	"encoding/pem"
     7  	"errors"
     8  )
     9  
    10  var (
    11  	ErrorPEMRequired                 = errors.New("Keys must be PEM-encoded")
    12  	ErrorUnsupportedPrivateKeyFormat = errors.New("Private keys must be in PKCS1 or PKCS8 format")
    13  	ErrorNotRSAPrivateKey            = errors.New("Only RSA private keys are supported")
    14  	ErrorNotRSAPublicKey             = errors.New("Only RSA public keys or certificates are suppored")
    15  )
    16  
    17  // Parser parses a chunk of bytes into a Pair.  Parser implementations must
    18  // always be safe for concurrent access.
    19  type Parser interface {
    20  	// Parse examines data to produce a Pair.  If the returned error is not nil,
    21  	// the Pair will always be nil.  This method is responsible for dealing with
    22  	// any required decoding, such as PEM or DER.
    23  	ParseKey(Purpose, []byte) (Pair, error)
    24  }
    25  
    26  // defaultParser is the internal default Parser implementation
    27  type defaultParser int
    28  
    29  func (p defaultParser) String() string {
    30  	return "defaultParser"
    31  }
    32  
    33  func (p defaultParser) parseRSAPrivateKey(purpose Purpose, decoded []byte) (Pair, error) {
    34  	var (
    35  		parsedKey interface{}
    36  		err       error
    37  	)
    38  
    39  	if parsedKey, err = x509.ParsePKCS1PrivateKey(decoded); err != nil {
    40  		if parsedKey, err = x509.ParsePKCS8PrivateKey(decoded); err != nil {
    41  			return nil, ErrorUnsupportedPrivateKeyFormat
    42  		}
    43  	}
    44  
    45  	privateKey, ok := parsedKey.(*rsa.PrivateKey)
    46  	if !ok {
    47  		return nil, ErrorNotRSAPrivateKey
    48  	}
    49  
    50  	return &rsaPair{
    51  		purpose: purpose,
    52  		public:  privateKey.Public(),
    53  		private: privateKey,
    54  	}, nil
    55  }
    56  
    57  func (p defaultParser) parseRSAPublicKey(purpose Purpose, decoded []byte) (Pair, error) {
    58  	var (
    59  		parsedKey interface{}
    60  		err       error
    61  	)
    62  
    63  	if parsedKey, err = x509.ParsePKIXPublicKey(decoded); err != nil {
    64  		return nil, err
    65  	}
    66  
    67  	publicKey, ok := parsedKey.(*rsa.PublicKey)
    68  	if !ok {
    69  		return nil, ErrorNotRSAPublicKey
    70  	}
    71  
    72  	return &rsaPair{
    73  		purpose: purpose,
    74  		public:  publicKey,
    75  		private: nil,
    76  	}, nil
    77  }
    78  
    79  func (p defaultParser) ParseKey(purpose Purpose, data []byte) (Pair, error) {
    80  	block, _ := pem.Decode(data)
    81  	if block == nil {
    82  		return nil, ErrorPEMRequired
    83  	}
    84  
    85  	if purpose.RequiresPrivateKey() {
    86  		return p.parseRSAPrivateKey(purpose, block.Bytes)
    87  	} else {
    88  		return p.parseRSAPublicKey(purpose, block.Bytes)
    89  	}
    90  }
    91  
    92  // DefaultParser is the global, singleton default parser.  All keys submitted to
    93  // this parser must be PEM-encoded.
    94  var DefaultParser Parser = defaultParser(0)