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 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// Parse 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