expose RSA key PEM parsing funcs

This commit is contained in:
Simon Jefford 2014-08-07 09:00:06 +01:00 committed by Dave Grijalva
parent 33523225e1
commit 1363e28b6a
3 changed files with 73 additions and 68 deletions

61
rsa.go
View File

@ -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
}

View File

@ -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)
} }

63
rsa_utils.go Normal file
View File

@ -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
}