From ed01d7bbf672e95b5068f2531ce1ff73b31036b0 Mon Sep 17 00:00:00 2001 From: Christian Rebischke Date: Sun, 5 Jul 2020 16:31:58 +0200 Subject: [PATCH] add new validatePrivateKey function + add key id to pub key In the past in-toto-keygen generated pubkeys did not have a public key ID in their JSON structure. This is going to change in the securesystemslib: https://github.com/secure-systems-lab/securesystemslib/pull/250 This commit adds the key ID to all our public key tests + and the carol.pub key. --- in_toto/keylib.go | 8 ++++---- in_toto/keylib_test.go | 22 +++++++--------------- in_toto/model.go | 13 +++++++++++++ in_toto/model_test.go | 2 +- test/data/carol.pub | 2 +- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/in_toto/keylib.go b/in_toto/keylib.go index b6024d08..fdfbe1e0 100644 --- a/in_toto/keylib.go +++ b/in_toto/keylib.go @@ -325,8 +325,8 @@ func ParseEd25519FromPrivateJSON(JSONString string) (Key, error) { return keyObj, fmt.Errorf("this doesn't appear to be an ed25519 key") } - if keyObj.KeyVal.Private == "" { - return keyObj, fmt.Errorf("this key is not a private key") + if err := validatePrivateKey(keyObj); err != nil { + return keyObj, err } // 64 hexadecimal digits => 32 bytes for the private portion of the key @@ -360,8 +360,8 @@ func ParseEd25519FromPublicJSON(JSONString string) (Key, error) { return keyObj, fmt.Errorf("this doesn't appear to be an ed25519 key") } - if keyObj.KeyVal.Private != "" { - return keyObj, fmt.Errorf("this key is not a public key") + if err := validatePubKey(keyObj); err != nil { + return keyObj, err } // 64 hexadecimal digits => 32 bytes for the public portion of the key diff --git a/in_toto/keylib_test.go b/in_toto/keylib_test.go index 15012f69..70378085 100644 --- a/in_toto/keylib_test.go +++ b/in_toto/keylib_test.go @@ -293,7 +293,7 @@ func TestParseEd25519FromPrivateJSON(t *testing.T) { expectedErrors := []string{ "this is not a valid JSON key object", - "this key is not a private key", + "in key '308e3f53523b632983a988b72a2e39c85fe8fc967116043ce51fa8d92a6aef64': private key cannot be empty", "the private field on this key is malformed", "this doesn't appear to be an ed25519 key", "this doesn't appear to be an ed25519 key", @@ -386,11 +386,11 @@ func TestGenerateEd25519Signature(t *testing.T) { func TestLoad25519PublicKey(t *testing.T) { var key Key - if err := key.LoadEd25519PublicKey("bob.pub"); err != nil { + if err := key.LoadEd25519PublicKey("carol.pub"); err != nil { t.Errorf("Failed to load ed25519 public key from file: (%s)", err) } - expectedPubKey := "e8912b58f47ae04a65d7437e3c82eb361f82d952b4d1b3dc5d90c6f37d7aac70" + expectedPubKey := "8c93f633f2378cc64dd7cbb0ed35eac59e1f28065f90cbbddb59878436fec037" if expectedPubKey != key.KeyVal.Public { t.Errorf("Loaded pubkey is not the expected key") } @@ -434,10 +434,10 @@ func TestParseEd25519FromPublicJSON(t *testing.T) { expectedError string }{ {"not a json", "this is not a valid JSON key object"}, - {`{"keytype": "ed25519", "scheme": "ed25519", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "e8912b58f47ae04a65d7437e3c82eb361f82d952b4d1b3dc5d90c6f37d7aac70", "private": "861fd1b466cfc6f73"}}`, "this key is not a public key"}, - {`{"keytype": "ed25519", "scheme": "ed25519", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "e8912b58f47ae04a65d74"}}`, "the public field on this key is malformed"}, - {`{"keytype": "25519", "scheme": "ed25519", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "e8912b58f47ae04a65d7437e3c82eb361f82d952b4d1b3dc5d90c6f37d7aac70"}}`, "this doesn't appear to be an ed25519 key"}, - {`{"keytype": "ed25519", "scheme": "cd25519", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "e8912b58f47ae04a65d7437e3c82eb361f82d952b4d1b3dc5d90c6f37d7aac70"}}`, "his doesn't appear to be an ed25519 key"}, + {`{"keytype": "ed25519", "scheme": "ed25519", "keyid": "d7c0baabc90b7bf218aa67461ec0c3c7f13a8a5d8552859c8fafe41588be01cf", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "8c93f633f2378cc64dd7cbb0ed35eac59e1f28065f90cbbddb59878436fec037", "private": "4cedf4d3369f8c83af472d0d329aedaa86265b74efb74b708f6a1ed23f290162"}}`, "private key found"}, + {`{"keytype": "ed25519", "scheme": "ed25519", "keyid": "d7c0baabc90b7bf218aa67461ec0c3c7f13a8a5d8552859c8fafe41588be01cf", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "8c93f633f2378cc64"}}`, "the public field on this key is malformed"}, + {`{"keytype": "25519", "scheme": "ed25519", "keyid": "d7c0baabc90b7bf218aa67461ec0c3c7f13a8a5d8552859c8fafe41588be01cf", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "8c93f633f2378cc64dd7cbb0ed35eac59e1f28065f90cbbddb59878436fec037"}}`, "this doesn't appear to be an ed25519 key"}, + {`{"keytype": "ed25519", "scheme": "ec25519", "keyid": "d7c0baabc90b7bf218aa67461ec0c3c7f13a8a5d8552859c8fafe41588be01cf", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "8c93f633f2378cc64dd7cbb0ed35eac59e1f28065f90cbbddb59878436fec037"}}}`, "this is not a valid JSON key object"}, } for _, table := range tables { @@ -446,12 +446,4 @@ func TestParseEd25519FromPublicJSON(t *testing.T) { t.Errorf("ParseEd25519FromPublicJSON returned (%s), expected '%s'", err, table.expectedError) } } - - // Generated through in-toto run 0.4.1 and thus it should be a happy key - validKey := `{"keytype": "ed25519", "scheme": "ed25519", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "e8912b58f47ae04a65d7437e3c82eb361f82d952b4d1b3dc5d90c6f37d7aac70"}}` - _, err := ParseEd25519FromPublicJSON(validKey) - if err != nil { - t.Errorf("ParseEd25519FromPublicJSON returned (%s), expected no error", - err) - } } diff --git a/in_toto/model.go b/in_toto/model.go index b8713520..867ca1b2 100644 --- a/in_toto/model.go +++ b/in_toto/model.go @@ -63,6 +63,19 @@ func validatePubKey(key Key) error { return nil } +/* +validatePrivateKey is a general function to validate if a key is a valid private key. +*/ +func validatePrivateKey(key Key) error { + if err := validateHexString(key.KeyId); err != nil { + return fmt.Errorf("keyid: %s", err.Error()) + } + if key.KeyVal.Private == "" { + return fmt.Errorf("in key '%s': private key cannot be empty", key.KeyId) + } + return nil +} + /* validateRSAPubKey checks if a passed key is a valid RSA public key. */ diff --git a/in_toto/model_test.go b/in_toto/model_test.go index 4100e219..4d010d28 100644 --- a/in_toto/model_test.go +++ b/in_toto/model_test.go @@ -1171,7 +1171,7 @@ func TestMetablockSignWithEd25519(t *testing.T) { pubkey := `{"keytype": "ed25519", "scheme": "ed25519", "keyid": "308e3f53523b632983a988b72a2e39c85fe8fc967116043ce51fa8d92a6aef64", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "8f93f549eb4cca8dc2142fb655ba2d0955d1824f79474f354e38d6a359e9d440", "private": ""}}` badkey, err := ParseEd25519FromPrivateJSON(pubkey) - if err == nil || !strings.Contains(err.Error(), "this key is not a private key") { + if err == nil || !strings.Contains(err.Error(), "private key cannot be empty") { t.Errorf("Metablock.Sign returned (%s), expected it to claim this "+ "key is not a private key", err) diff --git a/test/data/carol.pub b/test/data/carol.pub index 1af4d653..e80d7f25 100644 --- a/test/data/carol.pub +++ b/test/data/carol.pub @@ -1 +1 @@ -{"keytype": "ed25519", "scheme": "ed25519", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "8c93f633f2378cc64dd7cbb0ed35eac59e1f28065f90cbbddb59878436fec037"}} \ No newline at end of file +{"keytype": "ed25519", "scheme": "ed25519", "keyid": "d7c0baabc90b7bf218aa67461ec0c3c7f13a8a5d8552859c8fafe41588be01cf", "keyid_hash_algorithms": ["sha256", "sha512"], "keyval": {"public": "8c93f633f2378cc64dd7cbb0ed35eac59e1f28065f90cbbddb59878436fec037"}} \ No newline at end of file