blob: a5ababf956c4fc3ed74908c929b3e9e04d3fee7e [file] [log] [blame]
khenaidooab1f7bd2019-11-14 14:00:27 -05001package jwt
2
3import (
4 "crypto/rsa"
5 "crypto/x509"
6 "encoding/pem"
7 "errors"
8)
9
10var (
11 ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key")
12 ErrNotRSAPrivateKey = errors.New("Key is not a valid RSA private key")
13 ErrNotRSAPublicKey = errors.New("Key is not a valid RSA public key")
14)
15
16// Parse PEM encoded PKCS1 or PKCS8 private key
17func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
18 var err error
19
20 // Parse PEM block
21 var block *pem.Block
22 if block, _ = pem.Decode(key); block == nil {
23 return nil, ErrKeyMustBePEMEncoded
24 }
25
26 var parsedKey interface{}
27 if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
28 if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
29 return nil, err
30 }
31 }
32
33 var pkey *rsa.PrivateKey
34 var ok bool
35 if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok {
36 return nil, ErrNotRSAPrivateKey
37 }
38
39 return pkey, nil
40}
41
42// Parse PEM encoded PKCS1 or PKCS8 private key protected with password
43func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, 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 var parsedKey interface{}
53
54 var blockDecrypted []byte
55 if blockDecrypted, err = x509.DecryptPEMBlock(block, []byte(password)); err != nil {
56 return nil, err
57 }
58
59 if parsedKey, err = x509.ParsePKCS1PrivateKey(blockDecrypted); err != nil {
60 if parsedKey, err = x509.ParsePKCS8PrivateKey(blockDecrypted); err != nil {
61 return nil, err
62 }
63 }
64
65 var pkey *rsa.PrivateKey
66 var ok bool
67 if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok {
68 return nil, ErrNotRSAPrivateKey
69 }
70
71 return pkey, nil
72}
73
74// Parse PEM encoded PKCS1 or PKCS8 public key
75func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {
76 var err error
77
78 // Parse PEM block
79 var block *pem.Block
80 if block, _ = pem.Decode(key); block == nil {
81 return nil, ErrKeyMustBePEMEncoded
82 }
83
84 // Parse the key
85 var parsedKey interface{}
86 if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
87 if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
88 parsedKey = cert.PublicKey
89 } else {
90 return nil, err
91 }
92 }
93
94 var pkey *rsa.PublicKey
95 var ok bool
96 if pkey, ok = parsedKey.(*rsa.PublicKey); !ok {
97 return nil, ErrNotRSAPublicKey
98 }
99
100 return pkey, nil
101}