ecdsa_utils.go raw

   1  package jwt
   2  
   3  import (
   4  	"crypto/ecdsa"
   5  	"crypto/x509"
   6  	"encoding/pem"
   7  	"errors"
   8  )
   9  
  10  var (
  11  	ErrNotECPublicKey  = errors.New("key is not a valid ECDSA public key")
  12  	ErrNotECPrivateKey = errors.New("key is not a valid ECDSA private key")
  13  )
  14  
  15  // ParseECPrivateKeyFromPEM parses a PEM encoded Elliptic Curve Private Key Structure
  16  func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
  17  	var err error
  18  
  19  	// Parse PEM block
  20  	var block *pem.Block
  21  	if block, _ = pem.Decode(key); block == nil {
  22  		return nil, ErrKeyMustBePEMEncoded
  23  	}
  24  
  25  	// Parse the key
  26  	var parsedKey interface{}
  27  	if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil {
  28  		if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
  29  			return nil, err
  30  		}
  31  	}
  32  
  33  	var pkey *ecdsa.PrivateKey
  34  	var ok bool
  35  	if pkey, ok = parsedKey.(*ecdsa.PrivateKey); !ok {
  36  		return nil, ErrNotECPrivateKey
  37  	}
  38  
  39  	return pkey, nil
  40  }
  41  
  42  // ParseECPublicKeyFromPEM parses a PEM encoded PKCS1 or PKCS8 public key
  43  func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) {
  44  	var err error
  45  
  46  	// Parse PEM block
  47  	var block *pem.Block
  48  	if block, _ = pem.Decode(key); block == nil {
  49  		return nil, ErrKeyMustBePEMEncoded
  50  	}
  51  
  52  	// Parse the key
  53  	var parsedKey interface{}
  54  	if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
  55  		if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
  56  			parsedKey = cert.PublicKey
  57  		} else {
  58  			return nil, err
  59  		}
  60  	}
  61  
  62  	var pkey *ecdsa.PublicKey
  63  	var ok bool
  64  	if pkey, ok = parsedKey.(*ecdsa.PublicKey); !ok {
  65  		return nil, ErrNotECPublicKey
  66  	}
  67  
  68  	return pkey, nil
  69  }
  70