diff --git a/trustmanager/x509utils.go b/trustmanager/x509utils.go index 2661c7677c..0130d2d4be 100644 --- a/trustmanager/x509utils.go +++ b/trustmanager/x509utils.go @@ -495,3 +495,26 @@ func NewCertificate(gun string) (*x509.Certificate, error) { BasicConstraintsValid: true, }, nil } + +// X509PublickeyID returns a public key ID as a string, given a +// data.PublicKey that contains an X509 Certificate +func X509PublickeyID(certPubKey data.PublicKey) (string, error) { + cert, err := LoadCertFromPEM(certPubKey.Public()) + if err != nil { + return "", err + } + var finalAlgorithm data.KeyAlgorithm + + switch certPubKey.Algorithm() { + case data.ECDSAx509Key: + finalAlgorithm = data.ECDSAKey + case data.RSAx509Key: + finalAlgorithm = data.RSAKey + } + + pubKeyBytes, err := x509.MarshalPKIXPublicKey(cert.PublicKey) + if err != nil { + return "", err + } + return data.NewPublicKey(finalAlgorithm, pubKeyBytes).ID(), nil +} diff --git a/trustmanager/x509utils_test.go b/trustmanager/x509utils_test.go index 78830089c7..c2e5c03a31 100644 --- a/trustmanager/x509utils_test.go +++ b/trustmanager/x509utils_test.go @@ -3,10 +3,12 @@ package trustmanager import ( "crypto/rand" "crypto/x509" + "io/ioutil" "strings" "testing" "time" + "github.com/endophage/gotuf/data" "github.com/stretchr/testify/assert" ) @@ -144,3 +146,33 @@ func TestKeyOperations(t *testing.T) { assert.Equal(t, rsaKey.Private(), decryptedRSAKey.Private()) } + +// X509PublickeyID returns the public key ID of a cert rather than the cert ID +func TestRSAX509PublickeyID(t *testing.T) { + fileBytes, err := ioutil.ReadFile("../fixtures/notary-server.key") + assert.NoError(t, err) + + privKey, err := ParsePEMPrivateKey(fileBytes, "") + assert.NoError(t, err) + expectedTufID := privKey.ID() + + cert, err := LoadCertFromFile("../fixtures/notary-server.crt") + assert.NoError(t, err) + + rsaKeyBytes, err := x509.MarshalPKIXPublicKey(cert.PublicKey) + assert.NoError(t, err) + + sameWayTufID := data.NewPublicKey(data.RSAKey, rsaKeyBytes).ID() + + actualTufKeyMap := CertsToKeys([]*x509.Certificate{cert}) + assert.Len(t, actualTufKeyMap, 1) + var actualTufKey data.PublicKey + for _, v := range actualTufKeyMap { + actualTufKey = v + } + + actualTufID, err := X509PublickeyID(actualTufKey) + + assert.Equal(t, sameWayTufID, actualTufID) + assert.Equal(t, expectedTufID, actualTufID) +}