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

Standardize on-disk key formats #68

Merged
merged 3 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
10 changes: 9 additions & 1 deletion signerverifier/ecdsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import (
"os"
)

const ECDSAKeyType = "ecdsa"
const (
ECDSAKeyType = "ecdsa"
ECDSAKeyScheme = "ecdsa-sha2-nistp256"
)

// ECDSASignerVerifier is a dsse.SignerVerifier compliant interface to sign and
// verify signatures using ECDSA keys.
Expand Down Expand Up @@ -89,6 +92,11 @@ func (sv *ECDSASignerVerifier) Public() crypto.PublicKey {

// LoadECDSAKeyFromFile returns an SSLibKey instance for an ECDSA key stored in
// a file in the custom securesystemslib format.
//
// Deprecated: use LoadKey(). The custom serialization format has been
// deprecated. Use
// https://github.com/secure-systems-lab/securesystemslib/blob/main/docs/migrate_key.py
// to convert your key.
func LoadECDSAKeyFromFile(path string) (*SSLibKey, error) {
contents, err := os.ReadFile(path)
if err != nil {
Expand Down
91 changes: 91 additions & 0 deletions signerverifier/ecdsa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,55 @@ func TestECDSASignerVerifierWithDSSEEnvelope(t *testing.T) {
assert.Equal(t, "98adf38602c48c5479e9a991ee3f8cbf541ee4f985e00f7a5fc4148d9a45b704", acceptedKeys[0].KeyID)
}

func TestECDSASignerVerifierWithDSSEEnvelopeAndPEMKey(t *testing.T) {
key, err := LoadKey(ecdsaPrivateKey)
if err != nil {
t.Fatal(err)
}

sv, err := NewECDSASignerVerifierFromSSLibKey(key)
if err != nil {
t.Fatal(err)
}

payloadType := "application/vnd.dsse+json"
payload := []byte("test message")

es, err := dsse.NewEnvelopeSigner(sv)
if err != nil {
t.Error(err)
}

env, err := es.SignPayload(context.Background(), payloadType, payload)
if err != nil {
t.Error(err)
}

assert.Equal(t, "98adf38602c48c5479e9a991ee3f8cbf541ee4f985e00f7a5fc4148d9a45b704", env.Signatures[0].KeyID)
envPayload, err := env.DecodeB64Payload()
assert.Equal(t, payload, envPayload)
assert.Nil(t, err)

key, err = LoadKey(ecdsaPublicKey)
if err != nil {
t.Fatal(err)
}

sv, err = NewECDSASignerVerifierFromSSLibKey(key)
if err != nil {
t.Fatal(err)
}

ev, err := dsse.NewEnvelopeVerifier(sv)
if err != nil {
t.Error(err)
}

acceptedKeys, err := ev.Verify(context.Background(), env)
assert.Nil(t, err)
assert.Equal(t, "98adf38602c48c5479e9a991ee3f8cbf541ee4f985e00f7a5fc4148d9a45b704", acceptedKeys[0].KeyID)
}

func TestECDSASignerVerifierWithMetablockFile(t *testing.T) {
key, err := LoadECDSAKeyFromFile(filepath.Join("test-data", "ecdsa-test-key.pub"))
if err != nil {
Expand Down Expand Up @@ -189,3 +238,45 @@ func TestECDSASignerVerifierWithMetablockFile(t *testing.T) {
err = sv.Verify(context.Background(), encodedBytes, decodedSig)
assert.Nil(t, err)
}

func TestECDSASignerVerifierWithMetablockFileAndPEMKey(t *testing.T) {
key, err := LoadKey(ecdsaPublicKey)
if err != nil {
t.Fatal(err)
}

sv, err := NewECDSASignerVerifierFromSSLibKey(key)
if err != nil {
t.Fatal(err)
}

metadataBytes, err := os.ReadFile(filepath.Join("test-data", "test-ecdsa.98adf386.link"))
if err != nil {
t.Fatal(err)
}

mb := struct {
Signatures []struct {
KeyID string `json:"keyid"`
Sig string `json:"sig"`
} `json:"signatures"`
Signed any `json:"signed"`
}{}

if err := json.Unmarshal(metadataBytes, &mb); err != nil {
t.Fatal(err)
}

assert.Equal(t, "304502201fbb03c0937504182a48c66f9218bdcb2e99a07ada273e92e5e543867f98c8d7022100dbfa7bbf74fd76d76c1d08676419cba85bbd81dfb000f3ac6a786693ddc508f5", mb.Signatures[0].Sig)
assert.Equal(t, sv.keyID, mb.Signatures[0].KeyID)

encodedBytes, err := cjson.EncodeCanonical(mb.Signed)
if err != nil {
t.Fatal(err)
}

decodedSig := hexDecode(t, mb.Signatures[0].Sig)

err = sv.Verify(context.Background(), encodedBytes, decodedSig)
assert.Nil(t, err)
}
5 changes: 5 additions & 0 deletions signerverifier/ed25519.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ func (sv *ED25519SignerVerifier) Public() crypto.PublicKey {

// LoadED25519KeyFromFile returns an SSLibKey instance for an ED25519 key stored
// in a file in the custom securesystemslib format.
//
// Deprecated: use LoadKey(). The custom serialization format has been
// deprecated. Use
// https://github.com/secure-systems-lab/securesystemslib/blob/main/docs/migrate_key.py
// to convert your key.
func LoadED25519KeyFromFile(path string) (*SSLibKey, error) {
contents, err := os.ReadFile(path)
if err != nil {
Expand Down
91 changes: 91 additions & 0 deletions signerverifier/ed25519_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,55 @@ func TestED25519SignerVerifierWithDSSEEnvelope(t *testing.T) {
assert.Equal(t, "52e3b8e73279d6ebdd62a5016e2725ff284f569665eb92ccb145d83817a02997", acceptedKeys[0].KeyID)
}

func TestED25519SignerVerifierWithDSSEEnvelopeAndPEMKey(t *testing.T) {
key, err := LoadKey(ed25519PrivateKey)
if err != nil {
t.Fatal(err)
}

sv, err := NewED25519SignerVerifierFromSSLibKey(key)
if err != nil {
t.Fatal(err)
}

payloadType := "application/vnd.dsse+json"
payload := []byte("test message")

es, err := dsse.NewEnvelopeSigner(sv)
if err != nil {
t.Error(err)
}

env, err := es.SignPayload(context.Background(), payloadType, payload)
if err != nil {
t.Error(err)
}

assert.Equal(t, "52e3b8e73279d6ebdd62a5016e2725ff284f569665eb92ccb145d83817a02997", env.Signatures[0].KeyID)
envPayload, err := env.DecodeB64Payload()
assert.Equal(t, payload, envPayload)
assert.Nil(t, err)

key, err = LoadKey(ed25519PublicKey)
if err != nil {
t.Fatal(err)
}

sv, err = NewED25519SignerVerifierFromSSLibKey(key)
if err != nil {
t.Fatal(err)
}

ev, err := dsse.NewEnvelopeVerifier(sv)
if err != nil {
t.Error(err)
}

acceptedKeys, err := ev.Verify(context.Background(), env)
assert.Nil(t, err)
assert.Equal(t, "52e3b8e73279d6ebdd62a5016e2725ff284f569665eb92ccb145d83817a02997", acceptedKeys[0].KeyID)
}

func TestED25519SignerVerifierWithMetablockFile(t *testing.T) {
key, err := LoadED25519KeyFromFile(filepath.Join("test-data", "ed25519-test-key.pub"))
if err != nil {
Expand Down Expand Up @@ -205,3 +254,45 @@ func TestED25519SignerVerifierWithMetablockFile(t *testing.T) {
err = sv.Verify(context.Background(), encodedBytes, decodedSig)
assert.Nil(t, err)
}

func TestED25519SignerVerifierWithMetablockFileAndPEMKey(t *testing.T) {
key, err := LoadKey(ed25519PublicKey)
if err != nil {
t.Fatal(err)
}

sv, err := NewED25519SignerVerifierFromSSLibKey(key)
if err != nil {
t.Fatal(err)
}

metadataBytes, err := os.ReadFile(filepath.Join("test-data", "test-ed25519.52e3b8e7.link"))
if err != nil {
t.Fatal(err)
}

mb := struct {
Signatures []struct {
KeyID string `json:"keyid"`
Sig string `json:"sig"`
} `json:"signatures"`
Signed any `json:"signed"`
}{}

if err := json.Unmarshal(metadataBytes, &mb); err != nil {
t.Fatal(err)
}

assert.Equal(t, "4c8b7605a9195d4ddba54493bbb5257a9836c1d16056a027fd77e97b95a4f3e36f8bc3c9c9960387d68187760b3072a30c44f992c5bf8f7497c303a3b0a32403", mb.Signatures[0].Sig)
assert.Equal(t, sv.keyID, mb.Signatures[0].KeyID)

encodedBytes, err := cjson.EncodeCanonical(mb.Signed)
if err != nil {
t.Fatal(err)
}

decodedSig := hexDecode(t, mb.Signatures[0].Sig)

err = sv.Verify(context.Background(), encodedBytes, decodedSig)
assert.Nil(t, err)
}
15 changes: 12 additions & 3 deletions signerverifier/rsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ func (sv *RSAPSSSignerVerifier) Public() crypto.PublicKey {

// LoadRSAPSSKeyFromFile returns an SSLibKey instance for an RSA key stored in a
// file.
//
// Deprecated: use LoadKey(). The custom serialization format has been
// deprecated. Use
// https://github.com/secure-systems-lab/securesystemslib/blob/main/docs/migrate_key.py
// to convert your key.
func LoadRSAPSSKeyFromFile(path string) (*SSLibKey, error) {
contents, err := os.ReadFile(path)
if err != nil {
Expand All @@ -103,9 +108,13 @@ func LoadRSAPSSKeyFromFile(path string) (*SSLibKey, error) {
return LoadRSAPSSKeyFromBytes(contents)
}

// 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.

// 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.
//
// Deprecated: use LoadKey() for all key types, RSA is no longer the only key
// that uses PEM serialization.
func LoadRSAPSSKeyFromBytes(contents []byte) (*SSLibKey, error) {
pemData, keyObj, err := decodeAndParsePEM(contents)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions signerverifier/rsa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func TestRSAPSSSignerVerifierSignAndVerify(t *testing.T) {
}

func TestRSAPSSSignerVerifierWithDSSEEnvelope(t *testing.T) {
key, err := LoadRSAPSSKeyFromFile(filepath.Join("test-data", "rsa-test-key"))
key, err := LoadKey(rsaPrivateKey)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -130,7 +130,7 @@ func TestRSAPSSSignerVerifierWithDSSEEnvelope(t *testing.T) {
assert.Equal(t, payload, envPayload)
assert.Nil(t, err)

key, err = LoadRSAPSSKeyFromFile(filepath.Join("test-data", "rsa-test-key.pub"))
key, err = LoadKey(rsaPublicKey)
if err != nil {
t.Fatal(err)
}
Expand All @@ -151,7 +151,7 @@ func TestRSAPSSSignerVerifierWithDSSEEnvelope(t *testing.T) {
}

func TestRSAPSSSignerVerifierWithMetablockFile(t *testing.T) {
key, err := LoadRSAPSSKeyFromFile(filepath.Join("test-data", "rsa-test-key.pub"))
key, err := LoadKey(rsaPublicKey)
if err != nil {
t.Fatal(err)
}
Expand Down
Loading
Loading