1package jwt
2
3import (
4	"crypto/ecdsa"
5	"crypto/x509"
6	"encoding/pem"
7	"errors"
8)
9
10var (
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
16func 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
43func 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