From bc9155fd8476f011ecf3a03847afe91242155c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20Michelberger?= Date: Wed, 20 Dec 2017 19:29:17 +0100 Subject: [PATCH] Fix compatibility issue with credstash >=1.13.1 fixes #8 --- credstash/secret.go | 18 ++++++++++++++++++ credstash/secret_test.go | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/credstash/secret.go b/credstash/secret.go index 912d5bc..156f43e 100644 --- a/credstash/secret.go +++ b/credstash/secret.go @@ -170,6 +170,16 @@ func keyMaterialFromDBItem(item map[string]*dynamodb.AttributeValue) (keyMateria if material.HMAC, err = getStringAndDecode(item, "hmac", hex.DecodeString); err != nil { return keyMaterial{}, err } + // In credstash < 1.13.1 HMAC was store as a hex encoded string. After + // version 1.13.1 credstash started storing the value in a hex encoded + // binary value. To keep compatibility with both versions when the HMAC is + // empty after trying to decode it from a string field we try the binary + // field. + if len(material.HMAC) == 0 { + if material.HMAC, err = getBinaryStringAndDecode(item, "hmac", hex.DecodeString); err != nil { + return keyMaterial{}, err + } + } if material.Key, err = getStringAndDecode(item, "key", base64.StdEncoding.DecodeString); err != nil { return keyMaterial{}, err @@ -207,3 +217,11 @@ func getStringAndDecode(item map[string]*dynamodb.AttributeValue, key string, f } return f(s) } + +func getBinaryStringAndDecode(item map[string]*dynamodb.AttributeValue, key string, f func(string) ([]byte, error)) ([]byte, error) { + value, ok := item[key] + if !ok { + return nil, fmt.Errorf("missing key: %s", key) + } + return f(string(value.B)) +} diff --git a/credstash/secret_test.go b/credstash/secret_test.go index 54eb6bb..ff49813 100644 --- a/credstash/secret_test.go +++ b/credstash/secret_test.go @@ -115,6 +115,18 @@ func TestKeyMaterialFromDDBResult(t *testing.T) { item: dummyItemWithMissingKey(), shouldFail: true, }, + { + desc: "binary HMAC field", + item: dummyItemWithBinaryHMAC("01020304"), + km: keyMaterial{ + Name: "test_key", + Version: "0000000000000000001", + Digest: "SHA256", + Key: []byte{1, 2, 3, 4}, + Content: []byte{1, 2, 3, 4}, + HMAC: []byte{1, 2, 3, 4}, + }, + }, } for _, tt := range testCases { @@ -172,6 +184,12 @@ func dummyItemWithAllFields() map[string]*dynamodb.AttributeValue { } } +func dummyItemWithBinaryHMAC(hmac string) map[string]*dynamodb.AttributeValue { + item := dummyItemWithAllFields() + item["hmac"] = &dynamodb.AttributeValue{B: []byte(hmac)} + return item +} + func dummyItemWithWrongKey() map[string]*dynamodb.AttributeValue { item := dummyItemWithAllFields() item["key"] = attrValueString("not base64")