forked from mirror/jwt
expose RSA key PEM parsing funcs
This commit is contained in:
parent
33523225e1
commit
1363e28b6a
61
rsa.go
61
rsa.go
|
@ -4,8 +4,6 @@ import (
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
|
||||||
"encoding/pem"
|
|
||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -60,7 +58,7 @@ func (m *SigningMethodRSA) Verify(signingString, signature string, key interface
|
||||||
|
|
||||||
switch k := key.(type) {
|
switch k := key.(type) {
|
||||||
case []byte:
|
case []byte:
|
||||||
if rsaKey, err = m.parsePublicKey(k); err != nil {
|
if rsaKey, err = ParsePublicKeyFromPEM(k); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case *rsa.PublicKey:
|
case *rsa.PublicKey:
|
||||||
|
@ -86,7 +84,7 @@ func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string,
|
||||||
|
|
||||||
switch k := key.(type) {
|
switch k := key.(type) {
|
||||||
case []byte:
|
case []byte:
|
||||||
if rsaKey, err = m.parsePrivateKey(k); err != nil {
|
if rsaKey, err = ParsePrivateKeyFromPEM(k); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
case *rsa.PrivateKey:
|
case *rsa.PrivateKey:
|
||||||
|
@ -105,58 +103,3 @@ func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string,
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse PEM encoded PKCS1 or PKCS8 public key
|
|
||||||
func (m *SigningMethodRSA) parsePublicKey(key []byte) (*rsa.PublicKey, error) {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
// Parse PEM block
|
|
||||||
var block *pem.Block
|
|
||||||
if block, _ = pem.Decode(key); block == nil {
|
|
||||||
return nil, errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the key
|
|
||||||
var parsedKey interface{}
|
|
||||||
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
|
|
||||||
if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
|
|
||||||
parsedKey = cert.PublicKey
|
|
||||||
} else {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var pkey *rsa.PublicKey
|
|
||||||
var ok bool
|
|
||||||
if pkey, ok = parsedKey.(*rsa.PublicKey); !ok {
|
|
||||||
return nil, errors.New("Key is not a valid RSA public key")
|
|
||||||
}
|
|
||||||
|
|
||||||
return pkey, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse PEM encoded PKCS1 or PKCS8 private key
|
|
||||||
func (m *SigningMethodRSA) parsePrivateKey(key []byte) (*rsa.PrivateKey, error) {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
// Parse PEM block
|
|
||||||
var block *pem.Block
|
|
||||||
if block, _ = pem.Decode(key); block == nil {
|
|
||||||
return nil, errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key")
|
|
||||||
}
|
|
||||||
|
|
||||||
var parsedKey interface{}
|
|
||||||
if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
|
|
||||||
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var pkey *rsa.PrivateKey
|
|
||||||
var ok bool
|
|
||||||
if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok {
|
|
||||||
return nil, errors.New("Key is not a valid RSA private key")
|
|
||||||
}
|
|
||||||
|
|
||||||
return pkey, nil
|
|
||||||
}
|
|
||||||
|
|
17
rsa_test.go
17
rsa_test.go
|
@ -81,7 +81,7 @@ func TestRSASign(t *testing.T) {
|
||||||
func TestRSAVerifyWithPreParsedPrivateKey(t *testing.T) {
|
func TestRSAVerifyWithPreParsedPrivateKey(t *testing.T) {
|
||||||
key, _ := ioutil.ReadFile("test/sample_key.pub")
|
key, _ := ioutil.ReadFile("test/sample_key.pub")
|
||||||
method := GetSigningMethod("RS256").(*SigningMethodRSA)
|
method := GetSigningMethod("RS256").(*SigningMethodRSA)
|
||||||
parsedKey, err := method.parsePublicKey(key)
|
parsedKey, err := ParsePublicKeyFromPEM(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ func TestRSAVerifyWithPreParsedPrivateKey(t *testing.T) {
|
||||||
func TestRSAWithPreParsedPrivateKey(t *testing.T) {
|
func TestRSAWithPreParsedPrivateKey(t *testing.T) {
|
||||||
key, _ := ioutil.ReadFile("test/sample_key")
|
key, _ := ioutil.ReadFile("test/sample_key")
|
||||||
method := GetSigningMethod("RS256").(*SigningMethodRSA)
|
method := GetSigningMethod("RS256").(*SigningMethodRSA)
|
||||||
parsedKey, err := method.parsePrivateKey(key)
|
parsedKey, err := ParsePrivateKeyFromPEM(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -115,31 +115,30 @@ func TestRSAKeyParsing(t *testing.T) {
|
||||||
key, _ := ioutil.ReadFile("test/sample_key")
|
key, _ := ioutil.ReadFile("test/sample_key")
|
||||||
pubKey, _ := ioutil.ReadFile("test/sample_key.pub")
|
pubKey, _ := ioutil.ReadFile("test/sample_key.pub")
|
||||||
badKey := []byte("All your base are belong to key")
|
badKey := []byte("All your base are belong to key")
|
||||||
method := GetSigningMethod("RS256").(*SigningMethodRSA)
|
|
||||||
|
|
||||||
// Test parsePrivateKey
|
// Test parsePrivateKey
|
||||||
if _, e := method.parsePrivateKey(key); e != nil {
|
if _, e := ParsePrivateKeyFromPEM(key); e != nil {
|
||||||
t.Errorf("Failed to parse valid private key: %v", e)
|
t.Errorf("Failed to parse valid private key: %v", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
if k, e := method.parsePrivateKey(pubKey); e == nil {
|
if k, e := ParsePrivateKeyFromPEM(pubKey); e == nil {
|
||||||
t.Errorf("Parsed public key as valid private key: %v", k)
|
t.Errorf("Parsed public key as valid private key: %v", k)
|
||||||
}
|
}
|
||||||
|
|
||||||
if k, e := method.parsePrivateKey(badKey); e == nil {
|
if k, e := ParsePrivateKeyFromPEM(badKey); e == nil {
|
||||||
t.Errorf("Parsed invalid key as valid private key: %v", k)
|
t.Errorf("Parsed invalid key as valid private key: %v", k)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test parsePublicKey
|
// Test parsePublicKey
|
||||||
if _, e := method.parsePublicKey(pubKey); e != nil {
|
if _, e := ParsePublicKeyFromPEM(pubKey); e != nil {
|
||||||
t.Errorf("Failed to parse valid public key: %v", e)
|
t.Errorf("Failed to parse valid public key: %v", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
if k, e := method.parsePublicKey(key); e == nil {
|
if k, e := ParsePublicKeyFromPEM(key); e == nil {
|
||||||
t.Errorf("Parsed private key as valid public key: %v", k)
|
t.Errorf("Parsed private key as valid public key: %v", k)
|
||||||
}
|
}
|
||||||
|
|
||||||
if k, e := method.parsePublicKey(badKey); e == nil {
|
if k, e := ParsePublicKeyFromPEM(badKey); e == nil {
|
||||||
t.Errorf("Parsed invalid key as valid private key: %v", k)
|
t.Errorf("Parsed invalid key as valid private key: %v", k)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Parse PEM encoded PKCS1 or PKCS8 private key
|
||||||
|
func ParsePrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Parse PEM block
|
||||||
|
var block *pem.Block
|
||||||
|
if block, _ = pem.Decode(key); block == nil {
|
||||||
|
return nil, errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key")
|
||||||
|
}
|
||||||
|
|
||||||
|
var parsedKey interface{}
|
||||||
|
if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
|
||||||
|
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var pkey *rsa.PrivateKey
|
||||||
|
var ok bool
|
||||||
|
if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok {
|
||||||
|
return nil, errors.New("Key is not a valid RSA private key")
|
||||||
|
}
|
||||||
|
|
||||||
|
return pkey, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse PEM encoded PKCS1 or PKCS8 public key
|
||||||
|
func ParsePublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Parse PEM block
|
||||||
|
var block *pem.Block
|
||||||
|
if block, _ = pem.Decode(key); block == nil {
|
||||||
|
return nil, errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the key
|
||||||
|
var parsedKey interface{}
|
||||||
|
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
|
||||||
|
if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
|
||||||
|
parsedKey = cert.PublicKey
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var pkey *rsa.PublicKey
|
||||||
|
var ok bool
|
||||||
|
if pkey, ok = parsedKey.(*rsa.PublicKey); !ok {
|
||||||
|
return nil, errors.New("Key is not a valid RSA public key")
|
||||||
|
}
|
||||||
|
|
||||||
|
return pkey, nil
|
||||||
|
}
|
Loading…
Reference in New Issue