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// Parse 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		return nil, err
29	}
30
31	var pkey *ecdsa.PrivateKey
32	var ok bool
33	if pkey, ok = parsedKey.(*ecdsa.PrivateKey); !ok {
34		return nil, ErrNotECPrivateKey
35	}
36
37	return pkey, nil
38}
39
40// Parse PEM encoded PKCS1 or PKCS8 public key
41func ParseECPublicKeyFromPEM(key []byte) (*ecdsa.PublicKey, error) {
42	var err error
43
44	// Parse PEM block
45	var block *pem.Block
46	if block, _ = pem.Decode(key); block == nil {
47		return nil, ErrKeyMustBePEMEncoded
48	}
49
50	// Parse the key
51	var parsedKey interface{}
52	if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
53		if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
54			parsedKey = cert.PublicKey
55		} else {
56			return nil, err
57		}
58	}
59
60	var pkey *ecdsa.PublicKey
61	var ok bool
62	if pkey, ok = parsedKey.(*ecdsa.PublicKey); !ok {
63		return nil, ErrNotECPublicKey
64	}
65
66	return pkey, nil
67}
68