Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changed LoadKeyFromSSLibBytes to Support RSA Keys #60

Merged
merged 5 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion signerverifier/ecdsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func LoadECDSAKeyFromFile(path string) (*SSLibKey, error) {
return nil, fmt.Errorf("unable to load ECDSA key from file: %w", err)
}

return loadKeyFromSSLibBytes(contents)
return LoadKeyFromSSLibBytes(contents)
}

func getECDSAHashedData(data []byte, curveSize int) []byte {
Expand Down
2 changes: 1 addition & 1 deletion signerverifier/ed25519.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,5 @@ func LoadED25519KeyFromFile(path string) (*SSLibKey, error) {
return nil, fmt.Errorf("unable to load ED25519 key from file: %w", err)
}

return loadKeyFromSSLibBytes(contents)
return LoadKeyFromSSLibBytes(contents)
}
46 changes: 33 additions & 13 deletions signerverifier/rsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ func LoadRSAPSSKeyFromFile(path string) (*SSLibKey, error) {
return nil, fmt.Errorf("unable to load RSA key from file: %w", err)
}

return LoadRSAPSSKeyFromBytes(contents)
neilnaveen marked this conversation as resolved.
Show resolved Hide resolved
}

// LoadRSAPSSKeyFromBytes is a function that takes a byte array as input. This byte array should represent a PEM encoded RSA key, as PEM encoding is required.
// The function returns an SSLibKey instance, which is a struct that holds the key data.

