From eac79506b1c78f06d9028a3ab0ffa5a6d7f30b52 Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 17:57:39 +0200 Subject: [PATCH 01/16] feat(model): message header interfaces --- pkg/model/format/header.go | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 pkg/model/format/header.go diff --git a/pkg/model/format/header.go b/pkg/model/format/header.go new file mode 100644 index 0000000..88d636d --- /dev/null +++ b/pkg/model/format/header.go @@ -0,0 +1,52 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package format + +import ( + "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" +) + +type Serializable interface { + Len() int + Bytes() []byte +} + +type messageHeaderBase interface { + Version() suite.MessageFormatVersion + AlgorithmSuite() *suite.AlgorithmSuite + MessageID() []byte + AADLength() int + AADData() MessageAAD + EncryptedDataKeyCount() int + EncryptedDataKeys() []MessageEDK + ContentType() suite.ContentType + FrameLength() int +} + +type MessageHeader interface { + Serializable + messageHeaderBase + Type() suite.MessageType // present only in V1 + Reserved() []byte // present only in V1 + IVLength() int // present only in V1 + AlgorithmSuiteData() []byte // present only in V2 +} + +type MessageEDK interface { + Serializable + ProviderID() string + ProviderInfo() string + EncryptedDataKey() []byte +} + +type MessageAAD interface { + Serializable + EncryptionContext() suite.EncryptionContext +} + +type MessageHeaderAuth interface { + Serializable + AuthData() []byte + IV() []byte // present only in V1 +} From 37fff66232f20d319184369fa01c1799bd66e2ee Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 18:01:30 +0200 Subject: [PATCH 02/16] feat(suite): Message Format V1 supported algorithms --- pkg/suite/algorithm.go | 107 ++++++++++++++++++++++++++--------- pkg/suite/algorithm_test.go | 89 +++++++++++++++++++++++++++++ pkg/suite/consts.go | 30 +++++++--- pkg/suite/consts_test.go | 22 +++++--- pkg/suite/validate.go | 50 +++++++++++++++++ pkg/suite/validate_test.go | 109 ++++++++++++++++++++++++++++++++++++ 6 files changed, 363 insertions(+), 44 deletions(-) create mode 100644 pkg/suite/validate.go create mode 100644 pkg/suite/validate_test.go diff --git a/pkg/suite/algorithm.go b/pkg/suite/algorithm.go index 5890419..49a945d 100644 --- a/pkg/suite/algorithm.go +++ b/pkg/suite/algorithm.go @@ -12,6 +12,7 @@ import ( "fmt" "hash" "io" + "strings" "golang.org/x/crypto/hkdf" @@ -24,7 +25,8 @@ type encAlgorithm string type cipherMode string const ( - messageIDLen = int(32) + messageIDV1Len = int(16) // V1 Message ID size 16 bytes (128-bit unsigned integer) + messageIDLen = int(32) // V2 Message ID size 32 bytes (256-bit unsigned integer) algorithmSuiteDataLen = int(32) bitSize = int(8) // 1 byte = 8 bits @@ -43,7 +45,7 @@ type encryptionSuite struct { AuthLen int } -//goland:noinspection GoSnakeCaseUsage,GoUnusedGlobalVariable +//goland:noinspection GoSnakeCaseUsage var ( aes_128_GCM_IV12_TAG16 = NewEncryptionSuite(aesAlg, gcmMode, 16, 12, 16) aes_192_GCM_IV12_TAG16 = NewEncryptionSuite(aesAlg, gcmMode, 24, 12, 16) @@ -60,10 +62,11 @@ type kdfSuite struct { HashFunc func() hash.Hash } -//goland:noinspection GoSnakeCaseUsage,GoUnusedGlobalVariable +//goland:noinspection GoSnakeCaseUsage var ( - hkdf_SHA256 = NewKdfSuite(hkdf.New, sha256.New) //nolint:unused - hkdf_SHA384 = NewKdfSuite(hkdf.New, sha512.New384) //nolint:unused + hkdf_NONE = NewKdfSuite(nil, nil) + hkdf_SHA256 = NewKdfSuite(hkdf.New, sha256.New) + hkdf_SHA384 = NewKdfSuite(hkdf.New, sha512.New384) hkdf_SHA512 = NewKdfSuite(hkdf.New, sha512.New) ) @@ -78,7 +81,7 @@ type authenticationSuite struct { SignatureLen int } -//goland:noinspection GoSnakeCaseUsage,GoUnusedGlobalVariable +//goland:noinspection GoSnakeCaseUsage var ( authSuite_NONE = newAuthenticationSuite(nil, nil, 0) authSuite_SHA256_ECDSA_P256 = newAuthenticationSuite(elliptic.P256(), sha256.New, 71) @@ -91,8 +94,9 @@ func newAuthenticationSuite(algorithm elliptic.Curve, hashFunc func() hash.Hash, type AlgorithmSuite struct { AlgorithmID uint16 + name string EncryptionSuite encryptionSuite - MessageFormatVersion int + MessageFormatVersion MessageFormatVersion KDFSuite kdfSuite Authentication authenticationSuite } @@ -102,24 +106,41 @@ func (as *AlgorithmSuite) GoString() string { return fmt.Sprintf("%#v", *as) } -func (as *AlgorithmSuite) Name() string { - if as.IsSigning() { - // AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384 - return fmt.Sprintf("%v_%d_%v_HKDF_SHA%d_COMMIT_KEY_ECDSA_P%d", - as.EncryptionSuite.Algorithm, - as.EncryptionSuite.DataKeyLen*bitSize, - as.EncryptionSuite.Mode, - as.KDFSuite.HashFunc().Size()*bitSize, - as.Authentication.Algorithm.Params().BitSize, - ) - } - // AES_256_GCM_HKDF_SHA512_COMMIT_KEY - return fmt.Sprintf("%v_%d_%v_HKDF_SHA%d_COMMIT_KEY", +func buildAlgorithmName(as *AlgorithmSuite) string { + var sb strings.Builder + // AES_256_GCM + sb.WriteString(fmt.Sprintf("%v_%d_%v", as.EncryptionSuite.Algorithm, as.EncryptionSuite.DataKeyLen*bitSize, as.EncryptionSuite.Mode, - as.KDFSuite.HashFunc().Size()*bitSize, - ) + )) + if as.MessageFormatVersion == V1 { + // _IV12_TAG16 + sb.WriteString(fmt.Sprintf("_IV%d_TAG%d", as.EncryptionSuite.IVLen, as.EncryptionSuite.AuthLen)) + } + + if as.KDFSuite.HashFunc != nil { + // _HKDF_SHA512 + sb.WriteString(fmt.Sprintf("_HKDF_SHA%d", as.KDFSuite.HashFunc().Size()*bitSize)) + } + + if as.IsCommitting() { + // _COMMIT_KEY + sb.WriteString("_COMMIT_KEY") + } + + if as.IsSigning() { + // _ECDSA_P384 + sb.WriteString(fmt.Sprintf("_ECDSA_P%d", as.Authentication.Algorithm.Params().BitSize)) + } + + // format: AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384 + return sb.String() +} + +func (as *AlgorithmSuite) Name() string { + // format: AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384 + return as.name } func (as *AlgorithmSuite) String() string { @@ -127,6 +148,11 @@ func (as *AlgorithmSuite) String() string { return fmt.Sprintf("AlgID 0x%04X: %s", as.AlgorithmID, as.Name()) } +func (as *AlgorithmSuite) IDString() string { + // format: 0578 + return fmt.Sprintf("%04X", as.AlgorithmID) +} + func (as *AlgorithmSuite) IDBytes() []byte { return conv.FromInt.UUint16BigEndian(as.AlgorithmID) } @@ -135,6 +161,10 @@ func (as *AlgorithmSuite) IsSigning() bool { return as.Authentication.Algorithm != nil } +func (as *AlgorithmSuite) IsKDFSupported() bool { + return as.KDFSuite.KDFFunc != nil +} + func (as *AlgorithmSuite) IsCommitting() bool { if bytes.HasPrefix(as.IDBytes(), []byte{0x05}) || bytes.HasPrefix(as.IDBytes(), []byte{0x04}) { return true @@ -143,28 +173,49 @@ func (as *AlgorithmSuite) IsCommitting() bool { } func (as *AlgorithmSuite) MessageIDLen() int { - // all supported algorithmSuite version 2 has 32 bytes MessageID length + // all supported algorithmSuite MessageFormatVersion 1 has 16 bytes MessageID length + if as.MessageFormatVersion == V1 { + return messageIDV1Len + } + // all supported algorithmSuite MessageFormatVersion 2 has 32 bytes MessageID length return messageIDLen } func (as *AlgorithmSuite) AlgorithmSuiteDataLen() int { + if as.MessageFormatVersion == V1 { + // Algorithm Suite Data field not present in MessageFormatVersion 1 + return 0 + } // all supported algorithmSuite version 2 has 32 bytes Algorithm Suite Data field length return algorithmSuiteDataLen } //goland:noinspection GoSnakeCaseUsage,GoUnusedGlobalVariable var ( - AES_256_GCM_HKDF_SHA512_COMMIT_KEY = newAlgorithmSuite(0x0478, aes_256_GCM_IV12_TAG16, 2, hkdf_SHA512, authSuite_NONE) - AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384 = newAlgorithmSuite(0x0578, aes_256_GCM_IV12_TAG16, 2, hkdf_SHA512, authSuite_SHA256_ECDSA_P384) - //AES_256_GCM_HKDF_SHA512_COMMIT_KEY_WRAPPING = newAlgorithmSuite(0x0470, aes_256_GCM_IV12_TAG16, 2, hkdf_SHA512, authSuite_NONE) - //AES_256_GCM_HKDF_SHA512_COMMIT_KEY_WRAPPING_ECDSA_P384 = newAlgorithmSuite(0x0570, aes_256_GCM_IV12_TAG16, 2, hkdf_SHA512, authSuite_SHA256_ECDSA_P384) + // MessageFormatVersion 1 algorithm suites + + AES_128_GCM_IV12_TAG16 = newAlgorithmSuite(0x0014, aes_128_GCM_IV12_TAG16, V1, hkdf_NONE, authSuite_NONE) + AES_192_GCM_IV12_TAG16 = newAlgorithmSuite(0x0046, aes_192_GCM_IV12_TAG16, V1, hkdf_NONE, authSuite_NONE) + AES_256_GCM_IV12_TAG16 = newAlgorithmSuite(0x0078, aes_256_GCM_IV12_TAG16, V1, hkdf_NONE, authSuite_NONE) + AES_128_GCM_IV12_TAG16_HKDF_SHA256 = newAlgorithmSuite(0x0114, aes_128_GCM_IV12_TAG16, V1, hkdf_SHA256, authSuite_NONE) + AES_192_GCM_IV12_TAG16_HKDF_SHA256 = newAlgorithmSuite(0x0146, aes_192_GCM_IV12_TAG16, V1, hkdf_SHA256, authSuite_NONE) + AES_256_GCM_IV12_TAG16_HKDF_SHA256 = newAlgorithmSuite(0x0178, aes_256_GCM_IV12_TAG16, V1, hkdf_SHA256, authSuite_NONE) + AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256 = newAlgorithmSuite(0x0214, aes_128_GCM_IV12_TAG16, V1, hkdf_SHA256, authSuite_SHA256_ECDSA_P256) + AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 = newAlgorithmSuite(0x0346, aes_192_GCM_IV12_TAG16, V1, hkdf_SHA384, authSuite_SHA256_ECDSA_P384) + AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384 = newAlgorithmSuite(0x0378, aes_256_GCM_IV12_TAG16, V1, hkdf_SHA384, authSuite_SHA256_ECDSA_P384) + + // MessageFormatVersion 2 algorithm suites with commitment + + AES_256_GCM_HKDF_SHA512_COMMIT_KEY = newAlgorithmSuite(0x0478, aes_256_GCM_IV12_TAG16, V2, hkdf_SHA512, authSuite_NONE) + AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384 = newAlgorithmSuite(0x0578, aes_256_GCM_IV12_TAG16, V2, hkdf_SHA512, authSuite_SHA256_ECDSA_P384) ) // Note: we are not accessing this map concurrently on write, so no need to use sync.Map. var algorithmLookup = map[uint16]*AlgorithmSuite{} //nolint:gochecknoglobals -func newAlgorithmSuite(algorithmID uint16, encryptionSuite encryptionSuite, messageFormatVersion int, kdfSuite kdfSuite, authentication authenticationSuite) *AlgorithmSuite { //nolint:unparam +func newAlgorithmSuite(algorithmID uint16, encryptionSuite encryptionSuite, messageFormatVersion MessageFormatVersion, kdfSuite kdfSuite, authentication authenticationSuite) *AlgorithmSuite { //nolint:unparam alg := &AlgorithmSuite{AlgorithmID: algorithmID, EncryptionSuite: encryptionSuite, MessageFormatVersion: messageFormatVersion, KDFSuite: kdfSuite, Authentication: authentication} + alg.name = buildAlgorithmName(alg) algorithmLookup[algorithmID] = alg return alg } diff --git a/pkg/suite/algorithm_test.go b/pkg/suite/algorithm_test.go index 7a6db84..bd9c859 100644 --- a/pkg/suite/algorithm_test.go +++ b/pkg/suite/algorithm_test.go @@ -4,6 +4,7 @@ package suite import ( + "fmt" "reflect" "testing" @@ -22,6 +23,15 @@ func Test_algorithm_ByID(t *testing.T) { }{ {"unknown_alg", args{0x0301}, nil, true}, {"zero_alg", args{0}, nil, true}, + {"AES_128_GCM_IV12_TAG16", args{0x0014}, AES_128_GCM_IV12_TAG16, false}, + {"AES_192_GCM_IV12_TAG16", args{0x0046}, AES_192_GCM_IV12_TAG16, false}, + {"AES_256_GCM_IV12_TAG16", args{0x0078}, AES_256_GCM_IV12_TAG16, false}, + {"AES_128_GCM_IV12_TAG16_HKDF_SHA256", args{0x0114}, AES_128_GCM_IV12_TAG16_HKDF_SHA256, false}, + {"AES_192_GCM_IV12_TAG16_HKDF_SHA256", args{0x0146}, AES_192_GCM_IV12_TAG16_HKDF_SHA256, false}, + {"AES_256_GCM_IV12_TAG16_HKDF_SHA256", args{0x0178}, AES_256_GCM_IV12_TAG16_HKDF_SHA256, false}, + {"AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256", args{0x0214}, AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256, false}, + {"AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384", args{0x0346}, AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, false}, + {"AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384", args{0x0378}, AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, false}, {"AES_256_GCM_HKDF_SHA512_COMMIT_KEY", args{0x0478}, AES_256_GCM_HKDF_SHA512_COMMIT_KEY, false}, {"AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384", args{0x0578}, AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, false}, } @@ -52,6 +62,8 @@ func Test_algorithm_FromBytes(t *testing.T) { }{ {"alg_nil", args{[]byte(nil)}, nil, true}, {"zero_alg", args{[]byte{0x00}}, nil, true}, + {"AES_256_GCM_IV12_TAG16", args{[]byte{0x00, 0x78}}, AES_256_GCM_IV12_TAG16, false}, + {"AES_256_GCM_IV12_TAG16_HKDF_SHA256", args{[]byte{0x01, 0x78}}, AES_256_GCM_IV12_TAG16_HKDF_SHA256, false}, {"AES_256_GCM_HKDF_SHA512_COMMIT_KEY", args{[]byte{0x04, 0x78}}, AES_256_GCM_HKDF_SHA512_COMMIT_KEY, false}, {"AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384", args{[]byte{0x05, 0x78}}, AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, false}, } @@ -121,6 +133,7 @@ func TestAlgorithmSuite_MessageIDLen(t *testing.T) { alg *AlgorithmSuite want int }{ + {"HKDF_SHA256", AES_256_GCM_IV12_TAG16_HKDF_SHA256, 16}, {"COMMIT_KEY", AES_256_GCM_HKDF_SHA512_COMMIT_KEY, 32}, {"COMMIT_KEY_ECDSA_P384", AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 32}, } @@ -157,6 +170,7 @@ func TestAlgorithmSuite_IsCommitting(t *testing.T) { alg *AlgorithmSuite want bool }{ + {"NOT_COMMITTING", AES_256_GCM_IV12_TAG16_HKDF_SHA256, false}, {"COMMIT_KEY", AES_256_GCM_HKDF_SHA512_COMMIT_KEY, true}, {"COMMIT_KEY_ECDSA_P384", AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, true}, {"NO_COMMIT_KEY", newAlgorithmSuite(0x0302, aes_256_GCM_IV12_TAG16, 2, hkdf_SHA512, authSuite_NONE), false}, @@ -176,6 +190,7 @@ func TestAlgorithmSuite_AlgorithmSuiteDataLen(t *testing.T) { alg *AlgorithmSuite want int }{ + {"HKDF_SHA256", AES_256_GCM_IV12_TAG16_HKDF_SHA256, 0}, {"COMMIT_KEY", AES_256_GCM_HKDF_SHA512_COMMIT_KEY, 32}, {"COMMIT_KEY_ECDSA_P384", AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 32}, } @@ -212,6 +227,15 @@ func TestAlgorithmSuite_Name(t *testing.T) { alg *AlgorithmSuite want string }{ + {"AES_128_GCM_IV12_TAG16", AES_128_GCM_IV12_TAG16, "AES_128_GCM_IV12_TAG16"}, + {"AES_192_GCM_IV12_TAG16", AES_192_GCM_IV12_TAG16, "AES_192_GCM_IV12_TAG16"}, + {"AES_256_GCM_IV12_TAG16", AES_256_GCM_IV12_TAG16, "AES_256_GCM_IV12_TAG16"}, + {"AES_128_GCM_IV12_TAG16_HKDF_SHA256", AES_128_GCM_IV12_TAG16_HKDF_SHA256, "AES_128_GCM_IV12_TAG16_HKDF_SHA256"}, + {"AES_192_GCM_IV12_TAG16_HKDF_SHA256", AES_192_GCM_IV12_TAG16_HKDF_SHA256, "AES_192_GCM_IV12_TAG16_HKDF_SHA256"}, + {"AES_256_GCM_IV12_TAG16_HKDF_SHA256", AES_256_GCM_IV12_TAG16_HKDF_SHA256, "AES_256_GCM_IV12_TAG16_HKDF_SHA256"}, + {"AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256", AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256, "AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256"}, + {"AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384", AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, "AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384"}, + {"AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384", AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, "AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384"}, {"AES_256_GCM_HKDF_SHA512_COMMIT_KEY", AES_256_GCM_HKDF_SHA512_COMMIT_KEY, "AES_256_GCM_HKDF_SHA512_COMMIT_KEY"}, {"AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384", AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, "AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384"}, } @@ -228,6 +252,9 @@ func TestAlgorithmSuite_String(t *testing.T) { alg *AlgorithmSuite want string }{ + {"AES_128_GCM_IV12_TAG16", AES_128_GCM_IV12_TAG16, "AlgID 0x0014: AES_128_GCM_IV12_TAG16"}, + {"AES_256_GCM_IV12_TAG16", AES_256_GCM_IV12_TAG16, "AlgID 0x0078: AES_256_GCM_IV12_TAG16"}, + {"AES_256_GCM_IV12_TAG16_HKDF_SHA256", AES_256_GCM_IV12_TAG16_HKDF_SHA256, "AlgID 0x0178: AES_256_GCM_IV12_TAG16_HKDF_SHA256"}, {"COMMIT_KEY", AES_256_GCM_HKDF_SHA512_COMMIT_KEY, "AlgID 0x0478: AES_256_GCM_HKDF_SHA512_COMMIT_KEY"}, {"COMMIT_KEY_ECDSA_P384", AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, "AlgID 0x0578: AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384"}, } @@ -237,3 +264,65 @@ func TestAlgorithmSuite_String(t *testing.T) { }) } } + +func TestAlgorithmSuite_GoString(t *testing.T) { + tests := []struct { + name string + alg *AlgorithmSuite + want string + }{ + { + name: "COMMIT_KEY_ECDSA_P384", + alg: AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + want: fmt.Sprintf("%#v", AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, fmt.Sprintf("%#v", tt.alg)) + }) + } +} + +func TestAlgorithmSuite_IDString(t *testing.T) { + tests := []struct { + name string + alg *AlgorithmSuite + want string + }{ + {"0014_AES_128_GCM_IV12_TAG16", AES_128_GCM_IV12_TAG16, "0014"}, + {"0078_AES_256_GCM_IV12_TAG16", AES_256_GCM_IV12_TAG16, "0078"}, + {"0178_AES_256_GCM_IV12_TAG16_HKDF_SHA256", AES_256_GCM_IV12_TAG16_HKDF_SHA256, "0178"}, + {"0478_COMMIT_KEY", AES_256_GCM_HKDF_SHA512_COMMIT_KEY, "0478"}, + {"0578_COMMIT_KEY_ECDSA_P384", AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, "0578"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, tt.alg.IDString(), "IDString()") + }) + } +} + +func TestAlgorithmSuite_IsKDFSupported(t *testing.T) { + tests := []struct { + name string + alg *AlgorithmSuite + want bool + }{ + {"0014_KDF_not_supported", AES_128_GCM_IV12_TAG16, false}, + {"0046_KDF_not_supported", AES_192_GCM_IV12_TAG16, false}, + {"0078_KDF_not_supported", AES_256_GCM_IV12_TAG16, false}, + {"0146_KDF_supported", AES_192_GCM_IV12_TAG16_HKDF_SHA256, true}, + {"0214_KDF_supported", AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256, true}, + {"0478_KDF_supported", AES_256_GCM_HKDF_SHA512_COMMIT_KEY, true}, + {"0578_KDF_supported", AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.alg.IsKDFSupported(); got != tt.want { + t.Errorf("IsKDFSupported() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/suite/consts.go b/pkg/suite/consts.go index 95d0480..0bfdca3 100644 --- a/pkg/suite/consts.go +++ b/pkg/suite/consts.go @@ -3,11 +3,14 @@ package suite -import "math" +import ( + "math" +) const ( - MinFrameSize = int(128) - MaxFrameSize = math.MaxUint32 + MinFrameSize = int(128) // Minimum allowed frame size + MaxFrameSize = math.MaxInt32 // Maximum allowed frame size which is math.MaxInt32 + BlockSize = int(128) // BlockSize is aes.BlockSize in bits (16 * 8) ) type ContentType uint8 @@ -27,10 +30,10 @@ const ( type CommitmentPolicy int8 const ( - _commitmentPolicyNone CommitmentPolicy = iota - 1 // -1 is NONE - CommitmentPolicyForbidEncryptAllowDecrypt // 0 - FORBID_ENCRYPT_ALLOW_DECRYPT - CommitmentPolicyRequireEncryptAllowDecrypt // 1 - REQUIRE_ENCRYPT_ALLOW_DECRYPT - CommitmentPolicyRequireEncryptRequireDecrypt // 2 - REQUIRE_ENCRYPT_REQUIRE_DECRYPT + _commitmentPolicyNone CommitmentPolicy = iota // 0 is NONE + CommitmentPolicyForbidEncryptAllowDecrypt // 1 - FORBID_ENCRYPT_ALLOW_DECRYPT + CommitmentPolicyRequireEncryptAllowDecrypt // 2 - REQUIRE_ENCRYPT_ALLOW_DECRYPT + CommitmentPolicyRequireEncryptRequireDecrypt // 3 - REQUIRE_ENCRYPT_REQUIRE_DECRYPT ) func (cp CommitmentPolicy) String() string { @@ -51,3 +54,16 @@ func (cp CommitmentPolicy) String() string { func (cp CommitmentPolicy) GoString() string { return cp.String() } + +type MessageFormatVersion uint8 + +const ( + V1 MessageFormatVersion = iota + 1 // 1 is V1 MessageFormatVersion + V2 // 2 is V2 MessageFormatVersion +) + +type MessageType int + +const ( + CustomerAEData MessageType = 128 // 128 is 80 in hex +) diff --git a/pkg/suite/consts_test.go b/pkg/suite/consts_test.go index 74ef94b..c3ca622 100644 --- a/pkg/suite/consts_test.go +++ b/pkg/suite/consts_test.go @@ -4,6 +4,7 @@ package suite import ( + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -11,21 +12,24 @@ import ( func TestCommitmentPolicy_String(t *testing.T) { tests := []struct { - name string - commitment CommitmentPolicy - expectedString string + name string + commitment CommitmentPolicy + wantString string + wantNum int }{ - {name: "CommitmentPolicy NONE", commitment: _commitmentPolicyNone, expectedString: "NONE"}, - {name: "CommitmentPolicy FORBID_ENCRYPT_ALLOW_DECRYPT", commitment: CommitmentPolicyForbidEncryptAllowDecrypt, expectedString: "FORBID_ENCRYPT_ALLOW_DECRYPT"}, - {name: "CommitmentPolicy REQUIRE_ENCRYPT_ALLOW_DECRYPT", commitment: CommitmentPolicyRequireEncryptAllowDecrypt, expectedString: "REQUIRE_ENCRYPT_ALLOW_DECRYPT"}, - {name: "CommitmentPolicy REQUIRE_ENCRYPT_REQUIRE_DECRYPT", commitment: CommitmentPolicyRequireEncryptRequireDecrypt, expectedString: "REQUIRE_ENCRYPT_REQUIRE_DECRYPT"}, + {name: "CommitmentPolicy NONE", commitment: _commitmentPolicyNone, wantString: "NONE", wantNum: 0}, + {name: "CommitmentPolicy FORBID_ENCRYPT_ALLOW_DECRYPT", commitment: CommitmentPolicyForbidEncryptAllowDecrypt, wantString: "FORBID_ENCRYPT_ALLOW_DECRYPT", wantNum: 1}, + {name: "CommitmentPolicy REQUIRE_ENCRYPT_ALLOW_DECRYPT", commitment: CommitmentPolicyRequireEncryptAllowDecrypt, wantString: "REQUIRE_ENCRYPT_ALLOW_DECRYPT", wantNum: 2}, + {name: "CommitmentPolicy REQUIRE_ENCRYPT_REQUIRE_DECRYPT", commitment: CommitmentPolicyRequireEncryptRequireDecrypt, wantString: "REQUIRE_ENCRYPT_REQUIRE_DECRYPT", wantNum: 3}, // a value not defined in our constants - {name: "Unknown CommitmentPolicy (fallback)", commitment: CommitmentPolicy(10), expectedString: "NONE"}, + {name: "Unknown CommitmentPolicy (fallback)", commitment: CommitmentPolicy(10), wantString: "NONE", wantNum: 10}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.expectedString, tt.commitment.String()) + assert.Equal(t, tt.wantString, tt.commitment.String()) + assert.Equal(t, tt.wantString, fmt.Sprintf("%#v", tt.commitment)) + assert.Equal(t, tt.wantNum, int(tt.commitment)) }) } } diff --git a/pkg/suite/validate.go b/pkg/suite/validate.go new file mode 100644 index 0000000..3ae218e --- /dev/null +++ b/pkg/suite/validate.go @@ -0,0 +1,50 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package suite + +import "fmt" + +func ValidateMessageVersion(v uint8) error { + version := MessageFormatVersion(v) + if version != V1 && version != V2 { + return fmt.Errorf("invalid message format version %v", v) + } + return nil +} + +func ValidateContentType(t ContentType) error { + if t != FramedContent { + return fmt.Errorf("ContentType %v not supported", t) + } + return nil +} + +func ValidateCommitmentPolicy(p CommitmentPolicy) error { + if p < CommitmentPolicyForbidEncryptAllowDecrypt || p > CommitmentPolicyRequireEncryptRequireDecrypt { + return fmt.Errorf("invalid CommitmentPolicy %v", p) + } + return nil +} + +// ValidateFrameLength validates the length of a frame. +// It checks if the frame length is within the allowed range and if it is +// a multiple of the block size of the crypto algorithm. +// +// If the frame length is out of range or not a multiple of the [BlockSize] +// (128), an error is returned. +// The allowed minimum frame size is [MinFrameSize] (128). +// +// The allowed maximum frame size is [MaxFrameSize] the maximum value of +// a signed 32-bit integer. +// +// The block size of the crypto algorithm is [BlockSize] 128. +func ValidateFrameLength(frameLength int) error { + if frameLength < MinFrameSize || frameLength%BlockSize != 0 { + return fmt.Errorf("frame length must be larger than %d and a multiple of the block size of the crypto algorithm: %d", MinFrameSize, BlockSize) + } + if frameLength > MaxFrameSize { + return fmt.Errorf("frame length too large: %d > %d", frameLength, MaxFrameSize) + } + return nil +} diff --git a/pkg/suite/validate_test.go b/pkg/suite/validate_test.go new file mode 100644 index 0000000..c74723b --- /dev/null +++ b/pkg/suite/validate_test.go @@ -0,0 +1,109 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package suite_test + +import ( + "fmt" + "math" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" +) + +func TestValidateMessageVersion(t *testing.T) { + errFormatFn := func(version suite.MessageFormatVersion) error { + return fmt.Errorf("invalid message format version %d", version) + } + tests := []struct { + name string + version suite.MessageFormatVersion + want error + }{ + {"Version_V1", suite.V1, nil}, + {"Version_V2", suite.V2, nil}, + {"Version_255", math.MaxUint8, errFormatFn(math.MaxUint8)}, + {"Version_0", 0, errFormatFn(0)}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := suite.ValidateMessageVersion(uint8(tt.version)) + assert.Equal(t, tt.want, err) + }) + } +} + +func TestValidateContentType(t *testing.T) { + errFormatFn := func(contentType suite.ContentType) error { + return fmt.Errorf("ContentType %d not supported", contentType) + } + tests := []struct { + name string + contentType suite.ContentType + want error + }{ + {"Framed Content", suite.FramedContent, nil}, + {"NonFramed Content", suite.NonFramedContent, errFormatFn(suite.NonFramedContent)}, + {"Unsupported Type", suite.ContentType(0), errFormatFn(0)}, + {"Max uint8", suite.ContentType(math.MaxUint8), errFormatFn(suite.ContentType(math.MaxUint8))}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := suite.ValidateContentType(tt.contentType) + assert.Equal(t, tt.want, err) + }) + } +} + +func TestValidateCommitmentPolicy(t *testing.T) { + type args struct { + p suite.CommitmentPolicy + } + tests := []struct { + name string + args args + wantErr assert.ErrorAssertionFunc + }{ + {"Unsupported Zero", args{suite.CommitmentPolicy(0)}, assert.Error}, + {"Unsupported Negative", args{suite.CommitmentPolicy(0)}, assert.Error}, + {"RequireEncryptAllowDecrypt", args{suite.CommitmentPolicyRequireEncryptAllowDecrypt}, assert.NoError}, + {"RequireEncryptRequireDecrypt", args{suite.CommitmentPolicyRequireEncryptRequireDecrypt}, assert.NoError}, + {"ForbidEncryptAllowDecrypt", args{suite.CommitmentPolicyForbidEncryptAllowDecrypt}, assert.NoError}, + {"Unsupported Max int8", args{suite.CommitmentPolicy(math.MaxInt8)}, assert.Error}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.wantErr(t, suite.ValidateCommitmentPolicy(tt.args.p), fmt.Sprintf("ValidateCommitmentPolicy(%v)", tt.args.p)) + }) + } +} + +func TestValidateFrameLength(t *testing.T) { + tests := []struct { + name string + frameLen int + wantErr bool + wantError string + }{ + {name: "ValidMinSize", frameLen: suite.MinFrameSize, wantErr: false}, + {name: "BelowMinSize", frameLen: suite.MinFrameSize - 1, wantErr: true, wantError: fmt.Sprintf("frame length must be larger than %d and a multiple of the block size of the crypto algorithm: %d", suite.MinFrameSize, suite.BlockSize)}, + {name: "ValidMaxSize", frameLen: suite.MaxFrameSize - 127, wantErr: false}, + {name: "AboveMaxSize", frameLen: suite.MaxFrameSize + 1, wantErr: true, wantError: fmt.Sprintf("frame length too large: %d > %d", suite.MaxFrameSize+1, suite.MaxFrameSize)}, + {name: "NonMultipleBlockSize", frameLen: suite.MinFrameSize + 1, wantErr: true, wantError: fmt.Sprintf("frame length must be larger than %d and a multiple of the block size of the crypto algorithm: %d", suite.MinFrameSize, suite.BlockSize)}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := suite.ValidateFrameLength(tt.frameLen) + if tt.wantErr { + assert.Error(t, err) + assert.Equal(t, tt.wantError, err.Error()) + } else { + assert.NoError(t, err) + } + }) + } +} From 276e887555d81605d81c09bea20aacffc4584398 Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 18:05:07 +0200 Subject: [PATCH 03/16] feat(kdf): Key derivation supports for non-committing (V1) algorithms --- pkg/utils/keyderivation/key_derivation.go | 47 +++++++++++++------ .../keyderivation/key_derivation_test.go | 32 ++++++++++--- 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/pkg/utils/keyderivation/key_derivation.go b/pkg/utils/keyderivation/key_derivation.go index f6a7e61..e925862 100644 --- a/pkg/utils/keyderivation/key_derivation.go +++ b/pkg/utils/keyderivation/key_derivation.go @@ -15,23 +15,43 @@ import ( var errKeyDerivation = errors.New("key derivation error") const ( - deriveKeyLabel = "DERIVEKEY" // label to calculate the derived key - commitLabel = "COMMITKEY" // label to calculate the commitment key - deriveKeyKdfInfoSize = 11 // 2 bytes AlgorithmID(uint16) + 9 bytes deriveKeyLabel label - commitKdfInfoSize = 9 // 9 bytes commitLabel - lengthCommit = 32 // used in serialization to calculate the commitment key length + deriveKeyLabel = "DERIVEKEY" // label to calculate the derived key + commitLabel = "COMMITKEY" // label to calculate the commitment key + deriveKeyKdfInfoV1Size = 18 // 2 bytes AlgorithmID(uint16) + 16 bytes messageID used in V1 + deriveKeyKdfInfoV2Size = 11 // 2 bytes AlgorithmID(uint16) + 9 bytes deriveKeyLabel label + commitKdfInfoSize = 9 // 9 bytes commitLabel + lengthCommit = 32 // used in serialization to calculate the commitment key length ) func DeriveDataEncryptionKey(dataKey []byte, alg *suite.AlgorithmSuite, messageID []byte) ([]byte, error) { if err := validateInputs(dataKey, alg); err != nil { return nil, fmt.Errorf("validate error: %v: %w", err.Error(), errKeyDerivation) } + + // for algorithms that do not support KDF, the data key is the derived key + if !alg.IsKDFSupported() { + key := make([]byte, len(dataKey)) + copy(key, dataKey) + return key, nil + } + var buf []byte - buf = make([]byte, 0, deriveKeyKdfInfoSize) // 2 bytes AlgorithmID + 9 bytes label - buf = append(buf, conv.FromInt.UUint16BigEndian(alg.AlgorithmID)...) - buf = append(buf, []byte(deriveKeyLabel)...) + var kdf io.Reader + if alg.IsCommitting() { + buf = make([]byte, 0, deriveKeyKdfInfoV2Size) // 2 bytes AlgorithmID + 9 bytes label + buf = append(buf, conv.FromInt.UUint16BigEndian(alg.AlgorithmID)...) + buf = append(buf, []byte(deriveKeyLabel)...) - kdf := alg.KDFSuite.KDFFunc(alg.KDFSuite.HashFunc, dataKey, messageID, buf) + // hashFn, secret, salt, info + kdf = alg.KDFSuite.KDFFunc(alg.KDFSuite.HashFunc, dataKey, messageID, buf) + } else { + buf = make([]byte, 0, deriveKeyKdfInfoV1Size) // 2 bytes AlgorithmID(uint16) + 16 bytes messageID + buf = append(buf, conv.FromInt.UUint16BigEndian(alg.AlgorithmID)...) + buf = append(buf, messageID...) + + // hashFn, secret, salt, info + kdf = alg.KDFSuite.KDFFunc(alg.KDFSuite.HashFunc, dataKey, nil, buf) + } derivedKey := make([]byte, alg.EncryptionSuite.DataKeyLen) if _, err := io.ReadFull(kdf, derivedKey); err != nil { @@ -64,11 +84,10 @@ func validateInputs(dataKey []byte, alg *suite.AlgorithmSuite) error { if alg == nil { return fmt.Errorf("algorithm suite is nil") } - if alg.KDFSuite.KDFFunc == nil { - return fmt.Errorf("kdf suite func is nil") - } - if alg.KDFSuite.HashFunc == nil { - return fmt.Errorf("hash func is nil") + if alg.IsKDFSupported() { + if alg.KDFSuite.HashFunc == nil { + return fmt.Errorf("hash func is nil") + } } if alg.EncryptionSuite.DataKeyLen == 0 { return fmt.Errorf("data key length is invalid") diff --git a/pkg/utils/keyderivation/key_derivation_test.go b/pkg/utils/keyderivation/key_derivation_test.go index 4935c1d..498eca3 100644 --- a/pkg/utils/keyderivation/key_derivation_test.go +++ b/pkg/utils/keyderivation/key_derivation_test.go @@ -4,7 +4,10 @@ package keyderivation import ( + "bytes" "crypto/sha512" + "hash" + "io" "testing" "github.com/stretchr/testify/assert" @@ -15,23 +18,39 @@ import ( ) func Test_DeriveDataEncryptionKey(t *testing.T) { + mockEOFKdfFunc := func(hash func() hash.Hash, secret, salt, info []byte) io.Reader { + return bytes.NewReader([]byte{0x00}) + } tests := []struct { name string + wantErr bool dk []byte alg *suite.AlgorithmSuite messageID []byte want []byte }{ - {"key1", []byte{0x01}, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY, []byte{}, []byte{0xc8, 0xdb, 0xb9, 0x26, 0xc7, 0xa4, 0xf9, 0xc9, 0x60, 0x6, 0x90, 0x34, 0x2d, 0xf6, 0x74, 0xd7, 0xf9, 0xb9, 0xb8, 0x20, 0x70, 0x5f, 0xe3, 0xfc, 0x84, 0x4b, 0x8f, 0x71, 0x8b, 0xca, 0x5, 0x2a}}, - {"key2", []byte{0x01}, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY, []byte{0x01}, []byte{0xd4, 0xfd, 0xcf, 0x9, 0x81, 0xa, 0x67, 0x64, 0xdd, 0xe7, 0x4d, 0x52, 0x42, 0xdf, 0x1c, 0x23, 0xfa, 0x3, 0x41, 0xaa, 0x7b, 0x58, 0x23, 0xf0, 0xf1, 0x69, 0xdc, 0x39, 0x36, 0xd9, 0x0, 0x78}}, - {"key3", []byte{0x02}, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY, []byte{}, []byte{0x5d, 0x2, 0x70, 0x41, 0x30, 0x42, 0x1e, 0xee, 0x1d, 0x4, 0xae, 0x6a, 0xdb, 0x1, 0x9d, 0x8, 0x67, 0xea, 0x77, 0x5b, 0x3e, 0x2f, 0xdc, 0xb4, 0xfe, 0x31, 0x16, 0xbf, 0xa9, 0xa6, 0x3d, 0x79}}, - {"key4_nil_messageID", []byte{0x02}, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY, nil, []byte{0x5d, 0x2, 0x70, 0x41, 0x30, 0x42, 0x1e, 0xee, 0x1d, 0x4, 0xae, 0x6a, 0xdb, 0x1, 0x9d, 0x8, 0x67, 0xea, 0x77, 0x5b, 0x3e, 0x2f, 0xdc, 0xb4, 0xfe, 0x31, 0x16, 0xbf, 0xa9, 0xa6, 0x3d, 0x79}}, - {"key5_rawDataKey", []byte("raw1DataKeyRAWRAWRAW_12345678901"), suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, nil, []byte{0xa6, 0x85, 0x3b, 0xd4, 0xa6, 0x83, 0xb4, 0xc0, 0xc7, 0x27, 0xc5, 0x75, 0xc7, 0xf, 0x66, 0x76, 0x73, 0x3b, 0x6, 0xb1, 0x1e, 0xd6, 0xcb, 0xeb, 0xa8, 0xee, 0x68, 0xa2, 0xe3, 0x26, 0xd6, 0x9d}}, - {"key6_rawDataKey2", []byte("raw2DataKeyRAWRAWRAW_12345678902"), suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, nil, []byte{0xb, 0xd0, 0xc9, 0xfb, 0x61, 0x3b, 0xb, 0x30, 0xcb, 0x27, 0x65, 0xf3, 0xb5, 0x99, 0xdc, 0x61, 0xeb, 0xc6, 0x70, 0x7f, 0xcb, 0xba, 0xb2, 0x9d, 0x37, 0x18, 0x90, 0x10, 0x27, 0xdf, 0x5d, 0x67}}, + {"key1", false, []byte{0x01}, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY, []byte{}, []byte{0xc8, 0xdb, 0xb9, 0x26, 0xc7, 0xa4, 0xf9, 0xc9, 0x60, 0x6, 0x90, 0x34, 0x2d, 0xf6, 0x74, 0xd7, 0xf9, 0xb9, 0xb8, 0x20, 0x70, 0x5f, 0xe3, 0xfc, 0x84, 0x4b, 0x8f, 0x71, 0x8b, 0xca, 0x5, 0x2a}}, + {"key2", false, []byte{0x01}, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY, []byte{0x01}, []byte{0xd4, 0xfd, 0xcf, 0x9, 0x81, 0xa, 0x67, 0x64, 0xdd, 0xe7, 0x4d, 0x52, 0x42, 0xdf, 0x1c, 0x23, 0xfa, 0x3, 0x41, 0xaa, 0x7b, 0x58, 0x23, 0xf0, 0xf1, 0x69, 0xdc, 0x39, 0x36, 0xd9, 0x0, 0x78}}, + {"key3", false, []byte{0x02}, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY, []byte{}, []byte{0x5d, 0x2, 0x70, 0x41, 0x30, 0x42, 0x1e, 0xee, 0x1d, 0x4, 0xae, 0x6a, 0xdb, 0x1, 0x9d, 0x8, 0x67, 0xea, 0x77, 0x5b, 0x3e, 0x2f, 0xdc, 0xb4, 0xfe, 0x31, 0x16, 0xbf, 0xa9, 0xa6, 0x3d, 0x79}}, + {"key4_nil_messageID", false, []byte{0x02}, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY, nil, []byte{0x5d, 0x2, 0x70, 0x41, 0x30, 0x42, 0x1e, 0xee, 0x1d, 0x4, 0xae, 0x6a, 0xdb, 0x1, 0x9d, 0x8, 0x67, 0xea, 0x77, 0x5b, 0x3e, 0x2f, 0xdc, 0xb4, 0xfe, 0x31, 0x16, 0xbf, 0xa9, 0xa6, 0x3d, 0x79}}, + {"key5_rawDataKey", false, []byte("raw1DataKeyRAWRAWRAW_12345678901"), suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, nil, []byte{0xa6, 0x85, 0x3b, 0xd4, 0xa6, 0x83, 0xb4, 0xc0, 0xc7, 0x27, 0xc5, 0x75, 0xc7, 0xf, 0x66, 0x76, 0x73, 0x3b, 0x6, 0xb1, 0x1e, 0xd6, 0xcb, 0xeb, 0xa8, 0xee, 0x68, 0xa2, 0xe3, 0x26, 0xd6, 0x9d}}, + {"key6_rawDataKey2", false, []byte("raw2DataKeyRAWRAWRAW_12345678902"), suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, nil, []byte{0xb, 0xd0, 0xc9, 0xfb, 0x61, 0x3b, 0xb, 0x30, 0xcb, 0x27, 0x65, 0xf3, 0xb5, 0x99, 0xdc, 0x61, 0xeb, 0xc6, 0x70, 0x7f, 0xcb, 0xba, 0xb2, 0x9d, 0x37, 0x18, 0x90, 0x10, 0x27, 0xdf, 0x5d, 0x67}}, + {"key7_128_not_committing", false, []byte{0x01}, suite.AES_128_GCM_IV12_TAG16_HKDF_SHA256, []byte{0x01}, []byte{0x68, 0x0, 0x2, 0x64, 0x4b, 0x71, 0x8d, 0x22, 0xa5, 0x8b, 0xd2, 0xe5, 0x6, 0x4, 0x9b, 0xc4}}, + {"key8_256_not_committing", false, []byte{0x02}, suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, []byte{0x03}, []byte{0x9b, 0xc5, 0x7c, 0x90, 0x4d, 0xe3, 0xab, 0x1e, 0xd2, 0x76, 0x6e, 0xb3, 0xe9, 0x7b, 0x46, 0xcd, 0xaa, 0xe8, 0x2c, 0x5, 0xf1, 0x7, 0xa0, 0xe8, 0x3a, 0x6e, 0x4e, 0xbd, 0x47, 0xac, 0x11, 0x82}}, + {"key9_128_without_KDF", false, make([]byte, 16), suite.AES_128_GCM_IV12_TAG16, []byte{0x03}, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, + {"key10_256_without_KDF", false, make([]byte, 32), suite.AES_256_GCM_IV12_TAG16, []byte{0x03}, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, + {"nil_data_key", true, nil, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY, nil, nil}, + {"committing_kdf_error", true, []byte{0x02}, &suite.AlgorithmSuite{AlgorithmID: 0x0478, KDFSuite: suite.NewKdfSuite(mockEOFKdfFunc, sha512.New), EncryptionSuite: suite.NewEncryptionSuite("", "", 16, 0, 0)}, nil, nil}, + {"non_committing_kdf_error", true, []byte{0x04}, &suite.AlgorithmSuite{AlgorithmID: 0x0178, KDFSuite: suite.NewKdfSuite(mockEOFKdfFunc, sha512.New), EncryptionSuite: suite.NewEncryptionSuite("", "", 16, 0, 0)}, nil, nil}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, err := DeriveDataEncryptionKey(tt.dk, tt.alg, tt.messageID) + if tt.wantErr { + assert.Nil(t, got) + require.Error(t, err) + return + } assert.NoError(t, err) assert.Len(t, got, tt.alg.EncryptionSuite.DataKeyLen) assert.Equal(t, tt.want, got) @@ -48,7 +67,6 @@ func Test_validateInputs(t *testing.T) { alg *suite.AlgorithmSuite }{ {"nil", true, "algorithm suite is nil", []byte{0x01}, nil}, - {"nil_kdf_suite", true, "kdf suite func is nil", []byte{0x01}, &suite.AlgorithmSuite{AlgorithmID: 0x0058, KDFSuite: suite.NewKdfSuite(nil, nil), EncryptionSuite: suite.NewEncryptionSuite("", "", 0, 0, 0)}}, {"nil_kdf_hash", true, "hash func is nil", []byte{0x01}, &suite.AlgorithmSuite{AlgorithmID: 0x0058, KDFSuite: suite.NewKdfSuite(hkdf.New, nil), EncryptionSuite: suite.NewEncryptionSuite("", "", 0, 0, 0)}}, {"invalid_data_key_len", true, "data key length is invalid", []byte{0x01}, &suite.AlgorithmSuite{AlgorithmID: 0x0058, KDFSuite: suite.NewKdfSuite(hkdf.New, sha512.New), EncryptionSuite: suite.NewEncryptionSuite("", "", 0, 0, 0)}}, {"invalid_data_key", true, "data key is empty", nil, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384}, From 4dd14cf811808233aa74797bd9639cf24bd4f417 Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 18:07:03 +0200 Subject: [PATCH 04/16] feat(encryption): return IV for header authentication V1 --- pkg/utils/encryption/gcm.go | 11 ++++++----- pkg/utils/encryption/gcm_test.go | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pkg/utils/encryption/gcm.go b/pkg/utils/encryption/gcm.go index d63265f..c047afc 100644 --- a/pkg/utils/encryption/gcm.go +++ b/pkg/utils/encryption/gcm.go @@ -37,7 +37,7 @@ type GcmBase interface { type AEADEncrypter interface { Encrypter - GenerateHeaderAuth(derivedDataKey, headerBytes []byte) ([]byte, error) + GenerateHeaderAuth(derivedDataKey, headerBytes []byte) ([]byte, []byte, error) ConstructIV(seqNum int) []byte } @@ -131,13 +131,14 @@ func (ge Gcm) ValidateHeaderAuth(derivedDataKey, headerAuthTag, headerBytes []by return nil } -func (ge Gcm) GenerateHeaderAuth(derivedDataKey, headerBytes []byte) ([]byte, error) { - _, headerAuth, err := ge.Encrypt(derivedDataKey, ge.ConstructIV(0), []byte(nil), headerBytes) +func (ge Gcm) GenerateHeaderAuth(derivedDataKey, headerBytes []byte) ([]byte, []byte, error) { + iv := ge.ConstructIV(0) + _, headerAuth, err := ge.Encrypt(derivedDataKey, iv, []byte(nil), headerBytes) if err != nil { - return nil, fmt.Errorf("invalid header auth: %w", err) + return nil, nil, fmt.Errorf("invalid header auth: %w", err) } - return headerAuth, nil + return headerAuth, iv, nil } // ConstructIV constructs IV diff --git a/pkg/utils/encryption/gcm_test.go b/pkg/utils/encryption/gcm_test.go index 71ef27d..e46fc33 100644 --- a/pkg/utils/encryption/gcm_test.go +++ b/pkg/utils/encryption/gcm_test.go @@ -71,7 +71,7 @@ func Test_Gcm_GenerateHeaderAuth(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ge := Gcm{} - got, err := ge.GenerateHeaderAuth(tt.args.derivedDataKey, tt.args.headerBytes) + got, _, err := ge.GenerateHeaderAuth(tt.args.derivedDataKey, tt.args.headerBytes) if (err != nil) != tt.wantErr { t.Errorf("GenerateHeaderAuth() error = %v, wantErr %v", err, tt.wantErr) return From 8c21b113f250db3d763fcae05596ce69f159cf34 Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 18:09:11 +0200 Subject: [PATCH 05/16] test(cmm): cover NewDefault with test --- pkg/materials/default_test.go | 84 +++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 pkg/materials/default_test.go diff --git a/pkg/materials/default_test.go b/pkg/materials/default_test.go new file mode 100644 index 0000000..40a526f --- /dev/null +++ b/pkg/materials/default_test.go @@ -0,0 +1,84 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package materials_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/chainifynet/aws-encryption-sdk-go/pkg/materials" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/types" +) + +type mockProvider struct { + model.MasterKeyProvider + ID string + Kind types.ProviderKind +} + +func (mock *mockProvider) ProviderID() string { + return mock.ID +} + +func (mock *mockProvider) ProviderKind() types.ProviderKind { + return mock.Kind +} + +func TestNewDefault(t *testing.T) { + tests := []struct { + name string + primary model.MasterKeyProvider + extra []model.MasterKeyProvider + wantErr bool + }{ + { + name: "Test with no extra providers", + primary: &mockProvider{ID: "provider1", Kind: types.AwsKms}, + extra: []model.MasterKeyProvider{}, + wantErr: false, + }, + { + name: "Test with extra providers with no duplicates", + primary: &mockProvider{ID: "provider1", Kind: types.AwsKms}, + extra: []model.MasterKeyProvider{ + &mockProvider{ID: "provider2", Kind: types.Raw}, + &mockProvider{ID: "provider3", Kind: types.AwsKms}, + }, + wantErr: false, + }, + { + name: "Test with extra Raw type providers having same ID", + primary: &mockProvider{ID: "provider1", Kind: types.AwsKms}, + extra: []model.MasterKeyProvider{ + &mockProvider{ID: "provider2", Kind: types.Raw}, + &mockProvider{ID: "provider2", Kind: types.Raw}, + }, + wantErr: true, + }, + { + name: "Test with primary and extra Raw type providers having same ID", + primary: &mockProvider{ID: "provider1", Kind: types.AwsKms}, + extra: []model.MasterKeyProvider{ + &mockProvider{ID: "provider1", Kind: types.Raw}, + &mockProvider{ID: "provider2", Kind: types.AwsKms}, + }, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := materials.NewDefault(tt.primary, tt.extra...) + if tt.wantErr { + assert.Error(t, err) + assert.Nil(t, result) + } else { + assert.NoError(t, err) + assert.NotNil(t, result) + } + }) + } +} From 22cf4c3729a4a25bbaa4dbaca5f0f9e63954fbfd Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 18:15:04 +0200 Subject: [PATCH 06/16] fix(deps): update examples deps --- example/basicEncryption/go.mod | 2 +- example/basicEncryption/go.sum | 2 ++ example/customAwsKmsConfig/go.mod | 8 ++++---- example/customAwsKmsConfig/go.sum | 8 ++++++++ example/discoveryFilterKmsProvider/go.mod | 8 ++++---- example/discoveryFilterKmsProvider/go.sum | 8 ++++++++ example/discoveryKmsProvider/go.mod | 8 ++++---- example/discoveryKmsProvider/go.sum | 8 ++++++++ example/mrkAwareKmsProvider/go.mod | 8 ++++---- example/mrkAwareKmsProvider/go.sum | 8 ++++++++ example/multipleKeyProvider/go.mod | 8 ++++---- example/multipleKeyProvider/go.sum | 8 ++++++++ example/multipleKmsKey/go.mod | 8 ++++---- example/multipleKmsKey/go.sum | 8 ++++++++ example/oneKmsKey/go.mod | 8 ++++---- example/oneKmsKey/go.sum | 8 ++++++++ example/oneKmsKeyUnsigned/go.mod | 8 ++++---- example/oneKmsKeyUnsigned/go.sum | 8 ++++++++ 18 files changed, 99 insertions(+), 33 deletions(-) diff --git a/example/basicEncryption/go.mod b/example/basicEncryption/go.mod index 8fee602..c71a469 100644 --- a/example/basicEncryption/go.mod +++ b/example/basicEncryption/go.mod @@ -8,7 +8,7 @@ require ( github.com/aws/aws-sdk-go-v2 v1.24.0 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect - github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 // indirect github.com/aws/smithy-go v1.19.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/example/basicEncryption/go.sum b/example/basicEncryption/go.sum index 54d6e7b..76f2a24 100644 --- a/example/basicEncryption/go.sum +++ b/example/basicEncryption/go.sum @@ -6,6 +6,8 @@ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 h1:N94sVhRACtXyVcjXxrw github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9/go.mod h1:hqamLz7g1/4EJP+GH5NBhcUMLjW+gKLQabgyz6/7WAU= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 h1:zzaFokMF7UVk22/Igtb93A1ReGP50uu99ldLWaEMfHc= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 h1:wN7AN7iOiAgT9HmdifZNSvbr6S7gSpLjSSOQHIaGmFc= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= diff --git a/example/customAwsKmsConfig/go.mod b/example/customAwsKmsConfig/go.mod index 935b2ff..941edb5 100644 --- a/example/customAwsKmsConfig/go.mod +++ b/example/customAwsKmsConfig/go.mod @@ -3,23 +3,23 @@ module github.com/chainifynet/aws-encryption-sdk-go/example/customAwsKmsConfig go 1.20 require ( - github.com/aws/aws-sdk-go-v2/config v1.26.1 + github.com/aws/aws-sdk-go-v2/config v1.26.2 github.com/chainifynet/aws-encryption-sdk-go v0.1.1 ) require ( github.com/aws/aws-sdk-go-v2 v1.24.0 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.16.12 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.13 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect - github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 // indirect github.com/aws/smithy-go v1.19.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/example/customAwsKmsConfig/go.sum b/example/customAwsKmsConfig/go.sum index be210fc..b6cefd7 100644 --- a/example/customAwsKmsConfig/go.sum +++ b/example/customAwsKmsConfig/go.sum @@ -2,8 +2,12 @@ github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7Aw github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/config v1.26.1 h1:z6DqMxclFGL3Zfo+4Q0rLnAZ6yVkzCRxhRMsiRQnD1o= github.com/aws/aws-sdk-go-v2/config v1.26.1/go.mod h1:ZB+CuKHRbb5v5F0oJtGdhFTelmrxd4iWO1lf0rQwSAg= +github.com/aws/aws-sdk-go-v2/config v1.26.2 h1:+RWLEIWQIGgrz2pBPAUoGgNGs1TOyF4Hml7hCnYj2jc= +github.com/aws/aws-sdk-go-v2/config v1.26.2/go.mod h1:l6xqvUxt0Oj7PI/SUXYLNyZ9T/yBPn3YTQcJLLOdtR8= github.com/aws/aws-sdk-go-v2/credentials v1.16.12 h1:v/WgB8NxprNvr5inKIiVVrXPuuTegM+K8nncFkr1usU= github.com/aws/aws-sdk-go-v2/credentials v1.16.12/go.mod h1:X21k0FjEJe+/pauud82HYiQbEr9jRKY3kXEIQ4hXeTQ= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13 h1:WLABQ4Cp4vXtXfOWOS3MEZKr6AAYUpMczLhgKtAjQ/8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13/go.mod h1:Qg6x82FXwW0sJHzYruxGiuApNo31UEtJvXVSZAXeWiw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 h1:w98BT5w+ao1/r5sUuiH6JkVzjowOKeOJRHERyy1vh58= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10/go.mod h1:K2WGI7vUvkIv1HoNbfBA1bvIZ+9kL3YVmWxeKuLQsiw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs= @@ -18,12 +22,16 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 h1:Nf2sHxjMJ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9/go.mod h1:idky4TER38YIjr2cADF1/ugFMKvZV7p//pVeV5LZbF0= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 h1:zzaFokMF7UVk22/Igtb93A1ReGP50uu99ldLWaEMfHc= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 h1:wN7AN7iOiAgT9HmdifZNSvbr6S7gSpLjSSOQHIaGmFc= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 h1:ldSFWz9tEHAwHNmjx2Cvy1MjP5/L9kNoR0skc6wyOOM= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5/go.mod h1:CaFfXLYL376jgbP7VKC96uFcU8Rlavak0UlAwk1Dlhc= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 h1:2k9KmFawS63euAkY4/ixVNsYYwrwnd5fIvgEKkfZFNM= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5/go.mod h1:W+nd4wWDVkSUIox9bacmkBP5NMFQeTJ/xqNabpzSR38= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 h1:5UYvv8JUvllZsRnfrcMQ+hJ9jNICmcgKPAO1CER25Wg= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 h1:HJeiuZ2fldpd0WqngyMR6KW7ofkXNLyOaHwEIGm39Cs= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= diff --git a/example/discoveryFilterKmsProvider/go.mod b/example/discoveryFilterKmsProvider/go.mod index b823d18..969a28b 100644 --- a/example/discoveryFilterKmsProvider/go.mod +++ b/example/discoveryFilterKmsProvider/go.mod @@ -6,18 +6,18 @@ require github.com/chainifynet/aws-encryption-sdk-go v0.1.1 require ( github.com/aws/aws-sdk-go-v2 v1.24.0 // indirect - github.com/aws/aws-sdk-go-v2/config v1.26.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.16.12 // indirect + github.com/aws/aws-sdk-go-v2/config v1.26.2 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.13 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect - github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 // indirect github.com/aws/smithy-go v1.19.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/example/discoveryFilterKmsProvider/go.sum b/example/discoveryFilterKmsProvider/go.sum index be210fc..b6cefd7 100644 --- a/example/discoveryFilterKmsProvider/go.sum +++ b/example/discoveryFilterKmsProvider/go.sum @@ -2,8 +2,12 @@ github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7Aw github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/config v1.26.1 h1:z6DqMxclFGL3Zfo+4Q0rLnAZ6yVkzCRxhRMsiRQnD1o= github.com/aws/aws-sdk-go-v2/config v1.26.1/go.mod h1:ZB+CuKHRbb5v5F0oJtGdhFTelmrxd4iWO1lf0rQwSAg= +github.com/aws/aws-sdk-go-v2/config v1.26.2 h1:+RWLEIWQIGgrz2pBPAUoGgNGs1TOyF4Hml7hCnYj2jc= +github.com/aws/aws-sdk-go-v2/config v1.26.2/go.mod h1:l6xqvUxt0Oj7PI/SUXYLNyZ9T/yBPn3YTQcJLLOdtR8= github.com/aws/aws-sdk-go-v2/credentials v1.16.12 h1:v/WgB8NxprNvr5inKIiVVrXPuuTegM+K8nncFkr1usU= github.com/aws/aws-sdk-go-v2/credentials v1.16.12/go.mod h1:X21k0FjEJe+/pauud82HYiQbEr9jRKY3kXEIQ4hXeTQ= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13 h1:WLABQ4Cp4vXtXfOWOS3MEZKr6AAYUpMczLhgKtAjQ/8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13/go.mod h1:Qg6x82FXwW0sJHzYruxGiuApNo31UEtJvXVSZAXeWiw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 h1:w98BT5w+ao1/r5sUuiH6JkVzjowOKeOJRHERyy1vh58= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10/go.mod h1:K2WGI7vUvkIv1HoNbfBA1bvIZ+9kL3YVmWxeKuLQsiw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs= @@ -18,12 +22,16 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 h1:Nf2sHxjMJ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9/go.mod h1:idky4TER38YIjr2cADF1/ugFMKvZV7p//pVeV5LZbF0= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 h1:zzaFokMF7UVk22/Igtb93A1ReGP50uu99ldLWaEMfHc= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 h1:wN7AN7iOiAgT9HmdifZNSvbr6S7gSpLjSSOQHIaGmFc= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 h1:ldSFWz9tEHAwHNmjx2Cvy1MjP5/L9kNoR0skc6wyOOM= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5/go.mod h1:CaFfXLYL376jgbP7VKC96uFcU8Rlavak0UlAwk1Dlhc= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 h1:2k9KmFawS63euAkY4/ixVNsYYwrwnd5fIvgEKkfZFNM= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5/go.mod h1:W+nd4wWDVkSUIox9bacmkBP5NMFQeTJ/xqNabpzSR38= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 h1:5UYvv8JUvllZsRnfrcMQ+hJ9jNICmcgKPAO1CER25Wg= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 h1:HJeiuZ2fldpd0WqngyMR6KW7ofkXNLyOaHwEIGm39Cs= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= diff --git a/example/discoveryKmsProvider/go.mod b/example/discoveryKmsProvider/go.mod index 272e025..b0e4d5a 100644 --- a/example/discoveryKmsProvider/go.mod +++ b/example/discoveryKmsProvider/go.mod @@ -3,23 +3,23 @@ module github.com/chainifynet/aws-encryption-sdk-go/example/discoveryKmsProvider go 1.20 require ( - github.com/aws/aws-sdk-go-v2/config v1.26.1 + github.com/aws/aws-sdk-go-v2/config v1.26.2 github.com/chainifynet/aws-encryption-sdk-go v0.1.1 ) require ( github.com/aws/aws-sdk-go-v2 v1.24.0 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.16.12 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.13 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect - github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 // indirect github.com/aws/smithy-go v1.19.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/example/discoveryKmsProvider/go.sum b/example/discoveryKmsProvider/go.sum index be210fc..b6cefd7 100644 --- a/example/discoveryKmsProvider/go.sum +++ b/example/discoveryKmsProvider/go.sum @@ -2,8 +2,12 @@ github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7Aw github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/config v1.26.1 h1:z6DqMxclFGL3Zfo+4Q0rLnAZ6yVkzCRxhRMsiRQnD1o= github.com/aws/aws-sdk-go-v2/config v1.26.1/go.mod h1:ZB+CuKHRbb5v5F0oJtGdhFTelmrxd4iWO1lf0rQwSAg= +github.com/aws/aws-sdk-go-v2/config v1.26.2 h1:+RWLEIWQIGgrz2pBPAUoGgNGs1TOyF4Hml7hCnYj2jc= +github.com/aws/aws-sdk-go-v2/config v1.26.2/go.mod h1:l6xqvUxt0Oj7PI/SUXYLNyZ9T/yBPn3YTQcJLLOdtR8= github.com/aws/aws-sdk-go-v2/credentials v1.16.12 h1:v/WgB8NxprNvr5inKIiVVrXPuuTegM+K8nncFkr1usU= github.com/aws/aws-sdk-go-v2/credentials v1.16.12/go.mod h1:X21k0FjEJe+/pauud82HYiQbEr9jRKY3kXEIQ4hXeTQ= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13 h1:WLABQ4Cp4vXtXfOWOS3MEZKr6AAYUpMczLhgKtAjQ/8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13/go.mod h1:Qg6x82FXwW0sJHzYruxGiuApNo31UEtJvXVSZAXeWiw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 h1:w98BT5w+ao1/r5sUuiH6JkVzjowOKeOJRHERyy1vh58= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10/go.mod h1:K2WGI7vUvkIv1HoNbfBA1bvIZ+9kL3YVmWxeKuLQsiw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs= @@ -18,12 +22,16 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 h1:Nf2sHxjMJ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9/go.mod h1:idky4TER38YIjr2cADF1/ugFMKvZV7p//pVeV5LZbF0= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 h1:zzaFokMF7UVk22/Igtb93A1ReGP50uu99ldLWaEMfHc= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 h1:wN7AN7iOiAgT9HmdifZNSvbr6S7gSpLjSSOQHIaGmFc= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 h1:ldSFWz9tEHAwHNmjx2Cvy1MjP5/L9kNoR0skc6wyOOM= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5/go.mod h1:CaFfXLYL376jgbP7VKC96uFcU8Rlavak0UlAwk1Dlhc= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 h1:2k9KmFawS63euAkY4/ixVNsYYwrwnd5fIvgEKkfZFNM= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5/go.mod h1:W+nd4wWDVkSUIox9bacmkBP5NMFQeTJ/xqNabpzSR38= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 h1:5UYvv8JUvllZsRnfrcMQ+hJ9jNICmcgKPAO1CER25Wg= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 h1:HJeiuZ2fldpd0WqngyMR6KW7ofkXNLyOaHwEIGm39Cs= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= diff --git a/example/mrkAwareKmsProvider/go.mod b/example/mrkAwareKmsProvider/go.mod index e95d131..6e44f3c 100644 --- a/example/mrkAwareKmsProvider/go.mod +++ b/example/mrkAwareKmsProvider/go.mod @@ -6,18 +6,18 @@ require github.com/chainifynet/aws-encryption-sdk-go v0.1.1 require ( github.com/aws/aws-sdk-go-v2 v1.24.0 // indirect - github.com/aws/aws-sdk-go-v2/config v1.26.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.16.12 // indirect + github.com/aws/aws-sdk-go-v2/config v1.26.2 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.13 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect - github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 // indirect github.com/aws/smithy-go v1.19.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/example/mrkAwareKmsProvider/go.sum b/example/mrkAwareKmsProvider/go.sum index be210fc..b6cefd7 100644 --- a/example/mrkAwareKmsProvider/go.sum +++ b/example/mrkAwareKmsProvider/go.sum @@ -2,8 +2,12 @@ github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7Aw github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/config v1.26.1 h1:z6DqMxclFGL3Zfo+4Q0rLnAZ6yVkzCRxhRMsiRQnD1o= github.com/aws/aws-sdk-go-v2/config v1.26.1/go.mod h1:ZB+CuKHRbb5v5F0oJtGdhFTelmrxd4iWO1lf0rQwSAg= +github.com/aws/aws-sdk-go-v2/config v1.26.2 h1:+RWLEIWQIGgrz2pBPAUoGgNGs1TOyF4Hml7hCnYj2jc= +github.com/aws/aws-sdk-go-v2/config v1.26.2/go.mod h1:l6xqvUxt0Oj7PI/SUXYLNyZ9T/yBPn3YTQcJLLOdtR8= github.com/aws/aws-sdk-go-v2/credentials v1.16.12 h1:v/WgB8NxprNvr5inKIiVVrXPuuTegM+K8nncFkr1usU= github.com/aws/aws-sdk-go-v2/credentials v1.16.12/go.mod h1:X21k0FjEJe+/pauud82HYiQbEr9jRKY3kXEIQ4hXeTQ= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13 h1:WLABQ4Cp4vXtXfOWOS3MEZKr6AAYUpMczLhgKtAjQ/8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13/go.mod h1:Qg6x82FXwW0sJHzYruxGiuApNo31UEtJvXVSZAXeWiw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 h1:w98BT5w+ao1/r5sUuiH6JkVzjowOKeOJRHERyy1vh58= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10/go.mod h1:K2WGI7vUvkIv1HoNbfBA1bvIZ+9kL3YVmWxeKuLQsiw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs= @@ -18,12 +22,16 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 h1:Nf2sHxjMJ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9/go.mod h1:idky4TER38YIjr2cADF1/ugFMKvZV7p//pVeV5LZbF0= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 h1:zzaFokMF7UVk22/Igtb93A1ReGP50uu99ldLWaEMfHc= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 h1:wN7AN7iOiAgT9HmdifZNSvbr6S7gSpLjSSOQHIaGmFc= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 h1:ldSFWz9tEHAwHNmjx2Cvy1MjP5/L9kNoR0skc6wyOOM= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5/go.mod h1:CaFfXLYL376jgbP7VKC96uFcU8Rlavak0UlAwk1Dlhc= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 h1:2k9KmFawS63euAkY4/ixVNsYYwrwnd5fIvgEKkfZFNM= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5/go.mod h1:W+nd4wWDVkSUIox9bacmkBP5NMFQeTJ/xqNabpzSR38= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 h1:5UYvv8JUvllZsRnfrcMQ+hJ9jNICmcgKPAO1CER25Wg= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 h1:HJeiuZ2fldpd0WqngyMR6KW7ofkXNLyOaHwEIGm39Cs= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= diff --git a/example/multipleKeyProvider/go.mod b/example/multipleKeyProvider/go.mod index e19c871..6865ece 100644 --- a/example/multipleKeyProvider/go.mod +++ b/example/multipleKeyProvider/go.mod @@ -6,18 +6,18 @@ require github.com/chainifynet/aws-encryption-sdk-go v0.1.1 require ( github.com/aws/aws-sdk-go-v2 v1.24.0 // indirect - github.com/aws/aws-sdk-go-v2/config v1.26.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.16.12 // indirect + github.com/aws/aws-sdk-go-v2/config v1.26.2 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.13 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect - github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 // indirect github.com/aws/smithy-go v1.19.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/example/multipleKeyProvider/go.sum b/example/multipleKeyProvider/go.sum index be210fc..b6cefd7 100644 --- a/example/multipleKeyProvider/go.sum +++ b/example/multipleKeyProvider/go.sum @@ -2,8 +2,12 @@ github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7Aw github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/config v1.26.1 h1:z6DqMxclFGL3Zfo+4Q0rLnAZ6yVkzCRxhRMsiRQnD1o= github.com/aws/aws-sdk-go-v2/config v1.26.1/go.mod h1:ZB+CuKHRbb5v5F0oJtGdhFTelmrxd4iWO1lf0rQwSAg= +github.com/aws/aws-sdk-go-v2/config v1.26.2 h1:+RWLEIWQIGgrz2pBPAUoGgNGs1TOyF4Hml7hCnYj2jc= +github.com/aws/aws-sdk-go-v2/config v1.26.2/go.mod h1:l6xqvUxt0Oj7PI/SUXYLNyZ9T/yBPn3YTQcJLLOdtR8= github.com/aws/aws-sdk-go-v2/credentials v1.16.12 h1:v/WgB8NxprNvr5inKIiVVrXPuuTegM+K8nncFkr1usU= github.com/aws/aws-sdk-go-v2/credentials v1.16.12/go.mod h1:X21k0FjEJe+/pauud82HYiQbEr9jRKY3kXEIQ4hXeTQ= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13 h1:WLABQ4Cp4vXtXfOWOS3MEZKr6AAYUpMczLhgKtAjQ/8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13/go.mod h1:Qg6x82FXwW0sJHzYruxGiuApNo31UEtJvXVSZAXeWiw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 h1:w98BT5w+ao1/r5sUuiH6JkVzjowOKeOJRHERyy1vh58= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10/go.mod h1:K2WGI7vUvkIv1HoNbfBA1bvIZ+9kL3YVmWxeKuLQsiw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs= @@ -18,12 +22,16 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 h1:Nf2sHxjMJ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9/go.mod h1:idky4TER38YIjr2cADF1/ugFMKvZV7p//pVeV5LZbF0= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 h1:zzaFokMF7UVk22/Igtb93A1ReGP50uu99ldLWaEMfHc= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 h1:wN7AN7iOiAgT9HmdifZNSvbr6S7gSpLjSSOQHIaGmFc= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 h1:ldSFWz9tEHAwHNmjx2Cvy1MjP5/L9kNoR0skc6wyOOM= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5/go.mod h1:CaFfXLYL376jgbP7VKC96uFcU8Rlavak0UlAwk1Dlhc= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 h1:2k9KmFawS63euAkY4/ixVNsYYwrwnd5fIvgEKkfZFNM= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5/go.mod h1:W+nd4wWDVkSUIox9bacmkBP5NMFQeTJ/xqNabpzSR38= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 h1:5UYvv8JUvllZsRnfrcMQ+hJ9jNICmcgKPAO1CER25Wg= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 h1:HJeiuZ2fldpd0WqngyMR6KW7ofkXNLyOaHwEIGm39Cs= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= diff --git a/example/multipleKmsKey/go.mod b/example/multipleKmsKey/go.mod index 945dc00..ee2d449 100644 --- a/example/multipleKmsKey/go.mod +++ b/example/multipleKmsKey/go.mod @@ -6,18 +6,18 @@ require github.com/chainifynet/aws-encryption-sdk-go v0.1.1 require ( github.com/aws/aws-sdk-go-v2 v1.24.0 // indirect - github.com/aws/aws-sdk-go-v2/config v1.26.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.16.12 // indirect + github.com/aws/aws-sdk-go-v2/config v1.26.2 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.13 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect - github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 // indirect github.com/aws/smithy-go v1.19.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/example/multipleKmsKey/go.sum b/example/multipleKmsKey/go.sum index be210fc..b6cefd7 100644 --- a/example/multipleKmsKey/go.sum +++ b/example/multipleKmsKey/go.sum @@ -2,8 +2,12 @@ github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7Aw github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/config v1.26.1 h1:z6DqMxclFGL3Zfo+4Q0rLnAZ6yVkzCRxhRMsiRQnD1o= github.com/aws/aws-sdk-go-v2/config v1.26.1/go.mod h1:ZB+CuKHRbb5v5F0oJtGdhFTelmrxd4iWO1lf0rQwSAg= +github.com/aws/aws-sdk-go-v2/config v1.26.2 h1:+RWLEIWQIGgrz2pBPAUoGgNGs1TOyF4Hml7hCnYj2jc= +github.com/aws/aws-sdk-go-v2/config v1.26.2/go.mod h1:l6xqvUxt0Oj7PI/SUXYLNyZ9T/yBPn3YTQcJLLOdtR8= github.com/aws/aws-sdk-go-v2/credentials v1.16.12 h1:v/WgB8NxprNvr5inKIiVVrXPuuTegM+K8nncFkr1usU= github.com/aws/aws-sdk-go-v2/credentials v1.16.12/go.mod h1:X21k0FjEJe+/pauud82HYiQbEr9jRKY3kXEIQ4hXeTQ= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13 h1:WLABQ4Cp4vXtXfOWOS3MEZKr6AAYUpMczLhgKtAjQ/8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13/go.mod h1:Qg6x82FXwW0sJHzYruxGiuApNo31UEtJvXVSZAXeWiw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 h1:w98BT5w+ao1/r5sUuiH6JkVzjowOKeOJRHERyy1vh58= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10/go.mod h1:K2WGI7vUvkIv1HoNbfBA1bvIZ+9kL3YVmWxeKuLQsiw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs= @@ -18,12 +22,16 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 h1:Nf2sHxjMJ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9/go.mod h1:idky4TER38YIjr2cADF1/ugFMKvZV7p//pVeV5LZbF0= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 h1:zzaFokMF7UVk22/Igtb93A1ReGP50uu99ldLWaEMfHc= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 h1:wN7AN7iOiAgT9HmdifZNSvbr6S7gSpLjSSOQHIaGmFc= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 h1:ldSFWz9tEHAwHNmjx2Cvy1MjP5/L9kNoR0skc6wyOOM= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5/go.mod h1:CaFfXLYL376jgbP7VKC96uFcU8Rlavak0UlAwk1Dlhc= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 h1:2k9KmFawS63euAkY4/ixVNsYYwrwnd5fIvgEKkfZFNM= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5/go.mod h1:W+nd4wWDVkSUIox9bacmkBP5NMFQeTJ/xqNabpzSR38= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 h1:5UYvv8JUvllZsRnfrcMQ+hJ9jNICmcgKPAO1CER25Wg= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 h1:HJeiuZ2fldpd0WqngyMR6KW7ofkXNLyOaHwEIGm39Cs= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= diff --git a/example/oneKmsKey/go.mod b/example/oneKmsKey/go.mod index 471797e..159c99d 100644 --- a/example/oneKmsKey/go.mod +++ b/example/oneKmsKey/go.mod @@ -6,18 +6,18 @@ require github.com/chainifynet/aws-encryption-sdk-go v0.1.1 require ( github.com/aws/aws-sdk-go-v2 v1.24.0 // indirect - github.com/aws/aws-sdk-go-v2/config v1.26.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.16.12 // indirect + github.com/aws/aws-sdk-go-v2/config v1.26.2 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.13 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect - github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 // indirect github.com/aws/smithy-go v1.19.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/example/oneKmsKey/go.sum b/example/oneKmsKey/go.sum index be210fc..b6cefd7 100644 --- a/example/oneKmsKey/go.sum +++ b/example/oneKmsKey/go.sum @@ -2,8 +2,12 @@ github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7Aw github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/config v1.26.1 h1:z6DqMxclFGL3Zfo+4Q0rLnAZ6yVkzCRxhRMsiRQnD1o= github.com/aws/aws-sdk-go-v2/config v1.26.1/go.mod h1:ZB+CuKHRbb5v5F0oJtGdhFTelmrxd4iWO1lf0rQwSAg= +github.com/aws/aws-sdk-go-v2/config v1.26.2 h1:+RWLEIWQIGgrz2pBPAUoGgNGs1TOyF4Hml7hCnYj2jc= +github.com/aws/aws-sdk-go-v2/config v1.26.2/go.mod h1:l6xqvUxt0Oj7PI/SUXYLNyZ9T/yBPn3YTQcJLLOdtR8= github.com/aws/aws-sdk-go-v2/credentials v1.16.12 h1:v/WgB8NxprNvr5inKIiVVrXPuuTegM+K8nncFkr1usU= github.com/aws/aws-sdk-go-v2/credentials v1.16.12/go.mod h1:X21k0FjEJe+/pauud82HYiQbEr9jRKY3kXEIQ4hXeTQ= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13 h1:WLABQ4Cp4vXtXfOWOS3MEZKr6AAYUpMczLhgKtAjQ/8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13/go.mod h1:Qg6x82FXwW0sJHzYruxGiuApNo31UEtJvXVSZAXeWiw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 h1:w98BT5w+ao1/r5sUuiH6JkVzjowOKeOJRHERyy1vh58= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10/go.mod h1:K2WGI7vUvkIv1HoNbfBA1bvIZ+9kL3YVmWxeKuLQsiw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs= @@ -18,12 +22,16 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 h1:Nf2sHxjMJ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9/go.mod h1:idky4TER38YIjr2cADF1/ugFMKvZV7p//pVeV5LZbF0= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 h1:zzaFokMF7UVk22/Igtb93A1ReGP50uu99ldLWaEMfHc= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 h1:wN7AN7iOiAgT9HmdifZNSvbr6S7gSpLjSSOQHIaGmFc= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 h1:ldSFWz9tEHAwHNmjx2Cvy1MjP5/L9kNoR0skc6wyOOM= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5/go.mod h1:CaFfXLYL376jgbP7VKC96uFcU8Rlavak0UlAwk1Dlhc= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 h1:2k9KmFawS63euAkY4/ixVNsYYwrwnd5fIvgEKkfZFNM= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5/go.mod h1:W+nd4wWDVkSUIox9bacmkBP5NMFQeTJ/xqNabpzSR38= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 h1:5UYvv8JUvllZsRnfrcMQ+hJ9jNICmcgKPAO1CER25Wg= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 h1:HJeiuZ2fldpd0WqngyMR6KW7ofkXNLyOaHwEIGm39Cs= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= diff --git a/example/oneKmsKeyUnsigned/go.mod b/example/oneKmsKeyUnsigned/go.mod index 0a6c0bf..e1149a7 100644 --- a/example/oneKmsKeyUnsigned/go.mod +++ b/example/oneKmsKeyUnsigned/go.mod @@ -6,18 +6,18 @@ require github.com/chainifynet/aws-encryption-sdk-go v0.1.1 require ( github.com/aws/aws-sdk-go-v2 v1.24.0 // indirect - github.com/aws/aws-sdk-go-v2/config v1.26.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.16.12 // indirect + github.com/aws/aws-sdk-go-v2/config v1.26.2 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.13 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect - github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 // indirect github.com/aws/smithy-go v1.19.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/example/oneKmsKeyUnsigned/go.sum b/example/oneKmsKeyUnsigned/go.sum index be210fc..b6cefd7 100644 --- a/example/oneKmsKeyUnsigned/go.sum +++ b/example/oneKmsKeyUnsigned/go.sum @@ -2,8 +2,12 @@ github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7Aw github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/config v1.26.1 h1:z6DqMxclFGL3Zfo+4Q0rLnAZ6yVkzCRxhRMsiRQnD1o= github.com/aws/aws-sdk-go-v2/config v1.26.1/go.mod h1:ZB+CuKHRbb5v5F0oJtGdhFTelmrxd4iWO1lf0rQwSAg= +github.com/aws/aws-sdk-go-v2/config v1.26.2 h1:+RWLEIWQIGgrz2pBPAUoGgNGs1TOyF4Hml7hCnYj2jc= +github.com/aws/aws-sdk-go-v2/config v1.26.2/go.mod h1:l6xqvUxt0Oj7PI/SUXYLNyZ9T/yBPn3YTQcJLLOdtR8= github.com/aws/aws-sdk-go-v2/credentials v1.16.12 h1:v/WgB8NxprNvr5inKIiVVrXPuuTegM+K8nncFkr1usU= github.com/aws/aws-sdk-go-v2/credentials v1.16.12/go.mod h1:X21k0FjEJe+/pauud82HYiQbEr9jRKY3kXEIQ4hXeTQ= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13 h1:WLABQ4Cp4vXtXfOWOS3MEZKr6AAYUpMczLhgKtAjQ/8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13/go.mod h1:Qg6x82FXwW0sJHzYruxGiuApNo31UEtJvXVSZAXeWiw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 h1:w98BT5w+ao1/r5sUuiH6JkVzjowOKeOJRHERyy1vh58= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10/go.mod h1:K2WGI7vUvkIv1HoNbfBA1bvIZ+9kL3YVmWxeKuLQsiw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs= @@ -18,12 +22,16 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 h1:Nf2sHxjMJ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9/go.mod h1:idky4TER38YIjr2cADF1/ugFMKvZV7p//pVeV5LZbF0= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6 h1:zzaFokMF7UVk22/Igtb93A1ReGP50uu99ldLWaEMfHc= github.com/aws/aws-sdk-go-v2/service/kms v1.27.6/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7 h1:wN7AN7iOiAgT9HmdifZNSvbr6S7gSpLjSSOQHIaGmFc= +github.com/aws/aws-sdk-go-v2/service/kms v1.27.7/go.mod h1:D9FVDkZjkZnnFHymJ3fPVz0zOUlNSd0xcIIVmmrAac8= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 h1:ldSFWz9tEHAwHNmjx2Cvy1MjP5/L9kNoR0skc6wyOOM= github.com/aws/aws-sdk-go-v2/service/sso v1.18.5/go.mod h1:CaFfXLYL376jgbP7VKC96uFcU8Rlavak0UlAwk1Dlhc= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 h1:2k9KmFawS63euAkY4/ixVNsYYwrwnd5fIvgEKkfZFNM= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5/go.mod h1:W+nd4wWDVkSUIox9bacmkBP5NMFQeTJ/xqNabpzSR38= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5 h1:5UYvv8JUvllZsRnfrcMQ+hJ9jNICmcgKPAO1CER25Wg= github.com/aws/aws-sdk-go-v2/service/sts v1.26.5/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 h1:HJeiuZ2fldpd0WqngyMR6KW7ofkXNLyOaHwEIGm39Cs= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= From 2e962e91e2c5bd30f572a57fb25a648e0c9584d2 Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 18:18:49 +0200 Subject: [PATCH 07/16] fix(lint): ignore gocognit linter for test files --- .golangci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index 83e4114..f0e75da 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -149,7 +149,7 @@ linters-settings: - opinionated settings: hugeParam: - sizeThreshold: 125 + sizeThreshold: 180 issues: fix: false @@ -169,6 +169,7 @@ issues: - maintidx - thelper - unused + - gocognit - linters: - gosimple text: "S1021:" From a0d547e3ce4c2157a76afb7934fd685e6dac4928 Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 18:22:25 +0200 Subject: [PATCH 08/16] refactor(util): refactored CommitmentPolicy validator and BodyAAD, moved under an internal package --- .../crypto}/policy/commitment.go | 29 ++++---- pkg/internal/crypto/policy/commitment_test.go | 66 +++++++++++++++++++ .../utils}/bodyaad/bodyaad.go | 20 ++---- .../utils}/bodyaad/bodyaad_test.go | 57 ++++++---------- 4 files changed, 110 insertions(+), 62 deletions(-) rename pkg/{helpers => internal/crypto}/policy/commitment.go (59%) create mode 100644 pkg/internal/crypto/policy/commitment_test.go rename pkg/{helpers => internal/utils}/bodyaad/bodyaad.go (59%) rename pkg/{helpers => internal/utils}/bodyaad/bodyaad_test.go (54%) diff --git a/pkg/helpers/policy/commitment.go b/pkg/internal/crypto/policy/commitment.go similarity index 59% rename from pkg/helpers/policy/commitment.go rename to pkg/internal/crypto/policy/commitment.go index d43c67f..de99987 100644 --- a/pkg/helpers/policy/commitment.go +++ b/pkg/internal/crypto/policy/commitment.go @@ -5,33 +5,40 @@ package policy import ( "errors" + "fmt" "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" ) -var Commitment commitmentValidator //nolint:gochecknoglobals - -type commitmentValidator struct{} - var errCommitmentEncryptNonCommitted = errors.New("configuration conflict. Cannot encrypt due to CommitmentPolicy requiring only non-committed messages") var errCommitmentEncrypt = errors.New("configuration conflict. Cannot encrypt due to CommitmentPolicy requiring only committed messages") var errCommitmentDecrypt = errors.New("configuration conflict. Cannot decrypt due to CommitmentPolicy requiring only committed messages") -func (commitmentValidator) ValidatePolicyOnEncrypt(policy suite.CommitmentPolicy, algorithm *suite.AlgorithmSuite) error { - if policy == suite.CommitmentPolicyForbidEncryptAllowDecrypt { - if algorithm != nil && algorithm.IsCommitting() { - return errCommitmentEncryptNonCommitted - } +func ValidateOnEncrypt(policy suite.CommitmentPolicy, algorithm *suite.AlgorithmSuite) error { + if err := suite.ValidateCommitmentPolicy(policy); err != nil { + return err + } + if algorithm == nil { + return fmt.Errorf("algorithm cannot be nil") + } + if policy == suite.CommitmentPolicyForbidEncryptAllowDecrypt && algorithm.IsCommitting() { + return errCommitmentEncryptNonCommitted } if policy == suite.CommitmentPolicyRequireEncryptAllowDecrypt || policy == suite.CommitmentPolicyRequireEncryptRequireDecrypt { - if algorithm != nil && !algorithm.IsCommitting() { + if !algorithm.IsCommitting() { return errCommitmentEncrypt } } return nil } -func (commitmentValidator) ValidatePolicyOnDecrypt(policy suite.CommitmentPolicy, algorithm *suite.AlgorithmSuite) error { +func ValidateOnDecrypt(policy suite.CommitmentPolicy, algorithm *suite.AlgorithmSuite) error { + if err := suite.ValidateCommitmentPolicy(policy); err != nil { + return err + } + if algorithm == nil { + return fmt.Errorf("algorithm cannot be nil") + } if policy == suite.CommitmentPolicyRequireEncryptRequireDecrypt && !algorithm.IsCommitting() { return errCommitmentDecrypt } diff --git a/pkg/internal/crypto/policy/commitment_test.go b/pkg/internal/crypto/policy/commitment_test.go new file mode 100644 index 0000000..555ae0a --- /dev/null +++ b/pkg/internal/crypto/policy/commitment_test.go @@ -0,0 +1,66 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package policy_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/crypto/policy" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" +) + +func TestValidateOnEncrypt(t *testing.T) { + type args struct { + policy suite.CommitmentPolicy + algorithm *suite.AlgorithmSuite + } + tests := []struct { + name string + args args + wantErr assert.ErrorAssertionFunc + }{ + {"Invalid Policy", args{0, nil}, assert.Error}, + {"Algorithm Nil", args{suite.CommitmentPolicyRequireEncryptRequireDecrypt, nil}, assert.Error}, + {"Policy 1 Require Non Committed Messages", args{suite.CommitmentPolicyForbidEncryptAllowDecrypt, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY}, assert.Error}, + {"Policy 2 Require Committed Messages", args{suite.CommitmentPolicyRequireEncryptAllowDecrypt, suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256}, assert.Error}, + {"Policy 3 Require Committed Messages", args{suite.CommitmentPolicyRequireEncryptRequireDecrypt, suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256}, assert.Error}, + {"Policy 2 Allow Committed Messages", args{suite.CommitmentPolicyRequireEncryptAllowDecrypt, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY}, assert.NoError}, + {"Policy 3 Allow Committed Messages", args{suite.CommitmentPolicyRequireEncryptRequireDecrypt, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY}, assert.NoError}, + {"Policy 1 Allow Non Committed Messages", args{suite.CommitmentPolicyForbidEncryptAllowDecrypt, suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256}, assert.NoError}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.wantErr(t, policy.ValidateOnEncrypt(tt.args.policy, tt.args.algorithm), fmt.Sprintf("ValidateOnEncrypt(%v, %v)", tt.args.policy, tt.args.algorithm)) + }) + } +} + +func TestValidateOnDecrypt(t *testing.T) { + type args struct { + policy suite.CommitmentPolicy + algorithm *suite.AlgorithmSuite + } + tests := []struct { + name string + args args + wantErr assert.ErrorAssertionFunc + }{ + {"Invalid Policy", args{0, nil}, assert.Error}, + {"Algorithm Nil", args{suite.CommitmentPolicyRequireEncryptRequireDecrypt, nil}, assert.Error}, + {"Policy 1 Allow Non Committed Messages", args{suite.CommitmentPolicyForbidEncryptAllowDecrypt, suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256}, assert.NoError}, + {"Policy 2 Allow Non Committed Messages", args{suite.CommitmentPolicyRequireEncryptAllowDecrypt, suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256}, assert.NoError}, + {"Policy 3 Require Committed Messages", args{suite.CommitmentPolicyRequireEncryptRequireDecrypt, suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256}, assert.Error}, + {"Policy 1 Allow Committed Messages", args{suite.CommitmentPolicyForbidEncryptAllowDecrypt, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY}, assert.NoError}, + {"Policy 2 Allow Committed Messages", args{suite.CommitmentPolicyRequireEncryptAllowDecrypt, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY}, assert.NoError}, + {"Policy 3 Allow Committed Messages", args{suite.CommitmentPolicyRequireEncryptRequireDecrypt, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY}, assert.NoError}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.wantErr(t, policy.ValidateOnDecrypt(tt.args.policy, tt.args.algorithm), fmt.Sprintf("ValidateOnDecrypt(%v, %v)", tt.args.policy, tt.args.algorithm)) + }) + } +} diff --git a/pkg/helpers/bodyaad/bodyaad.go b/pkg/internal/utils/bodyaad/bodyaad.go similarity index 59% rename from pkg/helpers/bodyaad/bodyaad.go rename to pkg/internal/utils/bodyaad/bodyaad.go index 9f9c748..3a9665f 100644 --- a/pkg/helpers/bodyaad/bodyaad.go +++ b/pkg/internal/utils/bodyaad/bodyaad.go @@ -4,8 +4,6 @@ package bodyaad import ( - "github.com/rs/zerolog/log" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" "github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/conv" ) @@ -15,23 +13,17 @@ const ( lengthLen = int(8) // length as big-endian 64-bit unsigned integer ) -var BodyAAD bodyAAD //nolint:gochecknoglobals - -type bodyAAD struct{} - -func (bodyAAD) ContentString(contentType suite.ContentType, finalFrame bool) []byte { - if contentType != suite.FramedContent { - // TODO refactor to return ([]byte, error), dont panic here! - log.Info().Msgf("%v", suite.CommitmentPolicyForbidEncryptAllowDecrypt) - log.Panic().Msg("NonFramed content type not supported") +func ContentString(contentType suite.ContentType, finalFrame bool) ([]byte, error) { + if err := suite.ValidateContentType(contentType); err != nil { + return nil, err } if finalFrame { - return []byte(suite.ContentAADFinalFrame) + return []byte(suite.ContentAADFinalFrame), nil } - return []byte(suite.ContentAADFrame) + return []byte(suite.ContentAADFrame), nil } -func (bodyAAD) ContentAADBytes(messageID, contentString []byte, seqNum, length int) []byte { +func ContentAADBytes(messageID, contentString []byte, seqNum, length int) []byte { bufLen := len(messageID) + len(contentString) + seqNumLen + // 4, seqNum as big-endian 32-bit unsigned integer diff --git a/pkg/helpers/bodyaad/bodyaad_test.go b/pkg/internal/utils/bodyaad/bodyaad_test.go similarity index 54% rename from pkg/helpers/bodyaad/bodyaad_test.go rename to pkg/internal/utils/bodyaad/bodyaad_test.go index 449c350..ba50390 100644 --- a/pkg/helpers/bodyaad/bodyaad_test.go +++ b/pkg/internal/utils/bodyaad/bodyaad_test.go @@ -1,7 +1,7 @@ // Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package bodyaad +package bodyaad_test import ( "reflect" @@ -9,35 +9,41 @@ import ( "github.com/stretchr/testify/assert" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/utils/bodyaad" "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" ) -func Test_bodyAAD_ContentString(t *testing.T) { +func TestContentString(t *testing.T) { type args struct { contentType suite.ContentType finalFrame bool } tests := []struct { - name string - args args - want []byte + name string + wantErr bool + args args + want []byte }{ - {"NotFinalFrame", args{suite.FramedContent, false}, []byte("AWSKMSEncryptionClient Frame")}, - {"FinalFrame", args{suite.FramedContent, true}, []byte("AWSKMSEncryptionClient Final Frame")}, + {"Not Final Frame", false, args{suite.FramedContent, false}, []byte("AWSKMSEncryptionClient Frame")}, + {"Final Frame", false, args{suite.FramedContent, true}, []byte("AWSKMSEncryptionClient Final Frame")}, + {"Non Framed Content", true, args{suite.NonFramedContent, true}, nil}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - bo := bodyAAD{} - if got := bo.ContentString(tt.args.contentType, tt.args.finalFrame); !reflect.DeepEqual(got, tt.want) { - t.Errorf("ContentString() = %v, want %v", got, tt.want) + got, err := bodyaad.ContentString(tt.args.contentType, tt.args.finalFrame) + if tt.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.want, got) } }) } } -func Test_bodyAAD_ContentAADBytes(t *testing.T) { - contentString := BodyAAD.ContentString(suite.FramedContent, false) - contentStringFinal := BodyAAD.ContentString(suite.FramedContent, true) +func TestContentAADBytes(t *testing.T) { + contentString, _ := bodyaad.ContentString(suite.FramedContent, false) + contentStringFinal, _ := bodyaad.ContentString(suite.FramedContent, true) type args struct { messageID []byte contentString []byte @@ -55,32 +61,9 @@ func Test_bodyAAD_ContentAADBytes(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - bo := bodyAAD{} - if got := bo.ContentAADBytes(tt.args.messageID, tt.args.contentString, tt.args.seqNum, tt.args.length); !reflect.DeepEqual(got, tt.want) { + if got := bodyaad.ContentAADBytes(tt.args.messageID, tt.args.contentString, tt.args.seqNum, tt.args.length); !reflect.DeepEqual(got, tt.want) { t.Errorf("ContentAADBytes() = %#v, want %#v", got, tt.want) } }) } } - -func TestBodyAAD_ContentStringPanic(t *testing.T) { - tests := []struct { - name string - f func() - isPanic bool - }{ - {"panicFinal", func() { BodyAAD.ContentString(suite.NonFramedContent, true) }, true}, - {"panicNotFinal", func() { BodyAAD.ContentString(suite.NonFramedContent, false) }, true}, - {"NotPanicFinal", func() { BodyAAD.ContentString(suite.FramedContent, true) }, false}, - {"NotPanicNotFinal", func() { BodyAAD.ContentString(suite.FramedContent, false) }, false}, - } - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - if test.isPanic { - assert.Panics(t, test.f) - } else { - assert.NotPanics(t, test.f) - } - }) - } -} From da85abaf531cd2e5e7e4113829779598367a467b Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 18:24:44 +0200 Subject: [PATCH 09/16] feat(client): use FrameLength and CommitmentPolicy validators --- pkg/client/options.go | 8 +++++--- pkg/clientconfig/client_config.go | 4 ++-- pkg/clientconfig/client_config_test.go | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pkg/client/options.go b/pkg/client/options.go index 3a77109..0531260 100644 --- a/pkg/client/options.go +++ b/pkg/client/options.go @@ -65,12 +65,14 @@ func WithAlgorithm(alg *suite.AlgorithmSuite) EncryptOptionFunc { // - EncryptOptionFunc: A function that sets the FrameLength field in EncryptOptions. // // Errors: -// - If frameLength is less than [suite.MinFrameSize] (128) or greater than [suite.MaxFrameSize] (4294967295), +// - If frameLength is less than [suite.MinFrameSize] (128) or greater than [suite.MaxFrameSize] (2147483647), // it returns an error indicating that the frame length is out of range. +// - If frameLength is not a multiple of the [suite.BlockSize] (128) of the crypto +// algorithm, it returns an error indicating that. func WithFrameLength(frameLength int) EncryptOptionFunc { return func(o *EncryptOptions) error { - if frameLength < suite.MinFrameSize || frameLength > suite.MaxFrameSize { - return fmt.Errorf("frame %d length out of range, allowed: min %d, max %d", frameLength, suite.MinFrameSize, suite.MaxFrameSize) + if err := suite.ValidateFrameLength(frameLength); err != nil { + return err } o.FrameLength = frameLength return nil diff --git a/pkg/clientconfig/client_config.go b/pkg/clientconfig/client_config.go index 5d1a49f..1154443 100644 --- a/pkg/clientconfig/client_config.go +++ b/pkg/clientconfig/client_config.go @@ -52,8 +52,8 @@ func NewConfigWithOpts(optFns ...ConfigOptionFunc) (*ClientConfig, error) { func WithCommitmentPolicy(policy suite.CommitmentPolicy) ConfigOptionFunc { return func(o *ConfigOptions) error { - if policy < suite.CommitmentPolicyForbidEncryptAllowDecrypt || policy > suite.CommitmentPolicyRequireEncryptRequireDecrypt { - return fmt.Errorf("CommitmentPolicy not allowed") + if err := suite.ValidateCommitmentPolicy(policy); err != nil { + return err } o.CommitmentPolicy = policy return nil diff --git a/pkg/clientconfig/client_config_test.go b/pkg/clientconfig/client_config_test.go index 7dc8560..d4b6bbc 100644 --- a/pkg/clientconfig/client_config_test.go +++ b/pkg/clientconfig/client_config_test.go @@ -48,7 +48,7 @@ func TestNewConfigWithOptsFaulty(t *testing.T) { assert.Nil(t, cfg2) cfg3, err3 := NewConfigWithOpts( - WithCommitmentPolicy(3), + WithCommitmentPolicy(4), WithMaxEncryptedDataKeys(10), ) From d29c780c8f49c96132991836f2633aa08a123b46 Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 18:25:48 +0200 Subject: [PATCH 10/16] fix(client): update client example output --- pkg/client/example_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/client/example_test.go b/pkg/client/example_test.go index 3418c44..d03b522 100644 --- a/pkg/client/example_test.go +++ b/pkg/client/example_test.go @@ -14,7 +14,7 @@ import ( func ExampleNewClient() { var c = client.NewClient() fmt.Printf("%#v", *c) - // Output: client.Client{config:clientconfig.ClientConfig{commitmentPolicy:2, maxEncryptedDataKeys:10}} + // Output: client.Client{config:clientconfig.ClientConfig{commitmentPolicy:3, maxEncryptedDataKeys:10}} } func ExampleNewClientWithConfig() { @@ -27,5 +27,5 @@ func ExampleNewClientWithConfig() { } var c = client.NewClientWithConfig(cfg) fmt.Printf("%#v", *c) - // Output: client.Client{config:clientconfig.ClientConfig{commitmentPolicy:2, maxEncryptedDataKeys:2}} + // Output: client.Client{config:clientconfig.ClientConfig{commitmentPolicy:3, maxEncryptedDataKeys:2}} } From e52a7bdd461bf6f12a4e68be4af221a079093c7c Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 18:27:59 +0200 Subject: [PATCH 11/16] feat(sdk): Message Format V1 support --- pkg/client/client.go | 22 +- pkg/crypto/base.go | 17 +- pkg/crypto/decrypter.go | 47 ++- pkg/crypto/encrypter.go | 53 +-- pkg/serialization/aad.go | 4 +- pkg/serialization/deserialize.go | 10 +- pkg/serialization/encrypteddatakey.go | 72 ++-- pkg/serialization/encrypteddatakey_test.go | 22 +- pkg/serialization/headerauthentication.go | 48 ++- .../headerauthentication_test.go | 125 ++++-- pkg/serialization/messageheader.go | 365 +++++++++++++----- pkg/serialization/messageheader_test.go | 328 +++++++++++----- 12 files changed, 755 insertions(+), 358 deletions(-) diff --git a/pkg/client/client.go b/pkg/client/client.go index b880e90..020ce22 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -11,7 +11,7 @@ import ( "github.com/chainifynet/aws-encryption-sdk-go/pkg/clientconfig" "github.com/chainifynet/aws-encryption-sdk-go/pkg/crypto" "github.com/chainifynet/aws-encryption-sdk-go/pkg/model" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/serialization" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" ) @@ -30,9 +30,9 @@ func NewClientWithConfig(cfg *clientconfig.ClientConfig) *Client { type BaseClient interface { clientConfig() clientconfig.ClientConfig - Encrypt(ctx context.Context, source []byte, ec suite.EncryptionContext, materialsManager model.CryptoMaterialsManager, optFns ...EncryptOptionFunc) ([]byte, *serialization.MessageHeader, error) - EncryptWithParams(ctx context.Context, source []byte, ec suite.EncryptionContext, materialsManager model.CryptoMaterialsManager, algorithm *suite.AlgorithmSuite, frameLength int) ([]byte, *serialization.MessageHeader, error) - Decrypt(ctx context.Context, ciphertext []byte, materialsManager model.CryptoMaterialsManager) ([]byte, *serialization.MessageHeader, error) + Encrypt(ctx context.Context, source []byte, ec suite.EncryptionContext, materialsManager model.CryptoMaterialsManager, optFns ...EncryptOptionFunc) ([]byte, format.MessageHeader, error) + EncryptWithParams(ctx context.Context, source []byte, ec suite.EncryptionContext, materialsManager model.CryptoMaterialsManager, algorithm *suite.AlgorithmSuite, frameLength int) ([]byte, format.MessageHeader, error) + Decrypt(ctx context.Context, ciphertext []byte, materialsManager model.CryptoMaterialsManager) ([]byte, format.MessageHeader, error) } var _ BaseClient = (*Client)(nil) @@ -58,9 +58,9 @@ func (c *Client) clientConfig() clientconfig.ClientConfig { // // Returns: // - []byte: The encrypted data. -// - [serialization.MessageHeader]: The header of the encrypted message. +// - [format.MessageHeader]: The header of the encrypted message. // - error: An error if encryption fails. -func (c *Client) EncryptWithParams(ctx context.Context, source []byte, ec suite.EncryptionContext, materialsManager model.CryptoMaterialsManager, algorithm *suite.AlgorithmSuite, frameLength int) ([]byte, *serialization.MessageHeader, error) { +func (c *Client) EncryptWithParams(ctx context.Context, source []byte, ec suite.EncryptionContext, materialsManager model.CryptoMaterialsManager, algorithm *suite.AlgorithmSuite, frameLength int) ([]byte, format.MessageHeader, error) { return c.Encrypt(ctx, source, ec, materialsManager, WithAlgorithm(algorithm), WithFrameLength(frameLength)) } @@ -81,7 +81,7 @@ func (c *Client) EncryptWithParams(ctx context.Context, source []byte, ec suite. // // Returns: // - []byte: The encrypted data. -// - [serialization.MessageHeader]: The header of the encrypted message. +// - [format.MessageHeader]: The header of the encrypted message. // - error: An error if encryption fails. // // Example usage: @@ -98,7 +98,7 @@ func (c *Client) EncryptWithParams(ctx context.Context, source []byte, ec suite. // 1. The Encrypt function allows customization of the encryption process through its optional parameters. // 2. The WithAlgorithm and WithFrameLength functions can be used to specify an encryption algorithm and frame length, // respectively. If these functions are not used, default values are applied. -func (c *Client) Encrypt(ctx context.Context, source []byte, ec suite.EncryptionContext, materialsManager model.CryptoMaterialsManager, optFns ...EncryptOptionFunc) ([]byte, *serialization.MessageHeader, error) { +func (c *Client) Encrypt(ctx context.Context, source []byte, ec suite.EncryptionContext, materialsManager model.CryptoMaterialsManager, optFns ...EncryptOptionFunc) ([]byte, format.MessageHeader, error) { opts := EncryptOptions{ Algorithm: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, FrameLength: DefaultFrameLength, @@ -122,14 +122,14 @@ func (c *Client) Encrypt(ctx context.Context, source []byte, ec suite.Encryption // // - ctx: context.Context. // - ciphertext []byte: The data to decrypt. -// - materialsManager [materials.CryptoMaterialsManager]: The manager that provides the cryptographic materials. +// - materialsManager [model.CryptoMaterialsManager]: The manager that provides the cryptographic materials. // // Returns: // // - []byte: The decrypted data. -// - [serialization.MessageHeader]: The header of the encrypted message. +// - [format.MessageHeader]: The header of the encrypted message. // - error: An error if decryption fails. -func (c *Client) Decrypt(ctx context.Context, ciphertext []byte, materialsManager model.CryptoMaterialsManager) ([]byte, *serialization.MessageHeader, error) { +func (c *Client) Decrypt(ctx context.Context, ciphertext []byte, materialsManager model.CryptoMaterialsManager) ([]byte, format.MessageHeader, error) { b, header, err := crypto.Decrypt(ctx, c.clientConfig(), ciphertext, materialsManager) if err != nil { return nil, nil, err diff --git a/pkg/crypto/base.go b/pkg/crypto/base.go index b4da53e..db0b43f 100644 --- a/pkg/crypto/base.go +++ b/pkg/crypto/base.go @@ -12,7 +12,7 @@ import ( "github.com/chainifynet/aws-encryption-sdk-go/pkg/clientconfig" "github.com/chainifynet/aws-encryption-sdk-go/pkg/crypto/signature" "github.com/chainifynet/aws-encryption-sdk-go/pkg/model" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/serialization" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" "github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/encryption" ) @@ -24,23 +24,24 @@ var ( ) const ( - firstByteEncryptedMessage = byte(0x02) + firstByteEncryptedMessageV1 = byte(0x01) + firstByteEncryptedMessageV2 = byte(0x02) ) type SdkDecrypter interface { - decrypt(ctx context.Context, ciphertext []byte) ([]byte, *serialization.MessageHeader, error) + decrypt(ctx context.Context, ciphertext []byte) ([]byte, format.MessageHeader, error) } type decrypter struct { cmm model.CryptoMaterialsManager config clientconfig.ClientConfig aeadDecrypter encryption.AEADDecrypter - header *serialization.MessageHeader + header format.MessageHeader verifier signature.Verifier _derivedDataKey []byte } -func Decrypt(ctx context.Context, config clientconfig.ClientConfig, ciphertext []byte, cmm model.CryptoMaterialsManager) ([]byte, *serialization.MessageHeader, error) { +func Decrypt(ctx context.Context, config clientconfig.ClientConfig, ciphertext []byte, cmm model.CryptoMaterialsManager) ([]byte, format.MessageHeader, error) { dec := decrypter{ cmm: cmm.GetInstance(), config: config, @@ -57,7 +58,7 @@ func Decrypt(ctx context.Context, config clientconfig.ClientConfig, ciphertext [ var _ SdkDecrypter = (*decrypter)(nil) type SdkEncrypter interface { - encrypt(ctx context.Context, source []byte, ec suite.EncryptionContext) ([]byte, *serialization.MessageHeader, error) + encrypt(ctx context.Context, source []byte, ec suite.EncryptionContext) ([]byte, format.MessageHeader, error) } type encrypter struct { @@ -66,13 +67,13 @@ type encrypter struct { algorithm *suite.AlgorithmSuite frameLength int aeadEncrypter encryption.AEADEncrypter - header *serialization.MessageHeader + header format.MessageHeader _derivedDataKey []byte signer signature.Signer ciphertextBuf *bytes.Buffer } -func Encrypt(ctx context.Context, config clientconfig.ClientConfig, source []byte, ec suite.EncryptionContext, cmm model.CryptoMaterialsManager, algorithm *suite.AlgorithmSuite, frameLength int) ([]byte, *serialization.MessageHeader, error) { +func Encrypt(ctx context.Context, config clientconfig.ClientConfig, source []byte, ec suite.EncryptionContext, cmm model.CryptoMaterialsManager, algorithm *suite.AlgorithmSuite, frameLength int) ([]byte, format.MessageHeader, error) { enc := encrypter{ cmm: cmm.GetInstance(), config: config, diff --git a/pkg/crypto/decrypter.go b/pkg/crypto/decrypter.go index 05a7c11..35ba3ba 100644 --- a/pkg/crypto/decrypter.go +++ b/pkg/crypto/decrypter.go @@ -10,16 +10,17 @@ import ( "fmt" "github.com/chainifynet/aws-encryption-sdk-go/pkg/crypto/signature" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/helpers/bodyaad" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/helpers/policy" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/crypto/policy" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/utils/bodyaad" "github.com/chainifynet/aws-encryption-sdk-go/pkg/model" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" "github.com/chainifynet/aws-encryption-sdk-go/pkg/serialization" "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" "github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/keyderivation" ) // decrypt ciphertext decryption -func (d *decrypter) decrypt(ctx context.Context, ciphertext []byte) ([]byte, *serialization.MessageHeader, error) { +func (d *decrypter) decrypt(ctx context.Context, ciphertext []byte) ([]byte, format.MessageHeader, error) { var b []byte b = make([]byte, len(ciphertext)) copy(b, ciphertext) @@ -29,7 +30,7 @@ func (d *decrypter) decrypt(ctx context.Context, ciphertext []byte) ([]byte, *se // early stage check if cipher text contains needed first byte of message version // by doing this we avoid mistakes with base64 byte sequence - if ciphertext[0] != firstByteEncryptedMessage { + if ciphertext[0] != firstByteEncryptedMessageV1 && ciphertext[0] != firstByteEncryptedMessageV2 { return nil, nil, fmt.Errorf("first byte does not contain message version: %w", ErrInvalidMessage) } buf := bytes.NewBuffer(b) @@ -44,7 +45,7 @@ func (d *decrypter) decrypt(ctx context.Context, ciphertext []byte) ([]byte, *se } if d.verifier != nil { - footer, errFooter := serialization.MessageFooter.FromBuffer(d.header.AlgorithmSuite, buf) + footer, errFooter := serialization.MessageFooter.FromBuffer(d.header.AlgorithmSuite(), buf) if errFooter != nil { return nil, nil, errFooter } @@ -64,27 +65,27 @@ func (d *decrypter) decryptHeader(ctx context.Context, buf *bytes.Buffer) error return err } - if errPolicy := policy.Commitment.ValidatePolicyOnDecrypt(d.config.CommitmentPolicy(), header.AlgorithmSuite); errPolicy != nil { + if errPolicy := policy.ValidateOnDecrypt(d.config.CommitmentPolicy(), header.AlgorithmSuite()); errPolicy != nil { return errPolicy } - if header.AlgorithmSuite.IsSigning() { + if header.AlgorithmSuite().IsSigning() { d.verifier = signature.NewECCVerifier( - header.AlgorithmSuite.Authentication.HashFunc, - header.AlgorithmSuite.Authentication.Algorithm, + header.AlgorithmSuite().Authentication.HashFunc, + header.AlgorithmSuite().Authentication.Algorithm, ) if err := d.updateVerifier(header.Bytes()); err != nil { return err } - if err := d.updateVerifier(headerAuth.Serialize()); err != nil { + if err := d.updateVerifier(headerAuth.Bytes()); err != nil { return err } } dmr := model.DecryptionMaterialsRequest{ - Algorithm: header.AlgorithmSuite, - EncryptedDataKeys: serialization.EDK.AsKeys(header.EncryptedDataKeys), - EncryptionContext: header.AADData.AsEncryptionContext(), + Algorithm: header.AlgorithmSuite(), + EncryptedDataKeys: serialization.EDK.AsKeys(header.EncryptedDataKeys()), + EncryptionContext: header.AADData().EncryptionContext(), } decMaterials, err := d.cmm.DecryptMaterials(ctx, dmr) @@ -98,18 +99,18 @@ func (d *decrypter) decryptHeader(ctx context.Context, buf *bytes.Buffer) error } } - derivedDataKey, err := keyderivation.DeriveDataEncryptionKey(decMaterials.DataKey().DataKey(), header.AlgorithmSuite, header.MessageID) + derivedDataKey, err := keyderivation.DeriveDataEncryptionKey(decMaterials.DataKey().DataKey(), header.AlgorithmSuite(), header.MessageID()) if err != nil { return fmt.Errorf("decrypt key derivation error: %w", err) } - if header.AlgorithmSuite.IsCommitting() { - expectedCommitmentKey, err := keyderivation.CalculateCommitmentKey(decMaterials.DataKey().DataKey(), header.AlgorithmSuite, header.MessageID) + if header.AlgorithmSuite().IsCommitting() { + expectedCommitmentKey, err := keyderivation.CalculateCommitmentKey(decMaterials.DataKey().DataKey(), header.AlgorithmSuite(), header.MessageID()) if err != nil { return fmt.Errorf("decrypt calculate commitment key error: %w", err) } - if ok := hmac.Equal(expectedCommitmentKey, header.AlgorithmSuiteData); !ok { + if ok := hmac.Equal(expectedCommitmentKey, header.AlgorithmSuiteData()); !ok { return fmt.Errorf("key commitment validation failed: key identity does not match the identity asserted in the message") } } @@ -132,7 +133,7 @@ func (d *decrypter) decryptHeader(ctx context.Context, buf *bytes.Buffer) error } func (d *decrypter) decryptBody(buf *bytes.Buffer) ([]byte, error) { - body, err := serialization.DeserializeBody(buf, d.header.AlgorithmSuite, d.header.FrameLength) + body, err := serialization.DeserializeBody(buf, d.header.AlgorithmSuite(), d.header.FrameLength()) if err != nil { return nil, fmt.Errorf("body error: %w", err) } @@ -141,9 +142,13 @@ func (d *decrypter) decryptBody(buf *bytes.Buffer) ([]byte, error) { readBytes := 0 for _, frame := range body.Frames() { - associatedData := bodyaad.BodyAAD.ContentAADBytes( - d.header.MessageID, - bodyaad.BodyAAD.ContentString(suite.FramedContent, frame.IsFinal()), + contentString, err := bodyaad.ContentString(suite.FramedContent, frame.IsFinal()) + if err != nil { + return nil, fmt.Errorf("decrypt frame error: %w", err) + } + associatedData := bodyaad.ContentAADBytes( + d.header.MessageID(), + contentString, frame.SequenceNumber(), len(frame.EncryptedContent()), ) diff --git a/pkg/crypto/encrypter.go b/pkg/crypto/encrypter.go index 38013a1..75a97c6 100644 --- a/pkg/crypto/encrypter.go +++ b/pkg/crypto/encrypter.go @@ -10,16 +10,17 @@ import ( "math" "github.com/chainifynet/aws-encryption-sdk-go/pkg/crypto/signature" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/helpers/bodyaad" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/helpers/policy" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/crypto/policy" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/utils/bodyaad" "github.com/chainifynet/aws-encryption-sdk-go/pkg/model" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" "github.com/chainifynet/aws-encryption-sdk-go/pkg/serialization" "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" "github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/keyderivation" "github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/rand" ) -func (e *encrypter) encrypt(ctx context.Context, source []byte, ec suite.EncryptionContext) ([]byte, *serialization.MessageHeader, error) { +func (e *encrypter) encrypt(ctx context.Context, source []byte, ec suite.EncryptionContext) ([]byte, format.MessageHeader, error) { var b []byte b = make([]byte, len(source)) copy(b, source) @@ -68,7 +69,7 @@ func (e *encrypter) encrypt(ctx context.Context, source []byte, ec suite.Encrypt } func (e *encrypter) prepareMessage(ctx context.Context, plaintextBuffer *bytes.Buffer, ec suite.EncryptionContext) error { - if err := policy.Commitment.ValidatePolicyOnEncrypt(e.config.CommitmentPolicy(), e.algorithm); err != nil { + if err := policy.ValidateOnEncrypt(e.config.CommitmentPolicy(), e.algorithm); err != nil { return err // just return err } @@ -118,29 +119,30 @@ func (e *encrypter) prepareMessage(ctx context.Context, plaintextBuffer *bytes.B } func (e *encrypter) generateHeader(messageID []byte, encMaterials model.EncryptionMaterial) error { - aadData := serialization.AAD.NewAADWithEncryptionContext(encMaterials.EncryptionContext()) - edks, err := serialization.EDK.FromEDKs(encMaterials.EncryptedDataKeys()) if err != nil { return fmt.Errorf("EDK error: %w", err) } - commitmentKey, err := keyderivation.CalculateCommitmentKey(encMaterials.DataEncryptionKey().DataKey(), e.algorithm, messageID) - if err != nil { - return fmt.Errorf("calculate commitment key error: %w", err) + var commitmentKey []byte + if e.algorithm.IsCommitting() { + commitmentKey, err = keyderivation.CalculateCommitmentKey(encMaterials.DataEncryptionKey().DataKey(), e.algorithm, messageID) + if err != nil { + return fmt.Errorf("calculate commitment key error: %w", err) + } } - params := serialization.MessageHeaderParams{ + params := serialization.HeaderParams{ AlgorithmSuite: e.algorithm, MessageID: messageID, - AADData: aadData, + EncryptionContext: encMaterials.EncryptionContext(), EncryptedDataKeys: edks, ContentType: suite.FramedContent, FrameLength: e.frameLength, AlgorithmSuiteData: commitmentKey, } - header, err := serialization.EncryptedMessageHeader.New(params) + header, err := serialization.NewHeader(params) if err != nil { return fmt.Errorf("header error: %w", err) } @@ -154,22 +156,22 @@ func (e *encrypter) generateHeader(messageID []byte, encMaterials model.Encrypti } func (e *encrypter) generateHeaderAuth() error { - headerAuthTag, err := e.aeadEncrypter.GenerateHeaderAuth(e._derivedDataKey, e.header.Bytes()) + headerAuthTag, iv, err := e.aeadEncrypter.GenerateHeaderAuth(e._derivedDataKey, e.header.Bytes()) if err != nil { return fmt.Errorf("header auth error: %w", err) } - headerAuthData, err := serialization.MessageHeaderAuth.New(headerAuthTag) + headerAuthData, err := serialization.NewHeaderAuth(e.header.Version(), iv, headerAuthTag) if err != nil { return fmt.Errorf("header auth serialize error: %w", err) } - if errBuf := e.updateBuffers(headerAuthData.Serialize()); errBuf != nil { + if errBuf := e.updateBuffers(headerAuthData.Bytes()); errBuf != nil { return errBuf // wrapped already in updateCiphertextBuf } return nil } func (e *encrypter) encryptBody(plaintextBuffer *bytes.Buffer) error { - body, errBody := serialization.MessageBody.NewBody(e.header.AlgorithmSuite, e.frameLength) + body, errBody := serialization.MessageBody.NewBody(e.header.AlgorithmSuite(), e.frameLength) if errBody != nil { return fmt.Errorf("body error: %w", errBody) } @@ -195,11 +197,12 @@ func (e *encrypter) encryptBody(plaintextBuffer *bytes.Buffer) error { for seqNum := 1; seqNum <= int(framesToRead); seqNum++ { bytesToRead, isFinal := calculateFrame() plaintext := plaintextBuffer.Next(bytesToRead) - ciphertext, authTag, err := e.encryptFrame(seqNum, isFinal, plaintext) + iv := e.aeadEncrypter.ConstructIV(seqNum) + ciphertext, authTag, err := e.encryptFrame(seqNum, isFinal, iv, plaintext) if err != nil { return err } - if errFrame := body.AddFrame(isFinal, seqNum, e.aeadEncrypter.ConstructIV(seqNum), len(plaintext), ciphertext, authTag); errFrame != nil { + if errFrame := body.AddFrame(isFinal, seqNum, iv, len(plaintext), ciphertext, authTag); errFrame != nil { return fmt.Errorf("body frame error: %w", errFrame) } } @@ -207,16 +210,20 @@ func (e *encrypter) encryptBody(plaintextBuffer *bytes.Buffer) error { return e.updateBuffers(body.Bytes()) } -func (e *encrypter) encryptFrame(seqNum int, isFinal bool, plaintext []byte) ([]byte, []byte, error) { - associatedData := bodyaad.BodyAAD.ContentAADBytes( - e.header.MessageID, - bodyaad.BodyAAD.ContentString(suite.FramedContent, isFinal), +func (e *encrypter) encryptFrame(seqNum int, isFinal bool, iv, plaintext []byte) ([]byte, []byte, error) { + contentString, err := bodyaad.ContentString(suite.FramedContent, isFinal) + if err != nil { + return nil, nil, fmt.Errorf("encrypt frame error: %w", err) + } + associatedData := bodyaad.ContentAADBytes( + e.header.MessageID(), + contentString, seqNum, len(plaintext), ) ciphertext, authTag, err := e.aeadEncrypter.Encrypt( e._derivedDataKey, - e.aeadEncrypter.ConstructIV(seqNum), + iv, plaintext, associatedData, ) diff --git a/pkg/serialization/aad.go b/pkg/serialization/aad.go index 2e7d3aa..934af63 100644 --- a/pkg/serialization/aad.go +++ b/pkg/serialization/aad.go @@ -125,10 +125,10 @@ func (d *aadData) Bytes() []byte { return buf } -// AsEncryptionContext +// EncryptionContext // // used during decryption process -func (d *aadData) AsEncryptionContext() suite.EncryptionContext { +func (d *aadData) EncryptionContext() suite.EncryptionContext { ec := make(suite.EncryptionContext) for _, pair := range d.kv { diff --git a/pkg/serialization/deserialize.go b/pkg/serialization/deserialize.go index 419dba7..a4e6b70 100644 --- a/pkg/serialization/deserialize.go +++ b/pkg/serialization/deserialize.go @@ -7,21 +7,21 @@ import ( "bytes" "errors" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" ) -//goland:noinspection GoExportedFuncWithUnexportedType -func DeserializeHeader(buf *bytes.Buffer, maxEncryptedDataKeys int) (*MessageHeader, *headerAuth, error) { //nolint:revive - header, err := EncryptedMessageHeader.fromBuffer(buf) +func DeserializeHeader(buf *bytes.Buffer, maxEncryptedDataKeys int) (format.MessageHeader, format.MessageHeaderAuth, error) { //nolint:revive + header, err := deserializeHeader(buf) if err != nil { return nil, nil, err } - if errEdk := EDK.validateMinMaxEDKs(header.EncryptedDataKeyCount, maxEncryptedDataKeys); errEdk != nil { + if errEdk := EDK.validateMinMaxEDKs(header.EncryptedDataKeyCount(), maxEncryptedDataKeys); errEdk != nil { return nil, nil, errEdk } - authData, err := MessageHeaderAuth.Deserialize(buf) + authData, err := deserializeHeaderAuth(header.Version(), buf) if err != nil { return nil, nil, err } diff --git a/pkg/serialization/encrypteddatakey.go b/pkg/serialization/encrypteddatakey.go index 444e1c0..e452f7a 100644 --- a/pkg/serialization/encrypteddatakey.go +++ b/pkg/serialization/encrypteddatakey.go @@ -14,6 +14,7 @@ import ( "github.com/chainifynet/aws-encryption-sdk-go/pkg/logger" "github.com/chainifynet/aws-encryption-sdk-go/pkg/model" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" "github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/conv" ) @@ -46,71 +47,80 @@ var ( ) type encryptedDataKey struct { - providerIDLen int // 2, lenFieldBytes, providerIDLen is length of ProviderID, always present. - ProviderID providerIdentity // string bytes, only awsKmsProviderID supported as ProviderID, always present. - providerInfoLen int // 2, lenFieldBytes, providerInfoLen is length of ProviderInfo, always present. - ProviderInfo string // string bytes, ProviderInfo usually is KMS Key ID ARN, not an alias! + providerIDLen int // 2, lenFieldBytes, providerIDLen is length of providerID, always present. + providerID providerIdentity // string bytes, only awsKmsProviderID supported as providerID, always present. + providerInfoLen int // 2, lenFieldBytes, providerInfoLen is length of providerInfo, always present. + providerInfo string // string bytes, providerInfo usually is KMS Key ID ARN, not an alias! encryptedDataKeyLen int // 2, lenFieldBytes, encryptedDataKeyLen is length of encryptedDataKey encryptedDataKey []byte // bytes, encryptedDataKey is encrypted data key content bytes } func (e edk) new(providerID providerIdentity, providerInfo string, encryptedDataKeyData []byte) (*encryptedDataKey, error) { if strings.HasPrefix(string(providerID), "aws") && providerID != awsKmsProviderID { - return nil, fmt.Errorf("ProviderID %s is not supported: %w", providerID, errEDK) + return nil, fmt.Errorf("providerID %s is not supported: %w", providerID, errEDK) } if strings.HasPrefix(providerInfo, "aws:") && providerID != awsKmsProviderID { - return nil, fmt.Errorf("ProviderInfo %s is not supported: %w", providerInfo, errEDK) + return nil, fmt.Errorf("providerInfo %s is not supported: %w", providerInfo, errEDK) } if len(providerInfo) > math.MaxUint32 { - return nil, fmt.Errorf("ProviderInfo is too large, out of range MaxUint32: %w", errEDK) + return nil, fmt.Errorf("providerInfo is too large, out of range MaxUint32: %w", errEDK) } return &encryptedDataKey{ providerIDLen: len(providerID), - ProviderID: providerID, + providerID: providerID, providerInfoLen: len(providerInfo), - ProviderInfo: providerInfo, + providerInfo: providerInfo, encryptedDataKeyLen: len(encryptedDataKeyData), encryptedDataKey: encryptedDataKeyData, }, nil } -func (edk encryptedDataKey) String() string { - return fmt.Sprintf("%#v", edk) +func (edk encryptedDataKey) ProviderID() string { + return string(edk.providerID) +} + +func (edk encryptedDataKey) ProviderInfo() string { + return edk.providerInfo } -func (edk encryptedDataKey) asKey() model.EncryptedDataKeyI { - return model.NewEncryptedDataKey( - model.WithKeyMeta(string(edk.ProviderID), edk.ProviderInfo), - edk.encryptedDataKey, - ) +func (edk encryptedDataKey) EncryptedDataKey() []byte { + return edk.encryptedDataKey +} + +func (edk encryptedDataKey) String() string { + return fmt.Sprintf("%#v", edk) } -func (edk encryptedDataKey) len() int { +func (edk encryptedDataKey) Len() int { return (EDK.LenFields * lenFieldBytes) + edk.providerIDLen + edk.providerInfoLen + edk.encryptedDataKeyLen } -func (edk encryptedDataKey) bytes() []byte { +func (edk encryptedDataKey) Bytes() []byte { var buf []byte - buf = make([]byte, 0, edk.len()) + buf = make([]byte, 0, edk.Len()) buf = append(buf, conv.FromInt.Uint16BigEndian(edk.providerIDLen)...) - buf = append(buf, []byte(edk.ProviderID)...) + buf = append(buf, []byte(edk.providerID)...) buf = append(buf, conv.FromInt.Uint16BigEndian(edk.providerInfoLen)...) - buf = append(buf, []byte(edk.ProviderInfo)...) + buf = append(buf, []byte(edk.providerInfo)...) buf = append(buf, conv.FromInt.Uint16BigEndian(edk.encryptedDataKeyLen)...) buf = append(buf, edk.encryptedDataKey...) return buf } -func (e edk) AsKeys(msgEDKs []encryptedDataKey) []model.EncryptedDataKeyI { +func (e edk) AsKeys(msgEDKs []format.MessageEDK) []model.EncryptedDataKeyI { edks := make([]model.EncryptedDataKeyI, 0, len(msgEDKs)) for _, k := range msgEDKs { - edks = append(edks, k.asKey()) + ek := model.NewEncryptedDataKey( + model.WithKeyMeta(k.ProviderID(), k.ProviderInfo()), + k.EncryptedDataKey(), + ) + edks = append(edks, ek) } return edks } @@ -125,7 +135,7 @@ func (e edk) validateMinMaxEDKs(k, max int) error { return nil } -func (e edk) fromBufferWithCount(buf *bytes.Buffer) (int, []encryptedDataKey, error) { +func (e edk) fromBufferWithCount(buf *bytes.Buffer) (int, []format.MessageEDK, error) { if buf.Len() < countFieldBytes { return 0, nil, fmt.Errorf("deserialize encrypted data keys count: %w", errEDK) } @@ -135,31 +145,31 @@ func (e edk) fromBufferWithCount(buf *bytes.Buffer) (int, []encryptedDataKey, er return 0, nil, fmt.Errorf("encrypted data keys not found in message header: %w", errEDK) } - var edks []encryptedDataKey + var edks []format.MessageEDK for i := 0; i < encryptedDataKeyCount; i++ { - encDataKey, err := e.fromBuffer(buf) + encDataKey, err := e.deserialize(buf) if err != nil { return 0, nil, fmt.Errorf("cant deserialize expected encrypted data key: %w", errors.Join(errEDK, err)) } - edks = append(edks, *encDataKey) + edks = append(edks, encDataKey) } return encryptedDataKeyCount, edks, nil } -func (e edk) FromEDKs(list []model.EncryptedDataKeyI) ([]encryptedDataKey, error) { - edks := make([]encryptedDataKey, 0, len(list)) +func (e edk) FromEDKs(list []model.EncryptedDataKeyI) ([]format.MessageEDK, error) { + edks := make([]format.MessageEDK, 0, len(list)) for _, keyI := range list { encDataKey, err := e.new(providerIdentity(keyI.KeyProvider().ProviderID), keyI.KeyProvider().KeyID, keyI.EncryptedDataKey()) if err != nil { return nil, err } - edks = append(edks, *encDataKey) + edks = append(edks, encDataKey) } return edks, nil } -func (e edk) fromBuffer(buf *bytes.Buffer) (*encryptedDataKey, error) { +func (e edk) deserialize(buf *bytes.Buffer) (*encryptedDataKey, error) { if buf.Len() < (lenFieldBytes * e.LenFields) { return nil, fmt.Errorf("deserialize encrypted data key") } diff --git a/pkg/serialization/encrypteddatakey_test.go b/pkg/serialization/encrypteddatakey_test.go index b2408fe..d680805 100644 --- a/pkg/serialization/encrypteddatakey_test.go +++ b/pkg/serialization/encrypteddatakey_test.go @@ -74,17 +74,17 @@ func Test_edk_new(t *testing.T) { edk1Mock := &encryptedDataKey{ providerIDLen: 7, - ProviderID: key1Mock.providerID, + providerID: key1Mock.providerID, providerInfoLen: 75, - ProviderInfo: key1Mock.providerInfo, + providerInfo: key1Mock.providerInfo, encryptedDataKeyLen: 184, encryptedDataKey: key1Mock.encryptedDataKeyData, } edk2Mock := &encryptedDataKey{ providerIDLen: 7, - ProviderID: key2Mock.providerID, + providerID: key2Mock.providerID, providerInfoLen: 75, - ProviderInfo: key2Mock.providerInfo, + providerInfo: key2Mock.providerInfo, encryptedDataKeyLen: 184, encryptedDataKey: key2Mock.encryptedDataKeyData, } @@ -115,13 +115,13 @@ func Test_edk_new(t *testing.T) { } assert.Equalf(t, tt.want, got, "new(%v, %v, %#v)", tt.args.providerID, tt.args.providerInfo, tt.args.encryptedDataKeyData) if tt.wantLen != 0 { - assert.Equalf(t, tt.wantBytes, got.bytes(), "bytes() (%v, %v, %#v)", tt.args.providerID, tt.args.providerInfo, tt.args.encryptedDataKeyData) - assert.Equalf(t, tt.wantLen, got.len(), "len() (%v, %v, %#v)", tt.args.providerID, tt.args.providerInfo, tt.args.encryptedDataKeyData) - buf := bytes.NewBuffer(got.bytes()) - got2, err2 := e.fromBuffer(buf) - assert.NoErrorf(t, err2, "fromBuffer() error = %v, (%v, %v, %#v)", err2, tt.args.providerID, tt.args.providerInfo, tt.args.encryptedDataKeyData) - assert.Equalf(t, tt.want, got2, "fromBuffer() (%v, %v, %#v)", tt.args.providerID, tt.args.providerInfo, tt.args.encryptedDataKeyData) - assert.Equalf(t, got, got2, "fromBuffer() (%v, %v, %#v)", tt.args.providerID, tt.args.providerInfo, tt.args.encryptedDataKeyData) + assert.Equalf(t, tt.wantBytes, got.Bytes(), "bytes() (%v, %v, %#v)", tt.args.providerID, tt.args.providerInfo, tt.args.encryptedDataKeyData) + assert.Equalf(t, tt.wantLen, got.Len(), "len() (%v, %v, %#v)", tt.args.providerID, tt.args.providerInfo, tt.args.encryptedDataKeyData) + buf := bytes.NewBuffer(got.Bytes()) + got2, err2 := e.deserialize(buf) + assert.NoErrorf(t, err2, "deserialize() error = %v, (%v, %v, %#v)", err2, tt.args.providerID, tt.args.providerInfo, tt.args.encryptedDataKeyData) + assert.Equalf(t, tt.want, got2, "deserialize() (%v, %v, %#v)", tt.args.providerID, tt.args.providerInfo, tt.args.encryptedDataKeyData) + assert.Equalf(t, got, got2, "deserialize() (%v, %v, %#v)", tt.args.providerID, tt.args.providerInfo, tt.args.encryptedDataKeyData) assert.Equalf(t, 0, buf.Len(), "buffer must have 0") } }) diff --git a/pkg/serialization/headerauthentication.go b/pkg/serialization/headerauthentication.go index 3cc6f20..1c2cf68 100644 --- a/pkg/serialization/headerauthentication.go +++ b/pkg/serialization/headerauthentication.go @@ -6,51 +6,73 @@ package serialization import ( "bytes" "fmt" + + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" ) const ( headerAuthDataLen = int(16) // TODO suite.AlgorithmSuite.EncryptionSuite.AuthLen + headerAuthIvLen = int(12) // iv only present in V1 TODO suite.AlgorithmSuite.EncryptionSuite.IvLen ) -var MessageHeaderAuth mha //nolint:gochecknoglobals - -type mha struct{} - type headerAuth struct { + version suite.MessageFormatVersion authenticationData []byte // 16 bytes, authenticationData is auth tag + iv []byte // 12 bytes, iv always 0x00 bytes in MessageFormatVersion V1, not present in V2 } func (ha headerAuth) AuthData() []byte { return ha.authenticationData } -func (h mha) New(authData []byte) (*headerAuth, error) { +func (ha headerAuth) IV() []byte { + return ha.iv +} + +func NewHeaderAuth(v suite.MessageFormatVersion, iv, authData []byte) (format.MessageHeaderAuth, error) { + // TODO validate MessageFormatVersion and iv if len(authData) != headerAuthDataLen { return nil, fmt.Errorf("incorect len of authData %d", len(authData)) } - return &headerAuth{authenticationData: authData}, nil + return &headerAuth{ + version: v, + iv: iv, + authenticationData: authData, + }, nil } func (ha headerAuth) Len() int { + if ha.version == suite.V1 { + return headerAuthIvLen + headerAuthDataLen // 12 + 16 bytes + } return headerAuthDataLen // 16 bytes, headerAuth.authenticationData is auth tag } -func (ha headerAuth) Serialize() []byte { +func (ha headerAuth) Bytes() []byte { var buf []byte - buf = make([]byte, 0, headerAuthDataLen) + buf = make([]byte, 0, ha.Len()) + if ha.version == suite.V1 { + buf = append(buf, ha.iv...) + } buf = append(buf, ha.authenticationData...) return buf } -// Deserialize can be private -// TODO andrew change to private -func (h mha) Deserialize(buf *bytes.Buffer) (*headerAuth, error) { +func deserializeHeaderAuth(v suite.MessageFormatVersion, buf *bytes.Buffer) (format.MessageHeaderAuth, error) { + var iv []byte + if v == suite.V1 { + if buf.Len() < headerAuthIvLen { + return nil, fmt.Errorf("cant read IV, empty buffer") + } + iv = buf.Next(headerAuthIvLen) + } if buf.Len() < headerAuthDataLen { - return nil, fmt.Errorf("empty buffer") + return nil, fmt.Errorf("cant read authData, empty buffer") } authData := buf.Next(headerAuthDataLen) // TODO copy authData into new slice, otherwise authData capacity is equal to buf capacity - return h.New(authData) + return NewHeaderAuth(v, iv, authData) } diff --git a/pkg/serialization/headerauthentication_test.go b/pkg/serialization/headerauthentication_test.go index d1f7c35..78026ba 100644 --- a/pkg/serialization/headerauthentication_test.go +++ b/pkg/serialization/headerauthentication_test.go @@ -8,11 +8,15 @@ import ( "testing" "github.com/stretchr/testify/assert" + + "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" ) -func Test_mha_New(t *testing.T) { +func Test_NewHeaderAuth(t *testing.T) { type args struct { + version suite.MessageFormatVersion authData []byte + iv []byte } tests := []struct { name string @@ -20,30 +24,31 @@ func Test_mha_New(t *testing.T) { want *headerAuth wantErr bool }{ - {"auth_Nil_Header", args{nil}, &headerAuth{nil}, true}, - {"auth_Nil_Header_2", args{[]uint8(nil)}, &headerAuth{nil}, true}, - {"auth_With_ShortHeader", args{[]byte{0x01}}, &headerAuth{[]byte{0x01}}, true}, - {"auth_Header_Valid_0", args{[]byte("validkeyvalidkey")}, &headerAuth{[]byte("validkeyvalidkey")}, false}, - {"auth_large_header", args{[]byte("largeHeaderDatalargeHeaderDatalargeHeaderData")}, &headerAuth{[]byte{0x6c, 0x61, 0x72, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61}}, true}, - {"auth_header_valid_1", args{[]byte("validkeyvalidkey")}, &headerAuth{[]byte{0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79}}, false}, - {"auth_header_valid_2", args{[]byte("VALIDKEYVALIDKEY")}, &headerAuth{[]byte{0x56, 0x41, 0x4c, 0x49, 0x44, 0x4b, 0x45, 0x59, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x4b, 0x45, 0x59}}, false}, + {"auth_Nil_Header", args{suite.V2, nil, nil}, &headerAuth{suite.V2, nil, nil}, true}, + {"auth_Nil_Header_2", args{suite.V2, []uint8(nil), nil}, &headerAuth{suite.V2, nil, nil}, true}, + {"auth_With_ShortHeader", args{suite.V2, []byte{0x01}, nil}, &headerAuth{suite.V2, []byte{0x01}, nil}, true}, + {"auth_Header_Valid_0", args{suite.V2, []byte("validkeyvalidkey"), nil}, &headerAuth{suite.V2, []byte("validkeyvalidkey"), nil}, false}, + {"auth_large_header", args{suite.V2, []byte("largeHeaderDatalargeHeaderDatalargeHeaderData"), nil}, &headerAuth{suite.V2, []byte{0x6c, 0x61, 0x72, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61}, nil}, true}, + {"auth_header_valid_1", args{suite.V2, []byte("validkeyvalidkey"), nil}, &headerAuth{suite.V2, []byte{0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79}, nil}, false}, + {"auth_header_valid_2", args{suite.V2, []byte("VALIDKEYVALIDKEY"), nil}, &headerAuth{suite.V2, []byte{0x56, 0x41, 0x4c, 0x49, 0x44, 0x4b, 0x45, 0x59, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x4b, 0x45, 0x59}, nil}, false}, + {"auth_header_V1_valid", args{suite.V1, []byte("validkeyvalidkey"), make([]byte, 12)}, &headerAuth{suite.V1, []byte{0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79}, make([]byte, 12)}, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - h := mha{} - got, err := h.New(tt.args.authData) + got, err := NewHeaderAuth(tt.args.version, tt.args.iv, tt.args.authData) if err != nil && tt.wantErr { - assert.Errorf(t, err, "New(%#v) error = %v, wantErr %v", tt.args.authData, err, tt.wantErr) + assert.Errorf(t, err, "NewHeaderAuth(%#v) error = %v, wantErr %v", tt.args.authData, err, tt.wantErr) return } - assert.NoErrorf(t, err, "New(%#v) error = %v, wantErr %v", tt.args.authData, err, tt.wantErr) - assert.Equalf(t, tt.want, got, "New() got = %#v, want %#v", got, tt.args.authData) + assert.NoErrorf(t, err, "NewHeaderAuth(%#v) error = %v, wantErr %v", tt.args.authData, err, tt.wantErr) + assert.Equalf(t, tt.want, got, "NewHeaderAuth() got = %#v, want %#v", got, tt.args.authData) }) } } func Test_headerAuth_AuthData(t *testing.T) { type fields struct { + version suite.MessageFormatVersion authenticationData []byte } tests := []struct { @@ -51,12 +56,14 @@ func Test_headerAuth_AuthData(t *testing.T) { fields fields want []byte }{ - {"auth_header_valid_1", fields{[]byte("validkeyvalidkey")}, []byte{0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79}}, - {"auth_header_valid_2", fields{[]byte("VALIDKEYVALIDKEY")}, []byte{0x56, 0x41, 0x4c, 0x49, 0x44, 0x4b, 0x45, 0x59, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x4b, 0x45, 0x59}}, + {"auth_header_valid_1", fields{suite.V2, []byte("validkeyvalidkey")}, []byte{0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79}}, + {"auth_header_valid_2", fields{suite.V2, []byte("VALIDKEYVALIDKEY")}, []byte{0x56, 0x41, 0x4c, 0x49, 0x44, 0x4b, 0x45, 0x59, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x4b, 0x45, 0x59}}, + {"auth_header_V1_valid", fields{suite.V1, []byte("VALIDKEYVALIDKEY")}, []byte{0x56, 0x41, 0x4c, 0x49, 0x44, 0x4b, 0x45, 0x59, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x4b, 0x45, 0x59}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ha := headerAuth{ + version: tt.fields.version, authenticationData: tt.fields.authenticationData, } assert.Equalf(t, tt.want, ha.AuthData(), "AuthData()") @@ -66,6 +73,7 @@ func Test_headerAuth_AuthData(t *testing.T) { func Test_headerAuth_Len(t *testing.T) { type fields struct { + version suite.MessageFormatVersion authenticationData []byte } tests := []struct { @@ -73,14 +81,16 @@ func Test_headerAuth_Len(t *testing.T) { fields fields want int }{ - {"auth_header_valid_1", fields{[]byte("validkeyvalidkey")}, 16}, - {"auth_header_valid_2", fields{[]byte("VALIDKEYVALIDKEY")}, 16}, - {"auth_header_invalid_nil", fields{nil}, 16}, - {"auth_header_invalid_1byte", fields{[]byte{0x01}}, 16}, + {"auth_header_valid_1", fields{suite.V2, []byte("validkeyvalidkey")}, 16}, + {"auth_header_valid_2", fields{suite.V2, []byte("VALIDKEYVALIDKEY")}, 16}, + {"auth_header_invalid_nil", fields{suite.V2, nil}, 16}, + {"auth_header_invalid_1byte", fields{suite.V2, []byte{0x01}}, 16}, + {"auth_header_v1", fields{suite.V1, []byte("validkeyvalidkey")}, 28}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ha := headerAuth{ + version: tt.fields.version, authenticationData: tt.fields.authenticationData, } assert.Equalf(t, tt.want, ha.Len(), "Len()") @@ -88,36 +98,42 @@ func Test_headerAuth_Len(t *testing.T) { } } -func Test_headerAuth_Serialize(t *testing.T) { +func Test_headerAuth_Bytes(t *testing.T) { type fields struct { + version suite.MessageFormatVersion authenticationData []byte + iv []byte } tests := []struct { name string fields fields want []byte }{ - {"auth_header_valid_1", fields{[]byte("validkeyvalidkey")}, []byte{0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79}}, - {"auth_header_valid_2", fields{[]byte("VALIDKEYVALIDKEY")}, []byte{0x56, 0x41, 0x4c, 0x49, 0x44, 0x4b, 0x45, 0x59, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x4b, 0x45, 0x59}}, - {"auth_header_invalid_size_1", fields{[]byte("invalid")}, []byte{0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64}}, - {"auth_header_invalid_size_2", fields{[]byte("123")}, []byte{0x31, 0x32, 0x33}}, - {"auth_header_invalid_nil", fields{nil}, []byte{}}, + {"auth_header_valid_1", fields{suite.V2, []byte("validkeyvalidkey"), nil}, []byte{0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79}}, + {"auth_header_valid_2", fields{suite.V2, []byte("VALIDKEYVALIDKEY"), nil}, []byte{0x56, 0x41, 0x4c, 0x49, 0x44, 0x4b, 0x45, 0x59, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x4b, 0x45, 0x59}}, + {"auth_header_invalid_size_1", fields{suite.V2, []byte("invalid"), nil}, []byte{0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64}}, + {"auth_header_invalid_size_2", fields{suite.V2, []byte("123"), nil}, []byte{0x31, 0x32, 0x33}}, + {"auth_header_invalid_nil", fields{suite.V2, nil, nil}, []byte{}}, + {"auth_header_V1_valid", fields{suite.V1, []byte("validkeyvalidkey"), make([]byte, 12)}, []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ha := headerAuth{ + version: tt.fields.version, authenticationData: tt.fields.authenticationData, + iv: tt.fields.iv, } - got := ha.Serialize() + got := ha.Bytes() gotCap := cap(got) - assert.Equalf(t, ha.Len(), gotCap, "Serialize() cap = %v, wantCap = %v", gotCap, ha.Len()) - assert.Equalf(t, tt.want, got, "Serialize()") + assert.Equalf(t, ha.Len(), gotCap, "Bytes() cap = %v, wantCap = %v", gotCap, ha.Len()) + assert.Equalf(t, tt.want, got, "Bytes()") }) } } -func Test_mha_Deserialize(t *testing.T) { +func Test_deserializeHeaderAuth(t *testing.T) { type args struct { + v suite.MessageFormatVersion buf *bytes.Buffer } type wants struct { @@ -133,24 +149,51 @@ func Test_mha_Deserialize(t *testing.T) { wants wants wantErr bool }{ - {"empty_buffer", args{bytes.NewBuffer(nil)}, wants{&headerAuth{nil}, 0, 0, 0, 0}, true}, - {"invalid_length_buffer", args{bytes.NewBuffer([]byte("123"))}, wants{&headerAuth{nil}, 3, 3, 3, 3}, true}, - {"exact_size_buffer", args{bytes.NewBuffer([]byte("validkeyvalidkey"))}, wants{&headerAuth{[]byte{0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79}}, 16, 16, 0, 16}, false}, - {"much_bigger_buffer", args{bytes.NewBuffer([]byte("validkeyvalidkey123"))}, wants{&headerAuth{[]byte{0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79}}, 19, 19, 3, 19}, false}, + {"empty_buffer", args{suite.V2, bytes.NewBuffer(nil)}, wants{&headerAuth{suite.V2, nil, nil}, 0, 0, 0, 0}, true}, + {"invalid_length_buffer", args{suite.V2, bytes.NewBuffer([]byte("123"))}, wants{&headerAuth{suite.V2, nil, nil}, 3, 3, 3, 3}, true}, + {"exact_size_buffer", args{suite.V2, bytes.NewBuffer([]byte("validkeyvalidkey"))}, wants{&headerAuth{suite.V2, []byte{0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79}, nil}, 16, 16, 0, 16}, false}, + {"much_bigger_buffer", args{suite.V2, bytes.NewBuffer([]byte("validkeyvalidkey123"))}, wants{&headerAuth{suite.V2, []byte{0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79}, nil}, 19, 19, 3, 19}, false}, + {"exact_size_buffer_V1", args{suite.V1, bytes.NewBuffer([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79})}, wants{&headerAuth{suite.V1, []byte{0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x6b, 0x65, 0x79}, make([]byte, 12)}, 28, 28, 0, 28}, false}, + {"invalid_length_buffer_V1", args{suite.V1, bytes.NewBuffer([]byte("123"))}, wants{&headerAuth{suite.V1, nil, nil}, 3, 3, 3, 3}, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - h := mha{} - got, err := h.Deserialize(tt.args.buf) - assert.Equalf(t, tt.wants.bufLenAfter, tt.args.buf.Len(), "Deserialize() must read exactly number of bytes, buf.Len() = %v, want %v", tt.args.buf.Len(), tt.wants.bufLenAfter) - assert.Equalf(t, tt.wants.bufCapAfter, tt.args.buf.Cap(), "Deserialize() must not resize buffer, buf.Cap() = %v, want %v", tt.args.buf.Cap(), tt.wants.bufCapAfter) - assert.Equalf(t, tt.wants.bufCap, tt.args.buf.Cap(), "Deserialize() must not resize buffer, buf.Cap() = %v, want %v", tt.args.buf.Cap(), tt.wants.bufCap) + got, err := deserializeHeaderAuth(tt.args.v, tt.args.buf) + assert.Equalf(t, tt.wants.bufLenAfter, tt.args.buf.Len(), "deserializeHeaderAuth() must read exactly number of bytes, buf.Len() = %v, want %v", tt.args.buf.Len(), tt.wants.bufLenAfter) + assert.Equalf(t, tt.wants.bufCapAfter, tt.args.buf.Cap(), "deserializeHeaderAuth() must not resize buffer, buf.Cap() = %v, want %v", tt.args.buf.Cap(), tt.wants.bufCapAfter) + assert.Equalf(t, tt.wants.bufCap, tt.args.buf.Cap(), "deserializeHeaderAuth() must not resize buffer, buf.Cap() = %v, want %v", tt.args.buf.Cap(), tt.wants.bufCap) if err != nil && tt.wantErr { - assert.Errorf(t, err, "Deserialize(%#v) error = %v, wantErr %v", tt.args.buf, err, tt.wantErr) + assert.Errorf(t, err, "deserializeHeaderAuth(%#v) error = %v, wantErr %v", tt.args.buf, err, tt.wantErr) return } - assert.NoErrorf(t, err, "Deserialize(%#v) error = %v, wantErr %v", tt.args.buf, err, tt.wantErr) - assert.Equalf(t, tt.wants.want, got, "Deserialize(%#v)", tt.args.buf) + assert.NoErrorf(t, err, "deserializeHeaderAuth(%#v) error = %v, wantErr %v", tt.args.buf, err, tt.wantErr) + assert.Equalf(t, tt.wants.want, got, "deserializeHeaderAuth(%#v)", tt.args.buf) + }) + } +} + +func Test_headerAuth_IV(t *testing.T) { + type fields struct { + version suite.MessageFormatVersion + authenticationData []byte + iv []byte + } + tests := []struct { + name string + fields fields + want []byte + }{ + {"auth_header_V1", fields{suite.V1, []byte("validkeyvalidkey"), make([]byte, 12)}, make([]byte, 12)}, + {"auth_header_V2", fields{suite.V2, []byte("validkeyvalidkey"), nil}, nil}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ha := headerAuth{ + version: tt.fields.version, + authenticationData: tt.fields.authenticationData, + iv: tt.fields.iv, + } + assert.Equalf(t, tt.want, ha.IV(), "IV()") }) } } diff --git a/pkg/serialization/messageheader.go b/pkg/serialization/messageheader.go index 96f846c..f65c98e 100644 --- a/pkg/serialization/messageheader.go +++ b/pkg/serialization/messageheader.go @@ -8,7 +8,7 @@ import ( "errors" "fmt" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/logger" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" "github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/conv" ) @@ -18,41 +18,53 @@ var ( errHeaderDeserialize = errors.New("header deserialization error") ) +var ( + //nolint:gochecknoglobals + reservedField = []uint8{0x00, 0x00, 0x00, 0x00} // 4, MessageHeader Reserved field. The value is encoded as the 4 bytes 00 00 00 00 in hexadecimal notation. +) + const ( - minimumHeaderBufferLen = int(77) + minimumHeaderBufferLen = int(18) ) // All AES-GCM algorithm suites have a 12-byte initialization vector and a 16-byte AES-GCM authentication tag. // reference https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/IV-reference.html -var EncryptedMessageHeader emh //nolint:gochecknoglobals +type messageHeader struct { + version suite.MessageFormatVersion // 1, comes from AlgorithmSuite, message version, always present. + algorithmSuite *suite.AlgorithmSuite // 2, AlgorithmID in AlgorithmSuite, supported only 0x0578 (1400) and 0x0478 (1144), always present. Reference (https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/algorithms-reference.html) + messageID []byte // 16 or 32, messageID (random 256-bit value). Always present. Algorithm suites with key commitment (algorithm ID 04xx and 05xx) for the extract step (HKDF with SHA-512) used as salt. + aadLen int // 2, aadLen is AAD Length (When the encryption context is empty, the value of the AAD Length field is 0), length AADData in bytes not including aadLen + authenticatedData format.MessageAAD // authenticatedData is aadData Key-Value Pair (AADData) data (Key-Value Pair Count + []keyValuePair data). Bytes varies, aadLen = N bytes of AADData. present if aadLen > 0. + encryptedDataKeyCount int // 2, EncryptedDataKeyCount is count of EncryptedDataKeys below, always present. + encryptedDataKeys []format.MessageEDK // EncryptedDataKeys varies + contentType suite.ContentType // 1, contentType is 0x01 Non-Framed or 0x02 Framed content + frameLength int // 4, frameLength is the length of each frame of framed data. It is a 4-byte value interpreted as a 32-bit unsigned integer that specifies the number of bytes in each frame. When the data is non-framed, that is, when the value of the contentType field is 0x01, this value must be 0. +} -type emh struct{} +type messageHeaderV1 struct { + messageHeader + messageType suite.MessageType // 1, format.MessageType, present only in V1 + reserved []byte // 4, reserved, present only in V1, always 0x00,0x00,0x00,0x00 + ivLen int // 1, length of IV, present only in V1, always 12 +} -type MessageHeader struct { - // // 1, comes from AlgorithmSuite, message version, supported only version 2, always present as 0x02. - AlgorithmSuite *suite.AlgorithmSuite // 2, AlgorithmID in AlgorithmSuite, supported only 0x0578 (1400) and 0x0478 (1144), always present. Reference (https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/algorithms-reference.html) - MessageID []byte // 32, MessageID (random 256-bit value). Always present. Algorithm suites with key commitment (algorithm ID 04xx and 05xx) for the extract step (HKDF with SHA-512) used as salt. - aadLen int // 2, aadLen is AAD Length (When the encryption context is empty, the value of the AAD Length field is 0), length AADData in bytes not including aadLen - AADData *aadData // AADData is AAD Key-Value Pair (AADData) data (Key-Value Pair Count + []keyValuePair data). Bytes varies, aadLen = N bytes of AADData. present if aadLen > 0. - EncryptedDataKeyCount int // 2, EncryptedDataKeyCount is count of EncryptedDataKeys below, always present. - EncryptedDataKeys []encryptedDataKey // EncryptedDataKeys varies - contentType suite.ContentType // 2, contentType is 0x01 Non-Framed or 0x02 Framed content - FrameLength int // 4, FrameLength is the length of each frame of framed data. It is a 4-byte value interpreted as a 32-bit unsigned integer that specifies the number of bytes in each frame. When the data is non-framed, that is, when the value of the contentType field is 0x01, this value must be 0. - AlgorithmSuiteData []byte // 32 bytes, AlgorithmSuiteData +type messageHeaderV2 struct { + messageHeader + algorithmSuiteData []byte // 32 bytes, algorithmSuiteData aka commitmentKey, present only in V2 } -type MessageHeaderParams struct { +type HeaderParams struct { AlgorithmSuite *suite.AlgorithmSuite MessageID []byte - AADData *aadData - EncryptedDataKeys []encryptedDataKey + EncryptionContext suite.EncryptionContext + EncryptedDataKeys []format.MessageEDK ContentType suite.ContentType FrameLength int AlgorithmSuiteData []byte } -func (mh emh) New(p MessageHeaderParams) (*MessageHeader, error) { +func NewHeader(p HeaderParams) (format.MessageHeader, error) { if p.AlgorithmSuite == nil { return nil, fmt.Errorf("invalid AlgorithmSuite: %v", p.AlgorithmSuite) } @@ -69,76 +81,45 @@ func (mh emh) New(p MessageHeaderParams) (*MessageHeader, error) { if len(p.AlgorithmSuiteData) != p.AlgorithmSuite.AlgorithmSuiteDataLen() { return nil, fmt.Errorf("invalid AlgorithmSuiteData length") } - aadLen := 0 - if p.AADData != nil { - aadLen = p.AADData.Len() - //return nil, fmt.Errorf("invalid AADData: %v", p.AADData) - } - if p.FrameLength < suite.MinFrameSize || p.FrameLength > suite.MaxFrameSize { + + authenticatedData := AAD.NewAADWithEncryptionContext(p.EncryptionContext) + aadLen := authenticatedData.Len() + + if err := suite.ValidateFrameLength(p.FrameLength); err != nil { return nil, fmt.Errorf("%v frame length out of range", p.FrameLength) } - if p.ContentType != suite.FramedContent { - return nil, fmt.Errorf("ContentType %v not supported", p.ContentType) + if err := suite.ValidateContentType(p.ContentType); err != nil { + return nil, fmt.Errorf("contentType: %w", err) } - return &MessageHeader{ - AlgorithmSuite: p.AlgorithmSuite, - MessageID: p.MessageID, + header := messageHeader{ + version: p.AlgorithmSuite.MessageFormatVersion, + algorithmSuite: p.AlgorithmSuite, + messageID: p.MessageID, aadLen: aadLen, - AADData: p.AADData, - EncryptedDataKeyCount: len(p.EncryptedDataKeys), - EncryptedDataKeys: p.EncryptedDataKeys, + authenticatedData: authenticatedData, + encryptedDataKeyCount: len(p.EncryptedDataKeys), + encryptedDataKeys: p.EncryptedDataKeys, contentType: p.ContentType, - FrameLength: p.FrameLength, - AlgorithmSuiteData: p.AlgorithmSuiteData, - }, nil -} - -//go:cover ignore -func (mh MessageHeader) String() string { - return fmt.Sprintf("%#v", mh) -} - -func (mh MessageHeader) Len() int { - edkLen := 0 - for _, key := range mh.EncryptedDataKeys { - edkLen += key.len() + frameLength: p.FrameLength, } - // 1 + 32 + 2 + 2 + 101 + 2 + 272 + 1 + 4 + 32 - return singleFieldBytes + // MessageHeader version of AlgorithmSuite - len(mh.AlgorithmSuite.IDBytes()) + // AlgorithmID of AlgorithmSuite - len(mh.MessageID) + - lenFieldBytes + // MessageHeader.aadLen field itself - mh.aadLen + // which is AADData.Len(), 0 if aadLen == 0 - countFieldBytes + // MessageHeader.EncryptedDataKeyCount - edkLen + - singleFieldBytes + // MessageHeader.contentType - len(conv.FromInt.Uint32BigEndian(mh.FrameLength)) + // MessageHeader.FrameLength - len(mh.AlgorithmSuiteData) -} + if p.AlgorithmSuite.MessageFormatVersion == suite.V2 { + return &messageHeaderV2{ + messageHeader: header, + algorithmSuiteData: p.AlgorithmSuiteData, + }, nil + } -func (mh MessageHeader) Bytes() []byte { - var buf []byte - buf = make([]byte, 0, mh.Len()) - buf = append(buf, uint8(mh.AlgorithmSuite.MessageFormatVersion)) // 1, MessageFormatVersion of AlgorithmSuite - buf = append(buf, mh.AlgorithmSuite.IDBytes()...) // 2, AlgorithmID of AlgorithmSuite - buf = append(buf, mh.MessageID...) // 32 - buf = append(buf, conv.FromInt.Uint16BigEndian(mh.aadLen)...) // 2 - if mh.aadLen > 0 && mh.AADData != nil { - buf = append(buf, mh.AADData.Bytes()...) // 2(count) + 25 + 29 + 45 = 101 - } - buf = append(buf, conv.FromInt.Uint16BigEndian(mh.EncryptedDataKeyCount)...) // 2 - for _, key := range mh.EncryptedDataKeys { - buf = append(buf, key.bytes()...) // 272 - } - buf = append(buf, uint8(mh.contentType)) // 1 - buf = append(buf, conv.FromInt.Uint32BigEndian(mh.FrameLength)...) // 4 - buf = append(buf, mh.AlgorithmSuiteData...) // 32 - return buf + return &messageHeaderV1{ + messageHeader: header, + messageType: suite.CustomerAEData, + reserved: reservedField, + ivLen: p.AlgorithmSuite.EncryptionSuite.IVLen, + }, nil } -func (mh emh) fromBuffer(buf *bytes.Buffer) (*MessageHeader, error) { +func deserializeHeader(buf *bytes.Buffer) (format.MessageHeader, error) { //nolint:cyclop if buf == nil { return nil, fmt.Errorf("empty buffer: %w", errHeaderDeserialize) } @@ -148,6 +129,19 @@ func (mh emh) fromBuffer(buf *bytes.Buffer) (*MessageHeader, error) { version := fieldReader.ReadSingleField(buf) + if err := suite.ValidateMessageVersion(version); err != nil { + return nil, fmt.Errorf("invalid version %v: %w", version, errHeaderDeserialize) + } + + messageVersion := suite.MessageFormatVersion(version) + + if messageVersion == suite.V1 { + messageType := fieldReader.ReadSingleField(buf) + if suite.MessageType(messageType) != suite.CustomerAEData { + return nil, fmt.Errorf("invalid messageType %v not supported: %w", messageType, errHeaderDeserialize) + } + } + algorithmID := buf.Next(algorithmIDFieldBytes) // AlgorithmID is 2 bytes, uint16 // validate AlgorithmID is supported @@ -157,23 +151,28 @@ func (mh emh) fromBuffer(buf *bytes.Buffer) (*MessageHeader, error) { } // validate message version is the same as AlgorithmSuite MessageFormatVersion - if int(version) != algorithmSuite.MessageFormatVersion { + if messageVersion != algorithmSuite.MessageFormatVersion { return nil, fmt.Errorf("%v message version not equal to Algorithm defined: %w", version, errHeaderInvalidVersion) } + if buf.Len() < algorithmSuite.MessageIDLen() { + return nil, fmt.Errorf("empty buffer, cant read messageID: %w", errHeaderDeserialize) + } messageID := buf.Next(algorithmSuite.MessageIDLen()) // here we ignore error since 0 is valid value for aadLen even with error // the rest will be handled by AADData.fromBuffer aadLen, _ := fieldReader.ReadLenField(buf) var aadData *aadData + var encryptionContext suite.EncryptionContext if aadLen > 0 { + if buf.Len() < aadLen { + return nil, fmt.Errorf("empty buffer, cant read aadData: %w", errHeaderDeserialize) + } aadData = AAD.FromBuffer(buf) + encryptionContext = aadData.EncryptionContext() } - // TODO support limit encrypted data keys feature when decrypt - // TODO andrew done in encryptionsdk/serialization/deserialize.go:16 - //encryptedDataKeyCount, encryptedDataKeys, err := EDK.fromBufferWithCount(buf) _, encryptedDataKeys, err := EDK.fromBufferWithCount(buf) if err != nil { return nil, fmt.Errorf("header EDK: %w", err) @@ -182,35 +181,209 @@ func (mh emh) fromBuffer(buf *bytes.Buffer) (*MessageHeader, error) { if buf.Len() < singleFieldBytes { return nil, fmt.Errorf("empty buffer, cant read contentType: %w", errHeaderDeserialize) } - contentType := fieldReader.ReadSingleField(buf) - if suite.ContentType(contentType) != suite.FramedContent { + contentType := suite.ContentType(fieldReader.ReadSingleField(buf)) + if err := suite.ValidateContentType(contentType); err != nil { return nil, fmt.Errorf("ContentType %v not supported: %w", contentType, errHeaderDeserialize) } + if messageVersion == suite.V1 { + if buf.Len() < len(reservedField) { + return nil, fmt.Errorf("empty buffer, cant read reservedField, %w", errHeaderDeserialize) + } + reserved := buf.Next(len(reservedField)) + if !bytes.Equal(reserved, reservedField) { + return nil, fmt.Errorf("invalid reservedField, %w", errHeaderDeserialize) + } + + if buf.Len() < singleFieldBytes { + return nil, fmt.Errorf("empty buffer, cant read ivLen: %w", errHeaderDeserialize) + } + + ivLen := fieldReader.ReadSingleField(buf) + if int(ivLen) != algorithmSuite.EncryptionSuite.IVLen { + return nil, fmt.Errorf("ivLen %v not supported: %w", ivLen, errHeaderDeserialize) + } + } + frameLength, err := fieldReader.ReadFrameField(buf) if err != nil { return nil, fmt.Errorf("cant read frameLength, %w", errHeaderDeserialize) } - // validate min(128) and max(maxUint32) frame len - if frameLength < suite.MinFrameSize || frameLength > suite.MaxFrameSize { + if err := suite.ValidateFrameLength(frameLength); err != nil { return nil, fmt.Errorf("%v frame length out of range: %w", frameLength, errHeaderDeserialize) } - if buf.Len() < algorithmSuite.AlgorithmSuiteDataLen() { - return nil, fmt.Errorf("empty buffer, cant read algorithmSuiteData, %w", errHeaderDeserialize) + var algorithmSuiteData []byte + if messageVersion == suite.V2 { + if buf.Len() < algorithmSuite.AlgorithmSuiteDataLen() { + return nil, fmt.Errorf("empty buffer, cant read algorithmSuiteData, %w", errHeaderDeserialize) + } + // should be 32, only for V2 + algorithmSuiteData = buf.Next(algorithmSuite.AlgorithmSuiteDataLen()) } - // should be 32 - algorithmSuiteData := buf.Next(algorithmSuite.AlgorithmSuiteDataLen()) - - log.Trace().MsgFunc(logger.FmtHex("AlgorithmSuiteData", algorithmSuiteData)) - return mh.New(MessageHeaderParams{ - MessageID: messageID, + return NewHeader(HeaderParams{ AlgorithmSuite: algorithmSuite, - AADData: aadData, + MessageID: messageID, + EncryptionContext: encryptionContext, EncryptedDataKeys: encryptedDataKeys, - ContentType: suite.ContentType(contentType), + ContentType: contentType, FrameLength: frameLength, AlgorithmSuiteData: algorithmSuiteData, }) } + +func (h *messageHeaderV1) Len() int { + edkLen := 0 + for _, key := range h.encryptedDataKeys { + edkLen += key.Len() + } + + // 1 + 1 + 2 + 16 + 2 + 2 + 101 + 2 + 272 + 1 + 4 + 1 + 4 + return singleFieldBytes + // 1 MessageHeader version of AlgorithmSuite + singleFieldBytes + // 1 MessageHeader type + len(h.algorithmSuite.IDBytes()) + // 2 AlgorithmID of AlgorithmSuite + len(h.messageID) + // 16 MessageID is 16 bytes for V1 + lenFieldBytes + // MessageHeader.aadLen field itself + h.aadLen + // which is AADData.Len(), 0 if aadLen == 0 + countFieldBytes + // 2, MessageHeader.EncryptedDataKeyCount + edkLen + // EncryptedDataKeys len + singleFieldBytes + // 1, MessageHeader.contentType + len(reservedField) + // 4, MessageHeader.Reserved + singleFieldBytes + // 1, MessageHeader.IvLen + len(conv.FromInt.Uint32BigEndian(h.frameLength)) // 4, MessageHeader.FrameLength +} + +func (h *messageHeaderV1) Bytes() []byte { + var buf []byte + buf = make([]byte, 0, h.Len()) + // 1, MessageFormatVersion of AlgorithmSuite + // 1, MessageType + buf = append(buf, uint8(h.algorithmSuite.MessageFormatVersion), uint8(h.messageType)) + buf = append(buf, h.algorithmSuite.IDBytes()...) // 2, AlgorithmID of AlgorithmSuite + buf = append(buf, h.messageID...) // 16 + buf = append(buf, conv.FromInt.Uint16BigEndian(h.aadLen)...) // 2 + writeAAD(&buf, h.aadLen, h.authenticatedData) // 2(count) + 25 + 29 + 45 = 101 + buf = append(buf, conv.FromInt.Uint16BigEndian(h.encryptedDataKeyCount)...) // 2 + writeEncryptedDataKeys(&buf, h.encryptedDataKeys) // 272 + buf = append(buf, uint8(h.contentType)) // 1 + buf = append(buf, reservedField...) // 4, Reserved + buf = append(buf, uint8(h.ivLen)) // 1, IvLen + buf = append(buf, conv.FromInt.Uint32BigEndian(h.frameLength)...) // 4 + return buf +} + +func (h *messageHeaderV2) Len() int { + edkLen := 0 + for _, key := range h.encryptedDataKeys { + edkLen += key.Len() + } + + // 1 + 32 + 2 + 2 + 101 + 2 + 272 + 1 + 4 + 32 + return singleFieldBytes + // MessageHeader version of AlgorithmSuite + len(h.algorithmSuite.IDBytes()) + // AlgorithmID of AlgorithmSuite + len(h.messageID) + + lenFieldBytes + // MessageHeader.aadLen field itself + h.aadLen + // whi ch is AADData.Len(), 0 if aadLen == 0 + countFieldBytes + // MessageHeader.EncryptedDataKeyCount + edkLen + + singleFieldBytes + // MessageHeader.contentType + len(conv.FromInt.Uint32BigEndian(h.frameLength)) + // MessageHeader.FrameLength + len(h.algorithmSuiteData) +} + +func (h *messageHeaderV2) Bytes() []byte { + var buf []byte + buf = make([]byte, 0, h.Len()) + buf = append(buf, uint8(h.algorithmSuite.MessageFormatVersion)) // 1, MessageFormatVersion of AlgorithmSuite + buf = append(buf, h.algorithmSuite.IDBytes()...) // 2, AlgorithmID of AlgorithmSuite + buf = append(buf, h.messageID...) // 32 + buf = append(buf, conv.FromInt.Uint16BigEndian(h.aadLen)...) // 2 + writeAAD(&buf, h.aadLen, h.authenticatedData) // 2(count) + 25 + 29 + 45 = 101 + buf = append(buf, conv.FromInt.Uint16BigEndian(h.encryptedDataKeyCount)...) // 2 + writeEncryptedDataKeys(&buf, h.encryptedDataKeys) // 272 + buf = append(buf, uint8(h.contentType)) // 1 + buf = append(buf, conv.FromInt.Uint32BigEndian(h.frameLength)...) // 4 + buf = append(buf, h.algorithmSuiteData...) // 32 + return buf +} + +func (h *messageHeader) Version() suite.MessageFormatVersion { + return h.version +} + +func (h *messageHeader) AlgorithmSuite() *suite.AlgorithmSuite { + return h.algorithmSuite +} + +func (h *messageHeader) MessageID() []byte { + return h.messageID +} + +func (h *messageHeader) AADLength() int { + return h.aadLen +} + +func (h *messageHeader) AADData() format.MessageAAD { + return h.authenticatedData +} + +func (h *messageHeader) EncryptedDataKeyCount() int { + return h.encryptedDataKeyCount +} + +func (h *messageHeader) EncryptedDataKeys() []format.MessageEDK { + return h.encryptedDataKeys +} + +func (h *messageHeader) ContentType() suite.ContentType { + return h.contentType +} + +func (h *messageHeader) FrameLength() int { + return h.frameLength +} + +func (h *messageHeaderV1) Type() suite.MessageType { + return h.messageType +} + +func (h *messageHeaderV1) Reserved() []byte { + return h.reserved +} + +func (h *messageHeaderV1) IVLength() int { + return h.ivLen +} + +func (h *messageHeaderV1) AlgorithmSuiteData() []byte { + return nil +} + +func (h *messageHeaderV2) Type() suite.MessageType { + return 0 +} + +func (h *messageHeaderV2) Reserved() []byte { + return nil +} + +func (h *messageHeaderV2) IVLength() int { + return 0 +} + +func (h *messageHeaderV2) AlgorithmSuiteData() []byte { + return h.algorithmSuiteData +} + +func writeAAD(buf *[]byte, aadLen int, data format.MessageAAD) { + if aadLen > 0 && data != nil { + *buf = append(*buf, data.Bytes()...) // 2(count) + 25 + 29 + 45 = 101 + } +} + +func writeEncryptedDataKeys(buf *[]byte, edks []format.MessageEDK) { + for _, key := range edks { + *buf = append(*buf, key.Bytes()...) // 272 + } +} diff --git a/pkg/serialization/messageheader_test.go b/pkg/serialization/messageheader_test.go index 1ca70dc..46b3c8c 100644 --- a/pkg/serialization/messageheader_test.go +++ b/pkg/serialization/messageheader_test.go @@ -11,133 +11,242 @@ import ( "github.com/stretchr/testify/assert" "github.com/chainifynet/aws-encryption-sdk-go/pkg/logger" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" ) -func Test_emh_New(t *testing.T) { +func TestNewHeader(t *testing.T) { type args struct { - p MessageHeaderParams + p HeaderParams } + edk1Mock, _ := EDK.new(awsKmsProviderID, "test", []byte("test")) - mh1Mock := &MessageHeader{ - AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, - MessageID: []byte("MessageID12MessageID12MessageID1"), - aadLen: 0, - AADData: nil, - EncryptedDataKeyCount: 1, - EncryptedDataKeys: []encryptedDataKey{*edk1Mock}, - contentType: suite.FramedContent, - FrameLength: 1024, - AlgorithmSuiteData: []byte("Algorithm12Algorithm12Algorithm1"), + mh1Mock := &messageHeaderV2{ + messageHeader: messageHeader{ + version: suite.V2, + algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + messageID: []byte("MessageID12MessageID12MessageID1"), + aadLen: 0, + authenticatedData: AAD.NewAAD(), + encryptedDataKeyCount: 1, + encryptedDataKeys: []format.MessageEDK{edk1Mock}, + contentType: suite.FramedContent, + frameLength: 1024, + }, + algorithmSuiteData: []byte("Algorithm12Algorithm12Algorithm1"), + } + + mh2Mock := &messageHeaderV2{ + messageHeader: messageHeader{ + version: suite.V2, + algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + messageID: []byte("MessageID12MessageID12MessageID1"), + aadLen: 0, + authenticatedData: AAD.NewAAD(), + encryptedDataKeyCount: 1, + encryptedDataKeys: []format.MessageEDK{edk1Mock}, + contentType: suite.FramedContent, + frameLength: 1024, + }, + algorithmSuiteData: []byte("Algorithm12Algorithm12Algorithm1"), + } + + mh3Mock := &messageHeaderV2{ + messageHeader: messageHeader{ + version: suite.V2, + algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + messageID: []byte("MessageID12MessageID12MessageID1"), + aadLen: 17, // Key-Value Pair Count: 1 = 2 bytes (count) + 2 bytes keyLen + 4 bytes key (test) + 2 bytes valueLen + 7 bytes value (testing) + authenticatedData: AAD.NewAADWithEncryptionContext(map[string]string{"test": "testing"}), + encryptedDataKeyCount: 1, + encryptedDataKeys: []format.MessageEDK{edk1Mock}, + contentType: suite.FramedContent, + frameLength: 1024, + }, + algorithmSuiteData: []byte("Algorithm12Algorithm12Algorithm1"), } - mh2Mock := &MessageHeader{ - AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, - MessageID: []byte("MessageID12MessageID12MessageID1"), - aadLen: 0, - AADData: AAD.NewAAD(), - EncryptedDataKeyCount: 1, - EncryptedDataKeys: []encryptedDataKey{*edk1Mock}, - contentType: suite.FramedContent, - FrameLength: 1024, - AlgorithmSuiteData: []byte("Algorithm12Algorithm12Algorithm1"), + + mh1MockV1 := &messageHeaderV1{ + messageHeader: messageHeader{ + version: suite.V1, + algorithmSuite: suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, + messageID: []byte("MessageMessage16"), + aadLen: 0, + authenticatedData: AAD.NewAAD(), + encryptedDataKeyCount: 1, + encryptedDataKeys: []format.MessageEDK{edk1Mock}, + contentType: suite.FramedContent, + frameLength: 1024, + }, + messageType: suite.CustomerAEData, + reserved: reservedField, + ivLen: 12, } - mh3Mock := &MessageHeader{ - AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, - MessageID: []byte("MessageID12MessageID12MessageID1"), - aadLen: 17, // Key-Value Pair Count: 1 = 2 bytes (count) + 2 bytes keyLen + 4 bytes key (test) + 2 bytes valueLen + 7 bytes value (testing) - AADData: AAD.NewAADWithEncryptionContext(map[string]string{"test": "testing"}), - EncryptedDataKeyCount: 1, - EncryptedDataKeys: []encryptedDataKey{*edk1Mock}, - contentType: suite.FramedContent, - FrameLength: 1024, - AlgorithmSuiteData: []byte("Algorithm12Algorithm12Algorithm1"), + + mh3MockV1 := &messageHeaderV1{ + messageHeader: messageHeader{ + version: suite.V1, + algorithmSuite: suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, + messageID: []byte("MessageMessage16"), + aadLen: 17, + authenticatedData: AAD.NewAADWithEncryptionContext(map[string]string{"test": "testing"}), + encryptedDataKeyCount: 1, + encryptedDataKeys: []format.MessageEDK{edk1Mock}, + contentType: suite.FramedContent, + frameLength: 1024, + }, + messageType: suite.CustomerAEData, + reserved: reservedField, + ivLen: 12, } tests := []struct { name string args args - want *MessageHeader - wantFromBuffer *MessageHeader + want format.MessageHeader + wantFromBuffer format.MessageHeader wantErr bool }{ - {"nilAlgorithmSuite", args{MessageHeaderParams{nil, []byte("test"), nil, nil, suite.NonFramedContent, 10, []byte("test")}}, nil, nil, true}, - {"invalidMessageID", args{MessageHeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, nil, nil, nil, suite.NonFramedContent, 10, []byte("test")}}, nil, nil, true}, - {"invalidMessageID", args{MessageHeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("test"), nil, nil, suite.NonFramedContent, 10, []byte("test")}}, nil, nil, true}, - {"invalidEncryptedDataKeys", args{MessageHeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), nil, nil, suite.NonFramedContent, 10, []byte("test")}}, nil, nil, true}, - {"invalidAlgorithmSuiteDataLen", args{MessageHeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), nil, []encryptedDataKey{*edk1Mock}, suite.NonFramedContent, 10, []byte("test")}}, nil, nil, true}, - {"invalidFrameLength", args{MessageHeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), AAD.NewAAD(), []encryptedDataKey{*edk1Mock}, suite.NonFramedContent, 10, []byte("Algorithm12Algorithm12Algorithm1")}}, nil, nil, true}, - {"invalidFrameLength", args{MessageHeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), AAD.NewAAD(), []encryptedDataKey{*edk1Mock}, suite.NonFramedContent, 4294967296, []byte("Algorithm12Algorithm12Algorithm1")}}, nil, nil, true}, - {"invalidContentType", args{MessageHeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), AAD.NewAAD(), []encryptedDataKey{*edk1Mock}, suite.ContentType(3), 1024, []byte("Algorithm12Algorithm12Algorithm1")}}, nil, nil, true}, - {"invalidContentType", args{MessageHeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), AAD.NewAAD(), []encryptedDataKey{*edk1Mock}, suite.ContentType(0), 1024, []byte("Algorithm12Algorithm12Algorithm1")}}, nil, nil, true}, - {"invalidContentType", args{MessageHeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), AAD.NewAAD(), []encryptedDataKey{*edk1Mock}, suite.NonFramedContent, 1024, []byte("Algorithm12Algorithm12Algorithm1")}}, nil, nil, true}, - {"valid", args{MessageHeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), nil, []encryptedDataKey{*edk1Mock}, suite.FramedContent, 1024, []byte("Algorithm12Algorithm12Algorithm1")}}, mh1Mock, nil, false}, - {"valid", args{MessageHeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), nil, []encryptedDataKey{*edk1Mock}, suite.FramedContent, 1024, []byte("Algorithm12Algorithm12Algorithm1")}}, mh1Mock, mh1Mock, false}, - {"valid", args{MessageHeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), AAD.NewAAD(), []encryptedDataKey{*edk1Mock}, suite.FramedContent, 1024, []byte("Algorithm12Algorithm12Algorithm1")}}, mh2Mock, mh1Mock, false}, - {"valid", args{MessageHeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), AAD.NewAADWithEncryptionContext(map[string]string{"test": "testing"}), []encryptedDataKey{*edk1Mock}, suite.FramedContent, 1024, []byte("Algorithm12Algorithm12Algorithm1")}}, mh3Mock, mh3Mock, false}, + {"nilAlgorithmSuite", args{HeaderParams{nil, []byte("test"), nil, nil, suite.NonFramedContent, 10, []byte("test")}}, nil, nil, true}, + {"unsupportedAlgorithm", args{HeaderParams{&suite.AlgorithmSuite{AlgorithmID: 0x0050}, nil, nil, nil, suite.NonFramedContent, 10, []byte("test")}}, nil, nil, true}, + {"invalidMessageID", args{HeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, nil, nil, nil, suite.NonFramedContent, 10, []byte("test")}}, nil, nil, true}, + {"invalidMessageID", args{HeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("test"), nil, nil, suite.NonFramedContent, 10, []byte("test")}}, nil, nil, true}, + {"invalidMessageID_V1", args{HeaderParams{suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, []byte("testtesttestt15"), nil, nil, suite.NonFramedContent, 10, []byte("test")}}, nil, nil, true}, + {"invalidEncryptedDataKeys", args{HeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), nil, nil, suite.NonFramedContent, 10, []byte("test")}}, nil, nil, true}, + {"invalidAlgorithmSuiteDataLen", args{HeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), nil, []format.MessageEDK{edk1Mock}, suite.NonFramedContent, 10, []byte("test")}}, nil, nil, true}, + {"invalidAlgorithmSuiteDataLen_V1", args{HeaderParams{suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, []byte("MessageMessage16"), nil, []format.MessageEDK{edk1Mock}, suite.NonFramedContent, 10, []byte("test")}}, nil, nil, true}, + {"invalidFrameLength", args{HeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), nil, []format.MessageEDK{edk1Mock}, suite.NonFramedContent, 10, []byte("Algorithm12Algorithm12Algorithm1")}}, nil, nil, true}, + {"invalidContentType", args{HeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), nil, []format.MessageEDK{edk1Mock}, suite.ContentType(3), 1024, []byte("Algorithm12Algorithm12Algorithm1")}}, nil, nil, true}, + {"invalidContentType", args{HeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), nil, []format.MessageEDK{edk1Mock}, suite.ContentType(0), 1024, []byte("Algorithm12Algorithm12Algorithm1")}}, nil, nil, true}, + {"invalidContentType", args{HeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), nil, []format.MessageEDK{edk1Mock}, suite.NonFramedContent, 1024, []byte("Algorithm12Algorithm12Algorithm1")}}, nil, nil, true}, + {"valid", args{HeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), nil, []format.MessageEDK{edk1Mock}, suite.FramedContent, 1024, []byte("Algorithm12Algorithm12Algorithm1")}}, mh1Mock, nil, false}, + {"valid", args{HeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), nil, []format.MessageEDK{edk1Mock}, suite.FramedContent, 1024, []byte("Algorithm12Algorithm12Algorithm1")}}, mh1Mock, mh1Mock, false}, + {"valid", args{HeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), map[string]string{}, []format.MessageEDK{edk1Mock}, suite.FramedContent, 1024, []byte("Algorithm12Algorithm12Algorithm1")}}, mh2Mock, mh1Mock, false}, + {"valid", args{HeaderParams{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, []byte("MessageID12MessageID12MessageID1"), map[string]string{"test": "testing"}, []format.MessageEDK{edk1Mock}, suite.FramedContent, 1024, []byte("Algorithm12Algorithm12Algorithm1")}}, mh3Mock, mh3Mock, false}, + {"valid_V1", args{HeaderParams{suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, []byte("MessageMessage16"), nil, []format.MessageEDK{edk1Mock}, suite.FramedContent, 1024, nil}}, mh1MockV1, nil, false}, + {"valid_V1", args{HeaderParams{suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, []byte("MessageMessage16"), nil, []format.MessageEDK{edk1Mock}, suite.FramedContent, 1024, nil}}, mh1MockV1, mh1MockV1, false}, + {"valid_V1", args{HeaderParams{suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, []byte("MessageMessage16"), map[string]string{"test": "testing"}, []format.MessageEDK{edk1Mock}, suite.FramedContent, 1024, nil}}, mh3MockV1, mh3MockV1, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - mh := emh{} - got, err := mh.New(tt.args.p) + got, err := NewHeader(tt.args.p) if err != nil && tt.wantErr { - assert.Errorf(t, err, "New(%#v) error = %v, wantErr %v", tt.args.p, err, tt.wantErr) + assert.Errorf(t, err, "NewHeader(%#v) error = %v, wantErr %v", tt.args.p, err, tt.wantErr) return } - logger.L().Trace(). - Str("bytes", logger.FmtBytes(got.Bytes())). - Int("len", got.Len()). - Msg("got") - assert.NoErrorf(t, err, "New(%#v) error = %v, wantErr %v", tt.args.p, err, tt.wantErr) - assert.Equalf(t, tt.want, got, "New(%#v)", tt.args.p) + assert.NoErrorf(t, err, "NewHeader(%#v) error = %v, wantErr %v", tt.args.p, err, tt.wantErr) + assert.Equalf(t, tt.want, got, "NewHeader(%#v)", tt.args.p) + + assert.Equal(t, tt.want.Version(), got.Version()) + assert.Equal(t, tt.want.AlgorithmSuite(), got.AlgorithmSuite()) + assert.Equal(t, tt.want.MessageID(), got.MessageID()) + assert.Equal(t, tt.want.AADLength(), got.AADLength()) + assert.Equal(t, tt.want.AADData(), got.AADData()) + assert.Equal(t, tt.want.EncryptedDataKeyCount(), got.EncryptedDataKeyCount()) + assert.Equal(t, tt.want.EncryptedDataKeys(), got.EncryptedDataKeys()) + assert.Equal(t, tt.want.ContentType(), got.ContentType()) + assert.Equal(t, tt.want.FrameLength(), got.FrameLength()) + assert.Equal(t, tt.want.Type(), got.Type()) + assert.Equal(t, tt.want.Reserved(), got.Reserved()) + assert.Equal(t, tt.want.IVLength(), got.IVLength()) + assert.Equal(t, tt.want.AlgorithmSuiteData(), got.AlgorithmSuiteData()) + if tt.wantFromBuffer != nil { + logger.L().Trace(). + Str("bytes", logger.FmtBytes(got.Bytes())). + Int("len", got.Len()). + Msg("got") gotBytes := got.Bytes() buf := bytes.NewBuffer(gotBytes) bufLen := buf.Len() - got2, err2 := mh.fromBuffer(buf) - assert.NoErrorf(t, err2, "fromBuffer(%#v) error = %v, wantErr %v", gotBytes, err2, tt.wantErr) - assert.Equalf(t, tt.wantFromBuffer, got2, "fromBuffer(%#v)", gotBytes) + got2, err2 := deserializeHeader(buf) + assert.NoErrorf(t, err2, "deserializeHeader(%#v) error = %v, wantErr %v", gotBytes, err2, tt.wantErr) + assert.Equalf(t, tt.wantFromBuffer, got2, "deserializeHeader(%#v)", gotBytes) assert.Equal(t, gotBytes, got2.Bytes()) assert.Equal(t, got.Bytes(), got2.Bytes()) assert.Equal(t, got.Len(), got2.Len()) assert.Equal(t, 0, buf.Len()) assert.Equal(t, bufLen, got.Len()) assert.Equal(t, bufLen, buf.Cap()) + + assert.Equal(t, tt.wantFromBuffer.Version(), got2.Version()) + assert.Equal(t, tt.wantFromBuffer.AlgorithmSuite(), got2.AlgorithmSuite()) + assert.Equal(t, tt.wantFromBuffer.MessageID(), got2.MessageID()) + assert.Equal(t, tt.wantFromBuffer.AADLength(), got2.AADLength()) + assert.Equal(t, tt.wantFromBuffer.AADData(), got2.AADData()) + assert.Equal(t, tt.wantFromBuffer.EncryptedDataKeyCount(), got2.EncryptedDataKeyCount()) + assert.Equal(t, tt.wantFromBuffer.EncryptedDataKeys(), got2.EncryptedDataKeys()) + assert.Equal(t, tt.wantFromBuffer.ContentType(), got2.ContentType()) + assert.Equal(t, tt.wantFromBuffer.FrameLength(), got2.FrameLength()) + assert.Equal(t, tt.wantFromBuffer.Type(), got2.Type()) + assert.Equal(t, tt.wantFromBuffer.Reserved(), got2.Reserved()) + assert.Equal(t, tt.wantFromBuffer.IVLength(), got2.IVLength()) + assert.Equal(t, tt.wantFromBuffer.AlgorithmSuiteData(), got2.AlgorithmSuiteData()) + } }) } } -func Test_emh_fromBuffer(t *testing.T) { +func Test_deserializeHeader(t *testing.T) { type args struct { buf *bytes.Buffer } + edk1Mock, _ := EDK.new(awsKmsProviderID, "arn:aws:kms:eu-west-1:123454678901:key/80bd2fac-c07d-438a-837e-36e19bd4d320", []byte{0x1, 0x2, 0x1, 0x0, 0x78, 0xbc, 0x28, 0x8c, 0x86, 0xd0, 0x80, 0xa8, 0x5d, 0xd, 0x60, 0x4e, 0xe6, 0xce, 0x2b, 0x44, 0xb8, 0x2b, 0xd9, 0xcc, 0xe, 0x8, 0x4a, 0x48, 0x3f, 0x27, 0xc9, 0x83, 0xca, 0x67, 0x3e, 0xa2, 0x4d, 0x1, 0x93, 0xb8, 0xe7, 0x67, 0x85, 0x90, 0xf6, 0x34, 0x1, 0x53, 0xc2, 0x23, 0x11, 0x9e, 0xc4, 0xb3, 0x0, 0x0, 0x0, 0x7e, 0x30, 0x7c, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x7, 0x6, 0xa0, 0x6f, 0x30, 0x6d, 0x2, 0x1, 0x0, 0x30, 0x68, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x7, 0x1, 0x30, 0x1e, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x1, 0x2e, 0x30, 0x11, 0x4, 0xc, 0x40, 0x44, 0x5c, 0xc0, 0x2a, 0x7b, 0x82, 0xdb, 0x21, 0x33, 0x7e, 0x59, 0x2, 0x1, 0x10, 0x80, 0x3b, 0x8a, 0xce, 0xe2, 0x3f, 0xee, 0x84, 0x25, 0x1a, 0x8e, 0xc6, 0xa8, 0x3d, 0x26, 0x80, 0x48, 0x1d, 0x53, 0x45, 0x65, 0x35, 0xf, 0x6d, 0x8b, 0xed, 0x5c, 0xd4, 0x10, 0xda, 0xf6, 0xf1, 0x55, 0x22, 0xd1, 0x35, 0xe9, 0x4e, 0xc0, 0xc5, 0x2a, 0xa9, 0x5b, 0xa3, 0x3, 0xec, 0x21, 0x80, 0x97, 0x76, 0x6e, 0xb0, 0xa1, 0xcd, 0xce, 0xe7, 0x29, 0xcc, 0x16, 0xc, 0xfc}) edk2Mock, _ := EDK.new(awsKmsProviderID, "arn:aws:kms:eu-west-1:123454678901:key/e070dfa5-bf44-488d-afad-4d57c5c8f3c5", []byte{0x1, 0x2, 0x2, 0x0, 0x78, 0x34, 0x28, 0xaa, 0x31, 0x8a, 0xbd, 0x1b, 0x42, 0x22, 0x29, 0xae, 0x7, 0x25, 0xf8, 0x29, 0x5f, 0x17, 0xdb, 0x91, 0x25, 0xb7, 0xa4, 0x3e, 0x79, 0xf0, 0x86, 0xb9, 0x40, 0xd3, 0xdd, 0x2, 0x91, 0x1, 0x92, 0xe5, 0x3f, 0x75, 0x27, 0xc9, 0x2d, 0x7b, 0x3f, 0xc2, 0x74, 0xe3, 0x2e, 0xcb, 0x3e, 0xb2, 0x0, 0x0, 0x0, 0x7e, 0x30, 0x7c, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x7, 0x6, 0xa0, 0x6f, 0x30, 0x6d, 0x2, 0x1, 0x0, 0x30, 0x68, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x7, 0x1, 0x30, 0x1e, 0x6, 0x9, 0x60, 0x86, 0x48, 0x1, 0x65, 0x3, 0x4, 0x1, 0x2e, 0x30, 0x11, 0x4, 0xc, 0x9, 0x46, 0x6, 0x3c, 0xe9, 0x7c, 0xf3, 0x80, 0xeb, 0x8b, 0x3a, 0x89, 0x2, 0x1, 0x10, 0x80, 0x3b, 0xd2, 0x9a, 0xfd, 0x12, 0xa1, 0x55, 0xd2, 0x5e, 0x1, 0x31, 0x9a, 0x6, 0x42, 0xd0, 0xa, 0xec, 0xa9, 0xed, 0xc3, 0x94, 0xa2, 0x43, 0x8d, 0xd1, 0x25, 0xce, 0x4a, 0x3c, 0x83, 0xdd, 0x15, 0x2d, 0x1, 0xa7, 0x1e, 0x20, 0x3, 0x6d, 0xa2, 0x4f, 0x3, 0x92, 0xb8, 0xe9, 0x88, 0xc7, 0x88, 0x74, 0x78, 0x1d, 0xfc, 0x9d, 0x52, 0x56, 0x27, 0x2c, 0xe, 0x13, 0xf8}) + messageFormatVersionV1 := []byte{0x1} messageFormatVersion := []byte{0x2} + messageType := []byte{0x80} // V1 + algorithmIDV1 := []byte{0x1, 0x78} algorithmID := []byte{0x5, 0x78} messageID := []byte{0xf6, 0xd9, 0x0, 0x98, 0xba, 0xfb, 0x87, 0xc8, 0xe9, 0x79, 0xae, 0x71, 0xa5, 0x71, 0x10, 0x2d, 0xe5, 0x14, 0x45, 0x85, 0xd3, 0xde, 0xc4, 0xc3, 0x89, 0xcc, 0xdd, 0x23, 0xa5, 0x9e, 0xf, 0x96} + messageIDV1 := []byte{0xf6, 0xd9, 0x0, 0x98, 0xba, 0xfb, 0x87, 0xc8, 0xe9, 0x79, 0xae, 0x71, 0xa5, 0x71, 0x10, 0x2d} aadLen := []byte{0x0, 0xbc} aadDataBytes := []byte{0x0, 0x4, 0x0, 0x15, 0x61, 0x77, 0x73, 0x2d, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x6b, 0x65, 0x79, 0x0, 0x44, 0x41, 0x79, 0x65, 0x56, 0x36, 0x78, 0x36, 0x78, 0x6e, 0x56, 0x52, 0x76, 0x31, 0x38, 0x76, 0x54, 0x74, 0x79, 0x74, 0x7a, 0x53, 0x49, 0x44, 0x35, 0x44, 0x71, 0x70, 0x48, 0x36, 0x65, 0x6a, 0x65, 0x4e, 0x6d, 0x47, 0x62, 0x55, 0x39, 0x33, 0x50, 0x43, 0x2f, 0x71, 0x75, 0x51, 0x55, 0x6e, 0x61, 0x69, 0x32, 0x41, 0x67, 0x7a, 0x54, 0x4e, 0x4c, 0x7a, 0x4a, 0x51, 0x67, 0x6c, 0x73, 0x5a, 0x46, 0x32, 0x41, 0x3d, 0x3d, 0x0, 0x5, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x0, 0x24, 0x34, 0x61, 0x35, 0x63, 0x38, 0x65, 0x62, 0x66, 0x2d, 0x66, 0x37, 0x64, 0x30, 0x2d, 0x34, 0x64, 0x30, 0x39, 0x2d, 0x38, 0x38, 0x63, 0x33, 0x2d, 0x35, 0x65, 0x64, 0x62, 0x34, 0x38, 0x35, 0x33, 0x39, 0x31, 0x36, 0x33, 0x0, 0x5, 0x6f, 0x72, 0x67, 0x49, 0x64, 0x0, 0xd, 0x6f, 0x72, 0x67, 0x2d, 0x75, 0x75, 0x69, 0x64, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x0, 0x6, 0x73, 0x6f, 0x6d, 0x65, 0x49, 0x64, 0x0, 0x10, 0x73, 0x6f, 0x6d, 0x65, 0x49, 0x64, 0x2d, 0x75, 0x75, 0x69, 0x64, 0x2d, 0x74, 0x65, 0x73, 0x74} edkCount := []byte{0x0, 0x2} // edk1 bytes and edk2 bytes from mocks contentType := []byte{0x2} - frameLength := []byte{0x0, 0x0, 0x4, 0x0} + frameLength := []byte{0x0, 0x0, 0x4, 0x0} // 1024 algorithmSuiteData := []byte{0x52, 0xdf, 0xed, 0x4c, 0x0, 0xb4, 0xd7, 0x95, 0x2f, 0xa8, 0x3c, 0x81, 0xdb, 0xee, 0xbe, 0x7f, 0x55, 0x9d, 0x48, 0x3e, 0x27, 0xd4, 0x18, 0xb6, 0x94, 0x49, 0xfb, 0xb8, 0xa6, 0x60, 0xdc, 0xe2} - mh1Mock := &MessageHeader{ - AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, - MessageID: messageID, - aadLen: 188, - AADData: AAD.NewAADWithEncryptionContext(map[string]string{"aws-crypto-public-key": "AyeV6x6xnVRv18vTtytzSID5DqpH6ejeNmGbU93PC/quQUnai2AgzTNLzJQglsZF2A==", "keyId": "4a5c8ebf-f7d0-4d09-88c3-5edb48539163", "orgId": "org-uuid-test", "someId": "someId-uuid-test"}), - EncryptedDataKeyCount: 2, - EncryptedDataKeys: []encryptedDataKey{*edk1Mock, *edk2Mock}, - contentType: suite.FramedContent, - FrameLength: 1024, - AlgorithmSuiteData: algorithmSuiteData, + reservedV1 := []uint8{0x00, 0x00, 0x00, 0x00} + ivLen := []byte{0x0c} // 12 + + mh1Mock := &messageHeaderV2{ + messageHeader: messageHeader{ + version: suite.V2, + algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + messageID: messageID, + aadLen: 188, + authenticatedData: AAD.NewAADWithEncryptionContext(map[string]string{"aws-crypto-public-key": "AyeV6x6xnVRv18vTtytzSID5DqpH6ejeNmGbU93PC/quQUnai2AgzTNLzJQglsZF2A==", "keyId": "4a5c8ebf-f7d0-4d09-88c3-5edb48539163", "orgId": "org-uuid-test", "someId": "someId-uuid-test"}), + encryptedDataKeyCount: 2, + encryptedDataKeys: []format.MessageEDK{edk1Mock, edk2Mock}, + contentType: suite.FramedContent, + frameLength: 1024, + }, + algorithmSuiteData: algorithmSuiteData, + } + + mh1MockV1 := &messageHeaderV1{ + messageHeader: messageHeader{ + version: suite.V1, + algorithmSuite: suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, + messageID: messageIDV1, + aadLen: 188, + authenticatedData: AAD.NewAADWithEncryptionContext(map[string]string{"aws-crypto-public-key": "AyeV6x6xnVRv18vTtytzSID5DqpH6ejeNmGbU93PC/quQUnai2AgzTNLzJQglsZF2A==", "keyId": "4a5c8ebf-f7d0-4d09-88c3-5edb48539163", "orgId": "org-uuid-test", "someId": "someId-uuid-test"}), + encryptedDataKeyCount: 2, + encryptedDataKeys: []format.MessageEDK{edk1Mock, edk2Mock}, + contentType: suite.FramedContent, + frameLength: 1024, + }, + messageType: suite.CustomerAEData, + reserved: reservedV1, + ivLen: 12, } - //argsBuf := new(bytes.Buffer) + concatSlices := func(slices ...[]byte) []byte { var result []byte for _, slice := range slices { @@ -149,41 +258,68 @@ func Test_emh_fromBuffer(t *testing.T) { tests := []struct { name string args args - want *MessageHeader + want format.MessageHeader wantErr assert.ErrorAssertionFunc }{ {"nilBuffer", args{nil}, nil, assert.Error}, {"emptyBuffer", args{bytes.NewBuffer(nil)}, nil, assert.Error}, - {"emptyBuffer", args{bytes.NewBuffer(bytes.Repeat([]byte{0x02}, 76))}, nil, assert.Error}, - {"invalidBuffer", args{bytes.NewBuffer(bytes.Repeat([]byte{0x02}, 77))}, nil, assert.Error}, - {"invalidBuffer", args{bytes.NewBuffer(bytes.Repeat([]byte{0x01}, 77))}, nil, assert.Error}, - {"invalidBuffer", args{bytes.NewBuffer(bytes.Repeat([]byte{0x00}, 77))}, nil, assert.Error}, - {"invalidBuffer", args{bytes.NewBuffer(bytes.Repeat([]byte{0x05, 0x78}, 77))}, nil, assert.Error}, - {"invalidBuffer", args{bytes.NewBuffer(bytes.Repeat([]byte{0x78, 0x05}, 77))}, nil, assert.Error}, - - {"incompleteBuffer", args{bytes.NewBuffer(messageFormatVersion)}, nil, assert.Error}, - {"incompleteBuffer", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID))}, nil, assert.Error}, - {"incompleteBuffer", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID))}, nil, assert.Error}, - {"incompleteBuffer", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen))}, nil, assert.Error}, - {"incompleteBuffer", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes))}, nil, assert.Error}, - {"incompleteBuffer", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes, edkCount))}, nil, assert.Error}, - {"incompleteBuffer", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes, edkCount, edk1Mock.bytes()))}, nil, assert.Error}, - {"incompleteBuffer", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes, edkCount, edk1Mock.bytes(), edk2Mock.bytes()))}, nil, assert.Error}, - {"incompleteBuffer", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes, edkCount, edk1Mock.bytes(), edk2Mock.bytes(), contentType))}, nil, assert.Error}, - {"incompleteBuffer", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes, edkCount, edk1Mock.bytes(), edk2Mock.bytes(), contentType, frameLength))}, nil, assert.Error}, - {"validBuffer", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes, edkCount, edk1Mock.bytes(), edk2Mock.bytes(), contentType, frameLength, algorithmSuiteData))}, mh1Mock, assert.NoError}, + {"emptyBuffer", args{bytes.NewBuffer(bytes.Repeat([]byte{0x02}, 54))}, nil, assert.Error}, + {"invalidBuffer", args{bytes.NewBuffer(bytes.Repeat([]byte{0x02}, 55))}, nil, assert.Error}, + {"invalidBuffer", args{bytes.NewBuffer(bytes.Repeat([]byte{0x01}, 55))}, nil, assert.Error}, + {"invalidBuffer", args{bytes.NewBuffer(bytes.Repeat([]byte{0x00}, 55))}, nil, assert.Error}, + {"invalidBuffer", args{bytes.NewBuffer(bytes.Repeat([]byte{0x05, 0x78}, 55))}, nil, assert.Error}, + {"invalidBuffer", args{bytes.NewBuffer(bytes.Repeat([]byte{0x78, 0x05}, 55))}, nil, assert.Error}, + + {"incompleteBuffer_V1", args{bytes.NewBuffer(messageFormatVersionV1)}, nil, assert.Error}, + {"incompleteBuffer_V2", args{bytes.NewBuffer(messageFormatVersion)}, nil, assert.Error}, + {"incompleteBuffer_V1", args{bytes.NewBuffer(concatSlices(messageFormatVersionV1, messageType, algorithmIDV1))}, nil, assert.Error}, + {"incompleteBuffer_V2", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID))}, nil, assert.Error}, + + {"incompleteBuffer_V2", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, make([]byte, 16)))}, nil, assert.Error}, + {"incompleteBuffer_V2", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID))}, nil, assert.Error}, + {"incompleteBuffer_V2", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen))}, nil, assert.Error}, + {"incompleteBuffer_V2", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes))}, nil, assert.Error}, + {"incompleteBuffer_V2", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes, edkCount))}, nil, assert.Error}, + {"incompleteBuffer_V2", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes()))}, nil, assert.Error}, + {"incompleteBuffer_V2", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes(), edk2Mock.Bytes()))}, nil, assert.Error}, + {"incompleteBuffer_V2", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes(), edk2Mock.Bytes(), contentType))}, nil, assert.Error}, + {"invalidContentType_V2", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes(), edk2Mock.Bytes(), []byte{0x1}))}, nil, assert.Error}, + {"incompleteBuffer_V2", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes(), edk2Mock.Bytes(), contentType, frameLength))}, nil, assert.Error}, + {"invalidFrameLength_V2", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes(), edk2Mock.Bytes(), contentType, []byte{0x00, 0x00, 0x03, 0xff}))}, nil, assert.Error}, // 1023 frame + {"incompatibleVersion_V1", args{bytes.NewBuffer(concatSlices(messageFormatVersionV1, messageType, algorithmID, messageID, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes(), edk2Mock.Bytes(), contentType, frameLength))}, nil, assert.Error}, + {"incompatibleVersion_V2", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmIDV1, messageID, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes(), edk2Mock.Bytes(), contentType, frameLength))}, nil, assert.Error}, + {"validBuffer_V2", args{bytes.NewBuffer(concatSlices(messageFormatVersion, algorithmID, messageID, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes(), edk2Mock.Bytes(), contentType, frameLength, algorithmSuiteData))}, mh1Mock, assert.NoError}, + + {"incompleteBuffer_V1", args{bytes.NewBuffer(concatSlices(messageFormatVersionV1, messageType, algorithmIDV1, messageIDV1, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes(), edk2Mock.Bytes(), contentType))}, nil, assert.Error}, + {"incompleteBuffer_V1", args{bytes.NewBuffer(concatSlices(messageFormatVersionV1, messageType, algorithmIDV1, messageIDV1, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes(), edk2Mock.Bytes(), contentType, reservedV1))}, nil, assert.Error}, + {"invalidReservedData_V1", args{bytes.NewBuffer(concatSlices(messageFormatVersionV1, messageType, algorithmIDV1, messageIDV1, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes(), edk2Mock.Bytes(), contentType, []byte{0x00, 0x00, 0x32, 0x00}))}, nil, assert.Error}, + {"incompleteBuffer_V1", args{bytes.NewBuffer(concatSlices(messageFormatVersionV1, messageType, algorithmIDV1, messageIDV1, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes(), edk2Mock.Bytes(), contentType, reservedV1, ivLen))}, nil, assert.Error}, + {"invalidIVLength_V1", args{bytes.NewBuffer(concatSlices(messageFormatVersionV1, messageType, algorithmIDV1, messageIDV1, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes(), edk2Mock.Bytes(), contentType, reservedV1, []byte{0x0f}))}, nil, assert.Error}, // ivLen 15 + {"validBuffer_V1", args{bytes.NewBuffer(concatSlices(messageFormatVersionV1, messageType, algorithmIDV1, messageIDV1, aadLen, aadDataBytes, edkCount, edk1Mock.Bytes(), edk2Mock.Bytes(), contentType, reservedV1, ivLen, frameLength))}, mh1MockV1, assert.NoError}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - mh := emh{} - got, err := mh.fromBuffer(tt.args.buf) - if !tt.wantErr(t, err, fmt.Sprintf("fromBuffer(%#v)", tt.args.buf)) { + got, err := deserializeHeader(tt.args.buf) + if !tt.wantErr(t, err, fmt.Sprintf("deserializeHeader(%v)", tt.args.buf)) { return } - assert.Equalf(t, tt.want, got, "fromBuffer(%#v)", tt.args.buf) + assert.Equalf(t, tt.want, got, "deserializeHeader(%v)", tt.args.buf) if tt.want != nil { assert.Equal(t, tt.want.Bytes(), got.Bytes()) assert.Equal(t, tt.want.Len(), got.Len()) + assert.Equal(t, tt.want.Version(), got.Version()) + assert.Equal(t, tt.want.AlgorithmSuite(), got.AlgorithmSuite()) + assert.Equal(t, tt.want.MessageID(), got.MessageID()) + assert.Equal(t, tt.want.AADLength(), got.AADLength()) + assert.Equal(t, tt.want.AADData(), got.AADData()) + assert.Equal(t, tt.want.EncryptedDataKeyCount(), got.EncryptedDataKeyCount()) + assert.Equal(t, tt.want.EncryptedDataKeys(), got.EncryptedDataKeys()) + assert.Equal(t, tt.want.ContentType(), got.ContentType()) + assert.Equal(t, tt.want.FrameLength(), got.FrameLength()) + assert.Equal(t, tt.want.Type(), got.Type()) + assert.Equal(t, tt.want.Reserved(), got.Reserved()) + assert.Equal(t, tt.want.IVLength(), got.IVLength()) + assert.Equal(t, tt.want.AlgorithmSuiteData(), got.AlgorithmSuiteData()) } }) } From 66b376458aedd4d887f6dffc348d796a446d24b6 Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 18:30:10 +0200 Subject: [PATCH 12/16] feat(examples): update examples to use MessageHeader interface methods --- example/basicEncryption/main.go | 2 +- example/customAwsKmsConfig/main.go | 8 ++++---- example/discoveryFilterKmsProvider/main.go | 6 +++--- example/discoveryKmsProvider/main.go | 6 +++--- example/mrkAwareKmsProvider/main.go | 8 ++++---- example/multipleKeyProvider/main.go | 8 ++++---- example/multipleKmsKey/main.go | 6 +++--- example/oneKmsKey/main.go | 8 ++++---- example/oneKmsKeyUnsigned/main.go | 8 ++++---- 9 files changed, 30 insertions(+), 30 deletions(-) diff --git a/example/basicEncryption/main.go b/example/basicEncryption/main.go index db52bc9..26e979e 100644 --- a/example/basicEncryption/main.go +++ b/example/basicEncryption/main.go @@ -43,7 +43,7 @@ func main() { panic(err) // handle error } - fmt.Printf("encrypted encryption context: %v\n", header.AADData.AsEncryptionContext()) + fmt.Printf("encrypted encryption context: %v\n", header.AADData().EncryptionContext()) // decrypt "encrypted" data decrypted, _, err := sdkClient.Decrypt(context.TODO(), encrypted, cmm) diff --git a/example/customAwsKmsConfig/main.go b/example/customAwsKmsConfig/main.go index b037e66..63775b8 100644 --- a/example/customAwsKmsConfig/main.go +++ b/example/customAwsKmsConfig/main.go @@ -61,16 +61,16 @@ func main() { panic(err) // handle error } - fmt.Printf("header AlgorithmSuite: %s\n", header.AlgorithmSuite.String()) + fmt.Printf("header AlgorithmSuite: %s\n", header.AlgorithmSuite().String()) // Output: header AlgorithmSuite: AlgID 0x0578: AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384 - fmt.Printf("header frameLength: %d\n", header.FrameLength) + fmt.Printf("header frameLength: %d\n", header.FrameLength()) // Output: header frameLength: 2048 - fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount) + fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount()) // Output: encrypted data key count: 1 - fmt.Printf("encrypted encryption context: %v\n", header.AADData.AsEncryptionContext()) + fmt.Printf("encrypted encryption context: %v\n", header.AADData().EncryptionContext()) // decrypt "encrypted" data decrypted, _, err := sdkClient.Decrypt(context.TODO(), encrypted, cmm) diff --git a/example/discoveryFilterKmsProvider/main.go b/example/discoveryFilterKmsProvider/main.go index c72eb46..1ef5c96 100644 --- a/example/discoveryFilterKmsProvider/main.go +++ b/example/discoveryFilterKmsProvider/main.go @@ -67,8 +67,8 @@ func main() { panic(err) // handle error } - fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount) - fmt.Printf("encrypted encryption context: %v\n", header.AADData.AsEncryptionContext()) + fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount()) + fmt.Printf("encrypted encryption context: %v\n", header.AADData().EncryptionContext()) // create a KMS key provider specifying explicitly nil for keyIDs, with // discovery enabled filter by accountIDs and partition @@ -93,7 +93,7 @@ func main() { // verify that "decrypted" encryption context in header has the same keys and values // as the original encryption context before using "decrypted" data. - decryptionContext := decHeader.AADData.AsEncryptionContext() + decryptionContext := decHeader.AADData().EncryptionContext() for k, v := range encryptionContext { if decryptionContext[k] != v { panic("decrypted encryption context does not match with the original encryption context") diff --git a/example/discoveryKmsProvider/main.go b/example/discoveryKmsProvider/main.go index 0885bf9..5fc3ef4 100644 --- a/example/discoveryKmsProvider/main.go +++ b/example/discoveryKmsProvider/main.go @@ -63,8 +63,8 @@ func main() { panic(err) // handle error } - fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount) - fmt.Printf("encrypted encryption context: %v\n", header.AADData.AsEncryptionContext()) + fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount()) + fmt.Printf("encrypted encryption context: %v\n", header.AADData().EncryptionContext()) // create a KMS key provider specifying explicitly nil for keyIDs, and enable discovery provider, err := kmsprovider.NewWithOpts( @@ -90,7 +90,7 @@ func main() { // verify that "decrypted" encryption context in header has the same keys and values // as the original encryption context before using "decrypted" data. - decryptionContext := decHeader.AADData.AsEncryptionContext() + decryptionContext := decHeader.AADData().EncryptionContext() for k, v := range encryptionContext { if decryptionContext[k] != v { panic("decrypted encryption context does not match with the original encryption context") diff --git a/example/mrkAwareKmsProvider/main.go b/example/mrkAwareKmsProvider/main.go index 9647f24..e06ef6b 100644 --- a/example/mrkAwareKmsProvider/main.go +++ b/example/mrkAwareKmsProvider/main.go @@ -69,8 +69,8 @@ func main() { panic(err) // handle error } - fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount) - fmt.Printf("encrypted encryption context: %v\n", header.AADData.AsEncryptionContext()) + fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount()) + fmt.Printf("encrypted encryption context: %v\n", header.AADData().EncryptionContext()) // create a MRK-aware KMS key provider specifying KMS MRK keyID in second region mrkKmsProvider2, err := kmsprovider.NewWithOpts( @@ -93,7 +93,7 @@ func main() { // verify that "decrypted" encryption context in header has the same keys and values // as the original encryption context before using "decrypted" data. - decryptionContext := decHeader.AADData.AsEncryptionContext() + decryptionContext := decHeader.AADData().EncryptionContext() for k, v := range encryptionContext { if decryptionContext[k] != v { panic("decrypted encryption context does not match with the original encryption context") @@ -136,7 +136,7 @@ func main() { // verify that "decrypted2" encryption context in header has the same keys and values // as the original encryption context before using "decrypted2" data. - decryptionContext2 := decHeader2.AADData.AsEncryptionContext() + decryptionContext2 := decHeader2.AADData().EncryptionContext() for k, v := range encryptionContext { if decryptionContext2[k] != v { panic("decrypted2 encryption context does not match with the original encryption context") diff --git a/example/multipleKeyProvider/main.go b/example/multipleKeyProvider/main.go index 1f55cca..86adb39 100644 --- a/example/multipleKeyProvider/main.go +++ b/example/multipleKeyProvider/main.go @@ -82,8 +82,8 @@ func main() { panic(err) // handle error } - fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount) - fmt.Printf("encrypted encryption context: %v\n", header.AADData.AsEncryptionContext()) + fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount()) + fmt.Printf("encrypted encryption context: %v\n", header.AADData().EncryptionContext()) // for each original master key, create a KMS key provider that only lists // that key, and use that provider to create corresponding CMM, and then @@ -107,7 +107,7 @@ func main() { // verify that "decrypted" encryption context in header has the same keys and values // as the original encryption context before using "decrypted" data. - decryptionContext := decHeader.AADData.AsEncryptionContext() + decryptionContext := decHeader.AADData().EncryptionContext() for k, v := range encryptionContext { if decryptionContext[k] != v { panic("decrypted encryption context does not match with the original encryption context") @@ -146,7 +146,7 @@ func main() { // verify that "decrypted" encryption context in header has the same keys and values // as the original encryption context before using "decrypted" data. - decryptionContext := decHeader.AADData.AsEncryptionContext() + decryptionContext := decHeader.AADData().EncryptionContext() for k, v := range encryptionContext { if decryptionContext[k] != v { panic("decrypted encryption context does not match with the original encryption context") diff --git a/example/multipleKmsKey/main.go b/example/multipleKmsKey/main.go index cc0dcf6..cdc5c14 100644 --- a/example/multipleKmsKey/main.go +++ b/example/multipleKmsKey/main.go @@ -66,8 +66,8 @@ func main() { panic(err) // handle error } - fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount) - fmt.Printf("encrypted encryption context: %v\n", header.AADData.AsEncryptionContext()) + fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount()) + fmt.Printf("encrypted encryption context: %v\n", header.AADData().EncryptionContext()) // for each original master key, create a KMS key provider that only lists // that key, and use that provider to create corresponding CMM, and then @@ -91,7 +91,7 @@ func main() { // verify that "decrypted" encryption context in header has the same keys and values // as the original encryption context before using "decrypted" data. - decryptionContext := decHeader.AADData.AsEncryptionContext() + decryptionContext := decHeader.AADData().EncryptionContext() for k, v := range encryptionContext { if decryptionContext[k] != v { panic("decrypted encryption context does not match with the original encryption context") diff --git a/example/oneKmsKey/main.go b/example/oneKmsKey/main.go index f36570d..ce9588a 100644 --- a/example/oneKmsKey/main.go +++ b/example/oneKmsKey/main.go @@ -47,13 +47,13 @@ func main() { panic(err) // handle error } - fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount) - fmt.Printf("encrypted encryption context: %v\n", header.AADData.AsEncryptionContext()) + fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount()) + fmt.Printf("encrypted encryption context: %v\n", header.AADData().EncryptionContext()) - fmt.Printf("header AlgorithmSuite: %s\n", header.AlgorithmSuite.String()) + fmt.Printf("header AlgorithmSuite: %s\n", header.AlgorithmSuite().String()) // Output: header AlgorithmSuite: AlgID 0x0578: AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384 - fmt.Printf("header frameLength: %d\n", header.FrameLength) + fmt.Printf("header frameLength: %d\n", header.FrameLength()) // Output: header frameLength: 4096 // decrypt "encrypted" data diff --git a/example/oneKmsKeyUnsigned/main.go b/example/oneKmsKeyUnsigned/main.go index bb02a4e..2d3a7a5 100644 --- a/example/oneKmsKeyUnsigned/main.go +++ b/example/oneKmsKeyUnsigned/main.go @@ -51,16 +51,16 @@ func main() { panic(err) // handle error } - fmt.Printf("header AlgorithmSuite: %s\n", header.AlgorithmSuite.String()) + fmt.Printf("header AlgorithmSuite: %s\n", header.AlgorithmSuite().String()) // Output: header AlgorithmSuite: AlgID 0x0478: AES_256_GCM_HKDF_SHA512_COMMIT_KEY - fmt.Printf("header frameLength: %d\n", header.FrameLength) + fmt.Printf("header frameLength: %d\n", header.FrameLength()) // Output: header frameLength: 1024 - fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount) + fmt.Printf("encrypted data key count: %d\n", header.EncryptedDataKeyCount()) // Output: encrypted data key count: 1 - fmt.Printf("encrypted encryption context: %v\n", header.AADData.AsEncryptionContext()) + fmt.Printf("encrypted encryption context: %v\n", header.AADData().EncryptionContext()) // Output: encrypted encryption context: map[Purpose:testing User:Alice Year:2023] // decrypt "encrypted" data From 57e23ca19ff5e25cbc391b5482d0a8776837fb82 Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 18:54:11 +0200 Subject: [PATCH 13/16] fix(ci): improve coverage target --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 585a975..1c2bb17 100644 --- a/Makefile +++ b/Makefile @@ -121,7 +121,8 @@ e2e-test-slow: test-cover: @#CGO_ENABLED=0 go test -count=1 -coverpkg=./... -covermode=atomic -coverprofile coverage.out ./... - @CGO_ENABLED=0 go test -tags ${CI_TAGS} -count=1 -coverpkg=./... -covermode=atomic -coverprofile coverage.out ./pkg/... + @CGO_ENABLED=0 go test -race -tags example,mocks,codegen,integration -count=1 -coverpkg=./... -covermode=atomic -coverprofile=coverage.out ./pkg/... + @#CGO_ENABLED=0 go test -tags ${CI_TAGS} -count=1 -coverpkg=./... -covermode=atomic -coverprofile coverage.out ./pkg/... @grep -v -E -f .covignore coverage.out > coverage.filtered.out @mv coverage.filtered.out coverage.out From d9fd6b3e34c2510230f6bfcb38791c326d5aa09e Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 18:58:40 +0200 Subject: [PATCH 14/16] test(e2e): update E2E tests to utilise V1 algorithms --- test/e2e/enc_dec_test.go | 237 ++++++++++++++++++++++++++++++------ test/e2e/testutils/cli.go | 30 +++-- test/e2e/testutils/setup.go | 30 +++-- 3 files changed, 241 insertions(+), 56 deletions(-) diff --git a/test/e2e/enc_dec_test.go b/test/e2e/enc_dec_test.go index eb36d94..beb8424 100644 --- a/test/e2e/enc_dec_test.go +++ b/test/e2e/enc_dec_test.go @@ -27,10 +27,11 @@ type testParam struct { tEC map[string]string tFrame int tEdk int - tClient func(maxEdk int) *client.Client + tClient func(maxEdk int, cp suite.CommitmentPolicy) *client.Client tCMM func(keyIDs []string, opts ...func(options *config.LoadOptions) error) model.CryptoMaterialsManager tCMMi model.CryptoMaterialsManager - tCliCmd func(keyIDs []string, ec map[string]string, frame int, edk int, alg string) *u.CliCmd + tCliCmd func(keyIDs []string, ec map[string]string, frame int, edk int, alg string, policy suite.CommitmentPolicy) *u.CliCmd + tPolicy suite.CommitmentPolicy } type tableTestCase struct { @@ -43,6 +44,48 @@ type tableTestCase struct { } var testEncryptDecryptTableShort = []tableTestCase{ + { + "Keys3_F256_Edk3", false, testFilesShort, + suite.AES_256_GCM_IV12_TAG16, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 256, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 256, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupDecryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + }, + { + "Keys3_F1024_Edk3", false, testFilesShort, + suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 1024, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 1024, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupDecryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + }, + { + "Keys2_F2048_Edk2", false, testFilesShort, + suite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, + &testParam{ + tKeys: []string{key1Arn, key2Arn}, tEC: testEc, tFrame: 2048, tEdk: 2, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + &testParam{ + tKeys: []string{key1Arn, key2Arn}, tEC: testEc, tFrame: 2048, tEdk: 2, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupDecryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + }, { "Keys3_F1024_Edk3", false, testFilesShort, algSig, &testParam{ @@ -62,6 +105,16 @@ var testEncryptDecryptTableShort = []tableTestCase{ tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, }, nil, }, + { + "Keys1_F192_Edk1", true, testFilesShort, + suite.AES_192_GCM_IV12_TAG16_HKDF_SHA256, + &testParam{ + tKeys: []string{key1Arn}, tEC: testEc, tFrame: 192, tEdk: 1, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + nil, + }, { "Keys1_F64_Edk1", true, testFilesShort, algSig, &testParam{ @@ -73,6 +126,36 @@ var testEncryptDecryptTableShort = []tableTestCase{ } var testEncryptDecryptTable = []tableTestCase{ + { + "Keys1_F512_Edk1", false, testFilesTable, + suite.AES_128_GCM_IV12_TAG16, + &testParam{ + tKeys: []string{key1Arn}, tEC: testEc, tFrame: 512, tEdk: 1, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + nil, + }, + { + "Keys2_F256_Edk2", false, testFilesTable, + suite.AES_192_GCM_IV12_TAG16, + &testParam{ + tKeys: []string{key1Arn, key2Arn}, tEC: testEc, tFrame: 256, tEdk: 2, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + nil, + }, + { + "Keys3_F128_Edk3", false, testFilesTable, + suite.AES_256_GCM_IV12_TAG16, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 128, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + nil, + }, { "Keys3_F1024_Edk3", false, testFilesTable, algSig, &testParam{ @@ -96,6 +179,76 @@ var testEncryptDecryptTable = []tableTestCase{ tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupDecryptCmd, }, }, + { + "Keys3_F1024_Edk3", false, testFilesTable, + suite.AES_128_GCM_IV12_TAG16_HKDF_SHA256, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 1024, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 1024, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupDecryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + }, + { + "Keys3_F1024_Edk3", false, testFilesTable, + suite.AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 1024, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 1024, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupDecryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + }, + { + "Keys3_F128_Edk3", false, testFilesTable, + suite.AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 128, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 128, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupDecryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + }, + { + "Keys3_F1024_Edk3", false, testFilesTable, + suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 1024, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 1024, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupDecryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + }, + { + "Keys3_F1024_Edk3", false, testFilesTable, + suite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 1024, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + &testParam{ + tKeys: []string{key1Arn, key2Arn, key3Arn}, tEC: testEc, tFrame: 1024, tEdk: 3, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupDecryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + }, { "Keys3_F1024_Edk3_CMM0", true, testFilesTable, algSig, &testParam{ @@ -252,28 +405,6 @@ var testEncryptDecryptTable = []tableTestCase{ tClient: u.SetupClient, tCMM: nil, tCMMi: cmm2keys23, tCliCmd: u.SetupDecryptCmd, }, }, - { - "CMM1(2)_Keys1(2)_F1024_Edk2_CMM1(2)", false, testFilesTable, algSig, - &testParam{ - tKeys: []string{key2Arn}, tEC: testEc, tFrame: 1024, tEdk: 2, - tClient: u.SetupClient, tCMM: nil, tCMMi: cmm1keys2, tCliCmd: u.SetupEncryptCmd, - }, - &testParam{ - tKeys: nil, tEC: testEc, tFrame: 1024, tEdk: 2, - tClient: u.SetupClient, tCMM: nil, tCMMi: cmm1keys2, tCliCmd: u.SetupDecryptCmd, - }, - }, - { - "CMM1(2)_Keys1(2)_F1024_Edk2_CMM1(2)", false, testFilesTable, algSig, - &testParam{ - tKeys: []string{key2Arn}, tEC: testEc, tFrame: 1024, tEdk: 2, - tClient: u.SetupClient, tCMM: nil, tCMMi: cmm1keys2, tCliCmd: u.SetupEncryptCmd, - }, - &testParam{ - tKeys: nil, tEC: testEc, tFrame: 1024, tEdk: 2, - tClient: u.SetupClient, tCMM: nil, tCMMi: cmm1keys2, tCliCmd: u.SetupDecryptCmd, - }, - }, { "CMM1(2)_Keys1(2)_F1024_Edk2_CMM1(2)", false, testFilesTable, algNoSig, @@ -319,6 +450,26 @@ var testEncryptDecryptTable = []tableTestCase{ }, nil, }, + { + "Keys1_F128_Edk1", false, testFilesTable, + suite.AES_128_GCM_IV12_TAG16_HKDF_SHA256_ECDSA_P256, + &testParam{ + tKeys: []string{key1Arn}, tEC: testEc, tFrame: 128, tEdk: 1, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + nil, + }, + { + "Keys1_F192_Edk1", true, testFilesTable, + suite.AES_192_GCM_IV12_TAG16_HKDF_SHA256, + &testParam{ + tKeys: []string{key1Arn}, tEC: testEc, tFrame: 192, tEdk: 1, + tClient: u.SetupClient, tCMM: u.SetupCMM, tCMMi: nil, tCliCmd: u.SetupEncryptCmd, + tPolicy: suite.CommitmentPolicyForbidEncryptAllowDecrypt, + }, + nil, + }, { "Keys1_F64_Edk1", true, testFilesTable, algSig, &testParam{ @@ -352,7 +503,7 @@ func Test_Integration_EncryptSDKDecryptCLI(t *testing.T) { for _, tc := range tests { for _, tf := range tc.tInputs { - t.Run(strings.Join([]string{tc.tName, u.AlgSuffix(tc.tAlg), tf.Name}, "_"), func(t *testing.T) { + t.Run(strings.Join([]string{tc.tName, tc.tAlg.IDString(), u.AlgSuffix(tc.tAlg), tf.Name}, "_"), func(t *testing.T) { ctx := context.Background() log.Debug(). Int("len", len(tf.data)). @@ -361,7 +512,7 @@ func Test_Integration_EncryptSDKDecryptCLI(t *testing.T) { Msg("Input") /////////// // encrypt with SDK - c := tc.tEnc.tClient(tc.tEnc.tEdk) + c := tc.tEnc.tClient(tc.tEnc.tEdk, tc.tEnc.tPolicy) assert.NotNil(t, c) var cmm model.CryptoMaterialsManager if tc.tEnc.tCMM != nil { @@ -388,10 +539,10 @@ func Test_Integration_EncryptSDKDecryptCLI(t *testing.T) { // decrypt with CLI var cmdDecrypt1 *u.CliCmd if tc.tDec == nil { - cmdDecrypt1 = u.NewDecryptCmd(tc.tEnc.tKeys, tc.tEnc.tEC, tc.tEnc.tFrame, tc.tEnc.tEdk) + cmdDecrypt1 = u.NewDecryptCmd(tc.tEnc.tKeys, tc.tEnc.tEC, tc.tEnc.tFrame, tc.tEnc.tEdk, tc.tEnc.tPolicy) require.NotNil(t, cmdDecrypt1) } else { - cmdDecrypt1 = tc.tDec.tCliCmd(tc.tDec.tKeys, tc.tDec.tEC, tc.tDec.tFrame, tc.tDec.tEdk, tc.tAlg.Name()) + cmdDecrypt1 = tc.tDec.tCliCmd(tc.tDec.tKeys, tc.tDec.tEC, tc.tDec.tFrame, tc.tDec.tEdk, tc.tAlg.Name(), tc.tDec.tPolicy) require.NotNil(t, cmdDecrypt1) } @@ -418,7 +569,7 @@ func Test_Integration_EncryptCLIDecryptSDK(t *testing.T) { for _, tc := range tests { for _, tf := range tc.tInputs { - t.Run(strings.Join([]string{tc.tName, u.AlgSuffix(tc.tAlg), tf.Name}, "_"), func(t *testing.T) { + t.Run(strings.Join([]string{tc.tName, tc.tAlg.IDString(), u.AlgSuffix(tc.tAlg), tf.Name}, "_"), func(t *testing.T) { ctx := context.Background() log.Debug(). Int("len", len(tf.data)). @@ -429,10 +580,10 @@ func Test_Integration_EncryptCLIDecryptSDK(t *testing.T) { // encrypt with CLI var cmdEncrypt1 *u.CliCmd if tc.tDec == nil { - cmdEncrypt1 = u.NewEncryptCmd(tc.tEnc.tKeys, tc.tEnc.tEC, tc.tEnc.tFrame, tc.tEnc.tEdk, tc.tAlg.Name()) + cmdEncrypt1 = u.NewEncryptCmd(tc.tEnc.tKeys, tc.tEnc.tEC, tc.tEnc.tFrame, tc.tEnc.tEdk, tc.tAlg.Name(), tc.tEnc.tPolicy) require.NotNil(t, cmdEncrypt1) } else { - cmdEncrypt1 = tc.tEnc.tCliCmd(tc.tEnc.tKeys, tc.tEnc.tEC, tc.tEnc.tFrame, tc.tEnc.tEdk, tc.tAlg.Name()) + cmdEncrypt1 = tc.tEnc.tCliCmd(tc.tEnc.tKeys, tc.tEnc.tEC, tc.tEnc.tFrame, tc.tEnc.tEdk, tc.tAlg.Name(), tc.tEnc.tPolicy) require.NotNil(t, cmdEncrypt1) } @@ -450,7 +601,12 @@ func Test_Integration_EncryptCLIDecryptSDK(t *testing.T) { /////////// // decrypt with SDK - c := tc.tEnc.tClient(tc.tEnc.tEdk) + var c *client.Client + if tc.tDec == nil { + c = tc.tEnc.tClient(tc.tEnc.tEdk, tc.tEnc.tPolicy) + } else { + c = tc.tDec.tClient(tc.tDec.tEdk, tc.tDec.tPolicy) + } assert.NotNil(t, c) var cmm model.CryptoMaterialsManager if tc.tDec == nil { @@ -487,10 +643,11 @@ func Test_Integration_EncryptSDK_DecryptCLI_EncryptCLI_DecryptSDK(t *testing.T) for _, tc := range tests { for _, tf := range tc.tInputs { - t.Run(strings.Join([]string{tc.tName, u.AlgSuffix(tc.tAlg), tf.Name}, "_"), func(t *testing.T) { + t.Run(strings.Join([]string{tc.tName, tc.tAlg.IDString(), u.AlgSuffix(tc.tAlg), tf.Name}, "_"), func(t *testing.T) { ctx := context.Background() tLog := log.With(). Str("test", tc.tName). + Str("algID", tc.tAlg.IDString()). Logger() tLog.Debug(). Str("alg", u.AlgSuffix(tc.tAlg)). @@ -499,7 +656,7 @@ func Test_Integration_EncryptSDK_DecryptCLI_EncryptCLI_DecryptSDK(t *testing.T) Msg("Input") /////////// // encrypt with SDK - c := tc.tEnc.tClient(tc.tEnc.tEdk) + c := tc.tEnc.tClient(tc.tEnc.tEdk, tc.tEnc.tPolicy) assert.NotNil(t, c) var cmm model.CryptoMaterialsManager if tc.tEnc.tCMM != nil { @@ -527,10 +684,10 @@ func Test_Integration_EncryptSDK_DecryptCLI_EncryptCLI_DecryptSDK(t *testing.T) // decrypt with CLI var cmdDecrypt1 *u.CliCmd if tc.tDec == nil { - cmdDecrypt1 = u.NewDecryptCmd(tc.tEnc.tKeys, tc.tEnc.tEC, tc.tEnc.tFrame, tc.tEnc.tEdk) + cmdDecrypt1 = u.NewDecryptCmd(tc.tEnc.tKeys, tc.tEnc.tEC, tc.tEnc.tFrame, tc.tEnc.tEdk, tc.tEnc.tPolicy) require.NotNil(t, cmdDecrypt1) } else { - cmdDecrypt1 = tc.tDec.tCliCmd(tc.tDec.tKeys, tc.tDec.tEC, tc.tDec.tFrame, tc.tDec.tEdk, tc.tAlg.Name()) + cmdDecrypt1 = tc.tDec.tCliCmd(tc.tDec.tKeys, tc.tDec.tEC, tc.tDec.tFrame, tc.tDec.tEdk, tc.tAlg.Name(), tc.tDec.tPolicy) require.NotNil(t, cmdDecrypt1) } @@ -550,10 +707,10 @@ func Test_Integration_EncryptSDK_DecryptCLI_EncryptCLI_DecryptSDK(t *testing.T) // encrypt with CLI var cmdEncrypt2 *u.CliCmd if tc.tDec == nil { - cmdEncrypt2 = u.NewEncryptCmd(tc.tEnc.tKeys, tc.tEnc.tEC, tc.tEnc.tFrame, tc.tEnc.tEdk, tc.tAlg.Name()) + cmdEncrypt2 = u.NewEncryptCmd(tc.tEnc.tKeys, tc.tEnc.tEC, tc.tEnc.tFrame, tc.tEnc.tEdk, tc.tAlg.Name(), tc.tEnc.tPolicy) require.NotNil(t, cmdEncrypt2) } else { - cmdEncrypt2 = tc.tEnc.tCliCmd(tc.tEnc.tKeys, tc.tEnc.tEC, tc.tEnc.tFrame, tc.tEnc.tEdk, tc.tAlg.Name()) + cmdEncrypt2 = tc.tEnc.tCliCmd(tc.tEnc.tKeys, tc.tEnc.tEC, tc.tEnc.tFrame, tc.tEnc.tEdk, tc.tAlg.Name(), tc.tEnc.tPolicy) require.NotNil(t, cmdEncrypt2) } @@ -592,9 +749,9 @@ func Test_Integration_EncryptSDK_DecryptCLI_EncryptCLI_DecryptSDK(t *testing.T) // using new cmm and client var c2 *client.Client if tc.tDec == nil { - c2 = tc.tEnc.tClient(tc.tEnc.tEdk) + c2 = tc.tEnc.tClient(tc.tEnc.tEdk, tc.tEnc.tPolicy) } else { - c2 = tc.tDec.tClient(tc.tDec.tEdk) + c2 = tc.tDec.tClient(tc.tDec.tEdk, tc.tDec.tPolicy) } assert.NotNil(t, c2) var cmm2 model.CryptoMaterialsManager diff --git a/test/e2e/testutils/cli.go b/test/e2e/testutils/cli.go index b834cd1..91f0d36 100644 --- a/test/e2e/testutils/cli.go +++ b/test/e2e/testutils/cli.go @@ -13,6 +13,7 @@ import ( "github.com/rs/zerolog" "github.com/chainifynet/aws-encryption-sdk-go/pkg/logger" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" ) var log = logger.L().Level(zerolog.DebugLevel) //nolint:gochecknoglobals @@ -30,8 +31,8 @@ type CliCmd struct { args []string } -func NewEncryptCmd(keyIDs []string, ec map[string]string, frame, edk int, alg string) *CliCmd { - command, args := encryptCmdArgs(keyIDs, ec, frame, edk, alg) +func NewEncryptCmd(keyIDs []string, ec map[string]string, frame, edk int, alg string, policy suite.CommitmentPolicy) *CliCmd { + command, args := encryptCmdArgs(keyIDs, ec, frame, edk, alg, mapCommitmentPolicy(policy)) //log.Trace().Str("command", command).Strs("args", args).Msg("new EncryptCmd") return &CliCmd{ stdout: new(bytes.Buffer), @@ -42,8 +43,8 @@ func NewEncryptCmd(keyIDs []string, ec map[string]string, frame, edk int, alg st } } -func NewDecryptCmd(keyIDs []string, ec map[string]string, frame, edk int) *CliCmd { - command, args := decryptCmdArgs(keyIDs, ec, frame, edk) +func NewDecryptCmd(keyIDs []string, ec map[string]string, frame, edk int, policy suite.CommitmentPolicy) *CliCmd { + command, args := decryptCmdArgs(keyIDs, ec, frame, edk, mapCommitmentPolicy(policy)) //log.Trace().Str("command", command).Strs("args", args).Msg("new DecryptCmd") return &CliCmd{ stdout: new(bytes.Buffer), @@ -127,7 +128,7 @@ func (c *CliCmd) Run(input []byte, wantErr bool) (output []byte, err error) { } //goland:noinspection GoUnusedParameter -func decryptCmdArgs(keyIDs []string, ec map[string]string, _, edk int) (command string, args []string) { +func decryptCmdArgs(keyIDs []string, ec map[string]string, _, edk int, policy string) (command string, args []string) { wrappedKeys := wrappingKeysArg(keyIDs) ecArgs := encryptionContextArg(ec) cmdArgs := []string{ @@ -137,7 +138,7 @@ func decryptCmdArgs(keyIDs []string, ec map[string]string, _, edk int) (command "--suppress-metadata", "--input", "-", "--output", "-", - "--commitment-policy", "require-encrypt-require-decrypt", // decrypt optional + "--commitment-policy", policy, // decrypt optional //"--frame-length", "1024", // enc only "--max-encrypted-data-keys", strconv.Itoa(edk), // dec optional } @@ -154,7 +155,7 @@ func decryptCmdArgs(keyIDs []string, ec map[string]string, _, edk int) (command return cliCmd, cmdArgs } -func encryptCmdArgs(keyIDs []string, ec map[string]string, frame, edk int, algorithm string) (command string, args []string) { +func encryptCmdArgs(keyIDs []string, ec map[string]string, frame, edk int, algorithm, policy string) (command string, args []string) { wrappedKeys := encryptWrappingKeysArg(keyIDs) ecArgs := encryptionContextArg(ec) cmdArgs := []string{ @@ -164,7 +165,7 @@ func encryptCmdArgs(keyIDs []string, ec map[string]string, frame, edk int, algor "--suppress-metadata", "--input", "-", "--output", "-", - "--commitment-policy", "require-encrypt-require-decrypt", + "--commitment-policy", policy, "--frame-length", strconv.Itoa(frame), // enc only "--max-encrypted-data-keys", strconv.Itoa(edk), // enc only } @@ -180,6 +181,19 @@ func encryptCmdArgs(keyIDs []string, ec map[string]string, frame, edk int, algor return cliCmd, cmdArgs } +func mapCommitmentPolicy(p suite.CommitmentPolicy) string { + switch p { + case suite.CommitmentPolicyForbidEncryptAllowDecrypt: + return "forbid-encrypt-allow-decrypt" + case suite.CommitmentPolicyRequireEncryptAllowDecrypt: + return "require-encrypt-allow-decrypt" + case suite.CommitmentPolicyRequireEncryptRequireDecrypt: + return "require-encrypt-require-decrypt" + default: + return "require-encrypt-require-decrypt" + } +} + func encryptionContextArg(ec map[string]string) []string { values := make([]string, 0, len(ec)) for k, v := range ec { diff --git a/test/e2e/testutils/setup.go b/test/e2e/testutils/setup.go index b58b33b..34d7ea1 100644 --- a/test/e2e/testutils/setup.go +++ b/test/e2e/testutils/setup.go @@ -18,18 +18,26 @@ func AlgSuffix(as *suite.AlgorithmSuite) string { if as == nil { return "NO_ALG" } + commit := "" + kdf := "" + if as.IsCommitting() { + commit = "_COMMIT" + } + if as.IsKDFSupported() { + kdf = "HKDF_" + } if as.IsSigning() { - return "SIGN" + return kdf + "SIGN" + commit } - return "NONE" + return kdf + "NONE" + commit } -var SetupEncryptCmd = func(keyIDs []string, ec map[string]string, frame int, edk int, alg string) *CliCmd { //nolint:gochecknoglobals,gocritic - return NewEncryptCmd(keyIDs, ec, frame, edk, alg) +var SetupEncryptCmd = func(keyIDs []string, ec map[string]string, frame int, edk int, alg string, policy suite.CommitmentPolicy) *CliCmd { //nolint:gochecknoglobals,gocritic + return NewEncryptCmd(keyIDs, ec, frame, edk, alg, policy) } -var SetupDecryptCmd = func(keyIDs []string, ec map[string]string, frame int, edk int, alg string) *CliCmd { //nolint:gochecknoglobals - return NewDecryptCmd(keyIDs, ec, frame, edk) +var SetupDecryptCmd = func(keyIDs []string, ec map[string]string, frame int, edk int, alg string, policy suite.CommitmentPolicy) *CliCmd { //nolint:gochecknoglobals + return NewDecryptCmd(keyIDs, ec, frame, edk, policy) } var SetupCMM = func(keyIDs []string, opts ...func(options *config.LoadOptions) error) model.CryptoMaterialsManager { //nolint:gochecknoglobals @@ -62,9 +70,15 @@ var SetupCMM = func(keyIDs []string, opts ...func(options *config.LoadOptions) e return cmm } -var SetupClient = func(maxEdk int) *client.Client { //nolint:gochecknoglobals +var SetupClient = func(maxEdk int, cp suite.CommitmentPolicy) *client.Client { //nolint:gochecknoglobals + var p suite.CommitmentPolicy + if cp == 0 { + p = suite.CommitmentPolicyRequireEncryptRequireDecrypt + } else { + p = cp + } cfg, err := clientconfig.NewConfigWithOpts( - clientconfig.WithCommitmentPolicy(suite.CommitmentPolicyRequireEncryptRequireDecrypt), + clientconfig.WithCommitmentPolicy(p), clientconfig.WithMaxEncryptedDataKeys(maxEdk), ) if err != nil { From df8f88c0d857ce72595ec141e04145df1104a8e8 Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 19:04:31 +0200 Subject: [PATCH 15/16] fix(version): bump SDK version --- pkg/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version.go b/pkg/version.go index de5dd77..a94bdd4 100644 --- a/pkg/version.go +++ b/pkg/version.go @@ -3,4 +3,4 @@ package pkg -const Version = "0.1.0" +const Version = "0.2.0" From aa52398c7288fe14884c2b6f3853802d45e1b424 Mon Sep 17 00:00:00 2001 From: wobondar Date: Fri, 22 Dec 2023 19:18:04 +0200 Subject: [PATCH 16/16] ci(e2e): workflow to run full E2E tests --- .github/workflows/go-e2e-full.yml | 65 +++++++++++++++++++++++++++++++ Makefile | 2 +- 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/go-e2e-full.yml diff --git a/.github/workflows/go-e2e-full.yml b/.github/workflows/go-e2e-full.yml new file mode 100644 index 0000000..4c8ab62 --- /dev/null +++ b/.github/workflows/go-e2e-full.yml @@ -0,0 +1,65 @@ +name: Go E2E full + +on: + workflow_dispatch: + +jobs: + integration: + name: Full Integration Tests + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + cache: false + go-version: 1.21.x + + - name: Load cached dependencies + uses: actions/cache@v3 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-e2e-full-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go-e2e-full- + + - name: Install dependencies + run: make deps + + - name: Unit tests + run: make unit + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install E2E dependencies + run: make e2e-deps + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.OIDC_AWS_ROLE_TO_ASSUME }} + aws-region: us-east-1 + mask-aws-account-id: true + output-credentials: true + role-duration-seconds: 900 + role-session-name: GithubOidcIntegAssumeRole + role-external-id: ${{ secrets.OIDC_AWS_ROLE_EXTERNAL_ID }} + + - name: E2E full tests + run: make e2e-test-full + env: + KEY_1_ARN: ${{ secrets.KEY_1_ARN }} + KEY_2_ARN: ${{ secrets.KEY_2_ARN }} + KEY_3_ARN: ${{ secrets.KEY_3_ARN }} + MRK_KEY_1_ARN: ${{ secrets.MRK_KEY_1_ARN }} + MRK_KEY_2_ARN: ${{ secrets.MRK_KEY_2_ARN }} diff --git a/Makefile b/Makefile index 1c2bb17..6f0fc4c 100644 --- a/Makefile +++ b/Makefile @@ -107,7 +107,7 @@ e2e-test-short: e2e-test-full: @echo "Running full e2e tests, it will take a while" - @gotestsum -f testname -- -timeout=15m -tags "integration" ${RUN_INTEG} ./test/e2e/... + @gotestsum -f ${GOTESTSUM_FMT} -- -timeout=15m -tags "integration" ${RUN_INTEG} ./test/e2e/... e2e-test-slow: @echo "Running very slow e2e tests"