func LoadRSAPSSKeyFromBytes(contents []byte) (*SSLibKey, error) {
pemData, keyObj, err := decodeAndParsePEM(contents)
if err != nil {
return nil, fmt.Errorf("unable to load RSA key from file: %w", err)
Expand All @@ -112,20 +119,13 @@ func LoadRSAPSSKeyFromFile(path string) (*SSLibKey, error) {
KeyVal: KeyVal{},
}

switch k := keyObj.(type) {
case *rsa.PublicKey:
pubKeyBytes, err := x509.MarshalPKIXPublicKey(k)
if err != nil {
return nil, fmt.Errorf("unable to load RSA key from file: %w", err)
}
key.KeyVal.Public = strings.TrimSpace(string(generatePEMBlock(pubKeyBytes, PublicKeyPEM)))
pubKeyBytes, err := marshalAndGeneratePEM(keyObj)
if err != nil {
return nil, fmt.Errorf("unable to load RSA key from file: %w", err)
}
key.KeyVal.Public = strings.TrimSpace(string(pubKeyBytes))

case *rsa.PrivateKey:
pubKeyBytes, err := x509.MarshalPKIXPublicKey(k.Public())
if err != nil {
return nil, fmt.Errorf("unable to load RSA key from file: %w", err)
}
key.KeyVal.Public = strings.TrimSpace(string(generatePEMBlock(pubKeyBytes, PublicKeyPEM)))
if _, ok := keyObj.(*rsa.PrivateKey); ok {
key.KeyVal.Private = strings.TrimSpace(string(generatePEMBlock(pemData.Bytes, RSAPrivateKeyPEM)))
}

Expand All @@ -139,3 +139,23 @@ func LoadRSAPSSKeyFromFile(path string) (*SSLibKey, error) {

return key, nil
}

func marshalAndGeneratePEM(key interface{}) ([]byte, error) {
var pubKeyBytes []byte
var err error

switch k := key.(type) {
case *rsa.PublicKey:
pubKeyBytes, err = x509.MarshalPKIXPublicKey(k)
case *rsa.PrivateKey:
pubKeyBytes, err = x509.MarshalPKIXPublicKey(k.Public())
default:
return nil, fmt.Errorf("unexpected key type: %T", k)
}

if err != nil {
return nil, err
}

return generatePEMBlock(pubKeyBytes, PublicKeyPEM), nil
}
7 changes: 3 additions & 4 deletions signerverifier/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,14 @@ var (
ErrFailedPEMParsing = errors.New("failed parsing the PEM block: unsupported PEM type")
)

// loadKeyFromSSLibBytes returns a pointer to a Key instance created from the
// LoadKeyFromSSLibBytes returns a pointer to a Key instance created from the
// contents of the bytes. The key contents are expected to be in the custom
// securesystemslib format.
func loadKeyFromSSLibBytes(contents []byte) (*SSLibKey, error) {
func LoadKeyFromSSLibBytes(contents []byte) (*SSLibKey, error) {
var key *SSLibKey
if err := json.Unmarshal(contents, &key); err != nil {
return nil, err
return LoadRSAPSSKeyFromBytes(contents)
}

if len(key.KeyID) == 0 {
keyID, err := calculateKeyID(key)
if err != nil {
Expand Down
41 changes: 41 additions & 0 deletions signerverifier/utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package signerverifier

import (
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
)

func TestLoadKeyFromSSLibBytes(t *testing.T) {
t.Run("RSA public key", func(t *testing.T) {
contents, err := os.ReadFile(filepath.Join("test-data", "rsa-test-key.pub"))
if err != nil {
t.Fatal(err)
}
key, err := LoadKeyFromSSLibBytes(contents)
assert.Nil(t, err)

assert.Equal(t, "4e8d20af09fcaed6c388a186427f94a5f7ff5591ec295f4aab2cff49ffe39e9b", key.KeyID)
assert.Equal(t, "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA04egZRic+dZMVtiQc56D\nejU4FF1q3aOkUKnD+Q4lTbj1zp6ODKJTcktupmrad68jqtMiSGG8he6ELFs377q8\nbbgEUMWgAf+06Q8oFvUSfOXzZNFI7H5SMPOJY5aDWIMIEZ8DlcO7TfkA7D3iAEJX\nxxTOVS3UAIk5umO7Y7t7yXr8O/C4u78krGazCnoblcekMLJZV4O/5BloWNAe/B1c\nvZdaZUf3brD4ZZrxEtXw/tefhn1aHsSUajVW2wwjSpKhqj7Z0XS3bDS3T95/3xsN\n6+hlS6A7rJfiWpKIRHj0vh2SXLDmmhQl1In8TD/aiycTUyWcBRHVPlYFgYPt6SaT\nVQSgMzSxC43/2fINb2fyt8SbUHJ3Ct+mzRzd/1AQikWhBdstJLxInewzjYE/sb+c\n2CmCxMPQG2BwmAWXaaumeJcXVPBlMgAcjMatM8bPByTbXpKDnQslOE7g/gswDIwn\nEm53T13mZzYUvbLJ0q3aljZVLIC3IZn3ZwA2yCWchBkVAgMBAAE=\n-----END PUBLIC KEY-----", key.KeyVal.Public)
assert.Equal(t, RSAKeyScheme, key.Scheme)
assert.Equal(t, RSAKeyType, key.KeyType)
})

t.Run("RSA private key", func(t *testing.T) {
contents, err := os.ReadFile(filepath.Join("test-data", "rsa-test-key"))
if err != nil {
t.Fatal(err)
}
key, err := LoadKeyFromSSLibBytes(contents)
assert.Nil(t, err)

assert.Equal(t, "4e8d20af09fcaed6c388a186427f94a5f7ff5591ec295f4aab2cff49ffe39e9b", key.KeyID)
assert.Equal(t, "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA04egZRic+dZMVtiQc56D\nejU4FF1q3aOkUKnD+Q4lTbj1zp6ODKJTcktupmrad68jqtMiSGG8he6ELFs377q8\nbbgEUMWgAf+06Q8oFvUSfOXzZNFI7H5SMPOJY5aDWIMIEZ8DlcO7TfkA7D3iAEJX\nxxTOVS3UAIk5umO7Y7t7yXr8O/C4u78krGazCnoblcekMLJZV4O/5BloWNAe/B1c\nvZdaZUf3brD4ZZrxEtXw/tefhn1aHsSUajVW2wwjSpKhqj7Z0XS3bDS3T95/3xsN\n6+hlS6A7rJfiWpKIRHj0vh2SXLDmmhQl1In8TD/aiycTUyWcBRHVPlYFgYPt6SaT\nVQSgMzSxC43/2fINb2fyt8SbUHJ3Ct+mzRzd/1AQikWhBdstJLxInewzjYE/sb+c\n2CmCxMPQG2BwmAWXaaumeJcXVPBlMgAcjMatM8bPByTbXpKDnQslOE7g/gswDIwn\nEm53T13mZzYUvbLJ0q3aljZVLIC3IZn3ZwA2yCWchBkVAgMBAAE=\n-----END PUBLIC KEY-----", key.KeyVal.Public)
expectedPrivateKey := "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----"
assert.Equal(t, expectedPrivateKey, key.KeyVal.Private)
assert.Equal(t, RSAKeyScheme, key.Scheme)
assert.Equal(t, RSAKeyType, key.KeyType)
})
}
Loading