diff --git a/.mockery.yaml b/.mockery.yaml index 38cffe7..71176d9 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -31,18 +31,43 @@ packages: CryptoMaterialsManager: DecryptionMaterial: EncryptionMaterial: + EncryptionBuffer: Wrapper: + DecryptionHandler: + config: + mockname: "MockDecrypter" + filename: "Decrypter_mock.go" + EncryptionHandler: + config: + mockname: "MockEncrypter" + filename: "Encrypter_mock.go" github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format: config: tags: "mocks" interfaces: MessageAAD: + MessageEDK: + MessageHeader: + MessageHeaderAuth: + MessageBody: + BodyFrame: + MessageFooter: + Deserializer: + Serializer: github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/encryption: interfaces: GcmBase: config: mockname: "MockEncrypter" filename: "Encrypter_mock.go" + AEADDecrypter: + AEADEncrypter: github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/rand: interfaces: RandomGenerator: + github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/crypto/signature: + config: + dir: mocks/{{ replaceAll .PackagePath "internal" "internal_" }} + interfaces: + Verifier: + Signer: diff --git a/Makefile b/Makefile index 5352be7..ba6b13a 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ deps: @echo "Installing dependencies" @go mod download -x all @go install gotest.tools/gotestsum@latest - @go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.1 + @go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.2 @go install github.com/vektra/mockery/v2@v2.38.0 @#go get github.com/stretchr/testify/mock@v1.8.4 diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/internal_/crypto/signature/Signer_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/internal_/crypto/signature/Signer_mock.go new file mode 100644 index 0000000..43ddb26 --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/internal_/crypto/signature/Signer_mock.go @@ -0,0 +1,245 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package signature + +import ( + elliptic "crypto/elliptic" + + mock "github.com/stretchr/testify/mock" +) + +// MockSigner is an autogenerated mock type for the Signer type +type MockSigner struct { + mock.Mock +} + +type MockSigner_Expecter struct { + mock *mock.Mock +} + +func (_m *MockSigner) EXPECT() *MockSigner_Expecter { + return &MockSigner_Expecter{mock: &_m.Mock} +} + +// Curve provides a mock function with given fields: +func (_m *MockSigner) Curve() elliptic.Curve { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Curve") + } + + var r0 elliptic.Curve + if rf, ok := ret.Get(0).(func() elliptic.Curve); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(elliptic.Curve) + } + } + + return r0 +} + +// MockSigner_Curve_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Curve' +type MockSigner_Curve_Call struct { + *mock.Call +} + +// Curve is a helper method to define mock.On call +func (_e *MockSigner_Expecter) Curve() *MockSigner_Curve_Call { + return &MockSigner_Curve_Call{Call: _e.mock.On("Curve")} +} + +func (_c *MockSigner_Curve_Call) Run(run func()) *MockSigner_Curve_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockSigner_Curve_Call) Return(_a0 elliptic.Curve) *MockSigner_Curve_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockSigner_Curve_Call) RunAndReturn(run func() elliptic.Curve) *MockSigner_Curve_Call { + _c.Call.Return(run) + return _c +} + +// Sign provides a mock function with given fields: +func (_m *MockSigner) Sign() ([]byte, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Sign") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func() ([]byte, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockSigner_Sign_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Sign' +type MockSigner_Sign_Call struct { + *mock.Call +} + +// Sign is a helper method to define mock.On call +func (_e *MockSigner_Expecter) Sign() *MockSigner_Sign_Call { + return &MockSigner_Sign_Call{Call: _e.mock.On("Sign")} +} + +func (_c *MockSigner_Sign_Call) Run(run func()) *MockSigner_Sign_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockSigner_Sign_Call) Return(_a0 []byte, _a1 error) *MockSigner_Sign_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockSigner_Sign_Call) RunAndReturn(run func() ([]byte, error)) *MockSigner_Sign_Call { + _c.Call.Return(run) + return _c +} + +// Sum provides a mock function with given fields: +func (_m *MockSigner) Sum() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Sum") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockSigner_Sum_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Sum' +type MockSigner_Sum_Call struct { + *mock.Call +} + +// Sum is a helper method to define mock.On call +func (_e *MockSigner_Expecter) Sum() *MockSigner_Sum_Call { + return &MockSigner_Sum_Call{Call: _e.mock.On("Sum")} +} + +func (_c *MockSigner_Sum_Call) Run(run func()) *MockSigner_Sum_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockSigner_Sum_Call) Return(_a0 []byte) *MockSigner_Sum_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockSigner_Sum_Call) RunAndReturn(run func() []byte) *MockSigner_Sum_Call { + _c.Call.Return(run) + return _c +} + +// Write provides a mock function with given fields: p +func (_m *MockSigner) Write(p []byte) (int, error) { + ret := _m.Called(p) + + if len(ret) == 0 { + panic("no return value specified for Write") + } + + var r0 int + var r1 error + if rf, ok := ret.Get(0).(func([]byte) (int, error)); ok { + return rf(p) + } + if rf, ok := ret.Get(0).(func([]byte) int); ok { + r0 = rf(p) + } else { + r0 = ret.Get(0).(int) + } + + if rf, ok := ret.Get(1).(func([]byte) error); ok { + r1 = rf(p) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockSigner_Write_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Write' +type MockSigner_Write_Call struct { + *mock.Call +} + +// Write is a helper method to define mock.On call +// - p []byte +func (_e *MockSigner_Expecter) Write(p interface{}) *MockSigner_Write_Call { + return &MockSigner_Write_Call{Call: _e.mock.On("Write", p)} +} + +func (_c *MockSigner_Write_Call) Run(run func(p []byte)) *MockSigner_Write_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]byte)) + }) + return _c +} + +func (_c *MockSigner_Write_Call) Return(n int, err error) *MockSigner_Write_Call { + _c.Call.Return(n, err) + return _c +} + +func (_c *MockSigner_Write_Call) RunAndReturn(run func([]byte) (int, error)) *MockSigner_Write_Call { + _c.Call.Return(run) + return _c +} + +// NewMockSigner creates a new instance of MockSigner. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockSigner(t interface { + mock.TestingT + Cleanup(func()) +}) *MockSigner { + mock := &MockSigner{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/internal_/crypto/signature/Verifier_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/internal_/crypto/signature/Verifier_mock.go new file mode 100644 index 0000000..ed50cd6 --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/internal_/crypto/signature/Verifier_mock.go @@ -0,0 +1,280 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package signature + +import ( + elliptic "crypto/elliptic" + + mock "github.com/stretchr/testify/mock" +) + +// MockVerifier is an autogenerated mock type for the Verifier type +type MockVerifier struct { + mock.Mock +} + +type MockVerifier_Expecter struct { + mock *mock.Mock +} + +func (_m *MockVerifier) EXPECT() *MockVerifier_Expecter { + return &MockVerifier_Expecter{mock: &_m.Mock} +} + +// Curve provides a mock function with given fields: +func (_m *MockVerifier) Curve() elliptic.Curve { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Curve") + } + + var r0 elliptic.Curve + if rf, ok := ret.Get(0).(func() elliptic.Curve); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(elliptic.Curve) + } + } + + return r0 +} + +// MockVerifier_Curve_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Curve' +type MockVerifier_Curve_Call struct { + *mock.Call +} + +// Curve is a helper method to define mock.On call +func (_e *MockVerifier_Expecter) Curve() *MockVerifier_Curve_Call { + return &MockVerifier_Curve_Call{Call: _e.mock.On("Curve")} +} + +func (_c *MockVerifier_Curve_Call) Run(run func()) *MockVerifier_Curve_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockVerifier_Curve_Call) Return(_a0 elliptic.Curve) *MockVerifier_Curve_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockVerifier_Curve_Call) RunAndReturn(run func() elliptic.Curve) *MockVerifier_Curve_Call { + _c.Call.Return(run) + return _c +} + +// LoadECCKey provides a mock function with given fields: data +func (_m *MockVerifier) LoadECCKey(data []byte) error { + ret := _m.Called(data) + + if len(ret) == 0 { + panic("no return value specified for LoadECCKey") + } + + var r0 error + if rf, ok := ret.Get(0).(func([]byte) error); ok { + r0 = rf(data) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockVerifier_LoadECCKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadECCKey' +type MockVerifier_LoadECCKey_Call struct { + *mock.Call +} + +// LoadECCKey is a helper method to define mock.On call +// - data []byte +func (_e *MockVerifier_Expecter) LoadECCKey(data interface{}) *MockVerifier_LoadECCKey_Call { + return &MockVerifier_LoadECCKey_Call{Call: _e.mock.On("LoadECCKey", data)} +} + +func (_c *MockVerifier_LoadECCKey_Call) Run(run func(data []byte)) *MockVerifier_LoadECCKey_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]byte)) + }) + return _c +} + +func (_c *MockVerifier_LoadECCKey_Call) Return(_a0 error) *MockVerifier_LoadECCKey_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockVerifier_LoadECCKey_Call) RunAndReturn(run func([]byte) error) *MockVerifier_LoadECCKey_Call { + _c.Call.Return(run) + return _c +} + +// Sum provides a mock function with given fields: +func (_m *MockVerifier) Sum() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Sum") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockVerifier_Sum_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Sum' +type MockVerifier_Sum_Call struct { + *mock.Call +} + +// Sum is a helper method to define mock.On call +func (_e *MockVerifier_Expecter) Sum() *MockVerifier_Sum_Call { + return &MockVerifier_Sum_Call{Call: _e.mock.On("Sum")} +} + +func (_c *MockVerifier_Sum_Call) Run(run func()) *MockVerifier_Sum_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockVerifier_Sum_Call) Return(_a0 []byte) *MockVerifier_Sum_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockVerifier_Sum_Call) RunAndReturn(run func() []byte) *MockVerifier_Sum_Call { + _c.Call.Return(run) + return _c +} + +// Verify provides a mock function with given fields: sig +func (_m *MockVerifier) Verify(sig []byte) error { + ret := _m.Called(sig) + + if len(ret) == 0 { + panic("no return value specified for Verify") + } + + var r0 error + if rf, ok := ret.Get(0).(func([]byte) error); ok { + r0 = rf(sig) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockVerifier_Verify_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Verify' +type MockVerifier_Verify_Call struct { + *mock.Call +} + +// Verify is a helper method to define mock.On call +// - sig []byte +func (_e *MockVerifier_Expecter) Verify(sig interface{}) *MockVerifier_Verify_Call { + return &MockVerifier_Verify_Call{Call: _e.mock.On("Verify", sig)} +} + +func (_c *MockVerifier_Verify_Call) Run(run func(sig []byte)) *MockVerifier_Verify_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]byte)) + }) + return _c +} + +func (_c *MockVerifier_Verify_Call) Return(_a0 error) *MockVerifier_Verify_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockVerifier_Verify_Call) RunAndReturn(run func([]byte) error) *MockVerifier_Verify_Call { + _c.Call.Return(run) + return _c +} + +// Write provides a mock function with given fields: p +func (_m *MockVerifier) Write(p []byte) (int, error) { + ret := _m.Called(p) + + if len(ret) == 0 { + panic("no return value specified for Write") + } + + var r0 int + var r1 error + if rf, ok := ret.Get(0).(func([]byte) (int, error)); ok { + return rf(p) + } + if rf, ok := ret.Get(0).(func([]byte) int); ok { + r0 = rf(p) + } else { + r0 = ret.Get(0).(int) + } + + if rf, ok := ret.Get(1).(func([]byte) error); ok { + r1 = rf(p) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockVerifier_Write_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Write' +type MockVerifier_Write_Call struct { + *mock.Call +} + +// Write is a helper method to define mock.On call +// - p []byte +func (_e *MockVerifier_Expecter) Write(p interface{}) *MockVerifier_Write_Call { + return &MockVerifier_Write_Call{Call: _e.mock.On("Write", p)} +} + +func (_c *MockVerifier_Write_Call) Run(run func(p []byte)) *MockVerifier_Write_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]byte)) + }) + return _c +} + +func (_c *MockVerifier_Write_Call) Return(n int, err error) *MockVerifier_Write_Call { + _c.Call.Return(n, err) + return _c +} + +func (_c *MockVerifier_Write_Call) RunAndReturn(run func([]byte) (int, error)) *MockVerifier_Write_Call { + _c.Call.Return(run) + return _c +} + +// NewMockVerifier creates a new instance of MockVerifier. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockVerifier(t interface { + mock.TestingT + Cleanup(func()) +}) *MockVerifier { + mock := &MockVerifier{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/Decrypter_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/Decrypter_mock.go new file mode 100644 index 0000000..fb944d8 --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/Decrypter_mock.go @@ -0,0 +1,107 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package model + +import ( + context "context" + + format "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" + mock "github.com/stretchr/testify/mock" +) + +// MockDecrypter is an autogenerated mock type for the DecryptionHandler type +type MockDecrypter struct { + mock.Mock +} + +type MockDecrypter_Expecter struct { + mock *mock.Mock +} + +func (_m *MockDecrypter) EXPECT() *MockDecrypter_Expecter { + return &MockDecrypter_Expecter{mock: &_m.Mock} +} + +// Decrypt provides a mock function with given fields: ctx, ciphertext +func (_m *MockDecrypter) Decrypt(ctx context.Context, ciphertext []byte) ([]byte, format.MessageHeader, error) { + ret := _m.Called(ctx, ciphertext) + + if len(ret) == 0 { + panic("no return value specified for Decrypt") + } + + var r0 []byte + var r1 format.MessageHeader + var r2 error + if rf, ok := ret.Get(0).(func(context.Context, []byte) ([]byte, format.MessageHeader, error)); ok { + return rf(ctx, ciphertext) + } + if rf, ok := ret.Get(0).(func(context.Context, []byte) []byte); ok { + r0 = rf(ctx, ciphertext) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []byte) format.MessageHeader); ok { + r1 = rf(ctx, ciphertext) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(format.MessageHeader) + } + } + + if rf, ok := ret.Get(2).(func(context.Context, []byte) error); ok { + r2 = rf(ctx, ciphertext) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// MockDecrypter_Decrypt_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Decrypt' +type MockDecrypter_Decrypt_Call struct { + *mock.Call +} + +// Decrypt is a helper method to define mock.On call +// - ctx context.Context +// - ciphertext []byte +func (_e *MockDecrypter_Expecter) Decrypt(ctx interface{}, ciphertext interface{}) *MockDecrypter_Decrypt_Call { + return &MockDecrypter_Decrypt_Call{Call: _e.mock.On("Decrypt", ctx, ciphertext)} +} + +func (_c *MockDecrypter_Decrypt_Call) Run(run func(ctx context.Context, ciphertext []byte)) *MockDecrypter_Decrypt_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]byte)) + }) + return _c +} + +func (_c *MockDecrypter_Decrypt_Call) Return(_a0 []byte, _a1 format.MessageHeader, _a2 error) *MockDecrypter_Decrypt_Call { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *MockDecrypter_Decrypt_Call) RunAndReturn(run func(context.Context, []byte) ([]byte, format.MessageHeader, error)) *MockDecrypter_Decrypt_Call { + _c.Call.Return(run) + return _c +} + +// NewMockDecrypter creates a new instance of MockDecrypter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockDecrypter(t interface { + mock.TestingT + Cleanup(func()) +}) *MockDecrypter { + mock := &MockDecrypter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/Encrypter_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/Encrypter_mock.go new file mode 100644 index 0000000..07677cd --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/Encrypter_mock.go @@ -0,0 +1,110 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package model + +import ( + context "context" + + format "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" + mock "github.com/stretchr/testify/mock" + + suite "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" +) + +// MockEncrypter is an autogenerated mock type for the EncryptionHandler type +type MockEncrypter struct { + mock.Mock +} + +type MockEncrypter_Expecter struct { + mock *mock.Mock +} + +func (_m *MockEncrypter) EXPECT() *MockEncrypter_Expecter { + return &MockEncrypter_Expecter{mock: &_m.Mock} +} + +// Encrypt provides a mock function with given fields: ctx, source, ec +func (_m *MockEncrypter) Encrypt(ctx context.Context, source []byte, ec suite.EncryptionContext) ([]byte, format.MessageHeader, error) { + ret := _m.Called(ctx, source, ec) + + if len(ret) == 0 { + panic("no return value specified for Encrypt") + } + + var r0 []byte + var r1 format.MessageHeader + var r2 error + if rf, ok := ret.Get(0).(func(context.Context, []byte, suite.EncryptionContext) ([]byte, format.MessageHeader, error)); ok { + return rf(ctx, source, ec) + } + if rf, ok := ret.Get(0).(func(context.Context, []byte, suite.EncryptionContext) []byte); ok { + r0 = rf(ctx, source, ec) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []byte, suite.EncryptionContext) format.MessageHeader); ok { + r1 = rf(ctx, source, ec) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(format.MessageHeader) + } + } + + if rf, ok := ret.Get(2).(func(context.Context, []byte, suite.EncryptionContext) error); ok { + r2 = rf(ctx, source, ec) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// MockEncrypter_Encrypt_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Encrypt' +type MockEncrypter_Encrypt_Call struct { + *mock.Call +} + +// Encrypt is a helper method to define mock.On call +// - ctx context.Context +// - source []byte +// - ec suite.EncryptionContext +func (_e *MockEncrypter_Expecter) Encrypt(ctx interface{}, source interface{}, ec interface{}) *MockEncrypter_Encrypt_Call { + return &MockEncrypter_Encrypt_Call{Call: _e.mock.On("Encrypt", ctx, source, ec)} +} + +func (_c *MockEncrypter_Encrypt_Call) Run(run func(ctx context.Context, source []byte, ec suite.EncryptionContext)) *MockEncrypter_Encrypt_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]byte), args[2].(suite.EncryptionContext)) + }) + return _c +} + +func (_c *MockEncrypter_Encrypt_Call) Return(_a0 []byte, _a1 format.MessageHeader, _a2 error) *MockEncrypter_Encrypt_Call { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *MockEncrypter_Encrypt_Call) RunAndReturn(run func(context.Context, []byte, suite.EncryptionContext) ([]byte, format.MessageHeader, error)) *MockEncrypter_Encrypt_Call { + _c.Call.Return(run) + return _c +} + +// NewMockEncrypter creates a new instance of MockEncrypter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockEncrypter(t interface { + mock.TestingT + Cleanup(func()) +}) *MockEncrypter { + mock := &MockEncrypter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/EncryptionBuffer_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/EncryptionBuffer_mock.go new file mode 100644 index 0000000..62e190d --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/EncryptionBuffer_mock.go @@ -0,0 +1,270 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package model + +import mock "github.com/stretchr/testify/mock" + +// MockEncryptionBuffer is an autogenerated mock type for the EncryptionBuffer type +type MockEncryptionBuffer struct { + mock.Mock +} + +type MockEncryptionBuffer_Expecter struct { + mock *mock.Mock +} + +func (_m *MockEncryptionBuffer) EXPECT() *MockEncryptionBuffer_Expecter { + return &MockEncryptionBuffer_Expecter{mock: &_m.Mock} +} + +// Bytes provides a mock function with given fields: +func (_m *MockEncryptionBuffer) Bytes() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Bytes") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockEncryptionBuffer_Bytes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bytes' +type MockEncryptionBuffer_Bytes_Call struct { + *mock.Call +} + +// Bytes is a helper method to define mock.On call +func (_e *MockEncryptionBuffer_Expecter) Bytes() *MockEncryptionBuffer_Bytes_Call { + return &MockEncryptionBuffer_Bytes_Call{Call: _e.mock.On("Bytes")} +} + +func (_c *MockEncryptionBuffer_Bytes_Call) Run(run func()) *MockEncryptionBuffer_Bytes_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockEncryptionBuffer_Bytes_Call) Return(_a0 []byte) *MockEncryptionBuffer_Bytes_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockEncryptionBuffer_Bytes_Call) RunAndReturn(run func() []byte) *MockEncryptionBuffer_Bytes_Call { + _c.Call.Return(run) + return _c +} + +// Len provides a mock function with given fields: +func (_m *MockEncryptionBuffer) Len() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Len") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// MockEncryptionBuffer_Len_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Len' +type MockEncryptionBuffer_Len_Call struct { + *mock.Call +} + +// Len is a helper method to define mock.On call +func (_e *MockEncryptionBuffer_Expecter) Len() *MockEncryptionBuffer_Len_Call { + return &MockEncryptionBuffer_Len_Call{Call: _e.mock.On("Len")} +} + +func (_c *MockEncryptionBuffer_Len_Call) Run(run func()) *MockEncryptionBuffer_Len_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockEncryptionBuffer_Len_Call) Return(_a0 int) *MockEncryptionBuffer_Len_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockEncryptionBuffer_Len_Call) RunAndReturn(run func() int) *MockEncryptionBuffer_Len_Call { + _c.Call.Return(run) + return _c +} + +// Read provides a mock function with given fields: p +func (_m *MockEncryptionBuffer) Read(p []byte) (int, error) { + ret := _m.Called(p) + + if len(ret) == 0 { + panic("no return value specified for Read") + } + + var r0 int + var r1 error + if rf, ok := ret.Get(0).(func([]byte) (int, error)); ok { + return rf(p) + } + if rf, ok := ret.Get(0).(func([]byte) int); ok { + r0 = rf(p) + } else { + r0 = ret.Get(0).(int) + } + + if rf, ok := ret.Get(1).(func([]byte) error); ok { + r1 = rf(p) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockEncryptionBuffer_Read_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Read' +type MockEncryptionBuffer_Read_Call struct { + *mock.Call +} + +// Read is a helper method to define mock.On call +// - p []byte +func (_e *MockEncryptionBuffer_Expecter) Read(p interface{}) *MockEncryptionBuffer_Read_Call { + return &MockEncryptionBuffer_Read_Call{Call: _e.mock.On("Read", p)} +} + +func (_c *MockEncryptionBuffer_Read_Call) Run(run func(p []byte)) *MockEncryptionBuffer_Read_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]byte)) + }) + return _c +} + +func (_c *MockEncryptionBuffer_Read_Call) Return(n int, err error) *MockEncryptionBuffer_Read_Call { + _c.Call.Return(n, err) + return _c +} + +func (_c *MockEncryptionBuffer_Read_Call) RunAndReturn(run func([]byte) (int, error)) *MockEncryptionBuffer_Read_Call { + _c.Call.Return(run) + return _c +} + +// Reset provides a mock function with given fields: +func (_m *MockEncryptionBuffer) Reset() { + _m.Called() +} + +// MockEncryptionBuffer_Reset_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Reset' +type MockEncryptionBuffer_Reset_Call struct { + *mock.Call +} + +// Reset is a helper method to define mock.On call +func (_e *MockEncryptionBuffer_Expecter) Reset() *MockEncryptionBuffer_Reset_Call { + return &MockEncryptionBuffer_Reset_Call{Call: _e.mock.On("Reset")} +} + +func (_c *MockEncryptionBuffer_Reset_Call) Run(run func()) *MockEncryptionBuffer_Reset_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockEncryptionBuffer_Reset_Call) Return() *MockEncryptionBuffer_Reset_Call { + _c.Call.Return() + return _c +} + +func (_c *MockEncryptionBuffer_Reset_Call) RunAndReturn(run func()) *MockEncryptionBuffer_Reset_Call { + _c.Call.Return(run) + return _c +} + +// Write provides a mock function with given fields: p +func (_m *MockEncryptionBuffer) Write(p []byte) (int, error) { + ret := _m.Called(p) + + if len(ret) == 0 { + panic("no return value specified for Write") + } + + var r0 int + var r1 error + if rf, ok := ret.Get(0).(func([]byte) (int, error)); ok { + return rf(p) + } + if rf, ok := ret.Get(0).(func([]byte) int); ok { + r0 = rf(p) + } else { + r0 = ret.Get(0).(int) + } + + if rf, ok := ret.Get(1).(func([]byte) error); ok { + r1 = rf(p) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockEncryptionBuffer_Write_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Write' +type MockEncryptionBuffer_Write_Call struct { + *mock.Call +} + +// Write is a helper method to define mock.On call +// - p []byte +func (_e *MockEncryptionBuffer_Expecter) Write(p interface{}) *MockEncryptionBuffer_Write_Call { + return &MockEncryptionBuffer_Write_Call{Call: _e.mock.On("Write", p)} +} + +func (_c *MockEncryptionBuffer_Write_Call) Run(run func(p []byte)) *MockEncryptionBuffer_Write_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]byte)) + }) + return _c +} + +func (_c *MockEncryptionBuffer_Write_Call) Return(n int, err error) *MockEncryptionBuffer_Write_Call { + _c.Call.Return(n, err) + return _c +} + +func (_c *MockEncryptionBuffer_Write_Call) RunAndReturn(run func([]byte) (int, error)) *MockEncryptionBuffer_Write_Call { + _c.Call.Return(run) + return _c +} + +// NewMockEncryptionBuffer creates a new instance of MockEncryptionBuffer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockEncryptionBuffer(t interface { + mock.TestingT + Cleanup(func()) +}) *MockEncryptionBuffer { + mock := &MockEncryptionBuffer{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/BodyFrame_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/BodyFrame_mock.go new file mode 100644 index 0000000..1026223 --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/BodyFrame_mock.go @@ -0,0 +1,357 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package format + +import mock "github.com/stretchr/testify/mock" + +// MockBodyFrame is an autogenerated mock type for the BodyFrame type +type MockBodyFrame struct { + mock.Mock +} + +type MockBodyFrame_Expecter struct { + mock *mock.Mock +} + +func (_m *MockBodyFrame) EXPECT() *MockBodyFrame_Expecter { + return &MockBodyFrame_Expecter{mock: &_m.Mock} +} + +// AuthenticationTag provides a mock function with given fields: +func (_m *MockBodyFrame) AuthenticationTag() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for AuthenticationTag") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockBodyFrame_AuthenticationTag_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthenticationTag' +type MockBodyFrame_AuthenticationTag_Call struct { + *mock.Call +} + +// AuthenticationTag is a helper method to define mock.On call +func (_e *MockBodyFrame_Expecter) AuthenticationTag() *MockBodyFrame_AuthenticationTag_Call { + return &MockBodyFrame_AuthenticationTag_Call{Call: _e.mock.On("AuthenticationTag")} +} + +func (_c *MockBodyFrame_AuthenticationTag_Call) Run(run func()) *MockBodyFrame_AuthenticationTag_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockBodyFrame_AuthenticationTag_Call) Return(_a0 []byte) *MockBodyFrame_AuthenticationTag_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockBodyFrame_AuthenticationTag_Call) RunAndReturn(run func() []byte) *MockBodyFrame_AuthenticationTag_Call { + _c.Call.Return(run) + return _c +} + +// Bytes provides a mock function with given fields: +func (_m *MockBodyFrame) Bytes() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Bytes") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockBodyFrame_Bytes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bytes' +type MockBodyFrame_Bytes_Call struct { + *mock.Call +} + +// Bytes is a helper method to define mock.On call +func (_e *MockBodyFrame_Expecter) Bytes() *MockBodyFrame_Bytes_Call { + return &MockBodyFrame_Bytes_Call{Call: _e.mock.On("Bytes")} +} + +func (_c *MockBodyFrame_Bytes_Call) Run(run func()) *MockBodyFrame_Bytes_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockBodyFrame_Bytes_Call) Return(_a0 []byte) *MockBodyFrame_Bytes_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockBodyFrame_Bytes_Call) RunAndReturn(run func() []byte) *MockBodyFrame_Bytes_Call { + _c.Call.Return(run) + return _c +} + +// EncryptedContent provides a mock function with given fields: +func (_m *MockBodyFrame) EncryptedContent() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for EncryptedContent") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockBodyFrame_EncryptedContent_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EncryptedContent' +type MockBodyFrame_EncryptedContent_Call struct { + *mock.Call +} + +// EncryptedContent is a helper method to define mock.On call +func (_e *MockBodyFrame_Expecter) EncryptedContent() *MockBodyFrame_EncryptedContent_Call { + return &MockBodyFrame_EncryptedContent_Call{Call: _e.mock.On("EncryptedContent")} +} + +func (_c *MockBodyFrame_EncryptedContent_Call) Run(run func()) *MockBodyFrame_EncryptedContent_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockBodyFrame_EncryptedContent_Call) Return(_a0 []byte) *MockBodyFrame_EncryptedContent_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockBodyFrame_EncryptedContent_Call) RunAndReturn(run func() []byte) *MockBodyFrame_EncryptedContent_Call { + _c.Call.Return(run) + return _c +} + +// IV provides a mock function with given fields: +func (_m *MockBodyFrame) IV() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for IV") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockBodyFrame_IV_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IV' +type MockBodyFrame_IV_Call struct { + *mock.Call +} + +// IV is a helper method to define mock.On call +func (_e *MockBodyFrame_Expecter) IV() *MockBodyFrame_IV_Call { + return &MockBodyFrame_IV_Call{Call: _e.mock.On("IV")} +} + +func (_c *MockBodyFrame_IV_Call) Run(run func()) *MockBodyFrame_IV_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockBodyFrame_IV_Call) Return(_a0 []byte) *MockBodyFrame_IV_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockBodyFrame_IV_Call) RunAndReturn(run func() []byte) *MockBodyFrame_IV_Call { + _c.Call.Return(run) + return _c +} + +// IsFinal provides a mock function with given fields: +func (_m *MockBodyFrame) IsFinal() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for IsFinal") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// MockBodyFrame_IsFinal_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsFinal' +type MockBodyFrame_IsFinal_Call struct { + *mock.Call +} + +// IsFinal is a helper method to define mock.On call +func (_e *MockBodyFrame_Expecter) IsFinal() *MockBodyFrame_IsFinal_Call { + return &MockBodyFrame_IsFinal_Call{Call: _e.mock.On("IsFinal")} +} + +func (_c *MockBodyFrame_IsFinal_Call) Run(run func()) *MockBodyFrame_IsFinal_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockBodyFrame_IsFinal_Call) Return(_a0 bool) *MockBodyFrame_IsFinal_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockBodyFrame_IsFinal_Call) RunAndReturn(run func() bool) *MockBodyFrame_IsFinal_Call { + _c.Call.Return(run) + return _c +} + +// Len provides a mock function with given fields: +func (_m *MockBodyFrame) Len() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Len") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// MockBodyFrame_Len_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Len' +type MockBodyFrame_Len_Call struct { + *mock.Call +} + +// Len is a helper method to define mock.On call +func (_e *MockBodyFrame_Expecter) Len() *MockBodyFrame_Len_Call { + return &MockBodyFrame_Len_Call{Call: _e.mock.On("Len")} +} + +func (_c *MockBodyFrame_Len_Call) Run(run func()) *MockBodyFrame_Len_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockBodyFrame_Len_Call) Return(_a0 int) *MockBodyFrame_Len_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockBodyFrame_Len_Call) RunAndReturn(run func() int) *MockBodyFrame_Len_Call { + _c.Call.Return(run) + return _c +} + +// SequenceNumber provides a mock function with given fields: +func (_m *MockBodyFrame) SequenceNumber() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for SequenceNumber") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// MockBodyFrame_SequenceNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SequenceNumber' +type MockBodyFrame_SequenceNumber_Call struct { + *mock.Call +} + +// SequenceNumber is a helper method to define mock.On call +func (_e *MockBodyFrame_Expecter) SequenceNumber() *MockBodyFrame_SequenceNumber_Call { + return &MockBodyFrame_SequenceNumber_Call{Call: _e.mock.On("SequenceNumber")} +} + +func (_c *MockBodyFrame_SequenceNumber_Call) Run(run func()) *MockBodyFrame_SequenceNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockBodyFrame_SequenceNumber_Call) Return(_a0 int) *MockBodyFrame_SequenceNumber_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockBodyFrame_SequenceNumber_Call) RunAndReturn(run func() int) *MockBodyFrame_SequenceNumber_Call { + _c.Call.Return(run) + return _c +} + +// NewMockBodyFrame creates a new instance of MockBodyFrame. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockBodyFrame(t interface { + mock.TestingT + Cleanup(func()) +}) *MockBodyFrame { + mock := &MockBodyFrame{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/Deserializer_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/Deserializer_mock.go new file mode 100644 index 0000000..25b99d5 --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/Deserializer_mock.go @@ -0,0 +1,228 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package format + +import ( + bytes "bytes" + + format "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" + mock "github.com/stretchr/testify/mock" + + suite "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" +) + +// MockDeserializer is an autogenerated mock type for the Deserializer type +type MockDeserializer struct { + mock.Mock +} + +type MockDeserializer_Expecter struct { + mock *mock.Mock +} + +func (_m *MockDeserializer) EXPECT() *MockDeserializer_Expecter { + return &MockDeserializer_Expecter{mock: &_m.Mock} +} + +// DeserializeBody provides a mock function with given fields: buf, algorithm, frameLen +func (_m *MockDeserializer) DeserializeBody(buf *bytes.Buffer, algorithm *suite.AlgorithmSuite, frameLen int) (format.MessageBody, error) { + ret := _m.Called(buf, algorithm, frameLen) + + if len(ret) == 0 { + panic("no return value specified for DeserializeBody") + } + + var r0 format.MessageBody + var r1 error + if rf, ok := ret.Get(0).(func(*bytes.Buffer, *suite.AlgorithmSuite, int) (format.MessageBody, error)); ok { + return rf(buf, algorithm, frameLen) + } + if rf, ok := ret.Get(0).(func(*bytes.Buffer, *suite.AlgorithmSuite, int) format.MessageBody); ok { + r0 = rf(buf, algorithm, frameLen) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(format.MessageBody) + } + } + + if rf, ok := ret.Get(1).(func(*bytes.Buffer, *suite.AlgorithmSuite, int) error); ok { + r1 = rf(buf, algorithm, frameLen) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockDeserializer_DeserializeBody_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeserializeBody' +type MockDeserializer_DeserializeBody_Call struct { + *mock.Call +} + +// DeserializeBody is a helper method to define mock.On call +// - buf *bytes.Buffer +// - algorithm *suite.AlgorithmSuite +// - frameLen int +func (_e *MockDeserializer_Expecter) DeserializeBody(buf interface{}, algorithm interface{}, frameLen interface{}) *MockDeserializer_DeserializeBody_Call { + return &MockDeserializer_DeserializeBody_Call{Call: _e.mock.On("DeserializeBody", buf, algorithm, frameLen)} +} + +func (_c *MockDeserializer_DeserializeBody_Call) Run(run func(buf *bytes.Buffer, algorithm *suite.AlgorithmSuite, frameLen int)) *MockDeserializer_DeserializeBody_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bytes.Buffer), args[1].(*suite.AlgorithmSuite), args[2].(int)) + }) + return _c +} + +func (_c *MockDeserializer_DeserializeBody_Call) Return(_a0 format.MessageBody, _a1 error) *MockDeserializer_DeserializeBody_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockDeserializer_DeserializeBody_Call) RunAndReturn(run func(*bytes.Buffer, *suite.AlgorithmSuite, int) (format.MessageBody, error)) *MockDeserializer_DeserializeBody_Call { + _c.Call.Return(run) + return _c +} + +// DeserializeFooter provides a mock function with given fields: alg, buf +func (_m *MockDeserializer) DeserializeFooter(alg *suite.AlgorithmSuite, buf *bytes.Buffer) (format.MessageFooter, error) { + ret := _m.Called(alg, buf) + + if len(ret) == 0 { + panic("no return value specified for DeserializeFooter") + } + + var r0 format.MessageFooter + var r1 error + if rf, ok := ret.Get(0).(func(*suite.AlgorithmSuite, *bytes.Buffer) (format.MessageFooter, error)); ok { + return rf(alg, buf) + } + if rf, ok := ret.Get(0).(func(*suite.AlgorithmSuite, *bytes.Buffer) format.MessageFooter); ok { + r0 = rf(alg, buf) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(format.MessageFooter) + } + } + + if rf, ok := ret.Get(1).(func(*suite.AlgorithmSuite, *bytes.Buffer) error); ok { + r1 = rf(alg, buf) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockDeserializer_DeserializeFooter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeserializeFooter' +type MockDeserializer_DeserializeFooter_Call struct { + *mock.Call +} + +// DeserializeFooter is a helper method to define mock.On call +// - alg *suite.AlgorithmSuite +// - buf *bytes.Buffer +func (_e *MockDeserializer_Expecter) DeserializeFooter(alg interface{}, buf interface{}) *MockDeserializer_DeserializeFooter_Call { + return &MockDeserializer_DeserializeFooter_Call{Call: _e.mock.On("DeserializeFooter", alg, buf)} +} + +func (_c *MockDeserializer_DeserializeFooter_Call) Run(run func(alg *suite.AlgorithmSuite, buf *bytes.Buffer)) *MockDeserializer_DeserializeFooter_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*suite.AlgorithmSuite), args[1].(*bytes.Buffer)) + }) + return _c +} + +func (_c *MockDeserializer_DeserializeFooter_Call) Return(_a0 format.MessageFooter, _a1 error) *MockDeserializer_DeserializeFooter_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockDeserializer_DeserializeFooter_Call) RunAndReturn(run func(*suite.AlgorithmSuite, *bytes.Buffer) (format.MessageFooter, error)) *MockDeserializer_DeserializeFooter_Call { + _c.Call.Return(run) + return _c +} + +// DeserializeHeader provides a mock function with given fields: buf, maxEncryptedDataKeys +func (_m *MockDeserializer) DeserializeHeader(buf *bytes.Buffer, maxEncryptedDataKeys int) (format.MessageHeader, format.MessageHeaderAuth, error) { + ret := _m.Called(buf, maxEncryptedDataKeys) + + if len(ret) == 0 { + panic("no return value specified for DeserializeHeader") + } + + var r0 format.MessageHeader + var r1 format.MessageHeaderAuth + var r2 error + if rf, ok := ret.Get(0).(func(*bytes.Buffer, int) (format.MessageHeader, format.MessageHeaderAuth, error)); ok { + return rf(buf, maxEncryptedDataKeys) + } + if rf, ok := ret.Get(0).(func(*bytes.Buffer, int) format.MessageHeader); ok { + r0 = rf(buf, maxEncryptedDataKeys) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(format.MessageHeader) + } + } + + if rf, ok := ret.Get(1).(func(*bytes.Buffer, int) format.MessageHeaderAuth); ok { + r1 = rf(buf, maxEncryptedDataKeys) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(format.MessageHeaderAuth) + } + } + + if rf, ok := ret.Get(2).(func(*bytes.Buffer, int) error); ok { + r2 = rf(buf, maxEncryptedDataKeys) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// MockDeserializer_DeserializeHeader_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeserializeHeader' +type MockDeserializer_DeserializeHeader_Call struct { + *mock.Call +} + +// DeserializeHeader is a helper method to define mock.On call +// - buf *bytes.Buffer +// - maxEncryptedDataKeys int +func (_e *MockDeserializer_Expecter) DeserializeHeader(buf interface{}, maxEncryptedDataKeys interface{}) *MockDeserializer_DeserializeHeader_Call { + return &MockDeserializer_DeserializeHeader_Call{Call: _e.mock.On("DeserializeHeader", buf, maxEncryptedDataKeys)} +} + +func (_c *MockDeserializer_DeserializeHeader_Call) Run(run func(buf *bytes.Buffer, maxEncryptedDataKeys int)) *MockDeserializer_DeserializeHeader_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*bytes.Buffer), args[1].(int)) + }) + return _c +} + +func (_c *MockDeserializer_DeserializeHeader_Call) Return(_a0 format.MessageHeader, _a1 format.MessageHeaderAuth, _a2 error) *MockDeserializer_DeserializeHeader_Call { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *MockDeserializer_DeserializeHeader_Call) RunAndReturn(run func(*bytes.Buffer, int) (format.MessageHeader, format.MessageHeaderAuth, error)) *MockDeserializer_DeserializeHeader_Call { + _c.Call.Return(run) + return _c +} + +// NewMockDeserializer creates a new instance of MockDeserializer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockDeserializer(t interface { + mock.TestingT + Cleanup(func()) +}) *MockDeserializer { + mock := &MockDeserializer{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageBody_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageBody_mock.go new file mode 100644 index 0000000..b810168 --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageBody_mock.go @@ -0,0 +1,227 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package format + +import ( + format "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" + mock "github.com/stretchr/testify/mock" +) + +// MockMessageBody is an autogenerated mock type for the MessageBody type +type MockMessageBody struct { + mock.Mock +} + +type MockMessageBody_Expecter struct { + mock *mock.Mock +} + +func (_m *MockMessageBody) EXPECT() *MockMessageBody_Expecter { + return &MockMessageBody_Expecter{mock: &_m.Mock} +} + +// AddFrame provides a mock function with given fields: final, seqNum, IV, contentLength, ciphertext, authTag +func (_m *MockMessageBody) AddFrame(final bool, seqNum int, IV []byte, contentLength int, ciphertext []byte, authTag []byte) error { + ret := _m.Called(final, seqNum, IV, contentLength, ciphertext, authTag) + + if len(ret) == 0 { + panic("no return value specified for AddFrame") + } + + var r0 error + if rf, ok := ret.Get(0).(func(bool, int, []byte, int, []byte, []byte) error); ok { + r0 = rf(final, seqNum, IV, contentLength, ciphertext, authTag) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockMessageBody_AddFrame_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddFrame' +type MockMessageBody_AddFrame_Call struct { + *mock.Call +} + +// AddFrame is a helper method to define mock.On call +// - final bool +// - seqNum int +// - IV []byte +// - contentLength int +// - ciphertext []byte +// - authTag []byte +func (_e *MockMessageBody_Expecter) AddFrame(final interface{}, seqNum interface{}, IV interface{}, contentLength interface{}, ciphertext interface{}, authTag interface{}) *MockMessageBody_AddFrame_Call { + return &MockMessageBody_AddFrame_Call{Call: _e.mock.On("AddFrame", final, seqNum, IV, contentLength, ciphertext, authTag)} +} + +func (_c *MockMessageBody_AddFrame_Call) Run(run func(final bool, seqNum int, IV []byte, contentLength int, ciphertext []byte, authTag []byte)) *MockMessageBody_AddFrame_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(bool), args[1].(int), args[2].([]byte), args[3].(int), args[4].([]byte), args[5].([]byte)) + }) + return _c +} + +func (_c *MockMessageBody_AddFrame_Call) Return(_a0 error) *MockMessageBody_AddFrame_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageBody_AddFrame_Call) RunAndReturn(run func(bool, int, []byte, int, []byte, []byte) error) *MockMessageBody_AddFrame_Call { + _c.Call.Return(run) + return _c +} + +// Bytes provides a mock function with given fields: +func (_m *MockMessageBody) Bytes() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Bytes") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockMessageBody_Bytes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bytes' +type MockMessageBody_Bytes_Call struct { + *mock.Call +} + +// Bytes is a helper method to define mock.On call +func (_e *MockMessageBody_Expecter) Bytes() *MockMessageBody_Bytes_Call { + return &MockMessageBody_Bytes_Call{Call: _e.mock.On("Bytes")} +} + +func (_c *MockMessageBody_Bytes_Call) Run(run func()) *MockMessageBody_Bytes_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageBody_Bytes_Call) Return(_a0 []byte) *MockMessageBody_Bytes_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageBody_Bytes_Call) RunAndReturn(run func() []byte) *MockMessageBody_Bytes_Call { + _c.Call.Return(run) + return _c +} + +// Frames provides a mock function with given fields: +func (_m *MockMessageBody) Frames() []format.BodyFrame { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Frames") + } + + var r0 []format.BodyFrame + if rf, ok := ret.Get(0).(func() []format.BodyFrame); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]format.BodyFrame) + } + } + + return r0 +} + +// MockMessageBody_Frames_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Frames' +type MockMessageBody_Frames_Call struct { + *mock.Call +} + +// Frames is a helper method to define mock.On call +func (_e *MockMessageBody_Expecter) Frames() *MockMessageBody_Frames_Call { + return &MockMessageBody_Frames_Call{Call: _e.mock.On("Frames")} +} + +func (_c *MockMessageBody_Frames_Call) Run(run func()) *MockMessageBody_Frames_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageBody_Frames_Call) Return(_a0 []format.BodyFrame) *MockMessageBody_Frames_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageBody_Frames_Call) RunAndReturn(run func() []format.BodyFrame) *MockMessageBody_Frames_Call { + _c.Call.Return(run) + return _c +} + +// Len provides a mock function with given fields: +func (_m *MockMessageBody) Len() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Len") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// MockMessageBody_Len_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Len' +type MockMessageBody_Len_Call struct { + *mock.Call +} + +// Len is a helper method to define mock.On call +func (_e *MockMessageBody_Expecter) Len() *MockMessageBody_Len_Call { + return &MockMessageBody_Len_Call{Call: _e.mock.On("Len")} +} + +func (_c *MockMessageBody_Len_Call) Run(run func()) *MockMessageBody_Len_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageBody_Len_Call) Return(_a0 int) *MockMessageBody_Len_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageBody_Len_Call) RunAndReturn(run func() int) *MockMessageBody_Len_Call { + _c.Call.Return(run) + return _c +} + +// NewMockMessageBody creates a new instance of MockMessageBody. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockMessageBody(t interface { + mock.TestingT + Cleanup(func()) +}) *MockMessageBody { + mock := &MockMessageBody{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageEDK_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageEDK_mock.go new file mode 100644 index 0000000..5a37286 --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageEDK_mock.go @@ -0,0 +1,263 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package format + +import mock "github.com/stretchr/testify/mock" + +// MockMessageEDK is an autogenerated mock type for the MessageEDK type +type MockMessageEDK struct { + mock.Mock +} + +type MockMessageEDK_Expecter struct { + mock *mock.Mock +} + +func (_m *MockMessageEDK) EXPECT() *MockMessageEDK_Expecter { + return &MockMessageEDK_Expecter{mock: &_m.Mock} +} + +// Bytes provides a mock function with given fields: +func (_m *MockMessageEDK) Bytes() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Bytes") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockMessageEDK_Bytes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bytes' +type MockMessageEDK_Bytes_Call struct { + *mock.Call +} + +// Bytes is a helper method to define mock.On call +func (_e *MockMessageEDK_Expecter) Bytes() *MockMessageEDK_Bytes_Call { + return &MockMessageEDK_Bytes_Call{Call: _e.mock.On("Bytes")} +} + +func (_c *MockMessageEDK_Bytes_Call) Run(run func()) *MockMessageEDK_Bytes_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageEDK_Bytes_Call) Return(_a0 []byte) *MockMessageEDK_Bytes_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageEDK_Bytes_Call) RunAndReturn(run func() []byte) *MockMessageEDK_Bytes_Call { + _c.Call.Return(run) + return _c +} + +// EncryptedDataKey provides a mock function with given fields: +func (_m *MockMessageEDK) EncryptedDataKey() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for EncryptedDataKey") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockMessageEDK_EncryptedDataKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EncryptedDataKey' +type MockMessageEDK_EncryptedDataKey_Call struct { + *mock.Call +} + +// EncryptedDataKey is a helper method to define mock.On call +func (_e *MockMessageEDK_Expecter) EncryptedDataKey() *MockMessageEDK_EncryptedDataKey_Call { + return &MockMessageEDK_EncryptedDataKey_Call{Call: _e.mock.On("EncryptedDataKey")} +} + +func (_c *MockMessageEDK_EncryptedDataKey_Call) Run(run func()) *MockMessageEDK_EncryptedDataKey_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageEDK_EncryptedDataKey_Call) Return(_a0 []byte) *MockMessageEDK_EncryptedDataKey_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageEDK_EncryptedDataKey_Call) RunAndReturn(run func() []byte) *MockMessageEDK_EncryptedDataKey_Call { + _c.Call.Return(run) + return _c +} + +// Len provides a mock function with given fields: +func (_m *MockMessageEDK) Len() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Len") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// MockMessageEDK_Len_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Len' +type MockMessageEDK_Len_Call struct { + *mock.Call +} + +// Len is a helper method to define mock.On call +func (_e *MockMessageEDK_Expecter) Len() *MockMessageEDK_Len_Call { + return &MockMessageEDK_Len_Call{Call: _e.mock.On("Len")} +} + +func (_c *MockMessageEDK_Len_Call) Run(run func()) *MockMessageEDK_Len_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageEDK_Len_Call) Return(_a0 int) *MockMessageEDK_Len_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageEDK_Len_Call) RunAndReturn(run func() int) *MockMessageEDK_Len_Call { + _c.Call.Return(run) + return _c +} + +// ProviderID provides a mock function with given fields: +func (_m *MockMessageEDK) ProviderID() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for ProviderID") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockMessageEDK_ProviderID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ProviderID' +type MockMessageEDK_ProviderID_Call struct { + *mock.Call +} + +// ProviderID is a helper method to define mock.On call +func (_e *MockMessageEDK_Expecter) ProviderID() *MockMessageEDK_ProviderID_Call { + return &MockMessageEDK_ProviderID_Call{Call: _e.mock.On("ProviderID")} +} + +func (_c *MockMessageEDK_ProviderID_Call) Run(run func()) *MockMessageEDK_ProviderID_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageEDK_ProviderID_Call) Return(_a0 string) *MockMessageEDK_ProviderID_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageEDK_ProviderID_Call) RunAndReturn(run func() string) *MockMessageEDK_ProviderID_Call { + _c.Call.Return(run) + return _c +} + +// ProviderInfo provides a mock function with given fields: +func (_m *MockMessageEDK) ProviderInfo() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for ProviderInfo") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockMessageEDK_ProviderInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ProviderInfo' +type MockMessageEDK_ProviderInfo_Call struct { + *mock.Call +} + +// ProviderInfo is a helper method to define mock.On call +func (_e *MockMessageEDK_Expecter) ProviderInfo() *MockMessageEDK_ProviderInfo_Call { + return &MockMessageEDK_ProviderInfo_Call{Call: _e.mock.On("ProviderInfo")} +} + +func (_c *MockMessageEDK_ProviderInfo_Call) Run(run func()) *MockMessageEDK_ProviderInfo_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageEDK_ProviderInfo_Call) Return(_a0 string) *MockMessageEDK_ProviderInfo_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageEDK_ProviderInfo_Call) RunAndReturn(run func() string) *MockMessageEDK_ProviderInfo_Call { + _c.Call.Return(run) + return _c +} + +// NewMockMessageEDK creates a new instance of MockMessageEDK. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockMessageEDK(t interface { + mock.TestingT + Cleanup(func()) +}) *MockMessageEDK { + mock := &MockMessageEDK{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageFooter_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageFooter_mock.go new file mode 100644 index 0000000..3fe7dea --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageFooter_mock.go @@ -0,0 +1,218 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package format + +import mock "github.com/stretchr/testify/mock" + +// MockMessageFooter is an autogenerated mock type for the MessageFooter type +type MockMessageFooter struct { + mock.Mock +} + +type MockMessageFooter_Expecter struct { + mock *mock.Mock +} + +func (_m *MockMessageFooter) EXPECT() *MockMessageFooter_Expecter { + return &MockMessageFooter_Expecter{mock: &_m.Mock} +} + +// Bytes provides a mock function with given fields: +func (_m *MockMessageFooter) Bytes() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Bytes") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockMessageFooter_Bytes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bytes' +type MockMessageFooter_Bytes_Call struct { + *mock.Call +} + +// Bytes is a helper method to define mock.On call +func (_e *MockMessageFooter_Expecter) Bytes() *MockMessageFooter_Bytes_Call { + return &MockMessageFooter_Bytes_Call{Call: _e.mock.On("Bytes")} +} + +func (_c *MockMessageFooter_Bytes_Call) Run(run func()) *MockMessageFooter_Bytes_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageFooter_Bytes_Call) Return(_a0 []byte) *MockMessageFooter_Bytes_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageFooter_Bytes_Call) RunAndReturn(run func() []byte) *MockMessageFooter_Bytes_Call { + _c.Call.Return(run) + return _c +} + +// Len provides a mock function with given fields: +func (_m *MockMessageFooter) Len() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Len") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// MockMessageFooter_Len_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Len' +type MockMessageFooter_Len_Call struct { + *mock.Call +} + +// Len is a helper method to define mock.On call +func (_e *MockMessageFooter_Expecter) Len() *MockMessageFooter_Len_Call { + return &MockMessageFooter_Len_Call{Call: _e.mock.On("Len")} +} + +func (_c *MockMessageFooter_Len_Call) Run(run func()) *MockMessageFooter_Len_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageFooter_Len_Call) Return(_a0 int) *MockMessageFooter_Len_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageFooter_Len_Call) RunAndReturn(run func() int) *MockMessageFooter_Len_Call { + _c.Call.Return(run) + return _c +} + +// SignLen provides a mock function with given fields: +func (_m *MockMessageFooter) SignLen() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for SignLen") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// MockMessageFooter_SignLen_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SignLen' +type MockMessageFooter_SignLen_Call struct { + *mock.Call +} + +// SignLen is a helper method to define mock.On call +func (_e *MockMessageFooter_Expecter) SignLen() *MockMessageFooter_SignLen_Call { + return &MockMessageFooter_SignLen_Call{Call: _e.mock.On("SignLen")} +} + +func (_c *MockMessageFooter_SignLen_Call) Run(run func()) *MockMessageFooter_SignLen_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageFooter_SignLen_Call) Return(_a0 int) *MockMessageFooter_SignLen_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageFooter_SignLen_Call) RunAndReturn(run func() int) *MockMessageFooter_SignLen_Call { + _c.Call.Return(run) + return _c +} + +// Signature provides a mock function with given fields: +func (_m *MockMessageFooter) Signature() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Signature") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockMessageFooter_Signature_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Signature' +type MockMessageFooter_Signature_Call struct { + *mock.Call +} + +// Signature is a helper method to define mock.On call +func (_e *MockMessageFooter_Expecter) Signature() *MockMessageFooter_Signature_Call { + return &MockMessageFooter_Signature_Call{Call: _e.mock.On("Signature")} +} + +func (_c *MockMessageFooter_Signature_Call) Run(run func()) *MockMessageFooter_Signature_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageFooter_Signature_Call) Return(_a0 []byte) *MockMessageFooter_Signature_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageFooter_Signature_Call) RunAndReturn(run func() []byte) *MockMessageFooter_Signature_Call { + _c.Call.Return(run) + return _c +} + +// NewMockMessageFooter creates a new instance of MockMessageFooter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockMessageFooter(t interface { + mock.TestingT + Cleanup(func()) +}) *MockMessageFooter { + mock := &MockMessageFooter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageHeaderAuth_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageHeaderAuth_mock.go new file mode 100644 index 0000000..2f2384d --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageHeaderAuth_mock.go @@ -0,0 +1,220 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package format + +import mock "github.com/stretchr/testify/mock" + +// MockMessageHeaderAuth is an autogenerated mock type for the MessageHeaderAuth type +type MockMessageHeaderAuth struct { + mock.Mock +} + +type MockMessageHeaderAuth_Expecter struct { + mock *mock.Mock +} + +func (_m *MockMessageHeaderAuth) EXPECT() *MockMessageHeaderAuth_Expecter { + return &MockMessageHeaderAuth_Expecter{mock: &_m.Mock} +} + +// AuthData provides a mock function with given fields: +func (_m *MockMessageHeaderAuth) AuthData() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for AuthData") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockMessageHeaderAuth_AuthData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthData' +type MockMessageHeaderAuth_AuthData_Call struct { + *mock.Call +} + +// AuthData is a helper method to define mock.On call +func (_e *MockMessageHeaderAuth_Expecter) AuthData() *MockMessageHeaderAuth_AuthData_Call { + return &MockMessageHeaderAuth_AuthData_Call{Call: _e.mock.On("AuthData")} +} + +func (_c *MockMessageHeaderAuth_AuthData_Call) Run(run func()) *MockMessageHeaderAuth_AuthData_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeaderAuth_AuthData_Call) Return(_a0 []byte) *MockMessageHeaderAuth_AuthData_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeaderAuth_AuthData_Call) RunAndReturn(run func() []byte) *MockMessageHeaderAuth_AuthData_Call { + _c.Call.Return(run) + return _c +} + +// Bytes provides a mock function with given fields: +func (_m *MockMessageHeaderAuth) Bytes() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Bytes") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockMessageHeaderAuth_Bytes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bytes' +type MockMessageHeaderAuth_Bytes_Call struct { + *mock.Call +} + +// Bytes is a helper method to define mock.On call +func (_e *MockMessageHeaderAuth_Expecter) Bytes() *MockMessageHeaderAuth_Bytes_Call { + return &MockMessageHeaderAuth_Bytes_Call{Call: _e.mock.On("Bytes")} +} + +func (_c *MockMessageHeaderAuth_Bytes_Call) Run(run func()) *MockMessageHeaderAuth_Bytes_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeaderAuth_Bytes_Call) Return(_a0 []byte) *MockMessageHeaderAuth_Bytes_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeaderAuth_Bytes_Call) RunAndReturn(run func() []byte) *MockMessageHeaderAuth_Bytes_Call { + _c.Call.Return(run) + return _c +} + +// IV provides a mock function with given fields: +func (_m *MockMessageHeaderAuth) IV() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for IV") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockMessageHeaderAuth_IV_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IV' +type MockMessageHeaderAuth_IV_Call struct { + *mock.Call +} + +// IV is a helper method to define mock.On call +func (_e *MockMessageHeaderAuth_Expecter) IV() *MockMessageHeaderAuth_IV_Call { + return &MockMessageHeaderAuth_IV_Call{Call: _e.mock.On("IV")} +} + +func (_c *MockMessageHeaderAuth_IV_Call) Run(run func()) *MockMessageHeaderAuth_IV_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeaderAuth_IV_Call) Return(_a0 []byte) *MockMessageHeaderAuth_IV_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeaderAuth_IV_Call) RunAndReturn(run func() []byte) *MockMessageHeaderAuth_IV_Call { + _c.Call.Return(run) + return _c +} + +// Len provides a mock function with given fields: +func (_m *MockMessageHeaderAuth) Len() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Len") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// MockMessageHeaderAuth_Len_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Len' +type MockMessageHeaderAuth_Len_Call struct { + *mock.Call +} + +// Len is a helper method to define mock.On call +func (_e *MockMessageHeaderAuth_Expecter) Len() *MockMessageHeaderAuth_Len_Call { + return &MockMessageHeaderAuth_Len_Call{Call: _e.mock.On("Len")} +} + +func (_c *MockMessageHeaderAuth_Len_Call) Run(run func()) *MockMessageHeaderAuth_Len_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeaderAuth_Len_Call) Return(_a0 int) *MockMessageHeaderAuth_Len_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeaderAuth_Len_Call) RunAndReturn(run func() int) *MockMessageHeaderAuth_Len_Call { + _c.Call.Return(run) + return _c +} + +// NewMockMessageHeaderAuth creates a new instance of MockMessageHeaderAuth. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockMessageHeaderAuth(t interface { + mock.TestingT + Cleanup(func()) +}) *MockMessageHeaderAuth { + mock := &MockMessageHeaderAuth{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageHeader_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageHeader_mock.go new file mode 100644 index 0000000..6e8b7cc --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/MessageHeader_mock.go @@ -0,0 +1,728 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package format + +import ( + format "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" + mock "github.com/stretchr/testify/mock" + + suite "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" +) + +// MockMessageHeader is an autogenerated mock type for the MessageHeader type +type MockMessageHeader struct { + mock.Mock +} + +type MockMessageHeader_Expecter struct { + mock *mock.Mock +} + +func (_m *MockMessageHeader) EXPECT() *MockMessageHeader_Expecter { + return &MockMessageHeader_Expecter{mock: &_m.Mock} +} + +// AADData provides a mock function with given fields: +func (_m *MockMessageHeader) AADData() format.MessageAAD { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for AADData") + } + + var r0 format.MessageAAD + if rf, ok := ret.Get(0).(func() format.MessageAAD); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(format.MessageAAD) + } + } + + return r0 +} + +// MockMessageHeader_AADData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AADData' +type MockMessageHeader_AADData_Call struct { + *mock.Call +} + +// AADData is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) AADData() *MockMessageHeader_AADData_Call { + return &MockMessageHeader_AADData_Call{Call: _e.mock.On("AADData")} +} + +func (_c *MockMessageHeader_AADData_Call) Run(run func()) *MockMessageHeader_AADData_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_AADData_Call) Return(_a0 format.MessageAAD) *MockMessageHeader_AADData_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_AADData_Call) RunAndReturn(run func() format.MessageAAD) *MockMessageHeader_AADData_Call { + _c.Call.Return(run) + return _c +} + +// AADLength provides a mock function with given fields: +func (_m *MockMessageHeader) AADLength() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for AADLength") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// MockMessageHeader_AADLength_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AADLength' +type MockMessageHeader_AADLength_Call struct { + *mock.Call +} + +// AADLength is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) AADLength() *MockMessageHeader_AADLength_Call { + return &MockMessageHeader_AADLength_Call{Call: _e.mock.On("AADLength")} +} + +func (_c *MockMessageHeader_AADLength_Call) Run(run func()) *MockMessageHeader_AADLength_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_AADLength_Call) Return(_a0 int) *MockMessageHeader_AADLength_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_AADLength_Call) RunAndReturn(run func() int) *MockMessageHeader_AADLength_Call { + _c.Call.Return(run) + return _c +} + +// AlgorithmSuite provides a mock function with given fields: +func (_m *MockMessageHeader) AlgorithmSuite() *suite.AlgorithmSuite { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for AlgorithmSuite") + } + + var r0 *suite.AlgorithmSuite + if rf, ok := ret.Get(0).(func() *suite.AlgorithmSuite); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*suite.AlgorithmSuite) + } + } + + return r0 +} + +// MockMessageHeader_AlgorithmSuite_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AlgorithmSuite' +type MockMessageHeader_AlgorithmSuite_Call struct { + *mock.Call +} + +// AlgorithmSuite is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) AlgorithmSuite() *MockMessageHeader_AlgorithmSuite_Call { + return &MockMessageHeader_AlgorithmSuite_Call{Call: _e.mock.On("AlgorithmSuite")} +} + +func (_c *MockMessageHeader_AlgorithmSuite_Call) Run(run func()) *MockMessageHeader_AlgorithmSuite_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_AlgorithmSuite_Call) Return(_a0 *suite.AlgorithmSuite) *MockMessageHeader_AlgorithmSuite_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_AlgorithmSuite_Call) RunAndReturn(run func() *suite.AlgorithmSuite) *MockMessageHeader_AlgorithmSuite_Call { + _c.Call.Return(run) + return _c +} + +// AlgorithmSuiteData provides a mock function with given fields: +func (_m *MockMessageHeader) AlgorithmSuiteData() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for AlgorithmSuiteData") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockMessageHeader_AlgorithmSuiteData_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AlgorithmSuiteData' +type MockMessageHeader_AlgorithmSuiteData_Call struct { + *mock.Call +} + +// AlgorithmSuiteData is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) AlgorithmSuiteData() *MockMessageHeader_AlgorithmSuiteData_Call { + return &MockMessageHeader_AlgorithmSuiteData_Call{Call: _e.mock.On("AlgorithmSuiteData")} +} + +func (_c *MockMessageHeader_AlgorithmSuiteData_Call) Run(run func()) *MockMessageHeader_AlgorithmSuiteData_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_AlgorithmSuiteData_Call) Return(_a0 []byte) *MockMessageHeader_AlgorithmSuiteData_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_AlgorithmSuiteData_Call) RunAndReturn(run func() []byte) *MockMessageHeader_AlgorithmSuiteData_Call { + _c.Call.Return(run) + return _c +} + +// Bytes provides a mock function with given fields: +func (_m *MockMessageHeader) Bytes() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Bytes") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockMessageHeader_Bytes_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bytes' +type MockMessageHeader_Bytes_Call struct { + *mock.Call +} + +// Bytes is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) Bytes() *MockMessageHeader_Bytes_Call { + return &MockMessageHeader_Bytes_Call{Call: _e.mock.On("Bytes")} +} + +func (_c *MockMessageHeader_Bytes_Call) Run(run func()) *MockMessageHeader_Bytes_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_Bytes_Call) Return(_a0 []byte) *MockMessageHeader_Bytes_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_Bytes_Call) RunAndReturn(run func() []byte) *MockMessageHeader_Bytes_Call { + _c.Call.Return(run) + return _c +} + +// ContentType provides a mock function with given fields: +func (_m *MockMessageHeader) ContentType() suite.ContentType { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for ContentType") + } + + var r0 suite.ContentType + if rf, ok := ret.Get(0).(func() suite.ContentType); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(suite.ContentType) + } + + return r0 +} + +// MockMessageHeader_ContentType_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ContentType' +type MockMessageHeader_ContentType_Call struct { + *mock.Call +} + +// ContentType is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) ContentType() *MockMessageHeader_ContentType_Call { + return &MockMessageHeader_ContentType_Call{Call: _e.mock.On("ContentType")} +} + +func (_c *MockMessageHeader_ContentType_Call) Run(run func()) *MockMessageHeader_ContentType_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_ContentType_Call) Return(_a0 suite.ContentType) *MockMessageHeader_ContentType_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_ContentType_Call) RunAndReturn(run func() suite.ContentType) *MockMessageHeader_ContentType_Call { + _c.Call.Return(run) + return _c +} + +// EncryptedDataKeyCount provides a mock function with given fields: +func (_m *MockMessageHeader) EncryptedDataKeyCount() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for EncryptedDataKeyCount") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// MockMessageHeader_EncryptedDataKeyCount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EncryptedDataKeyCount' +type MockMessageHeader_EncryptedDataKeyCount_Call struct { + *mock.Call +} + +// EncryptedDataKeyCount is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) EncryptedDataKeyCount() *MockMessageHeader_EncryptedDataKeyCount_Call { + return &MockMessageHeader_EncryptedDataKeyCount_Call{Call: _e.mock.On("EncryptedDataKeyCount")} +} + +func (_c *MockMessageHeader_EncryptedDataKeyCount_Call) Run(run func()) *MockMessageHeader_EncryptedDataKeyCount_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_EncryptedDataKeyCount_Call) Return(_a0 int) *MockMessageHeader_EncryptedDataKeyCount_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_EncryptedDataKeyCount_Call) RunAndReturn(run func() int) *MockMessageHeader_EncryptedDataKeyCount_Call { + _c.Call.Return(run) + return _c +} + +// EncryptedDataKeys provides a mock function with given fields: +func (_m *MockMessageHeader) EncryptedDataKeys() []format.MessageEDK { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for EncryptedDataKeys") + } + + var r0 []format.MessageEDK + if rf, ok := ret.Get(0).(func() []format.MessageEDK); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]format.MessageEDK) + } + } + + return r0 +} + +// MockMessageHeader_EncryptedDataKeys_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EncryptedDataKeys' +type MockMessageHeader_EncryptedDataKeys_Call struct { + *mock.Call +} + +// EncryptedDataKeys is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) EncryptedDataKeys() *MockMessageHeader_EncryptedDataKeys_Call { + return &MockMessageHeader_EncryptedDataKeys_Call{Call: _e.mock.On("EncryptedDataKeys")} +} + +func (_c *MockMessageHeader_EncryptedDataKeys_Call) Run(run func()) *MockMessageHeader_EncryptedDataKeys_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_EncryptedDataKeys_Call) Return(_a0 []format.MessageEDK) *MockMessageHeader_EncryptedDataKeys_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_EncryptedDataKeys_Call) RunAndReturn(run func() []format.MessageEDK) *MockMessageHeader_EncryptedDataKeys_Call { + _c.Call.Return(run) + return _c +} + +// FrameLength provides a mock function with given fields: +func (_m *MockMessageHeader) FrameLength() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for FrameLength") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// MockMessageHeader_FrameLength_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FrameLength' +type MockMessageHeader_FrameLength_Call struct { + *mock.Call +} + +// FrameLength is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) FrameLength() *MockMessageHeader_FrameLength_Call { + return &MockMessageHeader_FrameLength_Call{Call: _e.mock.On("FrameLength")} +} + +func (_c *MockMessageHeader_FrameLength_Call) Run(run func()) *MockMessageHeader_FrameLength_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_FrameLength_Call) Return(_a0 int) *MockMessageHeader_FrameLength_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_FrameLength_Call) RunAndReturn(run func() int) *MockMessageHeader_FrameLength_Call { + _c.Call.Return(run) + return _c +} + +// IVLength provides a mock function with given fields: +func (_m *MockMessageHeader) IVLength() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for IVLength") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// MockMessageHeader_IVLength_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IVLength' +type MockMessageHeader_IVLength_Call struct { + *mock.Call +} + +// IVLength is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) IVLength() *MockMessageHeader_IVLength_Call { + return &MockMessageHeader_IVLength_Call{Call: _e.mock.On("IVLength")} +} + +func (_c *MockMessageHeader_IVLength_Call) Run(run func()) *MockMessageHeader_IVLength_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_IVLength_Call) Return(_a0 int) *MockMessageHeader_IVLength_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_IVLength_Call) RunAndReturn(run func() int) *MockMessageHeader_IVLength_Call { + _c.Call.Return(run) + return _c +} + +// Len provides a mock function with given fields: +func (_m *MockMessageHeader) Len() int { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Len") + } + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +// MockMessageHeader_Len_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Len' +type MockMessageHeader_Len_Call struct { + *mock.Call +} + +// Len is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) Len() *MockMessageHeader_Len_Call { + return &MockMessageHeader_Len_Call{Call: _e.mock.On("Len")} +} + +func (_c *MockMessageHeader_Len_Call) Run(run func()) *MockMessageHeader_Len_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_Len_Call) Return(_a0 int) *MockMessageHeader_Len_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_Len_Call) RunAndReturn(run func() int) *MockMessageHeader_Len_Call { + _c.Call.Return(run) + return _c +} + +// MessageID provides a mock function with given fields: +func (_m *MockMessageHeader) MessageID() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for MessageID") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockMessageHeader_MessageID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'MessageID' +type MockMessageHeader_MessageID_Call struct { + *mock.Call +} + +// MessageID is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) MessageID() *MockMessageHeader_MessageID_Call { + return &MockMessageHeader_MessageID_Call{Call: _e.mock.On("MessageID")} +} + +func (_c *MockMessageHeader_MessageID_Call) Run(run func()) *MockMessageHeader_MessageID_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_MessageID_Call) Return(_a0 []byte) *MockMessageHeader_MessageID_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_MessageID_Call) RunAndReturn(run func() []byte) *MockMessageHeader_MessageID_Call { + _c.Call.Return(run) + return _c +} + +// Reserved provides a mock function with given fields: +func (_m *MockMessageHeader) Reserved() []byte { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Reserved") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockMessageHeader_Reserved_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Reserved' +type MockMessageHeader_Reserved_Call struct { + *mock.Call +} + +// Reserved is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) Reserved() *MockMessageHeader_Reserved_Call { + return &MockMessageHeader_Reserved_Call{Call: _e.mock.On("Reserved")} +} + +func (_c *MockMessageHeader_Reserved_Call) Run(run func()) *MockMessageHeader_Reserved_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_Reserved_Call) Return(_a0 []byte) *MockMessageHeader_Reserved_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_Reserved_Call) RunAndReturn(run func() []byte) *MockMessageHeader_Reserved_Call { + _c.Call.Return(run) + return _c +} + +// Type provides a mock function with given fields: +func (_m *MockMessageHeader) Type() suite.MessageType { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Type") + } + + var r0 suite.MessageType + if rf, ok := ret.Get(0).(func() suite.MessageType); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(suite.MessageType) + } + + return r0 +} + +// MockMessageHeader_Type_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Type' +type MockMessageHeader_Type_Call struct { + *mock.Call +} + +// Type is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) Type() *MockMessageHeader_Type_Call { + return &MockMessageHeader_Type_Call{Call: _e.mock.On("Type")} +} + +func (_c *MockMessageHeader_Type_Call) Run(run func()) *MockMessageHeader_Type_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_Type_Call) Return(_a0 suite.MessageType) *MockMessageHeader_Type_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_Type_Call) RunAndReturn(run func() suite.MessageType) *MockMessageHeader_Type_Call { + _c.Call.Return(run) + return _c +} + +// Version provides a mock function with given fields: +func (_m *MockMessageHeader) Version() suite.MessageFormatVersion { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Version") + } + + var r0 suite.MessageFormatVersion + if rf, ok := ret.Get(0).(func() suite.MessageFormatVersion); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(suite.MessageFormatVersion) + } + + return r0 +} + +// MockMessageHeader_Version_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Version' +type MockMessageHeader_Version_Call struct { + *mock.Call +} + +// Version is a helper method to define mock.On call +func (_e *MockMessageHeader_Expecter) Version() *MockMessageHeader_Version_Call { + return &MockMessageHeader_Version_Call{Call: _e.mock.On("Version")} +} + +func (_c *MockMessageHeader_Version_Call) Run(run func()) *MockMessageHeader_Version_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockMessageHeader_Version_Call) Return(_a0 suite.MessageFormatVersion) *MockMessageHeader_Version_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockMessageHeader_Version_Call) RunAndReturn(run func() suite.MessageFormatVersion) *MockMessageHeader_Version_Call { + _c.Call.Return(run) + return _c +} + +// NewMockMessageHeader creates a new instance of MockMessageHeader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockMessageHeader(t interface { + mock.TestingT + Cleanup(func()) +}) *MockMessageHeader { + mock := &MockMessageHeader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/Serializer_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/Serializer_mock.go new file mode 100644 index 0000000..f1eeb6b --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format/Serializer_mock.go @@ -0,0 +1,275 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package format + +import ( + format "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" + mock "github.com/stretchr/testify/mock" + + suite "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" +) + +// MockSerializer is an autogenerated mock type for the Serializer type +type MockSerializer struct { + mock.Mock +} + +type MockSerializer_Expecter struct { + mock *mock.Mock +} + +func (_m *MockSerializer) EXPECT() *MockSerializer_Expecter { + return &MockSerializer_Expecter{mock: &_m.Mock} +} + +// SerializeBody provides a mock function with given fields: alg, frameLength +func (_m *MockSerializer) SerializeBody(alg *suite.AlgorithmSuite, frameLength int) (format.MessageBody, error) { + ret := _m.Called(alg, frameLength) + + if len(ret) == 0 { + panic("no return value specified for SerializeBody") + } + + var r0 format.MessageBody + var r1 error + if rf, ok := ret.Get(0).(func(*suite.AlgorithmSuite, int) (format.MessageBody, error)); ok { + return rf(alg, frameLength) + } + if rf, ok := ret.Get(0).(func(*suite.AlgorithmSuite, int) format.MessageBody); ok { + r0 = rf(alg, frameLength) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(format.MessageBody) + } + } + + if rf, ok := ret.Get(1).(func(*suite.AlgorithmSuite, int) error); ok { + r1 = rf(alg, frameLength) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockSerializer_SerializeBody_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SerializeBody' +type MockSerializer_SerializeBody_Call struct { + *mock.Call +} + +// SerializeBody is a helper method to define mock.On call +// - alg *suite.AlgorithmSuite +// - frameLength int +func (_e *MockSerializer_Expecter) SerializeBody(alg interface{}, frameLength interface{}) *MockSerializer_SerializeBody_Call { + return &MockSerializer_SerializeBody_Call{Call: _e.mock.On("SerializeBody", alg, frameLength)} +} + +func (_c *MockSerializer_SerializeBody_Call) Run(run func(alg *suite.AlgorithmSuite, frameLength int)) *MockSerializer_SerializeBody_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*suite.AlgorithmSuite), args[1].(int)) + }) + return _c +} + +func (_c *MockSerializer_SerializeBody_Call) Return(_a0 format.MessageBody, _a1 error) *MockSerializer_SerializeBody_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockSerializer_SerializeBody_Call) RunAndReturn(run func(*suite.AlgorithmSuite, int) (format.MessageBody, error)) *MockSerializer_SerializeBody_Call { + _c.Call.Return(run) + return _c +} + +// SerializeFooter provides a mock function with given fields: alg, signature +func (_m *MockSerializer) SerializeFooter(alg *suite.AlgorithmSuite, signature []byte) (format.MessageFooter, error) { + ret := _m.Called(alg, signature) + + if len(ret) == 0 { + panic("no return value specified for SerializeFooter") + } + + var r0 format.MessageFooter + var r1 error + if rf, ok := ret.Get(0).(func(*suite.AlgorithmSuite, []byte) (format.MessageFooter, error)); ok { + return rf(alg, signature) + } + if rf, ok := ret.Get(0).(func(*suite.AlgorithmSuite, []byte) format.MessageFooter); ok { + r0 = rf(alg, signature) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(format.MessageFooter) + } + } + + if rf, ok := ret.Get(1).(func(*suite.AlgorithmSuite, []byte) error); ok { + r1 = rf(alg, signature) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockSerializer_SerializeFooter_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SerializeFooter' +type MockSerializer_SerializeFooter_Call struct { + *mock.Call +} + +// SerializeFooter is a helper method to define mock.On call +// - alg *suite.AlgorithmSuite +// - signature []byte +func (_e *MockSerializer_Expecter) SerializeFooter(alg interface{}, signature interface{}) *MockSerializer_SerializeFooter_Call { + return &MockSerializer_SerializeFooter_Call{Call: _e.mock.On("SerializeFooter", alg, signature)} +} + +func (_c *MockSerializer_SerializeFooter_Call) Run(run func(alg *suite.AlgorithmSuite, signature []byte)) *MockSerializer_SerializeFooter_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*suite.AlgorithmSuite), args[1].([]byte)) + }) + return _c +} + +func (_c *MockSerializer_SerializeFooter_Call) Return(_a0 format.MessageFooter, _a1 error) *MockSerializer_SerializeFooter_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockSerializer_SerializeFooter_Call) RunAndReturn(run func(*suite.AlgorithmSuite, []byte) (format.MessageFooter, error)) *MockSerializer_SerializeFooter_Call { + _c.Call.Return(run) + return _c +} + +// SerializeHeader provides a mock function with given fields: p +func (_m *MockSerializer) SerializeHeader(p format.HeaderParams) (format.MessageHeader, error) { + ret := _m.Called(p) + + if len(ret) == 0 { + panic("no return value specified for SerializeHeader") + } + + var r0 format.MessageHeader + var r1 error + if rf, ok := ret.Get(0).(func(format.HeaderParams) (format.MessageHeader, error)); ok { + return rf(p) + } + if rf, ok := ret.Get(0).(func(format.HeaderParams) format.MessageHeader); ok { + r0 = rf(p) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(format.MessageHeader) + } + } + + if rf, ok := ret.Get(1).(func(format.HeaderParams) error); ok { + r1 = rf(p) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockSerializer_SerializeHeader_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SerializeHeader' +type MockSerializer_SerializeHeader_Call struct { + *mock.Call +} + +// SerializeHeader is a helper method to define mock.On call +// - p format.HeaderParams +func (_e *MockSerializer_Expecter) SerializeHeader(p interface{}) *MockSerializer_SerializeHeader_Call { + return &MockSerializer_SerializeHeader_Call{Call: _e.mock.On("SerializeHeader", p)} +} + +func (_c *MockSerializer_SerializeHeader_Call) Run(run func(p format.HeaderParams)) *MockSerializer_SerializeHeader_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(format.HeaderParams)) + }) + return _c +} + +func (_c *MockSerializer_SerializeHeader_Call) Return(_a0 format.MessageHeader, _a1 error) *MockSerializer_SerializeHeader_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockSerializer_SerializeHeader_Call) RunAndReturn(run func(format.HeaderParams) (format.MessageHeader, error)) *MockSerializer_SerializeHeader_Call { + _c.Call.Return(run) + return _c +} + +// SerializeHeaderAuth provides a mock function with given fields: v, iv, authData +func (_m *MockSerializer) SerializeHeaderAuth(v suite.MessageFormatVersion, iv []byte, authData []byte) (format.MessageHeaderAuth, error) { + ret := _m.Called(v, iv, authData) + + if len(ret) == 0 { + panic("no return value specified for SerializeHeaderAuth") + } + + var r0 format.MessageHeaderAuth + var r1 error + if rf, ok := ret.Get(0).(func(suite.MessageFormatVersion, []byte, []byte) (format.MessageHeaderAuth, error)); ok { + return rf(v, iv, authData) + } + if rf, ok := ret.Get(0).(func(suite.MessageFormatVersion, []byte, []byte) format.MessageHeaderAuth); ok { + r0 = rf(v, iv, authData) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(format.MessageHeaderAuth) + } + } + + if rf, ok := ret.Get(1).(func(suite.MessageFormatVersion, []byte, []byte) error); ok { + r1 = rf(v, iv, authData) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockSerializer_SerializeHeaderAuth_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SerializeHeaderAuth' +type MockSerializer_SerializeHeaderAuth_Call struct { + *mock.Call +} + +// SerializeHeaderAuth is a helper method to define mock.On call +// - v suite.MessageFormatVersion +// - iv []byte +// - authData []byte +func (_e *MockSerializer_Expecter) SerializeHeaderAuth(v interface{}, iv interface{}, authData interface{}) *MockSerializer_SerializeHeaderAuth_Call { + return &MockSerializer_SerializeHeaderAuth_Call{Call: _e.mock.On("SerializeHeaderAuth", v, iv, authData)} +} + +func (_c *MockSerializer_SerializeHeaderAuth_Call) Run(run func(v suite.MessageFormatVersion, iv []byte, authData []byte)) *MockSerializer_SerializeHeaderAuth_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(suite.MessageFormatVersion), args[1].([]byte), args[2].([]byte)) + }) + return _c +} + +func (_c *MockSerializer_SerializeHeaderAuth_Call) Return(_a0 format.MessageHeaderAuth, _a1 error) *MockSerializer_SerializeHeaderAuth_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockSerializer_SerializeHeaderAuth_Call) RunAndReturn(run func(suite.MessageFormatVersion, []byte, []byte) (format.MessageHeaderAuth, error)) *MockSerializer_SerializeHeaderAuth_Call { + _c.Call.Return(run) + return _c +} + +// NewMockSerializer creates a new instance of MockSerializer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockSerializer(t interface { + mock.TestingT + Cleanup(func()) +}) *MockSerializer { + mock := &MockSerializer{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/encryption/AEADDecrypter_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/encryption/AEADDecrypter_mock.go new file mode 100644 index 0000000..03041bb --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/encryption/AEADDecrypter_mock.go @@ -0,0 +1,144 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package encryption + +import mock "github.com/stretchr/testify/mock" + +// MockAEADDecrypter is an autogenerated mock type for the AEADDecrypter type +type MockAEADDecrypter struct { + mock.Mock +} + +type MockAEADDecrypter_Expecter struct { + mock *mock.Mock +} + +func (_m *MockAEADDecrypter) EXPECT() *MockAEADDecrypter_Expecter { + return &MockAEADDecrypter_Expecter{mock: &_m.Mock} +} + +// Decrypt provides a mock function with given fields: key, iv, ciphertext, tag, aadData +func (_m *MockAEADDecrypter) Decrypt(key []byte, iv []byte, ciphertext []byte, tag []byte, aadData []byte) ([]byte, error) { + ret := _m.Called(key, iv, ciphertext, tag, aadData) + + if len(ret) == 0 { + panic("no return value specified for Decrypt") + } + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func([]byte, []byte, []byte, []byte, []byte) ([]byte, error)); ok { + return rf(key, iv, ciphertext, tag, aadData) + } + if rf, ok := ret.Get(0).(func([]byte, []byte, []byte, []byte, []byte) []byte); ok { + r0 = rf(key, iv, ciphertext, tag, aadData) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func([]byte, []byte, []byte, []byte, []byte) error); ok { + r1 = rf(key, iv, ciphertext, tag, aadData) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockAEADDecrypter_Decrypt_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Decrypt' +type MockAEADDecrypter_Decrypt_Call struct { + *mock.Call +} + +// Decrypt is a helper method to define mock.On call +// - key []byte +// - iv []byte +// - ciphertext []byte +// - tag []byte +// - aadData []byte +func (_e *MockAEADDecrypter_Expecter) Decrypt(key interface{}, iv interface{}, ciphertext interface{}, tag interface{}, aadData interface{}) *MockAEADDecrypter_Decrypt_Call { + return &MockAEADDecrypter_Decrypt_Call{Call: _e.mock.On("Decrypt", key, iv, ciphertext, tag, aadData)} +} + +func (_c *MockAEADDecrypter_Decrypt_Call) Run(run func(key []byte, iv []byte, ciphertext []byte, tag []byte, aadData []byte)) *MockAEADDecrypter_Decrypt_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]byte), args[1].([]byte), args[2].([]byte), args[3].([]byte), args[4].([]byte)) + }) + return _c +} + +func (_c *MockAEADDecrypter_Decrypt_Call) Return(_a0 []byte, _a1 error) *MockAEADDecrypter_Decrypt_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockAEADDecrypter_Decrypt_Call) RunAndReturn(run func([]byte, []byte, []byte, []byte, []byte) ([]byte, error)) *MockAEADDecrypter_Decrypt_Call { + _c.Call.Return(run) + return _c +} + +// ValidateHeaderAuth provides a mock function with given fields: derivedDataKey, headerAuthTag, headerBytes +func (_m *MockAEADDecrypter) ValidateHeaderAuth(derivedDataKey []byte, headerAuthTag []byte, headerBytes []byte) error { + ret := _m.Called(derivedDataKey, headerAuthTag, headerBytes) + + if len(ret) == 0 { + panic("no return value specified for ValidateHeaderAuth") + } + + var r0 error + if rf, ok := ret.Get(0).(func([]byte, []byte, []byte) error); ok { + r0 = rf(derivedDataKey, headerAuthTag, headerBytes) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAEADDecrypter_ValidateHeaderAuth_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ValidateHeaderAuth' +type MockAEADDecrypter_ValidateHeaderAuth_Call struct { + *mock.Call +} + +// ValidateHeaderAuth is a helper method to define mock.On call +// - derivedDataKey []byte +// - headerAuthTag []byte +// - headerBytes []byte +func (_e *MockAEADDecrypter_Expecter) ValidateHeaderAuth(derivedDataKey interface{}, headerAuthTag interface{}, headerBytes interface{}) *MockAEADDecrypter_ValidateHeaderAuth_Call { + return &MockAEADDecrypter_ValidateHeaderAuth_Call{Call: _e.mock.On("ValidateHeaderAuth", derivedDataKey, headerAuthTag, headerBytes)} +} + +func (_c *MockAEADDecrypter_ValidateHeaderAuth_Call) Run(run func(derivedDataKey []byte, headerAuthTag []byte, headerBytes []byte)) *MockAEADDecrypter_ValidateHeaderAuth_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]byte), args[1].([]byte), args[2].([]byte)) + }) + return _c +} + +func (_c *MockAEADDecrypter_ValidateHeaderAuth_Call) Return(_a0 error) *MockAEADDecrypter_ValidateHeaderAuth_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAEADDecrypter_ValidateHeaderAuth_Call) RunAndReturn(run func([]byte, []byte, []byte) error) *MockAEADDecrypter_ValidateHeaderAuth_Call { + _c.Call.Return(run) + return _c +} + +// NewMockAEADDecrypter creates a new instance of MockAEADDecrypter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockAEADDecrypter(t interface { + mock.TestingT + Cleanup(func()) +}) *MockAEADDecrypter { + mock := &MockAEADDecrypter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/encryption/AEADEncrypter_mock.go b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/encryption/AEADEncrypter_mock.go new file mode 100644 index 0000000..7a38f10 --- /dev/null +++ b/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/encryption/AEADEncrypter_mock.go @@ -0,0 +1,220 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +//go:build mocks + +package encryption + +import mock "github.com/stretchr/testify/mock" + +// MockAEADEncrypter is an autogenerated mock type for the AEADEncrypter type +type MockAEADEncrypter struct { + mock.Mock +} + +type MockAEADEncrypter_Expecter struct { + mock *mock.Mock +} + +func (_m *MockAEADEncrypter) EXPECT() *MockAEADEncrypter_Expecter { + return &MockAEADEncrypter_Expecter{mock: &_m.Mock} +} + +// ConstructIV provides a mock function with given fields: seqNum +func (_m *MockAEADEncrypter) ConstructIV(seqNum int) []byte { + ret := _m.Called(seqNum) + + if len(ret) == 0 { + panic("no return value specified for ConstructIV") + } + + var r0 []byte + if rf, ok := ret.Get(0).(func(int) []byte); ok { + r0 = rf(seqNum) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// MockAEADEncrypter_ConstructIV_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ConstructIV' +type MockAEADEncrypter_ConstructIV_Call struct { + *mock.Call +} + +// ConstructIV is a helper method to define mock.On call +// - seqNum int +func (_e *MockAEADEncrypter_Expecter) ConstructIV(seqNum interface{}) *MockAEADEncrypter_ConstructIV_Call { + return &MockAEADEncrypter_ConstructIV_Call{Call: _e.mock.On("ConstructIV", seqNum)} +} + +func (_c *MockAEADEncrypter_ConstructIV_Call) Run(run func(seqNum int)) *MockAEADEncrypter_ConstructIV_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(int)) + }) + return _c +} + +func (_c *MockAEADEncrypter_ConstructIV_Call) Return(_a0 []byte) *MockAEADEncrypter_ConstructIV_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAEADEncrypter_ConstructIV_Call) RunAndReturn(run func(int) []byte) *MockAEADEncrypter_ConstructIV_Call { + _c.Call.Return(run) + return _c +} + +// Encrypt provides a mock function with given fields: key, iv, plaintext, aadData +func (_m *MockAEADEncrypter) Encrypt(key []byte, iv []byte, plaintext []byte, aadData []byte) ([]byte, []byte, error) { + ret := _m.Called(key, iv, plaintext, aadData) + + if len(ret) == 0 { + panic("no return value specified for Encrypt") + } + + var r0 []byte + var r1 []byte + var r2 error + if rf, ok := ret.Get(0).(func([]byte, []byte, []byte, []byte) ([]byte, []byte, error)); ok { + return rf(key, iv, plaintext, aadData) + } + if rf, ok := ret.Get(0).(func([]byte, []byte, []byte, []byte) []byte); ok { + r0 = rf(key, iv, plaintext, aadData) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func([]byte, []byte, []byte, []byte) []byte); ok { + r1 = rf(key, iv, plaintext, aadData) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).([]byte) + } + } + + if rf, ok := ret.Get(2).(func([]byte, []byte, []byte, []byte) error); ok { + r2 = rf(key, iv, plaintext, aadData) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// MockAEADEncrypter_Encrypt_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Encrypt' +type MockAEADEncrypter_Encrypt_Call struct { + *mock.Call +} + +// Encrypt is a helper method to define mock.On call +// - key []byte +// - iv []byte +// - plaintext []byte +// - aadData []byte +func (_e *MockAEADEncrypter_Expecter) Encrypt(key interface{}, iv interface{}, plaintext interface{}, aadData interface{}) *MockAEADEncrypter_Encrypt_Call { + return &MockAEADEncrypter_Encrypt_Call{Call: _e.mock.On("Encrypt", key, iv, plaintext, aadData)} +} + +func (_c *MockAEADEncrypter_Encrypt_Call) Run(run func(key []byte, iv []byte, plaintext []byte, aadData []byte)) *MockAEADEncrypter_Encrypt_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]byte), args[1].([]byte), args[2].([]byte), args[3].([]byte)) + }) + return _c +} + +func (_c *MockAEADEncrypter_Encrypt_Call) Return(_a0 []byte, _a1 []byte, _a2 error) *MockAEADEncrypter_Encrypt_Call { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *MockAEADEncrypter_Encrypt_Call) RunAndReturn(run func([]byte, []byte, []byte, []byte) ([]byte, []byte, error)) *MockAEADEncrypter_Encrypt_Call { + _c.Call.Return(run) + return _c +} + +// GenerateHeaderAuth provides a mock function with given fields: derivedDataKey, headerBytes +func (_m *MockAEADEncrypter) GenerateHeaderAuth(derivedDataKey []byte, headerBytes []byte) ([]byte, []byte, error) { + ret := _m.Called(derivedDataKey, headerBytes) + + if len(ret) == 0 { + panic("no return value specified for GenerateHeaderAuth") + } + + var r0 []byte + var r1 []byte + var r2 error + if rf, ok := ret.Get(0).(func([]byte, []byte) ([]byte, []byte, error)); ok { + return rf(derivedDataKey, headerBytes) + } + if rf, ok := ret.Get(0).(func([]byte, []byte) []byte); ok { + r0 = rf(derivedDataKey, headerBytes) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func([]byte, []byte) []byte); ok { + r1 = rf(derivedDataKey, headerBytes) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).([]byte) + } + } + + if rf, ok := ret.Get(2).(func([]byte, []byte) error); ok { + r2 = rf(derivedDataKey, headerBytes) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// MockAEADEncrypter_GenerateHeaderAuth_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GenerateHeaderAuth' +type MockAEADEncrypter_GenerateHeaderAuth_Call struct { + *mock.Call +} + +// GenerateHeaderAuth is a helper method to define mock.On call +// - derivedDataKey []byte +// - headerBytes []byte +func (_e *MockAEADEncrypter_Expecter) GenerateHeaderAuth(derivedDataKey interface{}, headerBytes interface{}) *MockAEADEncrypter_GenerateHeaderAuth_Call { + return &MockAEADEncrypter_GenerateHeaderAuth_Call{Call: _e.mock.On("GenerateHeaderAuth", derivedDataKey, headerBytes)} +} + +func (_c *MockAEADEncrypter_GenerateHeaderAuth_Call) Run(run func(derivedDataKey []byte, headerBytes []byte)) *MockAEADEncrypter_GenerateHeaderAuth_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]byte), args[1].([]byte)) + }) + return _c +} + +func (_c *MockAEADEncrypter_GenerateHeaderAuth_Call) Return(_a0 []byte, _a1 []byte, _a2 error) *MockAEADEncrypter_GenerateHeaderAuth_Call { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *MockAEADEncrypter_GenerateHeaderAuth_Call) RunAndReturn(run func([]byte, []byte) ([]byte, []byte, error)) *MockAEADEncrypter_GenerateHeaderAuth_Call { + _c.Call.Return(run) + return _c +} + +// NewMockAEADEncrypter creates a new instance of MockAEADEncrypter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockAEADEncrypter(t interface { + mock.TestingT + Cleanup(func()) +}) *MockAEADEncrypter { + mock := &MockAEADEncrypter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/client/client.go b/pkg/client/client.go index 020ce22..6dee0a7 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -10,6 +10,8 @@ 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/internal/crypto/decrypter" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/crypto/encrypter" "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/suite" @@ -32,7 +34,7 @@ type BaseClient interface { clientConfig() clientconfig.ClientConfig 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) + Decrypt(ctx context.Context, ciphertext []byte, materialsManager model.CryptoMaterialsManager, optFns ...DecryptOptionFunc) ([]byte, format.MessageHeader, error) } var _ BaseClient = (*Client)(nil) @@ -48,6 +50,8 @@ func (c *Client) clientConfig() clientconfig.ClientConfig { // EncryptWithParams is similar to Encrypt but allows specifying additional options such as // the algorithm suite and frame length as arguments instead of functional EncryptOptionFunc options. // +// Deprecated: Will be removed in upcoming version. Use Encrypt instead. +// // Parameters: // - ctx context.Context: The context for the operation. // - source []byte: The data to encrypt. @@ -99,16 +103,26 @@ func (c *Client) EncryptWithParams(ctx context.Context, source []byte, ec suite. // 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, format.MessageHeader, error) { + if err := validateParams(ctx, source, materialsManager); err != nil { + return nil, nil, fmt.Errorf("validation error: %w", errors.Join(crypto.ErrEncryption, err)) + } opts := EncryptOptions{ Algorithm: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, FrameLength: DefaultFrameLength, + Handler: encrypter.New, } for _, optFn := range optFns { if err := optFn(&opts); err != nil { return nil, nil, fmt.Errorf("invalid encrypt option: %w", errors.Join(crypto.ErrEncryption, err)) } } - ciphertext, header, err := crypto.Encrypt(ctx, c.clientConfig(), source, ec, materialsManager, opts.Algorithm, opts.FrameLength) + conf := crypto.EncrypterConfig{ + ClientCfg: c.clientConfig(), + Algorithm: opts.Algorithm, + FrameLength: opts.FrameLength, + } + handler := opts.Handler(conf, materialsManager) + ciphertext, header, err := handler.Encrypt(ctx, source, ec) if err != nil { return nil, nil, err } @@ -123,14 +137,29 @@ func (c *Client) Encrypt(ctx context.Context, source []byte, ec suite.Encryption // - ctx: context.Context. // - ciphertext []byte: The data to decrypt. // - materialsManager [model.CryptoMaterialsManager]: The manager that provides the cryptographic materials. +// - optFns DecryptOptionFunc: A variadic set of optional functions for configuring decryption options such as +// custom decryption handler. // // Returns: // // - []byte: The decrypted data. // - [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, format.MessageHeader, error) { - b, header, err := crypto.Decrypt(ctx, c.clientConfig(), ciphertext, materialsManager) +func (c *Client) Decrypt(ctx context.Context, ciphertext []byte, materialsManager model.CryptoMaterialsManager, optFns ...DecryptOptionFunc) ([]byte, format.MessageHeader, error) { + if err := validateParams(ctx, ciphertext, materialsManager); err != nil { + return nil, nil, fmt.Errorf("validation error: %w", errors.Join(crypto.ErrDecryption, err)) + } + + opts := DecryptOptions{ + Handler: decrypter.New, + } + for _, optFn := range optFns { + if err := optFn(&opts); err != nil { + return nil, nil, fmt.Errorf("invalid decrypt option: %w", errors.Join(crypto.ErrDecryption, err)) + } + } + handler := opts.Handler(crypto.DecrypterConfig{ClientCfg: c.clientConfig()}, materialsManager) + b, header, err := handler.Decrypt(ctx, ciphertext) if err != nil { return nil, nil, err } diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index 6379c02..bff623e 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -4,13 +4,23 @@ package client_test import ( + "context" "fmt" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + mocks "github.com/chainifynet/aws-encryption-sdk-go/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model" + mocksformat "github.com/chainifynet/aws-encryption-sdk-go/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" "github.com/chainifynet/aws-encryption-sdk-go/pkg/client" "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/materials" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/providers/rawprovider" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" ) func Test_NewClient(t *testing.T) { @@ -29,3 +39,372 @@ func Test_NewClientWithConfig(t *testing.T) { assert.NotSame(t, *cl1, *cl2) assert.Equal(t, fmt.Sprintf("%v", cl1), fmt.Sprintf("%v", cl2)) } + +func TestClient_Decrypt(t *testing.T) { + ciphertextMock := []byte("encrypted-data") + plaintextMock := []byte("decrypted-data") + tests := []struct { + name string + ciphertext []byte + cmm model.CryptoMaterialsManager + setupMocks func(t *testing.T, d *mocks.MockDecrypter) []client.DecryptOptionFunc + want []byte + wantErr bool + wantErrStr string + wantErrType error + }{ + { + name: "Valid Decrypt", + ciphertext: ciphertextMock, + cmm: mocks.NewMockCryptoMaterialsManager(t), + setupMocks: func(t *testing.T, d *mocks.MockDecrypter) []client.DecryptOptionFunc { + d.EXPECT().Decrypt(mock.Anything, mock.Anything). + Return(plaintextMock, mocksformat.NewMockMessageHeader(t), nil).Once() + + return []client.DecryptOptionFunc{ + client.WithDecryptionHandler(func(config crypto.DecrypterConfig, cmm model.CryptoMaterialsManager) model.DecryptionHandler { + return d + }), + } + }, + want: plaintextMock, + wantErr: false, + }, + { + name: "Invalid CMM", + ciphertext: ciphertextMock, + cmm: nil, + setupMocks: func(t *testing.T, d *mocks.MockDecrypter) []client.DecryptOptionFunc { + return []client.DecryptOptionFunc{} + }, + want: nil, + wantErr: true, + wantErrStr: "validation error", + wantErrType: crypto.ErrDecryption, + }, + { + name: "Nil Ciphertext", + ciphertext: nil, + cmm: mocks.NewMockCryptoMaterialsManager(t), + setupMocks: func(t *testing.T, d *mocks.MockDecrypter) []client.DecryptOptionFunc { + return []client.DecryptOptionFunc{} + }, + want: nil, + wantErr: true, + wantErrStr: "validation error", + wantErrType: crypto.ErrDecryption, + }, + { + name: "Empty Ciphertext", + ciphertext: []byte(""), + cmm: mocks.NewMockCryptoMaterialsManager(t), + setupMocks: func(t *testing.T, d *mocks.MockDecrypter) []client.DecryptOptionFunc { + return []client.DecryptOptionFunc{} + }, + want: nil, + wantErr: true, + wantErrStr: "validation error", + wantErrType: crypto.ErrDecryption, + }, + { + name: "Invalid Decrypt Handler", + ciphertext: ciphertextMock, + cmm: mocks.NewMockCryptoMaterialsManager(t), + setupMocks: func(t *testing.T, d *mocks.MockDecrypter) []client.DecryptOptionFunc { + return []client.DecryptOptionFunc{ + client.WithDecryptionHandler(nil), + } + }, + want: nil, + wantErr: true, + wantErrStr: "invalid decrypt option", + wantErrType: crypto.ErrDecryption, + }, + { + name: "Decrypt Error", + ciphertext: ciphertextMock, + cmm: mocks.NewMockCryptoMaterialsManager(t), + setupMocks: func(t *testing.T, d *mocks.MockDecrypter) []client.DecryptOptionFunc { + d.EXPECT().Decrypt(mock.Anything, mock.Anything). + Return(nil, nil, fmt.Errorf("SDK error: %w", crypto.ErrDecryption)).Once() + + return []client.DecryptOptionFunc{ + client.WithDecryptionHandler(func(config crypto.DecrypterConfig, cmm model.CryptoMaterialsManager) model.DecryptionHandler { + return d + }), + } + }, + want: nil, + wantErr: true, + wantErrStr: "SDK error", + wantErrType: crypto.ErrDecryption, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + c := client.NewClient() + + decrypterMock := mocks.NewMockDecrypter(t) + + optFns := tt.setupMocks(t, decrypterMock) + + got, header, err := c.Decrypt(ctx, tt.ciphertext, tt.cmm, optFns...) + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrStr != "" { + assert.ErrorContains(t, err, tt.wantErrStr) + } + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + assert.Nil(t, got) + assert.Nil(t, header) + } else { + assert.NoError(t, err) + assert.NotNil(t, got) + assert.NotNil(t, header) + assert.Equal(t, tt.want, got) + } + }) + } +} + +func TestClient_Encrypt(t *testing.T) { + plaintextMock := []byte("plaintext-data") + ciphertextMock := []byte("encrypted-data") + tests := []struct { + name string + source []byte + ec suite.EncryptionContext + cmm model.CryptoMaterialsManager + setupMocks func(t *testing.T, e *mocks.MockEncrypter) []client.EncryptOptionFunc + + want []byte + wantErr bool + wantErrStr string + wantErrType error + }{ + { + name: "Valid Encrypt", + source: plaintextMock, + ec: suite.EncryptionContext{ + "purpose": "test", + }, + cmm: mocks.NewMockCryptoMaterialsManager(t), + setupMocks: func(t *testing.T, e *mocks.MockEncrypter) []client.EncryptOptionFunc { + e.EXPECT().Encrypt(mock.Anything, mock.Anything, mock.Anything). + Return(ciphertextMock, mocksformat.NewMockMessageHeader(t), nil).Once() + + return []client.EncryptOptionFunc{ + client.WithEncryptionHandler(func(config crypto.EncrypterConfig, cmm model.CryptoMaterialsManager) model.EncryptionHandler { + return e + }), + } + }, + want: ciphertextMock, + wantErr: false, + }, + { + name: "Valid Encrypt With Params", + source: plaintextMock, + ec: suite.EncryptionContext{ + "purpose": "test", + }, + cmm: mocks.NewMockCryptoMaterialsManager(t), + setupMocks: func(t *testing.T, e *mocks.MockEncrypter) []client.EncryptOptionFunc { + e.EXPECT().Encrypt(mock.Anything, mock.Anything, mock.Anything). + Return(ciphertextMock, mocksformat.NewMockMessageHeader(t), nil).Once() + + return []client.EncryptOptionFunc{ + client.WithEncryptionHandler(func(config crypto.EncrypterConfig, cmm model.CryptoMaterialsManager) model.EncryptionHandler { + return e + }), + client.WithAlgorithm(suite.AES_192_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384), + client.WithFrameLength(1024), + } + }, + want: ciphertextMock, + wantErr: false, + }, + { + name: "Invalid CMM", + source: plaintextMock, + ec: suite.EncryptionContext{ + "purpose": "test", + }, + cmm: nil, + setupMocks: func(t *testing.T, e *mocks.MockEncrypter) []client.EncryptOptionFunc { + return []client.EncryptOptionFunc{} + }, + want: nil, + wantErr: true, + wantErrStr: "validation error", + wantErrType: crypto.ErrEncryption, + }, + { + name: "Nil Source", + source: nil, + ec: suite.EncryptionContext{ + "purpose": "test", + }, + cmm: mocks.NewMockCryptoMaterialsManager(t), + setupMocks: func(t *testing.T, e *mocks.MockEncrypter) []client.EncryptOptionFunc { + return []client.EncryptOptionFunc{} + }, + want: nil, + wantErr: true, + wantErrStr: "validation error", + wantErrType: crypto.ErrEncryption, + }, + { + name: "Empty Source", + source: []byte(""), + ec: suite.EncryptionContext{ + "purpose": "test", + }, + cmm: mocks.NewMockCryptoMaterialsManager(t), + setupMocks: func(t *testing.T, e *mocks.MockEncrypter) []client.EncryptOptionFunc { + return []client.EncryptOptionFunc{} + }, + want: nil, + wantErr: true, + wantErrStr: "validation error", + wantErrType: crypto.ErrEncryption, + }, + { + name: "Invalid Encrypt Handler", + source: plaintextMock, + ec: suite.EncryptionContext{ + "purpose": "test", + }, + cmm: mocks.NewMockCryptoMaterialsManager(t), + setupMocks: func(t *testing.T, e *mocks.MockEncrypter) []client.EncryptOptionFunc { + return []client.EncryptOptionFunc{ + client.WithEncryptionHandler(nil), + } + }, + want: nil, + wantErr: true, + wantErrStr: "invalid encrypt option", + wantErrType: crypto.ErrEncryption, + }, + { + name: "Invalid Frame Length", + source: plaintextMock, + ec: suite.EncryptionContext{ + "purpose": "test", + }, + cmm: mocks.NewMockCryptoMaterialsManager(t), + setupMocks: func(t *testing.T, e *mocks.MockEncrypter) []client.EncryptOptionFunc { + return []client.EncryptOptionFunc{ + client.WithFrameLength(-1), + } + }, + want: nil, + wantErr: true, + wantErrStr: "invalid encrypt option", + wantErrType: crypto.ErrEncryption, + }, + { + name: "Unsupported Algorithm", + source: plaintextMock, + ec: suite.EncryptionContext{ + "purpose": "test", + }, + cmm: mocks.NewMockCryptoMaterialsManager(t), + setupMocks: func(t *testing.T, e *mocks.MockEncrypter) []client.EncryptOptionFunc { + return []client.EncryptOptionFunc{ + client.WithAlgorithm(&suite.AlgorithmSuite{AlgorithmID: 0x0301}), + } + }, + want: nil, + wantErr: true, + wantErrStr: "invalid encrypt option", + wantErrType: crypto.ErrEncryption, + }, + { + name: "Encrypt Error", + source: plaintextMock, + ec: suite.EncryptionContext{ + "purpose": "test", + }, + cmm: mocks.NewMockCryptoMaterialsManager(t), + setupMocks: func(t *testing.T, e *mocks.MockEncrypter) []client.EncryptOptionFunc { + e.EXPECT().Encrypt(mock.Anything, mock.Anything, mock.Anything). + Return(nil, nil, fmt.Errorf("SDK error: %w", crypto.ErrEncryption)).Once() + + return []client.EncryptOptionFunc{ + client.WithEncryptionHandler(func(config crypto.EncrypterConfig, cmm model.CryptoMaterialsManager) model.EncryptionHandler { + return e + }), + } + }, + want: nil, + wantErr: true, + wantErrStr: "SDK error", + wantErrType: crypto.ErrEncryption, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + c := client.NewClient() + + encrypterMock := mocks.NewMockEncrypter(t) + + optFns := tt.setupMocks(t, encrypterMock) + + got, header, err := c.Encrypt(ctx, tt.source, tt.ec, tt.cmm, optFns...) + + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrStr != "" { + assert.ErrorContains(t, err, tt.wantErrStr) + } + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + assert.Nil(t, got) + assert.Nil(t, header) + } else { + assert.NoError(t, err) + assert.NotNil(t, got) + assert.NotNil(t, header) + assert.Equal(t, tt.want, got) + } + }) + } +} + +// TODO remove this test along with deprecated EncryptWithParams +func TestClient_EncryptWithParams(t *testing.T) { + //t.Skip("skipped for now, will be removed in the future.") + ctx := context.Background() + + // setup SDK client + c := client.NewClient() + require.NotNil(t, c) + + // setup raw key provider + rawKeyProvider, err := rawprovider.NewWithOpts( + "raw", + rawprovider.WithStaticKey("static1", []byte("raw1DataKeyRAWRAWRAW_12345678901")), + ) + require.NoError(t, err) + assert.NotNil(t, rawKeyProvider) + + // setup crypto materials manager + cmm, err := materials.NewDefault(rawKeyProvider) + require.NoError(t, err) + assert.NotNil(t, cmm) + + // encrypt data + //goland:noinspection GoDeprecation + ciphertext, header, err := c.EncryptWithParams(ctx, []byte("plaintext"), nil, cmm, + suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 4096, + ) + require.NoError(t, err) + assert.NotNil(t, ciphertext) + assert.NotNil(t, header) +} diff --git a/pkg/client/options.go b/pkg/client/options.go index 0531260..5018555 100644 --- a/pkg/client/options.go +++ b/pkg/client/options.go @@ -6,6 +6,8 @@ package client import ( "fmt" + "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/suite" ) @@ -20,9 +22,21 @@ const ( // - Algorithm [suite.AlgorithmSuite]: AlgorithmSuite that defines the encryption algorithm to be used. // If nil, a default [suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384] algorithm is used. // - FrameLength int: Specifies the frame length for encryption. If not set, a default value of DefaultFrameLength is used. +// - Handler: Specifies a function that creates [model.EncryptionHandler] encryption handler. +// If not set, a default [encrypter.New] function is used. type EncryptOptions struct { Algorithm *suite.AlgorithmSuite FrameLength int + Handler func(config crypto.EncrypterConfig, cmm model.CryptoMaterialsManager) model.EncryptionHandler +} + +// DecryptOptions defines the configuration options for the decryption process. +// +// Fields: +// - Handler: Specifies a function that creates [model.DecryptionHandler] decryption handler. +// If not set, a default [decrypter.New] function is used. +type DecryptOptions struct { + Handler func(config crypto.DecrypterConfig, cmm model.CryptoMaterialsManager) model.DecryptionHandler } // EncryptOptionFunc is a function type that applies a configuration option to an EncryptOptions struct. @@ -34,6 +48,15 @@ type EncryptOptions struct { // Use WithAlgorithm and WithFrameLength to create EncryptOptionFunc functions. type EncryptOptionFunc func(o *EncryptOptions) error +// DecryptOptionFunc is a function type that applies a configuration option to an DecryptOptions struct. +// It is used to customize the decryption process by setting various options in DecryptOptions. +// +// Each function of this type takes a pointer to an DecryptOptions struct and modifies it accordingly. +// It returns an error if the provided option is invalid or cannot be applied. +// +// Use WithDecryptionHandler to create DecryptOptionFunc function. +type DecryptOptionFunc func(o *DecryptOptions) error + // WithAlgorithm returns an EncryptOptionFunc that sets the encryption algorithm in EncryptOptions. // This function allows the caller to specify a custom algorithm for encryption. // @@ -50,6 +73,9 @@ func WithAlgorithm(alg *suite.AlgorithmSuite) EncryptOptionFunc { if alg == nil { return fmt.Errorf("algorithm must not be nil") } + if _, err := suite.Algorithm.ByID(alg.AlgorithmID); err != nil { + return fmt.Errorf("algorithm error: %w", err) + } o.Algorithm = alg return nil } @@ -78,3 +104,37 @@ func WithFrameLength(frameLength int) EncryptOptionFunc { return nil } } + +// WithEncryptionHandler returns an EncryptOptionFunc that sets the encryption handler in EncryptOptions. +// This function allows the caller to specify a custom encryption handler. +// +// Used mainly for testing purposes. +// +// Parameters: +// - h: A function that returns [model.EncryptionHandler]. +func WithEncryptionHandler(h func(config crypto.EncrypterConfig, cmm model.CryptoMaterialsManager) model.EncryptionHandler) EncryptOptionFunc { + return func(o *EncryptOptions) error { + if h == nil { + return fmt.Errorf("handler must not be nil") + } + o.Handler = h + return nil + } +} + +// WithDecryptionHandler returns an DecryptOptionFunc that sets the decryption handler in DecryptOptions. +// This function allows the caller to specify a custom decryption handler. +// +// Used mainly for testing purposes. +// +// Parameters: +// - h: A function that returns [model.DecryptionHandler]. +func WithDecryptionHandler(h func(config crypto.DecrypterConfig, cmm model.CryptoMaterialsManager) model.DecryptionHandler) DecryptOptionFunc { + return func(o *DecryptOptions) error { + if h == nil { + return fmt.Errorf("handler must not be nil") + } + o.Handler = h + return nil + } +} diff --git a/pkg/client/options_test.go b/pkg/client/options_test.go new file mode 100644 index 0000000..e45644f --- /dev/null +++ b/pkg/client/options_test.go @@ -0,0 +1,176 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package client_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + mocks "github.com/chainifynet/aws-encryption-sdk-go/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/client" + "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/suite" +) + +func TestWithAlgorithm(t *testing.T) { + tests := []struct { + name string + alg *suite.AlgorithmSuite + wantErr bool + wantErrStr string + }{ + { + name: "Valid Commit Algorithm", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + wantErr: false, + }, + { + name: "Valid Algorithm", + alg: suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, + wantErr: false, + }, + { + name: "Nil Algorithm", + alg: nil, + wantErr: true, + wantErrStr: "algorithm must not be nil", + }, + { + name: "Unsupported Algorithm", + alg: &suite.AlgorithmSuite{AlgorithmID: 0x0301}, + wantErr: true, + wantErrStr: "algorithm error", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + opts := &client.EncryptOptions{} + err := client.WithAlgorithm(tt.alg)(opts) + if tt.wantErr { + assert.Error(t, err) + assert.ErrorContains(t, err, tt.wantErrStr) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.alg, opts.Algorithm) + } + }) + } +} + +func TestWithFrameLength(t *testing.T) { + tests := []struct { + name string + frameLength int + wantErr bool + }{ + { + name: "ValidFrameLength", + frameLength: 1024, + wantErr: false, + }, + { + name: "InvalidFrameLength", + frameLength: -1, + wantErr: true, + }, + { + name: "ZeroFrameLength", + frameLength: 0, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + optFunc := client.WithFrameLength(tt.frameLength) + opt := &client.EncryptOptions{} + + if tt.wantErr { + require.Error(t, optFunc(opt)) + } else { + require.NoError(t, optFunc(opt)) + + assert.Equal(t, tt.frameLength, opt.FrameLength) + + err := suite.ValidateFrameLength(opt.FrameLength) + assert.NoError(t, err) + } + }) + } +} + +func TestWithEncryptionHandler(t *testing.T) { + tests := []struct { + name string + handler func(config crypto.EncrypterConfig, cmm model.CryptoMaterialsManager) model.EncryptionHandler + wantErr bool + }{ + { + name: "ValidHandler", + handler: func(config crypto.EncrypterConfig, cmm model.CryptoMaterialsManager) model.EncryptionHandler { + return mocks.NewMockEncrypter(t) + }, + wantErr: false, + }, + { + name: "NilHandler", + handler: nil, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + opts := &client.EncryptOptions{} + err := client.WithEncryptionHandler(tt.handler)(opts) + if tt.wantErr { + assert.Error(t, err) + assert.Equal(t, "handler must not be nil", fmt.Sprint(err)) + } else { + assert.NoError(t, err) + assert.NotNil(t, opts.Handler) + } + }) + } +} + +func TestWithDecryptionHandler(t *testing.T) { + tests := []struct { + name string + handler func(config crypto.DecrypterConfig, cmm model.CryptoMaterialsManager) model.DecryptionHandler + wantErr bool + }{ + { + name: "ValidHandler", + handler: func(config crypto.DecrypterConfig, cmm model.CryptoMaterialsManager) model.DecryptionHandler { + return mocks.NewMockDecrypter(t) + }, + wantErr: false, + }, + { + name: "NilHandler", + handler: nil, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + opts := &client.DecryptOptions{} + err := client.WithDecryptionHandler(tt.handler)(opts) + if tt.wantErr { + assert.Error(t, err) + assert.Equal(t, "handler must not be nil", fmt.Sprint(err)) + } else { + assert.NoError(t, err) + assert.NotNil(t, opts.Handler) + } + }) + } +} diff --git a/pkg/client/validate.go b/pkg/client/validate.go new file mode 100644 index 0000000..d2753af --- /dev/null +++ b/pkg/client/validate.go @@ -0,0 +1,25 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package client + +import ( + "context" + "fmt" + + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model" +) + +// validateParams validates the parameters for the given context, source, and CryptoMaterialsManager +func validateParams(ctx context.Context, b []byte, cmm model.CryptoMaterialsManager) error { + if ctx == nil { + return fmt.Errorf("nil context") + } + if len(b) == 0 { + return fmt.Errorf("empty source") + } + if cmm == nil { + return fmt.Errorf("nil materials manager") + } + return nil +} diff --git a/pkg/client/validate_test.go b/pkg/client/validate_test.go new file mode 100644 index 0000000..27334c6 --- /dev/null +++ b/pkg/client/validate_test.go @@ -0,0 +1,77 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package client + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + + mocks "github.com/chainifynet/aws-encryption-sdk-go/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model" +) + +func Test_validateParams(t *testing.T) { + tests := []struct { + name string + ctx context.Context //nolint:containedctx + source []byte + cmm model.CryptoMaterialsManager + wantErr bool + wantErrStr string + }{ + { + name: "valid", + ctx: context.Background(), + source: []byte("source"), + cmm: mocks.NewMockCryptoMaterialsManager(t), + wantErr: false, + }, + { + name: "nil context", + ctx: nil, + source: []byte("source"), + cmm: mocks.NewMockCryptoMaterialsManager(t), + wantErr: true, + wantErrStr: "nil context", + }, + { + name: "empty source", + ctx: context.Background(), + source: []byte(""), + cmm: mocks.NewMockCryptoMaterialsManager(t), + wantErr: true, + wantErrStr: "empty source", + }, + { + name: "nil source", + ctx: context.Background(), + source: nil, + cmm: mocks.NewMockCryptoMaterialsManager(t), + wantErr: true, + wantErrStr: "empty source", + }, + { + name: "nil cmm", + ctx: context.Background(), + source: []byte("source"), + cmm: nil, + wantErr: true, + wantErrStr: "nil materials manager", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := validateParams(tt.ctx, tt.source, tt.cmm) + if tt.wantErr { + assert.Error(t, err) + assert.ErrorContains(t, err, tt.wantErrStr) + } else { + assert.NoError(t, err) + } + }) + } +} diff --git a/pkg/crypto/base.go b/pkg/crypto/base.go deleted file mode 100644 index db0b43f..0000000 --- a/pkg/crypto/base.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -package crypto - -import ( - "bytes" - "context" - "errors" - "fmt" - - "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/model/format" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/encryption" -) - -var ( - ErrInvalidMessage = errors.New("invalid message format") - ErrDecryption = errors.New("decryption error") - ErrEncryption = errors.New("encryption error") -) - -const ( - firstByteEncryptedMessageV1 = byte(0x01) - firstByteEncryptedMessageV2 = byte(0x02) -) - -type SdkDecrypter interface { - decrypt(ctx context.Context, ciphertext []byte) ([]byte, format.MessageHeader, error) -} - -type decrypter struct { - cmm model.CryptoMaterialsManager - config clientconfig.ClientConfig - aeadDecrypter encryption.AEADDecrypter - header format.MessageHeader - verifier signature.Verifier - _derivedDataKey []byte -} - -func Decrypt(ctx context.Context, config clientconfig.ClientConfig, ciphertext []byte, cmm model.CryptoMaterialsManager) ([]byte, format.MessageHeader, error) { - dec := decrypter{ - cmm: cmm.GetInstance(), - config: config, - aeadDecrypter: encryption.Gcm{}, - } - - b, header, err := dec.decrypt(ctx, ciphertext) - if err != nil { - return nil, nil, fmt.Errorf("SDK error: %w", errors.Join(ErrDecryption, err)) - } - return b, header, nil -} - -var _ SdkDecrypter = (*decrypter)(nil) - -type SdkEncrypter interface { - encrypt(ctx context.Context, source []byte, ec suite.EncryptionContext) ([]byte, format.MessageHeader, error) -} - -type encrypter struct { - cmm model.CryptoMaterialsManager - config clientconfig.ClientConfig - algorithm *suite.AlgorithmSuite - frameLength int - aeadEncrypter encryption.AEADEncrypter - 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, format.MessageHeader, error) { - enc := encrypter{ - cmm: cmm.GetInstance(), - config: config, - algorithm: algorithm, - frameLength: frameLength, - aeadEncrypter: encryption.Gcm{}, - ciphertextBuf: new(bytes.Buffer), - } - ciphertext, header, err := enc.encrypt(ctx, source, ec) - if err != nil { - // TODO andrew clean up derived data key - return nil, nil, fmt.Errorf("SDK error: %w", errors.Join(ErrEncryption, err)) - } - return ciphertext, header, nil -} - -var _ SdkEncrypter = (*encrypter)(nil) diff --git a/pkg/crypto/config.go b/pkg/crypto/config.go new file mode 100644 index 0000000..504cb10 --- /dev/null +++ b/pkg/crypto/config.go @@ -0,0 +1,19 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package crypto + +import ( + "github.com/chainifynet/aws-encryption-sdk-go/pkg/clientconfig" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" +) + +type EncrypterConfig struct { + ClientCfg clientconfig.ClientConfig + Algorithm *suite.AlgorithmSuite + FrameLength int +} + +type DecrypterConfig struct { + ClientCfg clientconfig.ClientConfig +} diff --git a/pkg/crypto/errors.go b/pkg/crypto/errors.go new file mode 100644 index 0000000..a016678 --- /dev/null +++ b/pkg/crypto/errors.go @@ -0,0 +1,14 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package crypto + +import ( + "errors" +) + +var ( + ErrInvalidMessage = errors.New("invalid message format") + ErrDecryption = errors.New("decryption error") + ErrEncryption = errors.New("encryption error") +) diff --git a/pkg/internal/crypto/decrypter/consts.go b/pkg/internal/crypto/decrypter/consts.go new file mode 100644 index 0000000..c48ab9b --- /dev/null +++ b/pkg/internal/crypto/decrypter/consts.go @@ -0,0 +1,9 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package decrypter + +const ( + firstByteEncryptedMessageV1 = byte(0x01) + firstByteEncryptedMessageV2 = byte(0x02) +) diff --git a/pkg/crypto/decrypter.go b/pkg/internal/crypto/decrypter/decrypt.go similarity index 55% rename from pkg/crypto/decrypter.go rename to pkg/internal/crypto/decrypter/decrypt.go index 35ba3ba..52505ab 100644 --- a/pkg/crypto/decrypter.go +++ b/pkg/internal/crypto/decrypter/decrypt.go @@ -1,26 +1,59 @@ // Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package crypto +package decrypter import ( "bytes" "context" "crypto/hmac" + "errors" "fmt" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/crypto/signature" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/crypto" "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/crypto/policy" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/crypto/signature" "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/encryption" "github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/keyderivation" ) -// decrypt ciphertext decryption -func (d *decrypter) decrypt(ctx context.Context, ciphertext []byte) ([]byte, format.MessageHeader, error) { +type Decrypter struct { + cmm model.CryptoMaterialsManager + cfg crypto.DecrypterConfig + aeadDecrypter encryption.AEADDecrypter + deser format.Deserializer + header format.MessageHeader + verifier signature.Verifier + verifierFn signature.VerifierFunc + _derivedDataKey []byte +} + +func New(cfg crypto.DecrypterConfig, cmm model.CryptoMaterialsManager) model.DecryptionHandler { + return &Decrypter{ + cmm: cmm.GetInstance(), + cfg: cfg, + aeadDecrypter: encryption.Gcm{}, + deser: serialization.NewDeserializer(), + verifierFn: signature.NewECCVerifier, + } +} + +func (d *Decrypter) Decrypt(ctx context.Context, ciphertext []byte) ([]byte, format.MessageHeader, error) { + b, header, err := d.decryptData(ctx, ciphertext) + if err != nil { + d.reset(err) + return nil, nil, fmt.Errorf("SDK error: %w", errors.Join(crypto.ErrDecryption, err)) + } + d.reset(nil) + return b, header, nil +} + +// decryptData ciphertext decryption +func (d *Decrypter) decryptData(ctx context.Context, ciphertext []byte) ([]byte, format.MessageHeader, error) { var b []byte b = make([]byte, len(ciphertext)) copy(b, ciphertext) @@ -31,7 +64,7 @@ func (d *decrypter) decrypt(ctx context.Context, ciphertext []byte) ([]byte, for // 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] != firstByteEncryptedMessageV1 && ciphertext[0] != firstByteEncryptedMessageV2 { - return nil, nil, fmt.Errorf("first byte does not contain message version: %w", ErrInvalidMessage) + return nil, nil, fmt.Errorf("first byte does not contain message version: %w", crypto.ErrInvalidMessage) } buf := bytes.NewBuffer(b) @@ -45,12 +78,12 @@ func (d *decrypter) decrypt(ctx context.Context, ciphertext []byte) ([]byte, for } if d.verifier != nil { - footer, errFooter := serialization.MessageFooter.FromBuffer(d.header.AlgorithmSuite(), buf) + footer, errFooter := d.deser.DeserializeFooter(d.header.AlgorithmSuite(), buf) if errFooter != nil { return nil, nil, errFooter } - if errSig := d.verifier.Verify(footer.Signature); errSig != nil { + if errSig := d.verifier.Verify(footer.Signature()); errSig != nil { return nil, nil, errSig } } @@ -59,18 +92,18 @@ func (d *decrypter) decrypt(ctx context.Context, ciphertext []byte) ([]byte, for return body, d.header, nil } -func (d *decrypter) decryptHeader(ctx context.Context, buf *bytes.Buffer) error { - header, headerAuth, err := serialization.DeserializeHeader(buf, d.config.MaxEncryptedDataKeys()) +func (d *Decrypter) decryptHeader(ctx context.Context, buf *bytes.Buffer) error { + header, headerAuth, err := d.deser.DeserializeHeader(buf, d.cfg.ClientCfg.MaxEncryptedDataKeys()) if err != nil { return err } - if errPolicy := policy.ValidateOnDecrypt(d.config.CommitmentPolicy(), header.AlgorithmSuite()); errPolicy != nil { + if errPolicy := policy.ValidateOnDecrypt(d.cfg.ClientCfg.CommitmentPolicy(), header.AlgorithmSuite()); errPolicy != nil { return errPolicy } if header.AlgorithmSuite().IsSigning() { - d.verifier = signature.NewECCVerifier( + d.verifier = d.verifierFn( header.AlgorithmSuite().Authentication.HashFunc, header.AlgorithmSuite().Authentication.Algorithm, ) @@ -119,81 +152,77 @@ func (d *decrypter) decryptHeader(ctx context.Context, buf *bytes.Buffer) error return fmt.Errorf("decrypt header auth error: %w", errHeaderAuth) } - if d._derivedDataKey != nil { - return fmt.Errorf("decrypt derived data key already exists") - } d._derivedDataKey = derivedDataKey - - if d.header != nil { - return fmt.Errorf("decrypt header already exists") - } d.header = header return nil } -func (d *decrypter) decryptBody(buf *bytes.Buffer) ([]byte, error) { - body, err := serialization.DeserializeBody(buf, d.header.AlgorithmSuite(), d.header.FrameLength()) +func (d *Decrypter) decryptBody(buf *bytes.Buffer) ([]byte, error) { + body, err := d.deser.DeserializeBody(buf, d.header.AlgorithmSuite(), d.header.FrameLength()) if err != nil { - return nil, fmt.Errorf("body error: %w", err) + return nil, fmt.Errorf("deserialize body error: %w", err) } plaintext := new(bytes.Buffer) - readBytes := 0 for _, frame := range body.Frames() { - contentString, err := bodyaad.ContentString(suite.FramedContent, frame.IsFinal()) - if err != nil { - return nil, fmt.Errorf("decrypt frame error: %w", err) + b, errFrame := d.decryptFrame(frame) + if errFrame != nil { + return nil, fmt.Errorf("decrypt frame error: %w", errFrame) } - associatedData := bodyaad.ContentAADBytes( - d.header.MessageID(), - contentString, - frame.SequenceNumber(), - len(frame.EncryptedContent()), - ) - b, errAead := d.aeadDecrypter.Decrypt( - d._derivedDataKey, - frame.IV(), - frame.EncryptedContent(), - frame.AuthenticationTag(), - associatedData, - ) - if errAead != nil { - return nil, fmt.Errorf("decrypt frame error: %w", errAead) - } - readBytes += len(b) plaintext.Write(b) - // if alg is signing, write each frame bytes to verifier to update message hash - if d.verifier != nil { - if err := d.updateVerifier(frame.Bytes()); err != nil { - return nil, err - } - } - } - - if plaintext.Len() != readBytes { - return nil, fmt.Errorf("malformed body message size") } var plaintextData []byte plaintextData = make([]byte, plaintext.Len()) - wb, err := plaintext.Read(plaintextData) - if err != nil { - return nil, fmt.Errorf("malformed body message size: %w", err) - } - if wb != readBytes { - return nil, fmt.Errorf("malformed body message size") - } + _, _ = plaintext.Read(plaintextData) plaintext.Reset() return plaintextData, nil } -func (d *decrypter) updateVerifier(b []byte) error { +func (d *Decrypter) decryptFrame(frame format.BodyFrame) ([]byte, error) { + contentString, err := bodyaad.ContentString(d.header.ContentType(), frame.IsFinal()) + if err != nil { + return nil, fmt.Errorf("bodyaad error: %w", err) + } + associatedData := bodyaad.ContentAADBytes( + d.header.MessageID(), + contentString, + frame.SequenceNumber(), + len(frame.EncryptedContent()), + ) + b, err := d.aeadDecrypter.Decrypt( + d._derivedDataKey, + frame.IV(), + frame.EncryptedContent(), + frame.AuthenticationTag(), + associatedData, + ) + if err != nil { + return nil, fmt.Errorf("decrypt frame AEAD error: %w", err) + } + // if alg is signing, write each frame bytes to verifier to update message hash + if d.verifier != nil { + if err := d.updateVerifier(frame.Bytes()); err != nil { + return nil, err + } + } + return b, nil +} + +func (d *Decrypter) updateVerifier(b []byte) error { if _, err := d.verifier.Write(b); err != nil { return fmt.Errorf("verifier write error: %w", err) } return nil } + +func (d *Decrypter) reset(err error) { + d._derivedDataKey = nil + if err != nil { + d.header = nil + } +} diff --git a/pkg/internal/crypto/decrypter/decrypt_test.go b/pkg/internal/crypto/decrypter/decrypt_test.go new file mode 100644 index 0000000..8ce498c --- /dev/null +++ b/pkg/internal/crypto/decrypter/decrypt_test.go @@ -0,0 +1,1356 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package decrypter + +import ( + "bytes" + "context" + "crypto/elliptic" + "hash" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + signaturemock "github.com/chainifynet/aws-encryption-sdk-go/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/internal_/crypto/signature" + mocks "github.com/chainifynet/aws-encryption-sdk-go/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model" + formatmocks "github.com/chainifynet/aws-encryption-sdk-go/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" + encryptionmocks "github.com/chainifynet/aws-encryption-sdk-go/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/encryption" + "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/internal/crypto/signature" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" +) + +func TestNew(t *testing.T) { + tests := []struct { + name string + cfg crypto.DecrypterConfig + setupMocks func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager) + }{ + { + name: "Valid Decrypter", + cfg: crypto.DecrypterConfig{ + ClientCfg: clientconfig.ClientConfig{}, + }, + setupMocks: func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager) { + cmm.EXPECT().GetInstance().Return(cmm).Once() + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmm := mocks.NewMockCryptoMaterialsManager(t) + tt.setupMocks(t, cmm) + + got := New(tt.cfg, cmm) + assert.NotNil(t, got) + + assert.IsType(t, &Decrypter{}, got) + + assert.Equal(t, tt.cfg, got.(*Decrypter).cfg) + assert.Equal(t, cmm, got.(*Decrypter).cmm) + assert.NotNil(t, got.(*Decrypter).aeadDecrypter) + assert.NotNil(t, got.(*Decrypter).deser) + assert.NotNil(t, got.(*Decrypter).verifierFn) + + assert.Nil(t, got.(*Decrypter).header) + assert.Nil(t, got.(*Decrypter).verifier) + assert.Nil(t, got.(*Decrypter)._derivedDataKey) + }) + } +} + +func TestDecrypter_updateVerifier(t *testing.T) { + tests := []struct { + name string + b []byte + setupMocks func(t *testing.T, verifier *signaturemock.MockVerifier) + wantErr bool + }{ + { + name: "Update Success", + b: []byte("test"), + setupMocks: func(t *testing.T, verifier *signaturemock.MockVerifier) { + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Once() + }, + wantErr: false, + }, + { + name: "Update Write Error", + b: []byte("test"), + setupMocks: func(t *testing.T, verifier *signaturemock.MockVerifier) { + verifier.EXPECT().Write(mock.Anything).Return(0, assert.AnError).Once() + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + verifier := signaturemock.NewMockVerifier(t) + tt.setupMocks(t, verifier) + d := &Decrypter{ + verifier: verifier, + } + + err := d.updateVerifier(tt.b) + if tt.wantErr { + assert.Error(t, err) + assert.ErrorContains(t, err, "verifier write error") + } else { + assert.NoError(t, err) + } + }) + } +} + +func setupEDKMock(t *testing.T) *formatmocks.MockMessageEDK { + edk := formatmocks.NewMockMessageEDK(t) + edk.EXPECT().ProviderID().Return("test-aws").Once() + edk.EXPECT().ProviderInfo().Return("test-info").Once() + edk.EXPECT().EncryptedDataKey().Return([]byte("test-edk")).Once() + return edk +} + +func setupAADMock(t *testing.T) *formatmocks.MockMessageAAD { + aad := formatmocks.NewMockMessageAAD(t) + aad.EXPECT().EncryptionContext().Return(nil).Once() + return aad +} + +func TestDecrypter_Decrypt(t *testing.T) { + algSuiteDataMock := []byte{0x7F, 0xBF, 0x61, 0xB4, 0x54, 0x5F, 0x30, 0x62, 0x59, 0x76, 0xF1, 0x19, 0x7C, 0x15, 0xFF, 0xB1, 0x57, 0x6C, 0x9E, 0xCC, 0xEF, 0xB1, 0x84, 0x9C, 0x8, 0x9B, 0x2A, 0xA6, 0x8, 0xA9, 0x6C, 0x95} + tests := []struct { + name string + clientCfgOpts []clientconfig.ConfigOptionFunc + ciphertext []byte + setupMocks func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) + want []byte + wantErr bool + wantErrType error + wantErrStr string + }{ + { + name: "Valid Decrypt", + ciphertext: []byte{0x02, 0x00}, + setupMocks: func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) { + // header + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384).Times(10) + header.EXPECT().Bytes().Return([]byte("test")).Twice() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + header.EXPECT().FrameLength().Return(1024).Once() + header.EXPECT().ContentType().Return(suite.FramedContent).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Times(3) + header.EXPECT().AlgorithmSuiteData().Return(algSuiteDataMock).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().Bytes().Return([]byte("test-auth")).Once() + headerAuth.EXPECT().AuthData().Return([]byte("test-auth-data")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Times(3) + verifier.EXPECT().LoadECCKey(mock.Anything).Return(nil).Once() + + dataKey := mocks.NewMockDataKey(t) + dataKey.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + + decMaterials := mocks.NewMockDecryptionMaterial(t) + decMaterials.EXPECT().VerificationKey().Return([]byte("test-key")).Once() + decMaterials.EXPECT().DataKey().Return(dataKey).Twice() + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(decMaterials, nil).Once() + + aeadDecrypter.EXPECT().ValidateHeaderAuth(mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() + + // body + frame := formatmocks.NewMockBodyFrame(t) + frame.EXPECT().IsFinal().Return(true).Once() + frame.EXPECT().SequenceNumber().Return(1).Once() + frame.EXPECT().EncryptedContent().Return([]byte("test-content")).Twice() + frame.EXPECT().IV().Return([]byte("test-iv")).Once() + frame.EXPECT().AuthenticationTag().Return([]byte("test-tag")).Once() + frame.EXPECT().Bytes().Return([]byte("test-frame")).Once() + + body := formatmocks.NewMockMessageBody(t) + body.EXPECT().Frames(). + Return([]format.BodyFrame{frame}).Once() + + deser.EXPECT().DeserializeBody(mock.Anything, mock.Anything, mock.Anything). + Return(body, nil).Once() + + aeadDecrypter.EXPECT().Decrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return([]byte("decrypted1"), nil).Once() + + // footer + footer := formatmocks.NewMockMessageFooter(t) + footer.EXPECT().Signature().Return([]byte("test-signature")).Once() + + deser.EXPECT().DeserializeFooter(mock.Anything, mock.Anything). + Return(footer, nil).Once() + + verifier.EXPECT().Verify(mock.Anything).Return(nil).Once() + }, + want: []byte("decrypted1"), + wantErr: false, + }, + { + name: "Decrypt Error", + ciphertext: nil, + setupMocks: func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) { + }, + want: nil, + wantErr: true, + wantErrType: crypto.ErrDecryption, + wantErrStr: "SDK error", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + + cmm := mocks.NewMockCryptoMaterialsManager(t) + deser := formatmocks.NewMockDeserializer(t) + verifier := signaturemock.NewMockVerifier(t) + aeadDecrypter := encryptionmocks.NewMockAEADDecrypter(t) + + tt.setupMocks(t, cmm, verifier, aeadDecrypter, deser) + + verifierFn := func(hashFn func() hash.Hash, c elliptic.Curve) signature.Verifier { + return verifier + } + + clientCfg, _ := clientconfig.NewConfigWithOpts(tt.clientCfgOpts...) + cfgMock := crypto.DecrypterConfig{ + ClientCfg: *clientCfg, + } + + d := &Decrypter{ + cmm: cmm, + cfg: cfgMock, + aeadDecrypter: aeadDecrypter, + deser: deser, + verifierFn: verifierFn, + } + + plaintext, h, err := d.Decrypt(ctx, tt.ciphertext) + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + if tt.wantErrStr != "" { + assert.ErrorContains(t, err, tt.wantErrStr) + } + assert.Nil(t, h) + assert.Nil(t, plaintext) + assert.Nil(t, d._derivedDataKey) + assert.Nil(t, d.header) + } else { + assert.NoError(t, err) + assert.NotNil(t, h) + assert.Equal(t, tt.want, plaintext) + assert.Nil(t, d._derivedDataKey) + } + }) + } +} + +func TestDecrypter_decryptData(t *testing.T) { + algSuiteDataMock := []byte{0x7F, 0xBF, 0x61, 0xB4, 0x54, 0x5F, 0x30, 0x62, 0x59, 0x76, 0xF1, 0x19, 0x7C, 0x15, 0xFF, 0xB1, 0x57, 0x6C, 0x9E, 0xCC, 0xEF, 0xB1, 0x84, 0x9C, 0x8, 0x9B, 0x2A, 0xA6, 0x8, 0xA9, 0x6C, 0x95} + tests := []struct { + name string + clientCfgOpts []clientconfig.ConfigOptionFunc + ciphertext []byte + setupMocks func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) + want []byte + wantErr bool + wantErrType error + wantErrStr string + }{ + { + name: "Valid Decrypt", + ciphertext: []byte{0x02, 0x00}, + setupMocks: func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) { + // header + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384).Times(10) + header.EXPECT().Bytes().Return([]byte("test")).Twice() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + header.EXPECT().FrameLength().Return(1024).Once() + header.EXPECT().ContentType().Return(suite.FramedContent).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Times(3) + header.EXPECT().AlgorithmSuiteData().Return(algSuiteDataMock).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().Bytes().Return([]byte("test-auth")).Once() + headerAuth.EXPECT().AuthData().Return([]byte("test-auth-data")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Times(3) + verifier.EXPECT().LoadECCKey(mock.Anything).Return(nil).Once() + + dataKey := mocks.NewMockDataKey(t) + dataKey.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + + decMaterials := mocks.NewMockDecryptionMaterial(t) + decMaterials.EXPECT().VerificationKey().Return([]byte("test-key")).Once() + decMaterials.EXPECT().DataKey().Return(dataKey).Twice() + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(decMaterials, nil).Once() + + aeadDecrypter.EXPECT().ValidateHeaderAuth(mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() + + // body + frame := formatmocks.NewMockBodyFrame(t) + frame.EXPECT().IsFinal().Return(true).Once() + frame.EXPECT().SequenceNumber().Return(1).Once() + frame.EXPECT().EncryptedContent().Return([]byte("test-content")).Twice() + frame.EXPECT().IV().Return([]byte("test-iv")).Once() + frame.EXPECT().AuthenticationTag().Return([]byte("test-tag")).Once() + frame.EXPECT().Bytes().Return([]byte("test-frame")).Once() + + body := formatmocks.NewMockMessageBody(t) + body.EXPECT().Frames(). + Return([]format.BodyFrame{frame}).Once() + + deser.EXPECT().DeserializeBody(mock.Anything, mock.Anything, mock.Anything). + Return(body, nil).Once() + + aeadDecrypter.EXPECT().Decrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return([]byte("decrypted1"), nil).Once() + + // footer + footer := formatmocks.NewMockMessageFooter(t) + footer.EXPECT().Signature().Return([]byte("test-signature")).Once() + + deser.EXPECT().DeserializeFooter(mock.Anything, mock.Anything). + Return(footer, nil).Once() + + verifier.EXPECT().Verify(mock.Anything).Return(nil).Once() + }, + want: []byte("decrypted1"), + wantErr: false, + }, + { + name: "Empty Ciphertext", + ciphertext: nil, + setupMocks: func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) { + + }, + want: nil, + wantErr: true, + wantErrStr: "empty ciphertext", + }, + { + name: "Invalid Ciphertext First Bytes", + ciphertext: []byte{0x03}, + setupMocks: func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) { + }, + want: nil, + wantErr: true, + wantErrType: crypto.ErrInvalidMessage, + wantErrStr: "first byte does not contain message version", + }, + { + name: "Header Decrypt Error", + ciphertext: []byte{0x02, 0x00}, + setupMocks: func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) { + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(nil, nil, assert.AnError).Once() + }, + want: nil, + wantErr: true, + wantErrType: assert.AnError, + }, + { + name: "Body Decrypt Error", + ciphertext: []byte{0x02, 0x00}, + setupMocks: func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) { + // header + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite(). + Return(suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384).Times(9) + header.EXPECT().Bytes().Return([]byte("test")).Twice() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + header.EXPECT().FrameLength().Return(1024).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Times(2) + header.EXPECT().AlgorithmSuiteData().Return(algSuiteDataMock).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().Bytes().Return([]byte("test-auth")).Once() + headerAuth.EXPECT().AuthData().Return([]byte("test-auth-data")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Times(2) + verifier.EXPECT().LoadECCKey(mock.Anything).Return(nil).Once() + + dataKey := mocks.NewMockDataKey(t) + dataKey.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + + decMaterials := mocks.NewMockDecryptionMaterial(t) + decMaterials.EXPECT().VerificationKey().Return([]byte("test-key")).Once() + decMaterials.EXPECT().DataKey().Return(dataKey).Twice() + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(decMaterials, nil).Once() + + aeadDecrypter.EXPECT().ValidateHeaderAuth(mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() + + // body + deser.EXPECT().DeserializeBody(mock.Anything, mock.Anything, mock.Anything). + Return(nil, assert.AnError).Once() + }, + want: nil, + wantErr: true, + wantErrType: assert.AnError, + }, + { + name: "Footer Deserialize Error", + ciphertext: []byte{0x02, 0x00}, + setupMocks: func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) { + // header + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite(). + Return(suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384).Times(10) + header.EXPECT().Bytes().Return([]byte("test")).Twice() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + header.EXPECT().FrameLength().Return(1024).Once() + header.EXPECT().ContentType().Return(suite.FramedContent).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Times(3) + header.EXPECT().AlgorithmSuiteData().Return(algSuiteDataMock).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().Bytes().Return([]byte("test-auth")).Once() + headerAuth.EXPECT().AuthData().Return([]byte("test-auth-data")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Times(3) + verifier.EXPECT().LoadECCKey(mock.Anything).Return(nil).Once() + + dataKey := mocks.NewMockDataKey(t) + dataKey.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + + decMaterials := mocks.NewMockDecryptionMaterial(t) + decMaterials.EXPECT().VerificationKey().Return([]byte("test-key")).Once() + decMaterials.EXPECT().DataKey().Return(dataKey).Twice() + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(decMaterials, nil).Once() + + aeadDecrypter.EXPECT().ValidateHeaderAuth(mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() + + // body + frame := formatmocks.NewMockBodyFrame(t) + frame.EXPECT().IsFinal().Return(true).Once() + frame.EXPECT().SequenceNumber().Return(1).Once() + frame.EXPECT().EncryptedContent().Return([]byte("test-content")).Twice() + frame.EXPECT().IV().Return([]byte("test-iv")).Once() + frame.EXPECT().AuthenticationTag().Return([]byte("test-tag")).Once() + frame.EXPECT().Bytes().Return([]byte("test-frame")).Once() + + body := formatmocks.NewMockMessageBody(t) + body.EXPECT().Frames(). + Return([]format.BodyFrame{frame}).Once() + + deser.EXPECT().DeserializeBody(mock.Anything, mock.Anything, mock.Anything). + Return(body, nil).Once() + + aeadDecrypter.EXPECT().Decrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return([]byte("decrypted1"), nil).Once() + + // footer + deser.EXPECT().DeserializeFooter(mock.Anything, mock.Anything). + Return(nil, assert.AnError).Once() + }, + want: nil, + wantErr: true, + wantErrType: assert.AnError, + }, + { + name: "Footer Signature Error", + ciphertext: []byte{0x02, 0x00}, + setupMocks: func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) { + // header + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite(). + Return(suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384).Times(10) + header.EXPECT().Bytes().Return([]byte("test")).Twice() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + header.EXPECT().FrameLength().Return(1024).Once() + header.EXPECT().ContentType().Return(suite.FramedContent).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Times(3) + header.EXPECT().AlgorithmSuiteData().Return(algSuiteDataMock).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().Bytes().Return([]byte("test-auth")).Once() + headerAuth.EXPECT().AuthData().Return([]byte("test-auth-data")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Times(3) + verifier.EXPECT().LoadECCKey(mock.Anything).Return(nil).Once() + + dataKey := mocks.NewMockDataKey(t) + dataKey.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + + decMaterials := mocks.NewMockDecryptionMaterial(t) + decMaterials.EXPECT().VerificationKey().Return([]byte("test-key")).Once() + decMaterials.EXPECT().DataKey().Return(dataKey).Twice() + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(decMaterials, nil).Once() + + aeadDecrypter.EXPECT().ValidateHeaderAuth(mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() + + // body + frame := formatmocks.NewMockBodyFrame(t) + frame.EXPECT().IsFinal().Return(true).Once() + frame.EXPECT().SequenceNumber().Return(1).Once() + frame.EXPECT().EncryptedContent().Return([]byte("test-content")).Twice() + frame.EXPECT().IV().Return([]byte("test-iv")).Once() + frame.EXPECT().AuthenticationTag().Return([]byte("test-tag")).Once() + frame.EXPECT().Bytes().Return([]byte("test-frame")).Once() + + body := formatmocks.NewMockMessageBody(t) + body.EXPECT().Frames(). + Return([]format.BodyFrame{frame}).Once() + + deser.EXPECT().DeserializeBody(mock.Anything, mock.Anything, mock.Anything). + Return(body, nil).Once() + + aeadDecrypter.EXPECT().Decrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return([]byte("decrypted1"), nil).Once() + + // footer + footer := formatmocks.NewMockMessageFooter(t) + footer.EXPECT().Signature().Return([]byte("test-signature")).Once() + + deser.EXPECT().DeserializeFooter(mock.Anything, mock.Anything). + Return(footer, nil).Once() + + verifier.EXPECT().Verify(mock.Anything).Return(assert.AnError).Once() + }, + want: nil, + wantErr: true, + wantErrType: assert.AnError, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + + cmm := mocks.NewMockCryptoMaterialsManager(t) + deser := formatmocks.NewMockDeserializer(t) + verifier := signaturemock.NewMockVerifier(t) + aeadDecrypter := encryptionmocks.NewMockAEADDecrypter(t) + + tt.setupMocks(t, cmm, verifier, aeadDecrypter, deser) + + verifierFn := func(hashFn func() hash.Hash, c elliptic.Curve) signature.Verifier { + return verifier + } + + clientCfg, _ := clientconfig.NewConfigWithOpts(tt.clientCfgOpts...) + cfgMock := crypto.DecrypterConfig{ + ClientCfg: *clientCfg, + } + + d := &Decrypter{ + cmm: cmm, + cfg: cfgMock, + aeadDecrypter: aeadDecrypter, + deser: deser, + verifierFn: verifierFn, + } + + plaintext, h, err := d.decryptData(ctx, tt.ciphertext) + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + if tt.wantErrStr != "" { + assert.ErrorContains(t, err, tt.wantErrStr) + } + assert.Nil(t, h) + assert.Nil(t, plaintext) + } else { + assert.NoError(t, err) + assert.NotNil(t, h) + assert.Equal(t, tt.want, plaintext) + } + }) + } +} + +func TestDecrypter_decryptHeader(t *testing.T) { + algSuiteDataMock := []byte{0x7F, 0xBF, 0x61, 0xB4, 0x54, 0x5F, 0x30, 0x62, 0x59, 0x76, 0xF1, 0x19, 0x7C, 0x15, 0xFF, 0xB1, 0x57, 0x6C, 0x9E, 0xCC, 0xEF, 0xB1, 0x84, 0x9C, 0x8, 0x9B, 0x2A, 0xA6, 0x8, 0xA9, 0x6C, 0x95} + tests := []struct { + name string + clientCfgOpts []clientconfig.ConfigOptionFunc + alg *suite.AlgorithmSuite + setupMocks func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) + wantErr bool + wantErrType error + wantErrStr string + }{ + { + name: "Valid Committing Signing", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) { + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(alg).Times(8) + header.EXPECT().Bytes().Return([]byte("test")).Twice() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Twice() + header.EXPECT().AlgorithmSuiteData().Return(algSuiteDataMock).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().Bytes().Return([]byte("test-auth")).Once() + headerAuth.EXPECT().AuthData().Return([]byte("test-auth-data")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Twice() + verifier.EXPECT().LoadECCKey(mock.Anything).Return(nil).Once() + + dataKey := mocks.NewMockDataKey(t) + dataKey.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + + decMaterials := mocks.NewMockDecryptionMaterial(t) + decMaterials.EXPECT().VerificationKey().Return([]byte("test-key")).Once() + decMaterials.EXPECT().DataKey().Return(dataKey).Twice() + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(decMaterials, nil).Once() + + aeadDecrypter.EXPECT().ValidateHeaderAuth(mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() + }, + wantErr: false, + }, + { + name: "Valid Committing NonSigning", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY, + setupMocks: func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) { + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(alg).Times(6) + header.EXPECT().Bytes().Return([]byte("test")).Once() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Twice() + header.EXPECT().AlgorithmSuiteData().Return(algSuiteDataMock).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().AuthData().Return([]byte("test-auth-data")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + dataKey := mocks.NewMockDataKey(t) + dataKey.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + + decMaterials := mocks.NewMockDecryptionMaterial(t) + decMaterials.EXPECT().DataKey().Return(dataKey).Twice() + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(decMaterials, nil).Once() + + aeadDecrypter.EXPECT().ValidateHeaderAuth(mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() + }, + wantErr: false, + }, + { + name: "Valid NonCommitting NonSigning", + clientCfgOpts: []clientconfig.ConfigOptionFunc{ + clientconfig.WithCommitmentPolicy(suite.CommitmentPolicyRequireEncryptAllowDecrypt), + }, + alg: suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, + setupMocks: func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) { + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(alg).Times(5) + header.EXPECT().Bytes().Return([]byte("test")).Once() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().AuthData().Return([]byte("test-auth-data")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + dataKey := mocks.NewMockDataKey(t) + dataKey.EXPECT().DataKey().Return([]byte("test-data-key")).Once() + + decMaterials := mocks.NewMockDecryptionMaterial(t) + decMaterials.EXPECT().DataKey().Return(dataKey).Once() + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(decMaterials, nil).Once() + + aeadDecrypter.EXPECT().ValidateHeaderAuth(mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() + }, + wantErr: false, + }, + { + name: "Valid NonCommitting Signing", + clientCfgOpts: []clientconfig.ConfigOptionFunc{ + clientconfig.WithCommitmentPolicy(suite.CommitmentPolicyForbidEncryptAllowDecrypt), + }, + alg: suite.AES_256_GCM_IV12_TAG16_HKDF_SHA384_ECDSA_P384, + setupMocks: func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) { + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(alg).Times(7) + header.EXPECT().Bytes().Return([]byte("test")).Twice() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().Bytes().Return([]byte("test-auth")).Once() + headerAuth.EXPECT().AuthData().Return([]byte("test-auth-data")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Twice() + verifier.EXPECT().LoadECCKey(mock.Anything).Return(nil).Once() + + dataKey := mocks.NewMockDataKey(t) + dataKey.EXPECT().DataKey().Return([]byte("test-data-key")).Once() + + decMaterials := mocks.NewMockDecryptionMaterial(t) + decMaterials.EXPECT().VerificationKey().Return([]byte("test-key")).Once() + decMaterials.EXPECT().DataKey().Return(dataKey).Once() + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(decMaterials, nil).Once() + + aeadDecrypter.EXPECT().ValidateHeaderAuth(mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() + }, + wantErr: false, + }, + { + name: "Deserialize Header Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) { + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything). + Return(nil, nil, assert.AnError).Once() + }, + wantErr: true, + wantErrType: assert.AnError, + }, + { + name: "Policy Conflict Error", + alg: suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, + setupMocks: func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) { + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(alg).Times(1) + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + }, + wantErr: true, + }, + { + name: "Verifier Update Header Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) { + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(alg).Times(4) + header.EXPECT().Bytes().Return([]byte("test")).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write(mock.Anything).Return(0, assert.AnError).Once() + }, + wantErr: true, + wantErrType: assert.AnError, + }, + { + name: "Verifier Update Header Auth Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) { + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(alg).Times(4) + header.EXPECT().Bytes().Return([]byte("test")).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().Bytes().Return([]byte("test-auth")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write([]byte("test")).Return(4, nil).Once() + verifier.EXPECT().Write([]byte("test-auth")).Return(0, assert.AnError).Once() + }, + wantErr: true, + wantErrType: assert.AnError, + }, + { + name: "CMM DecryptMaterials Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) { + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(alg).Times(5) + header.EXPECT().Bytes().Return([]byte("test")).Once() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().Bytes().Return([]byte("test-auth")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Twice() + + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(nil, assert.AnError).Once() + }, + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "decrypt materials", + }, + { + name: "Verifier Elliptic Key Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) { + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(alg).Times(5) + header.EXPECT().Bytes().Return([]byte("test")).Once() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().Bytes().Return([]byte("test-auth")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Twice() + verifier.EXPECT().LoadECCKey(mock.Anything).Return(assert.AnError).Once() + + decMaterials := mocks.NewMockDecryptionMaterial(t) + decMaterials.EXPECT().VerificationKey().Return([]byte("test-key")).Once() + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(decMaterials, nil).Once() + }, + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "decrypt verifier error", + }, + { + name: "Derive DataKey Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) { + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(alg).Times(6) + header.EXPECT().Bytes().Return([]byte("test")).Once() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().Bytes().Return([]byte("test-auth")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Twice() + verifier.EXPECT().LoadECCKey(mock.Anything).Return(nil).Once() + + dataKey := mocks.NewMockDataKey(t) + dataKey.EXPECT().DataKey().Return(nil).Once() // that result in key derivation error + + decMaterials := mocks.NewMockDecryptionMaterial(t) + decMaterials.EXPECT().VerificationKey().Return([]byte("test-key")).Once() + decMaterials.EXPECT().DataKey().Return(dataKey).Once() + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(decMaterials, nil).Once() + }, + wantErr: true, + wantErrStr: "decrypt key derivation error", + }, + { + name: "Commitment Key Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) { + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(alg).Times(8) + header.EXPECT().Bytes().Return([]byte("test")).Once() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Twice() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().Bytes().Return([]byte("test-auth")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Twice() + verifier.EXPECT().LoadECCKey(mock.Anything).Return(nil).Once() + + dataKey := mocks.NewMockDataKey(t) + dataKey.EXPECT().DataKey().Return([]byte("test-data-key")).Once() + dataKey.EXPECT().DataKey().Return(nil).Once() // that result in key commitment error + + decMaterials := mocks.NewMockDecryptionMaterial(t) + decMaterials.EXPECT().VerificationKey().Return([]byte("test-key")).Once() + decMaterials.EXPECT().DataKey().Return(dataKey).Twice() + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(decMaterials, nil).Once() + }, + wantErr: true, + wantErrStr: "decrypt calculate commitment key error", + }, + { + name: "Commitment Key Match Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) { + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(alg).Times(8) + header.EXPECT().Bytes().Return([]byte("test")).Once() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Twice() + header.EXPECT().AlgorithmSuiteData().Return([]byte{0x00}).Once() // that result in key commitment error + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().Bytes().Return([]byte("test-auth")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Twice() + verifier.EXPECT().LoadECCKey(mock.Anything).Return(nil).Once() + + dataKey := mocks.NewMockDataKey(t) + dataKey.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + + decMaterials := mocks.NewMockDecryptionMaterial(t) + decMaterials.EXPECT().VerificationKey().Return([]byte("test-key")).Once() + decMaterials.EXPECT().DataKey().Return(dataKey).Twice() + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(decMaterials, nil).Once() + }, + wantErr: true, + wantErrStr: "key commitment validation failed", + }, + { + name: "Header Auth Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, alg *suite.AlgorithmSuite, cmm *mocks.MockCryptoMaterialsManager, deser *formatmocks.MockDeserializer, verifier *signaturemock.MockVerifier, aeadDecrypter *encryptionmocks.MockAEADDecrypter) { + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().AlgorithmSuite().Return(alg).Times(8) + header.EXPECT().Bytes().Return([]byte("test")).Twice() + header.EXPECT().EncryptedDataKeys().Return([]format.MessageEDK{setupEDKMock(t)}).Once() + header.EXPECT().AADData().Return(setupAADMock(t)).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Twice() + header.EXPECT().AlgorithmSuiteData().Return(algSuiteDataMock).Once() + + headerAuth := formatmocks.NewMockMessageHeaderAuth(t) + headerAuth.EXPECT().Bytes().Return([]byte("test-auth")).Once() + headerAuth.EXPECT().AuthData().Return([]byte("test-auth-data")).Once() + + deser.EXPECT().DeserializeHeader(mock.Anything, mock.Anything).Return(header, headerAuth, nil).Once() + + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Twice() + verifier.EXPECT().LoadECCKey(mock.Anything).Return(nil).Once() + + dataKey := mocks.NewMockDataKey(t) + dataKey.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + + decMaterials := mocks.NewMockDecryptionMaterial(t) + decMaterials.EXPECT().VerificationKey().Return([]byte("test-key")).Once() + decMaterials.EXPECT().DataKey().Return(dataKey).Twice() + cmm.EXPECT().DecryptMaterials(mock.Anything, mock.Anything).Return(decMaterials, nil).Once() + + aeadDecrypter.EXPECT().ValidateHeaderAuth(mock.Anything, mock.Anything, mock.Anything).Return(assert.AnError).Once() + }, + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "decrypt header auth error", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + + cmm := mocks.NewMockCryptoMaterialsManager(t) + deser := formatmocks.NewMockDeserializer(t) + verifier := signaturemock.NewMockVerifier(t) + aeadDecrypter := encryptionmocks.NewMockAEADDecrypter(t) + + tt.setupMocks(t, tt.alg, cmm, deser, verifier, aeadDecrypter) + + verifierFn := func(hashFn func() hash.Hash, c elliptic.Curve) signature.Verifier { + return verifier + } + + clientCfg, _ := clientconfig.NewConfigWithOpts(tt.clientCfgOpts...) + cfgMock := crypto.DecrypterConfig{ + ClientCfg: *clientCfg, + } + + d := &Decrypter{ + cmm: cmm, + cfg: cfgMock, + aeadDecrypter: aeadDecrypter, + deser: deser, + verifierFn: verifierFn, + } + + err := d.decryptHeader(ctx, bytes.NewBuffer([]byte("test"))) + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + if tt.wantErrStr != "" { + assert.ErrorContains(t, err, tt.wantErrStr) + } + assert.Nil(t, d.header) + assert.Empty(t, d._derivedDataKey) + } else { + assert.NoError(t, err) + assert.NotNil(t, d.header) + assert.NotEmpty(t, d._derivedDataKey) + if tt.alg.IsSigning() { + assert.NotNil(t, d.verifier) + } else { + assert.Nil(t, d.verifier) + } + } + }) + } +} + +func TestDecrypter_decryptBody(t *testing.T) { + tests := []struct { + name string + derivedDataKey []byte + setupMocks func(t *testing.T, header *formatmocks.MockMessageHeader, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) + want []byte + wantErr bool + wantErrType error + wantErrStr string + }{ + { + name: "Valid Decrypt", + derivedDataKey: []byte("test-key"), + setupMocks: func(t *testing.T, header *formatmocks.MockMessageHeader, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) { + header.EXPECT().AlgorithmSuite(). + Return(suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY).Once() + header.EXPECT().FrameLength().Return(1024).Once() + header.EXPECT().ContentType().Return(suite.FramedContent).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Once() + + frame := formatmocks.NewMockBodyFrame(t) + frame.EXPECT().IsFinal().Return(true).Once() + frame.EXPECT().SequenceNumber().Return(1).Once() + frame.EXPECT().EncryptedContent().Return([]byte("test-content")).Twice() + frame.EXPECT().IV().Return([]byte("test-iv")).Once() + frame.EXPECT().AuthenticationTag().Return([]byte("test-tag")).Once() + + body := formatmocks.NewMockMessageBody(t) + body.EXPECT().Frames(). + Return([]format.BodyFrame{frame}).Once() + + deser.EXPECT().DeserializeBody(mock.Anything, mock.Anything, mock.Anything). + Return(body, nil).Once() + + aeadDecrypter.EXPECT().Decrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return([]byte("decrypted1"), nil).Once() + }, + want: []byte("decrypted1"), + wantErr: false, + }, + { + name: "Valid Two Frames Decrypt", + derivedDataKey: []byte("test-key"), + setupMocks: func(t *testing.T, header *formatmocks.MockMessageHeader, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) { + header.EXPECT().AlgorithmSuite(). + Return(suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY).Once() + header.EXPECT().FrameLength().Return(1024).Once() + header.EXPECT().ContentType().Return(suite.FramedContent).Twice() + header.EXPECT().MessageID().Return([]byte("test-id")).Twice() + + frame1 := formatmocks.NewMockBodyFrame(t) + frame1.EXPECT().IsFinal().Return(false).Once() + frame1.EXPECT().SequenceNumber().Return(1).Once() + frame1.EXPECT().EncryptedContent().Return([]byte("test-content1")).Twice() + frame1.EXPECT().IV().Return([]byte("test-iv")).Once() + frame1.EXPECT().AuthenticationTag().Return([]byte("test-tag")).Once() + + frame2 := formatmocks.NewMockBodyFrame(t) + frame2.EXPECT().IsFinal().Return(true).Once() + frame2.EXPECT().SequenceNumber().Return(2).Once() + frame2.EXPECT().EncryptedContent().Return([]byte("test-content2")).Twice() + frame2.EXPECT().IV().Return([]byte("test-iv")).Once() + frame2.EXPECT().AuthenticationTag().Return([]byte("test-tag")).Once() + + body := formatmocks.NewMockMessageBody(t) + body.EXPECT().Frames(). + Return([]format.BodyFrame{frame1, frame2}).Once() + + deser.EXPECT().DeserializeBody(mock.Anything, mock.Anything, mock.Anything). + Return(body, nil).Once() + + aeadDecrypter.EXPECT().Decrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return([]byte("decrypted1"), nil).Once() + aeadDecrypter.EXPECT().Decrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return([]byte("decrypted2"), nil).Once() + }, + want: []byte("decrypted1decrypted2"), + wantErr: false, + }, + { + name: "Deserialize Body Error", + derivedDataKey: []byte("test-key"), + setupMocks: func(t *testing.T, header *formatmocks.MockMessageHeader, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) { + header.EXPECT().AlgorithmSuite(). + Return(suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY).Once() + header.EXPECT().FrameLength().Return(1024).Once() + + deser.EXPECT().DeserializeBody(mock.Anything, mock.Anything, mock.Anything). + Return(nil, assert.AnError).Once() + }, + want: nil, + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "deserialize body error", + }, + { + name: "Decrypt Frame Error", + derivedDataKey: []byte("test-key"), + setupMocks: func(t *testing.T, header *formatmocks.MockMessageHeader, aeadDecrypter *encryptionmocks.MockAEADDecrypter, deser *formatmocks.MockDeserializer) { + header.EXPECT().AlgorithmSuite(). + Return(suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY).Once() + header.EXPECT().FrameLength().Return(1024).Once() + header.EXPECT().ContentType().Return(suite.NonFramedContent).Once() // that result in decrypt frame error + + frame := formatmocks.NewMockBodyFrame(t) + frame.EXPECT().IsFinal().Return(true).Once() + + body := formatmocks.NewMockMessageBody(t) + body.EXPECT().Frames(). + Return([]format.BodyFrame{frame}).Once() + + deser.EXPECT().DeserializeBody(mock.Anything, mock.Anything, mock.Anything). + Return(body, nil).Once() + }, + want: nil, + wantErr: true, + wantErrStr: "decrypt frame error", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + header := formatmocks.NewMockMessageHeader(t) + deser := formatmocks.NewMockDeserializer(t) + aeadDecrypter := encryptionmocks.NewMockAEADDecrypter(t) + + tt.setupMocks(t, header, aeadDecrypter, deser) + + d := &Decrypter{ + aeadDecrypter: aeadDecrypter, + deser: deser, + _derivedDataKey: tt.derivedDataKey, + header: header, + } + + plaintext, err := d.decryptBody(bytes.NewBuffer([]byte("test"))) + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + if tt.wantErrStr != "" { + assert.ErrorContains(t, err, tt.wantErrStr) + } + assert.Nil(t, plaintext) + } else { + assert.NoError(t, err) + assert.NotNil(t, plaintext) + assert.Equal(t, tt.want, plaintext) + } + }) + } +} + +func TestDecrypter_decryptFrame(t *testing.T) { + tests := []struct { + name string + derivedDataKey []byte + setupMocks func(t *testing.T, header *formatmocks.MockMessageHeader, aeadDecrypter *encryptionmocks.MockAEADDecrypter, frame *formatmocks.MockBodyFrame) signature.Verifier + want []byte + wantErr bool + wantErrType error + wantErrStr string + }{ + { + name: "Valid Decrypt Final Frame", + derivedDataKey: []byte("test-key"), + setupMocks: func(t *testing.T, header *formatmocks.MockMessageHeader, aeadDecrypter *encryptionmocks.MockAEADDecrypter, frame *formatmocks.MockBodyFrame) signature.Verifier { + header.EXPECT().ContentType().Return(suite.FramedContent).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Once() + + frame.EXPECT().IsFinal().Return(true).Once() + frame.EXPECT().SequenceNumber().Return(1).Once() + frame.EXPECT().EncryptedContent().Return([]byte("test-content")).Twice() + frame.EXPECT().IV().Return([]byte("test-iv")).Once() + frame.EXPECT().AuthenticationTag().Return([]byte("test-tag")).Once() + frame.EXPECT().Bytes().Return([]byte("test-frame")).Once() + + aeadDecrypter.EXPECT().Decrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return([]byte("test-decrypted"), nil).Once() + + verifier := signaturemock.NewMockVerifier(t) + verifier.EXPECT().Write(mock.Anything).Return(4, nil).Once() + return verifier + }, + want: []byte("test-decrypted"), + wantErr: false, + }, + { + name: "Valid Decrypt NonFinal Frame", + derivedDataKey: []byte("test-key2"), + setupMocks: func(t *testing.T, header *formatmocks.MockMessageHeader, aeadDecrypter *encryptionmocks.MockAEADDecrypter, frame *formatmocks.MockBodyFrame) signature.Verifier { + header.EXPECT().ContentType().Return(suite.FramedContent).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Once() + + frame.EXPECT().IsFinal().Return(false).Once() + frame.EXPECT().SequenceNumber().Return(2).Once() + frame.EXPECT().EncryptedContent().Return([]byte("test-content")).Twice() + frame.EXPECT().IV().Return([]byte("test-iv")).Once() + frame.EXPECT().AuthenticationTag().Return([]byte("test-tag")).Once() + + aeadDecrypter.EXPECT().Decrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return([]byte("test-decrypted2"), nil).Once() + + return nil + }, + want: []byte("test-decrypted2"), + wantErr: false, + }, + { + name: "BodyAAD NonFramed Error", + derivedDataKey: []byte("test-key"), + setupMocks: func(t *testing.T, header *formatmocks.MockMessageHeader, aeadDecrypter *encryptionmocks.MockAEADDecrypter, frame *formatmocks.MockBodyFrame) signature.Verifier { + header.EXPECT().ContentType().Return(suite.NonFramedContent).Once() + + frame.EXPECT().IsFinal().Return(true).Once() + return nil + }, + want: nil, + wantErr: true, + wantErrStr: "bodyaad error", + }, + { + name: "AEAD Decrypt Error", + derivedDataKey: []byte("test-key"), + setupMocks: func(t *testing.T, header *formatmocks.MockMessageHeader, aeadDecrypter *encryptionmocks.MockAEADDecrypter, frame *formatmocks.MockBodyFrame) signature.Verifier { + header.EXPECT().ContentType().Return(suite.FramedContent).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Once() + + frame.EXPECT().IsFinal().Return(true).Once() + frame.EXPECT().SequenceNumber().Return(1).Once() + frame.EXPECT().EncryptedContent().Return([]byte("test-content")).Twice() + frame.EXPECT().IV().Return([]byte("test-iv")).Once() + frame.EXPECT().AuthenticationTag().Return([]byte("test-tag")).Once() + + aeadDecrypter.EXPECT().Decrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil, assert.AnError).Once() + + return nil + }, + want: nil, + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "decrypt frame AEAD error", + }, + { + name: "Verifier Error", + derivedDataKey: []byte("test-key"), + setupMocks: func(t *testing.T, header *formatmocks.MockMessageHeader, aeadDecrypter *encryptionmocks.MockAEADDecrypter, frame *formatmocks.MockBodyFrame) signature.Verifier { + header.EXPECT().ContentType().Return(suite.FramedContent).Once() + header.EXPECT().MessageID().Return([]byte("test-id")).Once() + + frame.EXPECT().IsFinal().Return(true).Once() + frame.EXPECT().SequenceNumber().Return(1).Once() + frame.EXPECT().EncryptedContent().Return([]byte("test-content")).Twice() + frame.EXPECT().IV().Return([]byte("test-iv")).Once() + frame.EXPECT().AuthenticationTag().Return([]byte("test-tag")).Once() + frame.EXPECT().Bytes().Return([]byte("test-frame")).Once() + + aeadDecrypter.EXPECT().Decrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return([]byte("test-decrypted"), nil).Once() + + verifier := signaturemock.NewMockVerifier(t) + verifier.EXPECT().Write(mock.Anything).Return(0, assert.AnError).Once() + return verifier + }, + want: nil, + wantErr: true, + wantErrType: assert.AnError, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + header := formatmocks.NewMockMessageHeader(t) + aeadDecrypter := encryptionmocks.NewMockAEADDecrypter(t) + frame := formatmocks.NewMockBodyFrame(t) + + verifier := tt.setupMocks(t, header, aeadDecrypter, frame) + + d := &Decrypter{ + aeadDecrypter: aeadDecrypter, + verifier: verifier, + _derivedDataKey: tt.derivedDataKey, + header: header, + } + + b, err := d.decryptFrame(frame) + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + if tt.wantErrStr != "" { + assert.ErrorContains(t, err, tt.wantErrStr) + } + assert.Nil(t, b) + } else { + assert.NoError(t, err) + assert.NotNil(t, b) + assert.Equal(t, tt.want, b) + } + }) + } +} + +func TestDecrypter_reset(t *testing.T) { + tests := []struct { + name string + header format.MessageHeader + derivedDataKey []byte + err error + wantHeader bool + }{ + { + name: "Reset Cleanup", + header: formatmocks.NewMockMessageHeader(t), + derivedDataKey: []byte("test-key"), + err: nil, + wantHeader: false, + }, + { + name: "Reset On Error", + header: formatmocks.NewMockMessageHeader(t), + derivedDataKey: []byte("test-key"), + err: assert.AnError, + wantHeader: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + d := &Decrypter{ + header: tt.header, + _derivedDataKey: tt.derivedDataKey, + } + d.reset(tt.err) + if tt.wantHeader { + assert.Nil(t, d.header) + } + assert.Empty(t, d._derivedDataKey) + }) + } +} diff --git a/pkg/crypto/encrypter.go b/pkg/internal/crypto/encrypter/encrypt.go similarity index 50% rename from pkg/crypto/encrypter.go rename to pkg/internal/crypto/encrypter/encrypt.go index 75a97c6..e18c414 100644 --- a/pkg/crypto/encrypter.go +++ b/pkg/internal/crypto/encrypter/encrypt.go @@ -1,26 +1,62 @@ // Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package crypto +package encrypter import ( "bytes" "context" + "errors" "fmt" "math" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/crypto/signature" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/crypto" "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/crypto/policy" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/crypto/signature" "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/encryption" "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, format.MessageHeader, error) { +type Encrypter struct { + cmm model.CryptoMaterialsManager + cfg crypto.EncrypterConfig + aeadEncrypter encryption.AEADEncrypter + ser format.Serializer + header format.MessageHeader + _derivedDataKey []byte + signer signature.Signer + signerFn signature.SignerFunc + ciphertextBuf model.EncryptionBuffer +} + +func New(cfg crypto.EncrypterConfig, cmm model.CryptoMaterialsManager) model.EncryptionHandler { + return &Encrypter{ + cmm: cmm.GetInstance(), + cfg: cfg, + aeadEncrypter: encryption.Gcm{}, + ser: serialization.NewSerializer(), + signerFn: signature.NewECCSigner, + ciphertextBuf: new(bytes.Buffer), + } +} + +func (e *Encrypter) Encrypt(ctx context.Context, source []byte, ec suite.EncryptionContext) ([]byte, format.MessageHeader, error) { + ciphertext, header, err := e.encryptData(ctx, source, ec) + if err != nil { + e.reset(err) + return nil, nil, fmt.Errorf("SDK error: %w", errors.Join(crypto.ErrEncryption, err)) + } + e.reset(nil) + return ciphertext, header, nil +} + +func (e *Encrypter) encryptData(ctx context.Context, source []byte, ec suite.EncryptionContext) ([]byte, format.MessageHeader, error) { var b []byte b = make([]byte, len(source)) copy(b, source) @@ -28,7 +64,7 @@ func (e *encrypter) encrypt(ctx context.Context, source []byte, ec suite.Encrypt return nil, nil, fmt.Errorf("empty source") } buf := bytes.NewBuffer(b) - if err := e.prepareMessage(ctx, buf, ec); err != nil { + if err := e.prepareMessage(ctx, buf.Len(), ec); err != nil { return nil, nil, fmt.Errorf("prepare message error: %w", err) } @@ -40,14 +76,12 @@ func (e *encrypter) encrypt(ctx context.Context, source []byte, ec suite.Encrypt return nil, nil, fmt.Errorf("encrypt error: %w", err) } - // TODO andrew clean up derivedDataKey - if e.signer != nil { sign, err := e.signer.Sign() if err != nil { return nil, nil, fmt.Errorf("encrypt sign error: %w", err) } - footer, err := serialization.MessageFooter.NewFooter(e.algorithm, sign) + footer, err := e.ser.SerializeFooter(e.cfg.Algorithm, sign) if err != nil { return nil, nil, fmt.Errorf("encrypt sign error: %w", err) } @@ -68,47 +102,43 @@ func (e *encrypter) encrypt(ctx context.Context, source []byte, ec suite.Encrypt return ciphertext, e.header, nil } -func (e *encrypter) prepareMessage(ctx context.Context, plaintextBuffer *bytes.Buffer, ec suite.EncryptionContext) error { - if err := policy.ValidateOnEncrypt(e.config.CommitmentPolicy(), e.algorithm); err != nil { +func (e *Encrypter) prepareMessage(ctx context.Context, plaintextLen int, ec suite.EncryptionContext) error { + if err := policy.ValidateOnEncrypt(e.cfg.ClientCfg.CommitmentPolicy(), e.cfg.Algorithm); err != nil { return err // just return err } emr := model.EncryptionMaterialsRequest{ EncryptionContext: ec, - Algorithm: e.algorithm, - PlaintextLength: plaintextBuffer.Len(), + Algorithm: e.cfg.Algorithm, + PlaintextLength: plaintextLen, } encMaterials, err := e.cmm.GetEncryptionMaterials(ctx, emr) if err != nil { return fmt.Errorf("encrypt materials: %w", err) } - if len(encMaterials.EncryptedDataKeys()) > e.config.MaxEncryptedDataKeys() { + if len(encMaterials.EncryptedDataKeys()) > e.cfg.ClientCfg.MaxEncryptedDataKeys() { return fmt.Errorf("materials: max encrypted data keys exceeded") } - if e.algorithm.IsSigning() { - e.signer = signature.NewECCSigner( - e.algorithm.Authentication.HashFunc, - e.algorithm.Authentication.Algorithm, - e.algorithm.Authentication.SignatureLen, + if e.cfg.Algorithm.IsSigning() { + e.signer = e.signerFn( + e.cfg.Algorithm.Authentication.HashFunc, + e.cfg.Algorithm.Authentication.Algorithm, + e.cfg.Algorithm.Authentication.SignatureLen, encMaterials.SigningKey(), ) } - // TODO validate frame length https://github.com/aws/aws-encryption-sdk-python/blob/93f01d655d6bce704bd8779cc9c4acb5f96b980c/src/aws_encryption_sdk/internal/utils/__init__.py#L44 - - messageID, err := rand.CryptoRandomBytes(e.algorithm.MessageIDLen()) + messageID, err := rand.CryptoRandomBytes(e.cfg.Algorithm.MessageIDLen()) if err != nil { return fmt.Errorf("messageID error: %w", err) } - derivedDataKey, err := keyderivation.DeriveDataEncryptionKey(encMaterials.DataEncryptionKey().DataKey(), e.algorithm, messageID) + derivedDataKey, err := keyderivation.DeriveDataEncryptionKey(encMaterials.DataEncryptionKey().DataKey(), e.cfg.Algorithm, messageID) if err != nil { return fmt.Errorf("key derivation failed: %w", err) } - - // TODO andrew clean up this after use e._derivedDataKey = derivedDataKey if errHeader := e.generateHeader(messageID, encMaterials); errHeader != nil { @@ -118,84 +148,61 @@ func (e *encrypter) prepareMessage(ctx context.Context, plaintextBuffer *bytes.B return nil } -func (e *encrypter) generateHeader(messageID []byte, encMaterials model.EncryptionMaterial) error { +func (e *Encrypter) generateHeader(messageID []byte, encMaterials model.EncryptionMaterial) error { edks, err := serialization.EDK.FromEDKs(encMaterials.EncryptedDataKeys()) if err != nil { return fmt.Errorf("EDK error: %w", err) } var commitmentKey []byte - if e.algorithm.IsCommitting() { - commitmentKey, err = keyderivation.CalculateCommitmentKey(encMaterials.DataEncryptionKey().DataKey(), e.algorithm, messageID) + if e.cfg.Algorithm.IsCommitting() { + commitmentKey, err = keyderivation.CalculateCommitmentKey(encMaterials.DataEncryptionKey().DataKey(), e.cfg.Algorithm, messageID) if err != nil { return fmt.Errorf("calculate commitment key error: %w", err) } } - params := serialization.HeaderParams{ - AlgorithmSuite: e.algorithm, + params := format.HeaderParams{ + AlgorithmSuite: e.cfg.Algorithm, MessageID: messageID, EncryptionContext: encMaterials.EncryptionContext(), EncryptedDataKeys: edks, ContentType: suite.FramedContent, - FrameLength: e.frameLength, + FrameLength: e.cfg.FrameLength, AlgorithmSuiteData: commitmentKey, } - header, err := serialization.NewHeader(params) + header, err := e.ser.SerializeHeader(params) if err != nil { - return fmt.Errorf("header error: %w", err) + return fmt.Errorf("header serialize error: %w", err) } e.header = header - if errBuf := e.updateBuffers(e.header.Bytes()); errBuf != nil { //nolint:revive - return errBuf - } - - return nil + return e.updateBuffers(e.header.Bytes()) } -func (e *encrypter) generateHeaderAuth() error { +func (e *Encrypter) generateHeaderAuth() error { 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.NewHeaderAuth(e.header.Version(), iv, headerAuthTag) + headerAuthData, err := e.ser.SerializeHeaderAuth(e.header.Version(), iv, headerAuthTag) if err != nil { return fmt.Errorf("header auth serialize error: %w", err) } - if errBuf := e.updateBuffers(headerAuthData.Bytes()); errBuf != nil { - return errBuf // wrapped already in updateCiphertextBuf - } - return nil + return e.updateBuffers(headerAuthData.Bytes()) } -func (e *encrypter) encryptBody(plaintextBuffer *bytes.Buffer) error { - body, errBody := serialization.MessageBody.NewBody(e.header.AlgorithmSuite(), e.frameLength) +func (e *Encrypter) encryptBody(plaintextBuffer *bytes.Buffer) error { + body, errBody := e.ser.SerializeBody(e.header.AlgorithmSuite(), e.cfg.FrameLength) if errBody != nil { return fmt.Errorf("body error: %w", errBody) } - framesToRead := math.Ceil(float64(plaintextBuffer.Len()) / float64(e.frameLength)) - - // Check if an extra final frame is needed when the plaintextBuffer - // length is exactly divisible by the frame length - if plaintextBuffer.Len()%e.frameLength == 0 { - framesToRead++ - } - - calculateFrame := func() (int, bool) { - if plaintextBuffer.Len() > e.frameLength { //nolint:gocritic - return e.frameLength, false - } else if plaintextBuffer.Len() == e.frameLength { - return e.frameLength, false - } else { //nolint:revive - return plaintextBuffer.Len(), true - } - } + frames := calcFrames(plaintextBuffer.Len(), e.cfg.FrameLength) - for seqNum := 1; seqNum <= int(framesToRead); seqNum++ { - bytesToRead, isFinal := calculateFrame() + for seqNum := 1; seqNum <= frames; seqNum++ { + bytesToRead, isFinal := calcFrameLen(plaintextBuffer.Len(), e.cfg.FrameLength) plaintext := plaintextBuffer.Next(bytesToRead) iv := e.aeadEncrypter.ConstructIV(seqNum) ciphertext, authTag, err := e.encryptFrame(seqNum, isFinal, iv, plaintext) @@ -210,8 +217,40 @@ func (e *encrypter) encryptBody(plaintextBuffer *bytes.Buffer) error { return e.updateBuffers(body.Bytes()) } -func (e *encrypter) encryptFrame(seqNum int, isFinal bool, iv, plaintext []byte) ([]byte, []byte, error) { - contentString, err := bodyaad.ContentString(suite.FramedContent, isFinal) +// calcFrames calculates the number of frames needed to store a given plaintext length, based on the frame length parameter. +// It returns the number of frames as an integer. +// +// The frames are calculated by dividing the plaintext length by the frame length and rounding up using math.Ceil. +// An extra final frame is added if the plaintext length is exactly divisible by the frame length. +func calcFrames(plaintextLen, frameLen int) int { + frames := math.Ceil(float64(plaintextLen) / float64(frameLen)) + // Check if an extra final frame is needed when the plaintextBuffer + // length is exactly divisible by the frame length + if plaintextLen%frameLen == 0 { + frames++ + } + return int(frames) +} + +// calcFrameLen calculates the frame length based on the buffer length and frame length parameters. +// It returns the calculated frame length and a boolean indicating whether it is the last frame or not. +// +// If bufLen is greater than frameLen, it returns frameLen and false. +// If bufLen is equal to frameLen, it returns frameLen and false. +// If bufLen is less than frameLen, it returns bufLen and true. +func calcFrameLen(bufLen, frameLen int) (int, bool) { + switch { + case bufLen > frameLen: + return frameLen, false // false means not last frame + case bufLen == frameLen: + return frameLen, false // false means not last frame + default: + return bufLen, true // true means last frame + } +} + +func (e *Encrypter) encryptFrame(seqNum int, isFinal bool, iv, plaintext []byte) ([]byte, []byte, error) { + contentString, err := bodyaad.ContentString(e.header.ContentType(), isFinal) if err != nil { return nil, nil, fmt.Errorf("encrypt frame error: %w", err) } @@ -233,7 +272,7 @@ func (e *encrypter) encryptFrame(seqNum int, isFinal bool, iv, plaintext []byte) return ciphertext, authTag, nil } -func (e *encrypter) updateCiphertextBuf(b []byte) error { +func (e *Encrypter) updateCiphertextBuf(b []byte) error { _, err := e.ciphertextBuf.Write(b) if err != nil { return fmt.Errorf("ciphertext buffer write error: %w", err) @@ -242,7 +281,7 @@ func (e *encrypter) updateCiphertextBuf(b []byte) error { return nil } -func (e *encrypter) updateBuffers(b []byte) error { +func (e *Encrypter) updateBuffers(b []byte) error { if err := e.updateCiphertextBuf(b); err != nil { return err } @@ -255,3 +294,10 @@ func (e *encrypter) updateBuffers(b []byte) error { return nil } + +func (e *Encrypter) reset(err error) { + e._derivedDataKey = nil + if err != nil { + e.header = nil + } +} diff --git a/pkg/internal/crypto/encrypter/encrypt_test.go b/pkg/internal/crypto/encrypter/encrypt_test.go new file mode 100644 index 0000000..bd5c89a --- /dev/null +++ b/pkg/internal/crypto/encrypter/encrypt_test.go @@ -0,0 +1,1909 @@ +package encrypter + +import ( + "bytes" + "context" + "crypto/ecdsa" + "crypto/elliptic" + "hash" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + signaturemock "github.com/chainifynet/aws-encryption-sdk-go/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/internal_/crypto/signature" + mocks "github.com/chainifynet/aws-encryption-sdk-go/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model" + formatmocks "github.com/chainifynet/aws-encryption-sdk-go/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" + encryptionmocks "github.com/chainifynet/aws-encryption-sdk-go/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/encryption" + randmocks "github.com/chainifynet/aws-encryption-sdk-go/mocks/github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/rand" + "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/internal/crypto/signature" + "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/suite" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/rand" +) + +func TestEncrypter_reset(t *testing.T) { + tests := []struct { + name string + header format.MessageHeader + derivedDataKey []byte + err error + wantHeader bool + }{ + { + name: "Reset Cleanup", + header: formatmocks.NewMockMessageHeader(t), + derivedDataKey: []byte("derivedDataKey"), + err: nil, + wantHeader: false, + }, + { + name: "Reset On Error", + header: formatmocks.NewMockMessageHeader(t), + derivedDataKey: []byte("derivedDataKey"), + err: assert.AnError, + wantHeader: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + e := &Encrypter{ + header: tt.header, + _derivedDataKey: tt.derivedDataKey, + } + e.reset(tt.err) + if tt.wantHeader { + assert.Nil(t, e.header) + } else { + assert.NotNil(t, e.header) + } + assert.Empty(t, e._derivedDataKey) + }) + } +} + +func TestNew(t *testing.T) { + tests := []struct { + name string + cfg crypto.EncrypterConfig + setupMocks func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager) + }{ + { + name: "Valid Encrypter", + cfg: crypto.EncrypterConfig{ + ClientCfg: clientconfig.ClientConfig{}, + Algorithm: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + FrameLength: 4096, + }, + setupMocks: func(t *testing.T, cmm *mocks.MockCryptoMaterialsManager) { + cmm.EXPECT().GetInstance().Return(cmm).Once() + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmm := mocks.NewMockCryptoMaterialsManager(t) + tt.setupMocks(t, cmm) + + got := New(tt.cfg, cmm) + assert.NotNil(t, got) + + assert.IsType(t, &Encrypter{}, got) + + assert.Equal(t, tt.cfg, got.(*Encrypter).cfg) + assert.Equal(t, cmm, got.(*Encrypter).cmm) + assert.NotNil(t, got.(*Encrypter).aeadEncrypter) + assert.NotNil(t, got.(*Encrypter).ser) + assert.NotNil(t, got.(*Encrypter).signerFn) + assert.NotNil(t, got.(*Encrypter).ciphertextBuf) + + assert.Nil(t, got.(*Encrypter).header) + assert.Nil(t, got.(*Encrypter).signer) + assert.Nil(t, got.(*Encrypter)._derivedDataKey) + }) + } +} + +func TestEncrypter_updateCiphertextBuf(t *testing.T) { + tests := []struct { + name string + setupMocks func(t *testing.T, buf *mocks.MockEncryptionBuffer) + ciphertext []byte + wantBuf []byte + wantErr bool + wantErrType error + }{ + { + name: "Empty ciphertext", + setupMocks: func(t *testing.T, buf *mocks.MockEncryptionBuffer) { + buf.EXPECT().Write(mock.Anything). + Return(0, nil).Once() + buf.EXPECT().Bytes(). + Return([]byte(nil)).Once() + }, + ciphertext: []byte{}, + wantBuf: []byte(nil), + wantErr: false, + }, + { + name: "Non-empty ciphertext", + setupMocks: func(t *testing.T, buf *mocks.MockEncryptionBuffer) { + buf.EXPECT().Write(mock.Anything). + Return(3, nil).Once() + buf.EXPECT().Bytes(). + Return([]byte{1, 2, 3}).Once() + }, + ciphertext: []byte{1, 2, 3}, + wantBuf: []byte{1, 2, 3}, + wantErr: false, + }, + { + name: "Error On Write", + setupMocks: func(t *testing.T, buf *mocks.MockEncryptionBuffer) { + buf.EXPECT().Write(mock.Anything). + Return(0, assert.AnError).Once() + }, + ciphertext: []byte{4, 5, 6}, + wantBuf: nil, + wantErr: true, + wantErrType: assert.AnError, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + buf := mocks.NewMockEncryptionBuffer(t) + tt.setupMocks(t, buf) + + e := &Encrypter{ + ciphertextBuf: buf, + } + err := e.updateCiphertextBuf(tt.ciphertext) + + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + } else { + assert.NoError(t, err) + assert.Equal(t, tt.wantBuf, e.ciphertextBuf.Bytes()) + } + }) + } +} + +func TestEncrypter_updateBuffers(t *testing.T) { + tests := []struct { + name string + setupMocks func(t *testing.T, buf *mocks.MockEncryptionBuffer) signature.Signer + ciphertext []byte + wantErr bool + wantErrType error + }{ + { + name: "Empty ciphertext", + setupMocks: func(t *testing.T, buf *mocks.MockEncryptionBuffer) signature.Signer { + buf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + return nil + }, + ciphertext: []byte{}, + wantErr: false, + }, + { + name: "Сiphertext With Signer", + setupMocks: func(t *testing.T, buf *mocks.MockEncryptionBuffer) signature.Signer { + buf.EXPECT().Write(mock.Anything).Return(3, nil).Once() + signer := signaturemock.NewMockSigner(t) + signer.EXPECT().Write(mock.Anything).Return(3, nil).Once() + return signer + }, + ciphertext: []byte{1, 2, 3}, + wantErr: false, + }, + { + name: "Buffer Write Error", + setupMocks: func(t *testing.T, buf *mocks.MockEncryptionBuffer) signature.Signer { + buf.EXPECT().Write(mock.Anything).Return(0, assert.AnError).Once() + return nil + }, + ciphertext: []byte{4, 5, 6}, + wantErr: true, + wantErrType: assert.AnError, + }, + { + name: "Signer Write Error", + setupMocks: func(t *testing.T, buf *mocks.MockEncryptionBuffer) signature.Signer { + buf.EXPECT().Write(mock.Anything).Return(3, nil).Once() + signer := signaturemock.NewMockSigner(t) + signer.EXPECT().Write(mock.Anything).Return(0, assert.AnError).Once() + return signer + }, + ciphertext: []byte{4, 5, 6}, + wantErr: true, + wantErrType: assert.AnError, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + buf := mocks.NewMockEncryptionBuffer(t) + signer := tt.setupMocks(t, buf) + + e := &Encrypter{ + ciphertextBuf: buf, + signer: signer, + } + err := e.updateBuffers(tt.ciphertext) + + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + } else { + assert.NoError(t, err) + } + }) + } +} + +func Test_calcFrameLen(t *testing.T) { + tests := []struct { + name string + bufLen int + frameLen int + wantResult int + wantIsLast bool + }{ + { + // case 1 + name: "Buffer length greater than frame length", + bufLen: 1000, + frameLen: 500, + wantResult: 500, + wantIsLast: false, + }, + { + // case 2 + name: "Buffer length equal to frame length", + bufLen: 1000, + frameLen: 1000, + wantResult: 1000, + wantIsLast: false, + }, + { + // case 3 default + name: "Buffer length less than frame length", + bufLen: 500, + frameLen: 1000, + wantResult: 500, + wantIsLast: true, + }, + { + // case 3 default + name: "Zero buffer length", + bufLen: 0, + frameLen: 500, + wantResult: 0, + wantIsLast: true, + }, + { + // case 1 + name: "Zero frame length", + bufLen: 500, + frameLen: 0, + wantResult: 0, + wantIsLast: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, isLast := calcFrameLen(tt.bufLen, tt.frameLen) + assert.Equal(t, tt.wantResult, result) + assert.Equal(t, tt.wantIsLast, isLast) + }) + } +} + +func Test_calcFrames(t *testing.T) { + tests := []struct { + name string + plaintextLen int + frameLen int + want int + }{ + { + // 1 empty frame + name: "Zero Plaintext", + plaintextLen: 0, + frameLen: 10, + want: 1, + }, + { + // 1 frame, 10 bytes, no extra frame + name: "Plaintext Less Than FrameLen", + plaintextLen: 10, + frameLen: 20, + want: 1, + }, + { + // 2 frame, 10 bytes x 1 frame + 1 extra empty frame + name: "Plaintext Equal To FrameLen ExtraFrame", + plaintextLen: 10, + frameLen: 10, + want: 2, + }, + { + // 6 frames, 10 bytes x 5 frames + 1 extra empty frame + name: "Plaintext Greater Than FrameLen ExtraFrame", + plaintextLen: 50, + frameLen: 10, + want: 6, + }, + { + // 7 frames, 10 bytes x 6 frames + 5 bytes x 1 frame + name: "Plaintext Greater Than FrameLen", + plaintextLen: 65, + frameLen: 10, + want: 7, + }, + { + name: "P_1024 F256", + plaintextLen: 1024, + frameLen: 256, + want: 5, + }, + { + name: "P_1024 F128", + plaintextLen: 1024, + frameLen: 128, + want: 9, + }, + { + name: "P_4096 F128", + plaintextLen: 4096, + frameLen: 128, + want: 33, + }, + { + name: "P_4096 F1024", + plaintextLen: 4096, + frameLen: 1024, + want: 5, + }, + { + name: "P_1Mb F1024", + plaintextLen: 1048576, + frameLen: 1024, + want: 1025, + }, + { + name: "P_1Mb F4096", + plaintextLen: 1048576, + frameLen: 4096, + want: 257, + }, + { + name: "P_1023 F1024", + plaintextLen: 1023, + frameLen: 1024, + want: 1, + }, + { + name: "P_1024 F1024", + plaintextLen: 1024, + frameLen: 1024, + want: 2, + }, + { + name: "P_1025 F1024", + plaintextLen: 1025, + frameLen: 1024, + want: 2, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := calcFrames(tt.plaintextLen, tt.frameLen) + assert.Equal(t, tt.want, got) + }) + } +} + +func TestEncrypter_encryptFrame(t *testing.T) { + type args struct { + seqNum int + isFinal bool + iv []byte + plaintext []byte + } + finalFrameMock := args{ + seqNum: 1, + isFinal: true, + iv: []byte("test-iv"), + plaintext: []byte("test-plaintext"), + } + frameMock := args{ + seqNum: 2, + isFinal: false, + iv: []byte("test-iv"), + plaintext: []byte("test-plaintext"), + } + tests := []struct { + name string + derivedDataKey []byte + args args + setupMocks func(t *testing.T, header *formatmocks.MockMessageHeader, aeadEncrypter *encryptionmocks.MockAEADEncrypter) + wantCiphertext []byte + wantAuthTag []byte + wantErr bool + wantErrType error + wantErrStr string + }{ + { + name: "BodyAAD Error", + derivedDataKey: []byte("derivedDataKey"), + args: finalFrameMock, + setupMocks: func(t *testing.T, header *formatmocks.MockMessageHeader, aeadEncrypter *encryptionmocks.MockAEADEncrypter) { + header.EXPECT().ContentType().Return(suite.NonFramedContent).Once() + }, + wantCiphertext: nil, + wantAuthTag: nil, + wantErr: true, + wantErrStr: "encrypt frame error", + }, + { + name: "AEAD Encrypt Error", + derivedDataKey: []byte("derivedDataKey"), + args: frameMock, + setupMocks: func(t *testing.T, header *formatmocks.MockMessageHeader, aeadEncrypter *encryptionmocks.MockAEADEncrypter) { + header.EXPECT().ContentType().Return(suite.FramedContent).Once() + header.EXPECT().MessageID().Return([]byte("test-message-id")).Once() + + aeadEncrypter.EXPECT().Encrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil, nil, assert.AnError).Once() + }, + wantCiphertext: nil, + wantAuthTag: nil, + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "encrypt frame error", + }, + { + name: "Valid Frame Encrypt", + derivedDataKey: []byte("derivedDataKey"), + args: frameMock, + setupMocks: func(t *testing.T, header *formatmocks.MockMessageHeader, aeadEncrypter *encryptionmocks.MockAEADEncrypter) { + header.EXPECT().ContentType().Return(suite.FramedContent).Once() + header.EXPECT().MessageID().Return([]byte("test-message-id")).Once() + + aeadEncrypter.EXPECT().Encrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return([]byte("ciphertext1"), []byte("authTag1"), nil).Once() + }, + wantCiphertext: []byte("ciphertext1"), + wantAuthTag: []byte("authTag1"), + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + header := formatmocks.NewMockMessageHeader(t) + aeadEncrypter := encryptionmocks.NewMockAEADEncrypter(t) + + tt.setupMocks(t, header, aeadEncrypter) + + e := &Encrypter{ + aeadEncrypter: aeadEncrypter, + header: header, + _derivedDataKey: tt.derivedDataKey, + } + + ciphertext, authTag, err := e.encryptFrame(tt.args.seqNum, tt.args.isFinal, tt.args.iv, tt.args.plaintext) + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + if tt.wantErrStr != "" { + assert.ErrorContains(t, err, tt.wantErrStr) + } + assert.Nil(t, ciphertext) + assert.Nil(t, authTag) + } else { + assert.NoError(t, err) + assert.NotNil(t, ciphertext) + assert.Equal(t, tt.wantCiphertext, ciphertext) + assert.NotNil(t, authTag) + assert.Equal(t, tt.wantAuthTag, authTag) + } + }) + } +} + +func TestEncrypter_encryptBody(t *testing.T) { + type mocksParams struct { + header *formatmocks.MockMessageHeader + aeadEncrypter *encryptionmocks.MockAEADEncrypter + ser *formatmocks.MockSerializer + ciphertextBuf *mocks.MockEncryptionBuffer + } + tests := []struct { + name string + derivedDataKey []byte + setupMocks func(t *testing.T, m mocksParams) + plaintext []byte + frameLen int + wantErr bool + wantErrType error + wantErrStr string + }{ + { + name: "Serialize Body Error", + derivedDataKey: []byte("derivedDataKey"), + setupMocks: func(t *testing.T, m mocksParams) { + m.header.EXPECT().AlgorithmSuite(). + Return(suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384).Once() + + m.ser.EXPECT().SerializeBody(mock.Anything, mock.Anything).Return(nil, assert.AnError).Once() + }, + plaintext: make([]byte, 1024), + frameLen: 512, + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "body error", + }, + { + name: "Encrypt Frame Error", + derivedDataKey: []byte("derivedDataKey"), + setupMocks: func(t *testing.T, m mocksParams) { + m.header.EXPECT().AlgorithmSuite(). + Return(suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384).Once() + + m.ser.EXPECT().SerializeBody(mock.Anything, mock.Anything). + Return(formatmocks.NewMockMessageBody(t), nil).Once() + + m.aeadEncrypter.EXPECT().ConstructIV(mock.Anything).Return([]byte("test-iv")).Once() + + m.header.EXPECT().ContentType().Return(suite.NonFramedContent).Once() + }, + plaintext: make([]byte, 1024), + frameLen: 512, + wantErr: true, + wantErrStr: "encrypt frame error", + }, + { + name: "Body Add Frame Error", + derivedDataKey: []byte("derivedDataKey"), + setupMocks: func(t *testing.T, m mocksParams) { + m.header.EXPECT().AlgorithmSuite(). + Return(suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384).Once() + + body := formatmocks.NewMockMessageBody(t) + + m.ser.EXPECT().SerializeBody(mock.Anything, mock.Anything). + Return(body, nil).Once() + + m.aeadEncrypter.EXPECT().ConstructIV(mock.Anything).Return([]byte("wrong-iv")).Once() + + m.header.EXPECT().ContentType().Return(suite.FramedContent).Once() + m.header.EXPECT().MessageID().Return([]byte("test-message-id")).Once() + + m.aeadEncrypter.EXPECT().Encrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return([]byte("ciphertext1"), []byte("authTag1"), nil).Once() + + body.EXPECT().AddFrame(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(assert.AnError).Once() + }, + plaintext: make([]byte, 1024), + frameLen: 512, + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "body frame error", + }, + { + name: "Valid Encrypt Body Two Frames", + derivedDataKey: []byte("derivedDataKey"), + setupMocks: func(t *testing.T, m mocksParams) { + m.header.EXPECT().AlgorithmSuite(). + Return(suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384).Once() + + body := formatmocks.NewMockMessageBody(t) + + m.ser.EXPECT().SerializeBody(mock.Anything, mock.Anything). + Return(body, nil).Once() + + m.aeadEncrypter.EXPECT().ConstructIV(mock.Anything).Return([]byte("testIv12byte")).Times(2) + + m.header.EXPECT().ContentType().Return(suite.FramedContent).Times(2) + m.header.EXPECT().MessageID().Return([]byte("test-message-id")).Times(2) + + m.aeadEncrypter.EXPECT().Encrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(make([]byte, 512), []byte("auth-Tag-16bytes"), nil).Times(2) + + body.EXPECT().AddFrame(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil).Times(2) + body.EXPECT().Bytes().Return([]byte("body-bytes")).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + }, + plaintext: make([]byte, 1023), + frameLen: 512, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + header := formatmocks.NewMockMessageHeader(t) + aeadEncrypter := encryptionmocks.NewMockAEADEncrypter(t) + ser := formatmocks.NewMockSerializer(t) + ciphertextBuf := mocks.NewMockEncryptionBuffer(t) + + tt.setupMocks(t, mocksParams{ + header: header, + aeadEncrypter: aeadEncrypter, + ser: ser, + ciphertextBuf: ciphertextBuf, + }) + + cfgMock := crypto.EncrypterConfig{ + FrameLength: tt.frameLen, + } + + e := &Encrypter{ + aeadEncrypter: aeadEncrypter, + cfg: cfgMock, + header: header, + ser: ser, + ciphertextBuf: ciphertextBuf, + _derivedDataKey: tt.derivedDataKey, + } + + err := e.encryptBody(bytes.NewBuffer(tt.plaintext)) + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + if tt.wantErrStr != "" { + assert.ErrorContains(t, err, tt.wantErrStr) + } + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestEncrypter_generateHeaderAuth(t *testing.T) { + type mocksParams struct { + header *formatmocks.MockMessageHeader + aeadEncrypter *encryptionmocks.MockAEADEncrypter + ser *formatmocks.MockSerializer + ciphertextBuf *mocks.MockEncryptionBuffer + } + tests := []struct { + name string + derivedDataKey []byte + setupMocks func(t *testing.T, m mocksParams) + wantErr bool + wantErrType error + wantErrStr string + }{ + { + name: "AEAD Auth Error", + derivedDataKey: []byte("derivedDataKey"), + setupMocks: func(t *testing.T, m mocksParams) { + m.header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + + m.aeadEncrypter.EXPECT().GenerateHeaderAuth(mock.Anything, mock.Anything). + Return(nil, nil, assert.AnError).Once() + }, + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "header auth error", + }, + { + name: "Serialize Header Auth Error", + derivedDataKey: []byte("derivedDataKey"), + setupMocks: func(t *testing.T, m mocksParams) { + m.header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + m.header.EXPECT().Version().Return(suite.V2).Once() + + m.aeadEncrypter.EXPECT().GenerateHeaderAuth(mock.Anything, mock.Anything). + Return([]byte("headerAuthTag"), []byte("auth-iv"), nil).Once() + + m.ser.EXPECT().SerializeHeaderAuth(mock.Anything, mock.Anything, mock.Anything). + Return(nil, assert.AnError).Once() + }, + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "header auth serialize error", + }, + { + name: "Valid Header Auth", + derivedDataKey: []byte("derivedDataKey"), + setupMocks: func(t *testing.T, m mocksParams) { + m.header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + m.header.EXPECT().Version().Return(suite.V2).Once() + + m.aeadEncrypter.EXPECT().GenerateHeaderAuth(mock.Anything, mock.Anything). + Return([]byte("headerAuthTag"), []byte("auth-iv"), nil).Once() + + headerAuthData := formatmocks.NewMockMessageHeaderAuth(t) + headerAuthData.EXPECT().Bytes().Return([]byte("headerAuthData-bytes")).Once() + + m.ser.EXPECT().SerializeHeaderAuth(mock.Anything, mock.Anything, mock.Anything). + Return(headerAuthData, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + header := formatmocks.NewMockMessageHeader(t) + aeadEncrypter := encryptionmocks.NewMockAEADEncrypter(t) + ser := formatmocks.NewMockSerializer(t) + ciphertextBuf := mocks.NewMockEncryptionBuffer(t) + + tt.setupMocks(t, mocksParams{ + header: header, + aeadEncrypter: aeadEncrypter, + ser: ser, + ciphertextBuf: ciphertextBuf, + }) + + e := &Encrypter{ + aeadEncrypter: aeadEncrypter, + header: header, + ser: ser, + ciphertextBuf: ciphertextBuf, + _derivedDataKey: tt.derivedDataKey, + } + + err := e.generateHeaderAuth() + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + if tt.wantErrStr != "" { + assert.ErrorContains(t, err, tt.wantErrStr) + } + } else { + assert.NoError(t, err) + } + }) + } +} + +func setupEDKMock(t *testing.T, providerID string) *mocks.MockEncryptedDataKey { + edk := mocks.NewMockEncryptedDataKey(t) + edk.EXPECT().KeyProvider().Return(model.WithKeyMeta(providerID, "test-info")).Twice() + edk.EXPECT().EncryptedDataKey().Return([]byte("test-edk")).Once() + return edk +} + +func TestEncrypter_generateHeader(t *testing.T) { + type mocksParams struct { + encMaterials *mocks.MockEncryptionMaterial + ser *formatmocks.MockSerializer + ciphertextBuf *mocks.MockEncryptionBuffer + } + tests := []struct { + name string + alg *suite.AlgorithmSuite + setupMocks func(t *testing.T, m mocksParams) + wantErr bool + wantErrType error + wantErrStr string + }{ + { + name: "EDK Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + edk1 := setupEDKMock(t, "aws-wrong") + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{edk1}).Once() + }, + wantErr: true, + wantErrStr: "EDK error", + }, + { + name: "Commitment Key Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + edk1 := setupEDKMock(t, "test-aws") + edk2 := setupEDKMock(t, "test-aws") + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{edk1, edk2}).Once() + dk := mocks.NewMockDataKey(t) + dk.EXPECT().DataKey().Return(nil).Once() + m.encMaterials.EXPECT().DataEncryptionKey().Return(dk).Once() + }, + wantErr: true, + wantErrStr: "calculate commitment key error", + }, + { + name: "Header Serialize Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + edk1 := setupEDKMock(t, "test-aws") + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{edk1}).Once() + dk := mocks.NewMockDataKey(t) + dk.EXPECT().DataKey().Return([]byte("test-data-key")).Once() + m.encMaterials.EXPECT().DataEncryptionKey().Return(dk).Once() + m.encMaterials.EXPECT().EncryptionContext().Return(nil).Once() + + m.ser.EXPECT().SerializeHeader(mock.Anything).Return(nil, assert.AnError).Once() + }, + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "header serialize error", + }, + { + name: "Valid Generate Header", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + edk1 := setupEDKMock(t, "test-aws") + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{edk1}).Once() + dk := mocks.NewMockDataKey(t) + dk.EXPECT().DataKey().Return([]byte("test-data-key")).Once() + m.encMaterials.EXPECT().DataEncryptionKey().Return(dk).Once() + m.encMaterials.EXPECT().EncryptionContext().Return(nil).Once() + + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + + m.ser.EXPECT().SerializeHeader(mock.Anything).Return(header, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + encMaterials := mocks.NewMockEncryptionMaterial(t) + ser := formatmocks.NewMockSerializer(t) + ciphertextBuf := mocks.NewMockEncryptionBuffer(t) + + tt.setupMocks(t, mocksParams{ + encMaterials: encMaterials, + ser: ser, + ciphertextBuf: ciphertextBuf, + }) + + e := &Encrypter{ + cfg: crypto.EncrypterConfig{ + Algorithm: tt.alg, + FrameLength: 4096, + }, + ser: ser, + ciphertextBuf: ciphertextBuf, + } + + err := e.generateHeader([]byte("test-message-id"), encMaterials) + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + if tt.wantErrStr != "" { + assert.ErrorContains(t, err, tt.wantErrStr) + } + assert.Nil(t, e.header) + } else { + assert.NoError(t, err) + assert.NotNil(t, e.header) + } + }) + } +} + +func TestEncrypter_prepareMessage(t *testing.T) { + type mocksParams struct { + cmm *mocks.MockCryptoMaterialsManager + encMaterials *mocks.MockEncryptionMaterial + ser *formatmocks.MockSerializer + ciphertextBuf *mocks.MockEncryptionBuffer + signer *signaturemock.MockSigner + rnd *randmocks.MockRandomGenerator + } + tests := []struct { + name string + clientCfgOpts []clientconfig.ConfigOptionFunc + alg *suite.AlgorithmSuite + setupMocks func(t *testing.T, m mocksParams) + wantErr bool + wantErrType error + wantErrStr string + }{ + { + name: "Policy Validation Error", + clientCfgOpts: []clientconfig.ConfigOptionFunc{ + clientconfig.WithCommitmentPolicy(suite.CommitmentPolicyRequireEncryptAllowDecrypt), + }, + alg: suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, + setupMocks: func(t *testing.T, m mocksParams) {}, + wantErr: true, + }, + { + name: "Get Encryption Materials Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + m.cmm.EXPECT().GetEncryptionMaterials(mock.Anything, mock.Anything). + Return(nil, assert.AnError).Once() + }, + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "encrypt materials", + }, + { + name: "CMM Max Keys Error", + clientCfgOpts: []clientconfig.ConfigOptionFunc{ + clientconfig.WithMaxEncryptedDataKeys(1), + }, + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{nil, nil}).Once() + m.cmm.EXPECT().GetEncryptionMaterials(mock.Anything, mock.Anything). + Return(m.encMaterials, nil).Once() + }, + wantErr: true, + wantErrStr: "max encrypted data keys exceeded", + }, + { + name: "MessageID CryptoRandom Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{nil}).Once() + m.encMaterials.EXPECT().SigningKey().Return(&ecdsa.PrivateKey{}).Once() + + m.cmm.EXPECT().GetEncryptionMaterials(mock.Anything, mock.Anything). + Return(m.encMaterials, nil).Once() + + m.rnd.EXPECT().CryptoRandomBytes(mock.Anything).Return(nil, assert.AnError).Once() + }, + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "messageID error", + }, + { + name: "Key Derivation Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{nil}).Once() + m.encMaterials.EXPECT().SigningKey().Return(&ecdsa.PrivateKey{}).Once() + + m.cmm.EXPECT().GetEncryptionMaterials(mock.Anything, mock.Anything). + Return(m.encMaterials, nil).Once() + + m.rnd.EXPECT().CryptoRandomBytes(mock.Anything).Return([]byte("message-ID"), nil).Once() + + dk := mocks.NewMockDataKey(t) + dk.EXPECT().DataKey().Return(nil).Once() + m.encMaterials.EXPECT().DataEncryptionKey().Return(dk).Once() + }, + wantErr: true, + wantErrStr: "key derivation failed", + }, + { + name: "Generate Header Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + edk1 := setupEDKMock(t, "aws-wrong") + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{edk1}).Twice() + m.encMaterials.EXPECT().SigningKey().Return(&ecdsa.PrivateKey{}).Once() + + m.cmm.EXPECT().GetEncryptionMaterials(mock.Anything, mock.Anything). + Return(m.encMaterials, nil).Once() + + m.rnd.EXPECT().CryptoRandomBytes(mock.Anything).Return([]byte("message-ID"), nil).Once() + + dk := mocks.NewMockDataKey(t) + dk.EXPECT().DataKey().Return([]byte("test-data-key")).Once() + m.encMaterials.EXPECT().DataEncryptionKey().Return(dk).Once() + }, + wantErr: true, + wantErrStr: "generate header error", + }, + { + name: "Valid Prepare Message", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + edk1 := setupEDKMock(t, "test-aws") + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{edk1}).Twice() + m.encMaterials.EXPECT().SigningKey().Return(&ecdsa.PrivateKey{}).Once() + + m.cmm.EXPECT().GetEncryptionMaterials(mock.Anything, mock.Anything). + Return(m.encMaterials, nil).Once() + + m.rnd.EXPECT().CryptoRandomBytes(mock.Anything).Return([]byte("message-ID"), nil).Once() + + dk := mocks.NewMockDataKey(t) + dk.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + m.encMaterials.EXPECT().DataEncryptionKey().Return(dk).Twice() + m.encMaterials.EXPECT().EncryptionContext().Return(nil).Once() + + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + + m.ser.EXPECT().SerializeHeader(mock.Anything).Return(header, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + + randomGen := randmocks.NewMockRandomGenerator(t) + defer func() { + rand.CryptoRandGen = rand.DefaultRandomGenerator{} + }() + rand.CryptoRandGen = randomGen + + cmm := mocks.NewMockCryptoMaterialsManager(t) + encMaterials := mocks.NewMockEncryptionMaterial(t) + ser := formatmocks.NewMockSerializer(t) + ciphertextBuf := mocks.NewMockEncryptionBuffer(t) + signer := signaturemock.NewMockSigner(t) + + tt.setupMocks(t, mocksParams{ + cmm: cmm, + encMaterials: encMaterials, + ser: ser, + ciphertextBuf: ciphertextBuf, + signer: signer, + rnd: randomGen, + }) + + signerFn := func(hashFn func() hash.Hash, c elliptic.Curve, signLen int, key *ecdsa.PrivateKey) signature.Signer { + return signer + } + + clientCfg, _ := clientconfig.NewConfigWithOpts(tt.clientCfgOpts...) + + e := &Encrypter{ + cmm: cmm, + cfg: crypto.EncrypterConfig{ + ClientCfg: *clientCfg, + Algorithm: tt.alg, + FrameLength: 4096, + }, + ser: ser, + ciphertextBuf: ciphertextBuf, + signerFn: signerFn, + } + + err := e.prepareMessage(ctx, 1024, nil) + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + if tt.wantErrStr != "" { + assert.ErrorContains(t, err, tt.wantErrStr) + } + assert.Nil(t, e.header) + } else { + assert.NoError(t, err) + assert.NotNil(t, e.header) + assert.NotEmpty(t, e._derivedDataKey) + } + }) + } +} + +func TestEncrypter_encryptData(t *testing.T) { + type mocksParams struct { + alg *suite.AlgorithmSuite + cmm *mocks.MockCryptoMaterialsManager + aeadEncrypter *encryptionmocks.MockAEADEncrypter + encMaterials *mocks.MockEncryptionMaterial + ser *formatmocks.MockSerializer + ciphertextBuf *mocks.MockEncryptionBuffer + signer *signaturemock.MockSigner + rnd *randmocks.MockRandomGenerator + } + tests := []struct { + name string + clientCfgOpts []clientconfig.ConfigOptionFunc + alg *suite.AlgorithmSuite + setupMocks func(t *testing.T, m mocksParams) + source []byte + wantErr bool + wantErrType error + wantErrStr string + }{ + { + name: "Empty Source Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) {}, + source: nil, + wantErr: true, + wantErrStr: "empty source", + }, + { + name: "Prepare Message Error", + clientCfgOpts: []clientconfig.ConfigOptionFunc{ + clientconfig.WithCommitmentPolicy(suite.CommitmentPolicyRequireEncryptAllowDecrypt), + }, + alg: suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, + setupMocks: func(t *testing.T, m mocksParams) {}, + source: make([]byte, 1023), + wantErr: true, + wantErrStr: "prepare message error", + }, + { + name: "Header Auth Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + edk1 := setupEDKMock(t, "test-aws") + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{edk1}).Twice() + m.encMaterials.EXPECT().SigningKey().Return(&ecdsa.PrivateKey{}).Once() + + m.cmm.EXPECT().GetEncryptionMaterials(mock.Anything, mock.Anything). + Return(m.encMaterials, nil).Once() + + m.rnd.EXPECT().CryptoRandomBytes(mock.Anything).Return([]byte("message-ID"), nil).Once() + + dk := mocks.NewMockDataKey(t) + dk.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + m.encMaterials.EXPECT().DataEncryptionKey().Return(dk).Twice() + m.encMaterials.EXPECT().EncryptionContext().Return(nil).Once() + + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + + m.ser.EXPECT().SerializeHeader(mock.Anything).Return(header, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + + m.aeadEncrypter.EXPECT().GenerateHeaderAuth(mock.Anything, mock.Anything). + Return(nil, nil, assert.AnError).Once() + }, + source: make([]byte, 1023), + wantErr: true, + wantErrStr: "encrypt error", + }, + { + name: "Encrypt Body Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + // prepare message + edk1 := setupEDKMock(t, "test-aws") + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{edk1}).Twice() + m.encMaterials.EXPECT().SigningKey().Return(&ecdsa.PrivateKey{}).Once() + + m.cmm.EXPECT().GetEncryptionMaterials(mock.Anything, mock.Anything). + Return(m.encMaterials, nil).Once() + + m.rnd.EXPECT().CryptoRandomBytes(mock.Anything).Return([]byte("message-ID"), nil).Once() + + // header + dk := mocks.NewMockDataKey(t) + dk.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + m.encMaterials.EXPECT().DataEncryptionKey().Return(dk).Twice() + m.encMaterials.EXPECT().EncryptionContext().Return(nil).Once() + + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + + m.ser.EXPECT().SerializeHeader(mock.Anything).Return(header, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // header auth + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + header.EXPECT().Version().Return(suite.V2).Once() + + m.aeadEncrypter.EXPECT().GenerateHeaderAuth(mock.Anything, mock.Anything). + Return([]byte("headerAuthTag"), []byte("auth-iv"), nil).Once() + + headerAuthData := formatmocks.NewMockMessageHeaderAuth(t) + headerAuthData.EXPECT().Bytes().Return([]byte("headerAuthData-bytes")).Once() + + m.ser.EXPECT().SerializeHeaderAuth(mock.Anything, mock.Anything, mock.Anything). + Return(headerAuthData, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // encrypt body + header.EXPECT().AlgorithmSuite(). + Return(m.alg).Once() + + m.ser.EXPECT().SerializeBody(mock.Anything, mock.Anything).Return(nil, assert.AnError).Once() + }, + source: make([]byte, 1023), + wantErr: true, + wantErrStr: "encrypt error", + }, + { + name: "Signer Sign Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + // prepare message + edk1 := setupEDKMock(t, "test-aws") + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{edk1}).Twice() + m.encMaterials.EXPECT().SigningKey().Return(&ecdsa.PrivateKey{}).Once() + + m.cmm.EXPECT().GetEncryptionMaterials(mock.Anything, mock.Anything). + Return(m.encMaterials, nil).Once() + + m.rnd.EXPECT().CryptoRandomBytes(mock.Anything).Return([]byte("message-ID"), nil).Once() + + // header + dk := mocks.NewMockDataKey(t) + dk.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + m.encMaterials.EXPECT().DataEncryptionKey().Return(dk).Twice() + m.encMaterials.EXPECT().EncryptionContext().Return(nil).Once() + + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + + m.ser.EXPECT().SerializeHeader(mock.Anything).Return(header, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // header auth + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + header.EXPECT().Version().Return(suite.V2).Once() + + m.aeadEncrypter.EXPECT().GenerateHeaderAuth(mock.Anything, mock.Anything). + Return([]byte("headerAuthTag"), []byte("auth-iv"), nil).Once() + + headerAuthData := formatmocks.NewMockMessageHeaderAuth(t) + headerAuthData.EXPECT().Bytes().Return([]byte("headerAuthData-bytes")).Once() + + m.ser.EXPECT().SerializeHeaderAuth(mock.Anything, mock.Anything, mock.Anything). + Return(headerAuthData, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // encrypt body + header.EXPECT().AlgorithmSuite(). + Return(m.alg).Once() + + body := formatmocks.NewMockMessageBody(t) + + m.ser.EXPECT().SerializeBody(mock.Anything, mock.Anything). + Return(body, nil).Once() + + m.aeadEncrypter.EXPECT().ConstructIV(mock.Anything).Return([]byte("testIv12byte")).Times(2) + + header.EXPECT().ContentType().Return(suite.FramedContent).Times(2) + header.EXPECT().MessageID().Return([]byte("test-message-id")).Times(2) + + m.aeadEncrypter.EXPECT().Encrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(make([]byte, 512), []byte("auth-Tag-16bytes"), nil).Times(2) + + body.EXPECT().AddFrame(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil).Times(2) + body.EXPECT().Bytes().Return([]byte("body-bytes")).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // signer + m.signer.EXPECT().Sign().Return(nil, assert.AnError).Once() + }, + source: make([]byte, 1023), + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "encrypt sign error", + }, + { + name: "Serialize Footer Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + // prepare message + edk1 := setupEDKMock(t, "test-aws") + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{edk1}).Twice() + m.encMaterials.EXPECT().SigningKey().Return(&ecdsa.PrivateKey{}).Once() + + m.cmm.EXPECT().GetEncryptionMaterials(mock.Anything, mock.Anything). + Return(m.encMaterials, nil).Once() + + m.rnd.EXPECT().CryptoRandomBytes(mock.Anything).Return([]byte("message-ID"), nil).Once() + + // header + dk := mocks.NewMockDataKey(t) + dk.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + m.encMaterials.EXPECT().DataEncryptionKey().Return(dk).Twice() + m.encMaterials.EXPECT().EncryptionContext().Return(nil).Once() + + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + + m.ser.EXPECT().SerializeHeader(mock.Anything).Return(header, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // header auth + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + header.EXPECT().Version().Return(suite.V2).Once() + + m.aeadEncrypter.EXPECT().GenerateHeaderAuth(mock.Anything, mock.Anything). + Return([]byte("headerAuthTag"), []byte("auth-iv"), nil).Once() + + headerAuthData := formatmocks.NewMockMessageHeaderAuth(t) + headerAuthData.EXPECT().Bytes().Return([]byte("headerAuthData-bytes")).Once() + + m.ser.EXPECT().SerializeHeaderAuth(mock.Anything, mock.Anything, mock.Anything). + Return(headerAuthData, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // encrypt body + header.EXPECT().AlgorithmSuite(). + Return(m.alg).Once() + + body := formatmocks.NewMockMessageBody(t) + + m.ser.EXPECT().SerializeBody(mock.Anything, mock.Anything). + Return(body, nil).Once() + + m.aeadEncrypter.EXPECT().ConstructIV(mock.Anything).Return([]byte("testIv12byte")).Times(2) + + header.EXPECT().ContentType().Return(suite.FramedContent).Times(2) + header.EXPECT().MessageID().Return([]byte("test-message-id")).Times(2) + + m.aeadEncrypter.EXPECT().Encrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(make([]byte, 512), []byte("auth-Tag-16bytes"), nil).Times(2) + + body.EXPECT().AddFrame(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil).Times(2) + body.EXPECT().Bytes().Return([]byte("body-bytes")).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // signer + m.signer.EXPECT().Sign().Return([]byte("signature"), nil).Once() + + m.ser.EXPECT().SerializeFooter(mock.Anything, mock.Anything). + Return(nil, assert.AnError).Once() + }, + source: make([]byte, 1023), + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "encrypt sign error", + }, + { + name: "Ciphertext Buffer Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + // prepare message + edk1 := setupEDKMock(t, "test-aws") + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{edk1}).Twice() + m.encMaterials.EXPECT().SigningKey().Return(&ecdsa.PrivateKey{}).Once() + + m.cmm.EXPECT().GetEncryptionMaterials(mock.Anything, mock.Anything). + Return(m.encMaterials, nil).Once() + + m.rnd.EXPECT().CryptoRandomBytes(mock.Anything).Return([]byte("message-ID"), nil).Once() + + // header + dk := mocks.NewMockDataKey(t) + dk.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + m.encMaterials.EXPECT().DataEncryptionKey().Return(dk).Twice() + m.encMaterials.EXPECT().EncryptionContext().Return(nil).Once() + + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + + m.ser.EXPECT().SerializeHeader(mock.Anything).Return(header, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // header auth + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + header.EXPECT().Version().Return(suite.V2).Once() + + m.aeadEncrypter.EXPECT().GenerateHeaderAuth(mock.Anything, mock.Anything). + Return([]byte("headerAuthTag"), []byte("auth-iv"), nil).Once() + + headerAuthData := formatmocks.NewMockMessageHeaderAuth(t) + headerAuthData.EXPECT().Bytes().Return([]byte("headerAuthData-bytes")).Once() + + m.ser.EXPECT().SerializeHeaderAuth(mock.Anything, mock.Anything, mock.Anything). + Return(headerAuthData, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // encrypt body + header.EXPECT().AlgorithmSuite(). + Return(m.alg).Once() + + body := formatmocks.NewMockMessageBody(t) + + m.ser.EXPECT().SerializeBody(mock.Anything, mock.Anything). + Return(body, nil).Once() + + m.aeadEncrypter.EXPECT().ConstructIV(mock.Anything).Return([]byte("testIv12byte")).Times(2) + + header.EXPECT().ContentType().Return(suite.FramedContent).Times(2) + header.EXPECT().MessageID().Return([]byte("test-message-id")).Times(2) + + m.aeadEncrypter.EXPECT().Encrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(make([]byte, 512), []byte("auth-Tag-16bytes"), nil).Times(2) + + body.EXPECT().AddFrame(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil).Times(2) + body.EXPECT().Bytes().Return([]byte("body-bytes")).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // signer + m.signer.EXPECT().Sign().Return([]byte("signature"), nil).Once() + + // footer + footer := formatmocks.NewMockMessageFooter(t) + footer.EXPECT().Bytes().Return([]byte("footer-bytes")).Once() + m.ser.EXPECT().SerializeFooter(mock.Anything, mock.Anything). + Return(footer, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, assert.AnError).Once() + }, + source: make([]byte, 1023), + wantErr: true, + wantErrType: assert.AnError, + }, + { + name: "Ciphertext Buffer Read Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + // prepare message + edk1 := setupEDKMock(t, "test-aws") + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{edk1}).Twice() + m.encMaterials.EXPECT().SigningKey().Return(&ecdsa.PrivateKey{}).Once() + + m.cmm.EXPECT().GetEncryptionMaterials(mock.Anything, mock.Anything). + Return(m.encMaterials, nil).Once() + + m.rnd.EXPECT().CryptoRandomBytes(mock.Anything).Return([]byte("message-ID"), nil).Once() + + // header + dk := mocks.NewMockDataKey(t) + dk.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + m.encMaterials.EXPECT().DataEncryptionKey().Return(dk).Twice() + m.encMaterials.EXPECT().EncryptionContext().Return(nil).Once() + + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + + m.ser.EXPECT().SerializeHeader(mock.Anything).Return(header, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // header auth + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + header.EXPECT().Version().Return(suite.V2).Once() + + m.aeadEncrypter.EXPECT().GenerateHeaderAuth(mock.Anything, mock.Anything). + Return([]byte("headerAuthTag"), []byte("auth-iv"), nil).Once() + + headerAuthData := formatmocks.NewMockMessageHeaderAuth(t) + headerAuthData.EXPECT().Bytes().Return([]byte("headerAuthData-bytes")).Once() + + m.ser.EXPECT().SerializeHeaderAuth(mock.Anything, mock.Anything, mock.Anything). + Return(headerAuthData, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // encrypt body + header.EXPECT().AlgorithmSuite(). + Return(m.alg).Once() + + body := formatmocks.NewMockMessageBody(t) + + m.ser.EXPECT().SerializeBody(mock.Anything, mock.Anything). + Return(body, nil).Once() + + m.aeadEncrypter.EXPECT().ConstructIV(mock.Anything).Return([]byte("testIv12byte")).Times(2) + + header.EXPECT().ContentType().Return(suite.FramedContent).Times(2) + header.EXPECT().MessageID().Return([]byte("test-message-id")).Times(2) + + m.aeadEncrypter.EXPECT().Encrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(make([]byte, 512), []byte("auth-Tag-16bytes"), nil).Times(2) + + body.EXPECT().AddFrame(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil).Times(2) + body.EXPECT().Bytes().Return([]byte("body-bytes")).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // signer + m.signer.EXPECT().Sign().Return([]byte("signature"), nil).Once() + + // footer + footer := formatmocks.NewMockMessageFooter(t) + footer.EXPECT().Bytes().Return([]byte("footer-bytes")).Once() + m.ser.EXPECT().SerializeFooter(mock.Anything, mock.Anything). + Return(footer, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.ciphertextBuf.EXPECT().Len().Return(1023).Once() + m.ciphertextBuf.EXPECT().Read(mock.Anything).Return(0, assert.AnError).Once() + }, + source: make([]byte, 1023), + wantErr: true, + wantErrType: assert.AnError, + wantErrStr: "ciphertext read error", + }, + { + name: "Valid Encrypt Data", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + // prepare message + edk1 := setupEDKMock(t, "test-aws") + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{edk1}).Twice() + m.encMaterials.EXPECT().SigningKey().Return(&ecdsa.PrivateKey{}).Once() + + m.cmm.EXPECT().GetEncryptionMaterials(mock.Anything, mock.Anything). + Return(m.encMaterials, nil).Once() + + m.rnd.EXPECT().CryptoRandomBytes(mock.Anything).Return([]byte("message-ID"), nil).Once() + + // header + dk := mocks.NewMockDataKey(t) + dk.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + m.encMaterials.EXPECT().DataEncryptionKey().Return(dk).Twice() + m.encMaterials.EXPECT().EncryptionContext().Return(nil).Once() + + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + + m.ser.EXPECT().SerializeHeader(mock.Anything).Return(header, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // header auth + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + header.EXPECT().Version().Return(suite.V2).Once() + + m.aeadEncrypter.EXPECT().GenerateHeaderAuth(mock.Anything, mock.Anything). + Return([]byte("headerAuthTag"), []byte("auth-iv"), nil).Once() + + headerAuthData := formatmocks.NewMockMessageHeaderAuth(t) + headerAuthData.EXPECT().Bytes().Return([]byte("headerAuthData-bytes")).Once() + + m.ser.EXPECT().SerializeHeaderAuth(mock.Anything, mock.Anything, mock.Anything). + Return(headerAuthData, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // encrypt body + header.EXPECT().AlgorithmSuite(). + Return(m.alg).Once() + + body := formatmocks.NewMockMessageBody(t) + + m.ser.EXPECT().SerializeBody(mock.Anything, mock.Anything). + Return(body, nil).Once() + + m.aeadEncrypter.EXPECT().ConstructIV(mock.Anything).Return([]byte("testIv12byte")).Times(2) + + header.EXPECT().ContentType().Return(suite.FramedContent).Times(2) + header.EXPECT().MessageID().Return([]byte("test-message-id")).Times(2) + + m.aeadEncrypter.EXPECT().Encrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(make([]byte, 512), []byte("auth-Tag-16bytes"), nil).Times(2) + + body.EXPECT().AddFrame(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil).Times(2) + body.EXPECT().Bytes().Return([]byte("body-bytes")).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // signer + m.signer.EXPECT().Sign().Return([]byte("signature"), nil).Once() + + // footer + footer := formatmocks.NewMockMessageFooter(t) + footer.EXPECT().Bytes().Return([]byte("footer-bytes")).Once() + m.ser.EXPECT().SerializeFooter(mock.Anything, mock.Anything). + Return(footer, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.ciphertextBuf.EXPECT().Len().Return(1023).Once() + m.ciphertextBuf.EXPECT().Read(mock.Anything).Return(1023, nil).Once() + m.ciphertextBuf.EXPECT().Reset().Return().Once() + }, + source: make([]byte, 1023), + wantErr: false, + //wantErrType: assert.AnError, + //wantErrStr: "ciphertext read error", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + + randomGen := randmocks.NewMockRandomGenerator(t) + defer func() { + rand.CryptoRandGen = rand.DefaultRandomGenerator{} + }() + rand.CryptoRandGen = randomGen + + cmm := mocks.NewMockCryptoMaterialsManager(t) + aeadEncrypter := encryptionmocks.NewMockAEADEncrypter(t) + encMaterials := mocks.NewMockEncryptionMaterial(t) + ser := formatmocks.NewMockSerializer(t) + ciphertextBuf := mocks.NewMockEncryptionBuffer(t) + signer := signaturemock.NewMockSigner(t) + + tt.setupMocks(t, mocksParams{ + alg: tt.alg, + cmm: cmm, + aeadEncrypter: aeadEncrypter, + encMaterials: encMaterials, + ser: ser, + ciphertextBuf: ciphertextBuf, + signer: signer, + rnd: randomGen, + }) + + signerFn := func(hashFn func() hash.Hash, c elliptic.Curve, signLen int, key *ecdsa.PrivateKey) signature.Signer { + return signer + } + + clientCfg, _ := clientconfig.NewConfigWithOpts(tt.clientCfgOpts...) + + e := &Encrypter{ + cmm: cmm, + aeadEncrypter: aeadEncrypter, + cfg: crypto.EncrypterConfig{ + ClientCfg: *clientCfg, + Algorithm: tt.alg, + FrameLength: 512, + }, + ser: ser, + ciphertextBuf: ciphertextBuf, + signerFn: signerFn, + } + + ciphertext, h, err := e.encryptData(ctx, tt.source, nil) + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + if tt.wantErrStr != "" { + assert.ErrorContains(t, err, tt.wantErrStr) + } + assert.Empty(t, ciphertext) + assert.Nil(t, h) + } else { + assert.NoError(t, err) + assert.NotEmpty(t, ciphertext) + assert.NotNil(t, h) + } + }) + } +} + +func TestEncrypter_Encrypt(t *testing.T) { + type mocksParams struct { + alg *suite.AlgorithmSuite + cmm *mocks.MockCryptoMaterialsManager + aeadEncrypter *encryptionmocks.MockAEADEncrypter + encMaterials *mocks.MockEncryptionMaterial + ser *formatmocks.MockSerializer + ciphertextBuf *mocks.MockEncryptionBuffer + signer *signaturemock.MockSigner + rnd *randmocks.MockRandomGenerator + } + tests := []struct { + name string + clientCfgOpts []clientconfig.ConfigOptionFunc + alg *suite.AlgorithmSuite + setupMocks func(t *testing.T, m mocksParams) + source []byte + wantErr bool + wantErrType error + wantErrStr string + }{ + { + name: "Encrypt Error", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) {}, + source: nil, + wantErr: true, + wantErrType: crypto.ErrEncryption, + wantErrStr: "SDK error", + }, + { + name: "Encrypt Success", + alg: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, + setupMocks: func(t *testing.T, m mocksParams) { + // prepare message + edk1 := setupEDKMock(t, "test-aws") + m.encMaterials.EXPECT().EncryptedDataKeys().Return([]model.EncryptedDataKeyI{edk1}).Twice() + m.encMaterials.EXPECT().SigningKey().Return(&ecdsa.PrivateKey{}).Once() + + m.cmm.EXPECT().GetEncryptionMaterials(mock.Anything, mock.Anything). + Return(m.encMaterials, nil).Once() + + m.rnd.EXPECT().CryptoRandomBytes(mock.Anything).Return([]byte("message-ID"), nil).Once() + + // header + dk := mocks.NewMockDataKey(t) + dk.EXPECT().DataKey().Return([]byte("test-data-key")).Twice() + m.encMaterials.EXPECT().DataEncryptionKey().Return(dk).Twice() + m.encMaterials.EXPECT().EncryptionContext().Return(nil).Once() + + header := formatmocks.NewMockMessageHeader(t) + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + + m.ser.EXPECT().SerializeHeader(mock.Anything).Return(header, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // header auth + header.EXPECT().Bytes().Return([]byte("header-bytes")).Once() + header.EXPECT().Version().Return(suite.V2).Once() + + m.aeadEncrypter.EXPECT().GenerateHeaderAuth(mock.Anything, mock.Anything). + Return([]byte("headerAuthTag"), []byte("auth-iv"), nil).Once() + + headerAuthData := formatmocks.NewMockMessageHeaderAuth(t) + headerAuthData.EXPECT().Bytes().Return([]byte("headerAuthData-bytes")).Once() + + m.ser.EXPECT().SerializeHeaderAuth(mock.Anything, mock.Anything, mock.Anything). + Return(headerAuthData, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // encrypt body + header.EXPECT().AlgorithmSuite(). + Return(m.alg).Once() + + body := formatmocks.NewMockMessageBody(t) + + m.ser.EXPECT().SerializeBody(mock.Anything, mock.Anything). + Return(body, nil).Once() + + m.aeadEncrypter.EXPECT().ConstructIV(mock.Anything).Return([]byte("testIv12byte")).Times(2) + + header.EXPECT().ContentType().Return(suite.FramedContent).Times(2) + header.EXPECT().MessageID().Return([]byte("test-message-id")).Times(2) + + m.aeadEncrypter.EXPECT().Encrypt(mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(make([]byte, 512), []byte("auth-Tag-16bytes"), nil).Times(2) + + body.EXPECT().AddFrame(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil).Times(2) + body.EXPECT().Bytes().Return([]byte("body-bytes")).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.signer.EXPECT().Write(mock.Anything).Return(0, nil).Once() + + // signer + m.signer.EXPECT().Sign().Return([]byte("signature"), nil).Once() + + // footer + footer := formatmocks.NewMockMessageFooter(t) + footer.EXPECT().Bytes().Return([]byte("footer-bytes")).Once() + m.ser.EXPECT().SerializeFooter(mock.Anything, mock.Anything). + Return(footer, nil).Once() + + m.ciphertextBuf.EXPECT().Write(mock.Anything).Return(0, nil).Once() + m.ciphertextBuf.EXPECT().Len().Return(1023).Once() + m.ciphertextBuf.EXPECT().Read(mock.Anything).Return(1023, nil).Once() + m.ciphertextBuf.EXPECT().Reset().Return().Once() + }, + source: make([]byte, 1023), + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + + randomGen := randmocks.NewMockRandomGenerator(t) + defer func() { + rand.CryptoRandGen = rand.DefaultRandomGenerator{} + }() + rand.CryptoRandGen = randomGen + + cmm := mocks.NewMockCryptoMaterialsManager(t) + aeadEncrypter := encryptionmocks.NewMockAEADEncrypter(t) + encMaterials := mocks.NewMockEncryptionMaterial(t) + ser := formatmocks.NewMockSerializer(t) + ciphertextBuf := mocks.NewMockEncryptionBuffer(t) + signer := signaturemock.NewMockSigner(t) + + tt.setupMocks(t, mocksParams{ + alg: tt.alg, + cmm: cmm, + aeadEncrypter: aeadEncrypter, + encMaterials: encMaterials, + ser: ser, + ciphertextBuf: ciphertextBuf, + signer: signer, + rnd: randomGen, + }) + + signerFn := func(hashFn func() hash.Hash, c elliptic.Curve, signLen int, key *ecdsa.PrivateKey) signature.Signer { + return signer + } + + clientCfg, _ := clientconfig.NewConfigWithOpts(tt.clientCfgOpts...) + + e := &Encrypter{ + cmm: cmm, + aeadEncrypter: aeadEncrypter, + cfg: crypto.EncrypterConfig{ + ClientCfg: *clientCfg, + Algorithm: tt.alg, + FrameLength: 512, + }, + ser: ser, + ciphertextBuf: ciphertextBuf, + signerFn: signerFn, + } + + ciphertext, h, err := e.Encrypt(ctx, tt.source, nil) + if tt.wantErr { + assert.Error(t, err) + if tt.wantErrType != nil { + assert.ErrorIs(t, err, tt.wantErrType) + } + if tt.wantErrStr != "" { + assert.ErrorContains(t, err, tt.wantErrStr) + } + assert.Empty(t, ciphertext) + assert.Nil(t, h) + assert.Nil(t, e.header) + assert.Empty(t, e._derivedDataKey) + } else { + assert.NoError(t, err) + assert.NotEmpty(t, ciphertext) + assert.NotNil(t, h) + assert.NotNil(t, e.header) + assert.Empty(t, e._derivedDataKey) + } + }) + } +} diff --git a/pkg/crypto/hasher/hash.go b/pkg/internal/crypto/hasher/hash.go similarity index 100% rename from pkg/crypto/hasher/hash.go rename to pkg/internal/crypto/hasher/hash.go diff --git a/pkg/crypto/hasher/hash_test.go b/pkg/internal/crypto/hasher/hash_test.go similarity index 100% rename from pkg/crypto/hasher/hash_test.go rename to pkg/internal/crypto/hasher/hash_test.go diff --git a/pkg/crypto/signature/signer.go b/pkg/internal/crypto/signature/signer.go similarity index 84% rename from pkg/crypto/signature/signer.go rename to pkg/internal/crypto/signature/signer.go index 3e26024..ecf07c3 100644 --- a/pkg/crypto/signature/signer.go +++ b/pkg/internal/crypto/signature/signer.go @@ -12,7 +12,7 @@ import ( "github.com/rs/zerolog/log" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/crypto/hasher" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/crypto/hasher" "github.com/chainifynet/aws-encryption-sdk-go/pkg/utils/rand" ) @@ -33,7 +33,9 @@ type ECCSigner struct { var _ Signer = (*ECCSigner)(nil) -func NewECCSigner(hashFn func() hash.Hash, c elliptic.Curve, signLen int, key *ecdsa.PrivateKey) *ECCSigner { +type SignerFunc func(hashFn func() hash.Hash, c elliptic.Curve, signLen int, key *ecdsa.PrivateKey) Signer + +func NewECCSigner(hashFn func() hash.Hash, c elliptic.Curve, signLen int, key *ecdsa.PrivateKey) Signer { return &ECCSigner{ Hasher: hasher.NewECCHasher(hashFn, c), signLen: signLen, diff --git a/pkg/crypto/signature/signer_test.go b/pkg/internal/crypto/signature/signer_test.go similarity index 94% rename from pkg/crypto/signature/signer_test.go rename to pkg/internal/crypto/signature/signer_test.go index 19b2b8a..352c426 100644 --- a/pkg/crypto/signature/signer_test.go +++ b/pkg/internal/crypto/signature/signer_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/crypto/hasher" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/crypto/hasher" ) func TestNewECCSigner(t *testing.T) { diff --git a/pkg/crypto/signature/verifier.go b/pkg/internal/crypto/signature/verifier.go similarity index 84% rename from pkg/crypto/signature/verifier.go rename to pkg/internal/crypto/signature/verifier.go index 1688f20..923e540 100644 --- a/pkg/crypto/signature/verifier.go +++ b/pkg/internal/crypto/signature/verifier.go @@ -10,7 +10,7 @@ import ( "fmt" "hash" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/crypto/hasher" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/crypto/hasher" ) var ( @@ -30,7 +30,9 @@ type ECCVerifier struct { var _ Verifier = (*ECCVerifier)(nil) -func NewECCVerifier(hashFn func() hash.Hash, c elliptic.Curve) *ECCVerifier { +type VerifierFunc func(hashFn func() hash.Hash, c elliptic.Curve) Verifier + +func NewECCVerifier(hashFn func() hash.Hash, c elliptic.Curve) Verifier { return &ECCVerifier{ Hasher: hasher.NewECCHasher(hashFn, c), } diff --git a/pkg/crypto/signature/verifier_test.go b/pkg/internal/crypto/signature/verifier_test.go similarity index 97% rename from pkg/crypto/signature/verifier_test.go rename to pkg/internal/crypto/signature/verifier_test.go index 007d2c8..0e2bfb1 100644 --- a/pkg/crypto/signature/verifier_test.go +++ b/pkg/internal/crypto/signature/verifier_test.go @@ -14,7 +14,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/chainifynet/aws-encryption-sdk-go/pkg/crypto/hasher" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/internal/crypto/hasher" ) func TestNewECCVerifier(t *testing.T) { diff --git a/pkg/model/encryption.go b/pkg/model/encryption.go new file mode 100644 index 0000000..d76ca4c --- /dev/null +++ b/pkg/model/encryption.go @@ -0,0 +1,27 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package model + +import ( + "context" + "io" + + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" +) + +type DecryptionHandler interface { + Decrypt(ctx context.Context, ciphertext []byte) ([]byte, format.MessageHeader, error) +} + +type EncryptionHandler interface { + Encrypt(ctx context.Context, source []byte, ec suite.EncryptionContext) ([]byte, format.MessageHeader, error) +} + +type EncryptionBuffer interface { + io.ReadWriter + Bytes() []byte + Len() int + Reset() +} diff --git a/pkg/model/format/body.go b/pkg/model/format/body.go new file mode 100644 index 0000000..5cbe22e --- /dev/null +++ b/pkg/model/format/body.go @@ -0,0 +1,19 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package format + +type BodyFrame interface { + Serializable + IsFinal() bool + SequenceNumber() int + IV() []byte + EncryptedContent() []byte + AuthenticationTag() []byte +} + +type MessageBody interface { + Serializable + Frames() []BodyFrame + AddFrame(final bool, seqNum int, IV []byte, contentLength int, ciphertext, authTag []byte) error +} diff --git a/pkg/model/format/footer.go b/pkg/model/format/footer.go new file mode 100644 index 0000000..465adac --- /dev/null +++ b/pkg/model/format/footer.go @@ -0,0 +1,10 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package format + +type MessageFooter interface { + Serializable + SignLen() int + Signature() []byte +} diff --git a/pkg/model/format/header.go b/pkg/model/format/header.go index 88d636d..85d7eb1 100644 --- a/pkg/model/format/header.go +++ b/pkg/model/format/header.go @@ -50,3 +50,13 @@ type MessageHeaderAuth interface { AuthData() []byte IV() []byte // present only in V1 } + +type HeaderParams struct { + AlgorithmSuite *suite.AlgorithmSuite + MessageID []byte + EncryptionContext suite.EncryptionContext + EncryptedDataKeys []MessageEDK + ContentType suite.ContentType + FrameLength int + AlgorithmSuiteData []byte +} diff --git a/pkg/model/format/serialization.go b/pkg/model/format/serialization.go new file mode 100644 index 0000000..4e8d945 --- /dev/null +++ b/pkg/model/format/serialization.go @@ -0,0 +1,23 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package format + +import ( + "bytes" + + "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" +) + +type Deserializer interface { + DeserializeHeader(buf *bytes.Buffer, maxEncryptedDataKeys int) (MessageHeader, MessageHeaderAuth, error) + DeserializeBody(buf *bytes.Buffer, algorithm *suite.AlgorithmSuite, frameLen int) (MessageBody, error) + DeserializeFooter(alg *suite.AlgorithmSuite, buf *bytes.Buffer) (MessageFooter, error) +} + +type Serializer interface { + SerializeHeader(p HeaderParams) (MessageHeader, error) + SerializeHeaderAuth(v suite.MessageFormatVersion, iv, authData []byte) (MessageHeaderAuth, error) + SerializeBody(alg *suite.AlgorithmSuite, frameLength int) (MessageBody, error) + SerializeFooter(alg *suite.AlgorithmSuite, signature []byte) (MessageFooter, error) +} diff --git a/pkg/serialization/deserialize.go b/pkg/serialization/deserialize.go index a4e6b70..dc758e6 100644 --- a/pkg/serialization/deserialize.go +++ b/pkg/serialization/deserialize.go @@ -5,13 +5,18 @@ package serialization import ( "bytes" - "errors" "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" ) -func DeserializeHeader(buf *bytes.Buffer, maxEncryptedDataKeys int) (format.MessageHeader, format.MessageHeaderAuth, error) { //nolint:revive +type Deserializer struct{} + +func NewDeserializer() format.Deserializer { + return &Deserializer{} +} + +func (d *Deserializer) DeserializeHeader(buf *bytes.Buffer, maxEncryptedDataKeys int) (format.MessageHeader, format.MessageHeaderAuth, error) { header, err := deserializeHeader(buf) if err != nil { return nil, nil, err @@ -29,20 +34,10 @@ func DeserializeHeader(buf *bytes.Buffer, maxEncryptedDataKeys int) (format.Mess return header, authData, nil } -//goland:noinspection GoExportedFuncWithUnexportedType -func DeserializeBody(buf *bytes.Buffer, algorithm *suite.AlgorithmSuite, frameLen int) (*body, error) { //nolint:revive - if buf.Len() < frameFieldBytes { - return nil, errors.New("malformed message") - } - deserializedBody, err := MessageBody.fromBuffer(algorithm, frameLen, buf) - if err != nil { - return nil, err - } - - // TODO andrew move this into footer deserialize - if algorithm.IsSigning() && buf.Len() > (lenFieldBytes+algorithm.Authentication.SignatureLen) { - return nil, errors.New("malformed large message") - } +func (d *Deserializer) DeserializeBody(buf *bytes.Buffer, algorithm *suite.AlgorithmSuite, frameLen int) (format.MessageBody, error) { + return deserializeBody(algorithm, frameLen, buf) +} - return deserializedBody, nil +func (d *Deserializer) DeserializeFooter(alg *suite.AlgorithmSuite, buf *bytes.Buffer) (format.MessageFooter, error) { + return deserializeFooter(alg, buf) } diff --git a/pkg/serialization/headerauthentication.go b/pkg/serialization/headerauthentication.go index 3da5598..321becd 100644 --- a/pkg/serialization/headerauthentication.go +++ b/pkg/serialization/headerauthentication.go @@ -30,7 +30,7 @@ func (ha headerAuth) IV() []byte { return ha.iv } -func NewHeaderAuth(v suite.MessageFormatVersion, iv, authData []byte) (format.MessageHeaderAuth, error) { +func newHeaderAuth(v suite.MessageFormatVersion, iv, authData []byte) (format.MessageHeaderAuth, error) { // TODO validate MessageFormatVersion and iv if len(authData) != headerAuthDataLen { return nil, fmt.Errorf("incorrect len of authData %d", len(authData)) @@ -74,5 +74,5 @@ func deserializeHeaderAuth(v suite.MessageFormatVersion, buf *bytes.Buffer) (for authData := buf.Next(headerAuthDataLen) // TODO copy authData into new slice, otherwise authData capacity is equal to buf capacity - return NewHeaderAuth(v, iv, authData) + return newHeaderAuth(v, iv, authData) } diff --git a/pkg/serialization/headerauthentication_test.go b/pkg/serialization/headerauthentication_test.go index 78026ba..b3cb4bf 100644 --- a/pkg/serialization/headerauthentication_test.go +++ b/pkg/serialization/headerauthentication_test.go @@ -35,13 +35,13 @@ func Test_NewHeaderAuth(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewHeaderAuth(tt.args.version, tt.args.iv, tt.args.authData) + got, err := newHeaderAuth(tt.args.version, tt.args.iv, tt.args.authData) if err != nil && tt.wantErr { - assert.Errorf(t, err, "NewHeaderAuth(%#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, "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) + 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) }) } } diff --git a/pkg/serialization/messagebody.go b/pkg/serialization/messagebody.go index 1e6e413..01b06c1 100644 --- a/pkg/serialization/messagebody.go +++ b/pkg/serialization/messagebody.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" + "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" ) @@ -23,14 +24,10 @@ var ( finalFrameIndicator = []uint8{0xFF, 0xFF, 0xFF, 0xFF} // 4, An indicator for the final frame. The value is encoded as the 4 bytes FF FF FF FF in hexadecimal notation. ) -var MessageBody messageBody //nolint:gochecknoglobals - -type messageBody struct{} - type body struct { algorithmSuite *suite.AlgorithmSuite frameLength int - frames []frame + frames []format.BodyFrame sequenceNumber int } @@ -43,7 +40,7 @@ type frame struct { authenticationTag []byte // 16, authenticationTag for the frame } -func (mb messageBody) NewBody(algorithmSuite *suite.AlgorithmSuite, frameLength int) (*body, error) { +func newBody(algorithmSuite *suite.AlgorithmSuite, frameLength int) (*body, error) { if algorithmSuite == nil { return nil, fmt.Errorf("empty algorithm suite: %w", errBodyDeserialize) } @@ -53,12 +50,12 @@ func (mb messageBody) NewBody(algorithmSuite *suite.AlgorithmSuite, frameLength return &body{ algorithmSuite: algorithmSuite, frameLength: frameLength, - frames: []frame{}, + frames: make([]format.BodyFrame, 0), sequenceNumber: 1, }, nil } -func (mb messageBody) fromBuffer(algorithmSuite *suite.AlgorithmSuite, frameLength int, buf *bytes.Buffer) (*body, error) { +func deserializeBody(algorithmSuite *suite.AlgorithmSuite, frameLength int, buf *bytes.Buffer) (*body, error) { if buf == nil { return nil, fmt.Errorf("empty buffer: %w", errBodyDeserialize) } @@ -67,7 +64,7 @@ func (mb messageBody) fromBuffer(algorithmSuite *suite.AlgorithmSuite, frameLeng if buf.Len() < frameFieldBytes { return nil, fmt.Errorf("malformed message: %w", errBodyDeserialize) } - data, errBody := mb.NewBody(algorithmSuite, frameLength) + data, errBody := newBody(algorithmSuite, frameLength) if errBody != nil { return nil, errBody } @@ -93,24 +90,24 @@ func (mb messageBody) fromBuffer(algorithmSuite *suite.AlgorithmSuite, frameLeng return data, nil } -func (b *body) len() int { +func (b *body) Len() int { var framesLength int for _, f := range b.frames { - framesLength += f.len() + framesLength += f.Len() } return framesLength } func (b *body) Bytes() []byte { var buf []byte - buf = make([]byte, 0, b.len()) + buf = make([]byte, 0, b.Len()) for _, f := range b.frames { buf = append(buf, f.Bytes()...) } return buf } -func (b *body) Frames() []frame { +func (b *body) Frames() []format.BodyFrame { return b.frames } @@ -129,7 +126,7 @@ func (b *body) AddFrame(final bool, seqNum int, IV []byte, contentLength int, ci return fmt.Errorf("contentLength mismatch: %w", errBodySerialize) } - b.frames = append(b.frames, frame{ + b.frames = append(b.frames, &frame{ isFinal: final, sequenceNumber: seqNum, iV: IV, @@ -141,12 +138,12 @@ func (b *body) AddFrame(final bool, seqNum int, IV []byte, contentLength int, ci return nil } -func (b *body) readFrame(buf *bytes.Buffer) (frame, error) { +func (b *body) readFrame(buf *bytes.Buffer) (*frame, error) { if buf == nil { - return frame{}, fmt.Errorf("empty buffer: %w", errFrame) + return nil, fmt.Errorf("empty buffer: %w", errFrame) } if buf.Len() < frameFieldBytes { - return frame{}, fmt.Errorf("empty buffer, cant read seqNum or finalFrameIndicator: %w", errFrame) + return nil, fmt.Errorf("empty buffer, cant read seqNum or finalFrameIndicator: %w", errFrame) } sequenceNumberOrFinal := buf.Next(frameFieldBytes) @@ -162,16 +159,16 @@ func (b *body) readFrame(buf *bytes.Buffer) (frame, error) { minBufferFrame := frameFieldBytes + b.algorithmSuite.EncryptionSuite.IVLen + frameFieldBytes + b.algorithmSuite.EncryptionSuite.AuthLen if buf.Len() < minBufferFrame { - return frame{}, fmt.Errorf("empty buffer, cant read a final frame: %w", errFrame) + return nil, fmt.Errorf("empty buffer, cant read a final frame: %w", errFrame) } sequenceNumber, err := fieldReader.ReadFrameField(buf) // checked by minBufferFrame if err != nil { - return frame{}, fmt.Errorf("cant read sequenceNumber: %w", errors.Join(errFrame, err)) + return nil, fmt.Errorf("cant read sequenceNumber: %w", errors.Join(errFrame, err)) } IV := buf.Next(b.algorithmSuite.EncryptionSuite.IVLen) // checked by minBufferFrame contentLength, err := fieldReader.ReadFrameField(buf) // checked by minBufferFrame if err != nil { - return frame{}, fmt.Errorf("cant read contentLength: %w", errors.Join(errFrame, err)) + return nil, fmt.Errorf("cant read contentLength: %w", errors.Join(errFrame, err)) } // contentLength of final frame will be 0 if both conditions are met: @@ -179,17 +176,17 @@ func (b *body) readFrame(buf *bytes.Buffer) (frame, error) { // - encryptedContent is empty // otherwise make sure buffer has enough bytes to read encryptedContent if contentLength != 0 && buf.Len() < contentLength { - return frame{}, fmt.Errorf("empty buffer, cant read encryptedContent: %w", errFrame) + return nil, fmt.Errorf("empty buffer, cant read encryptedContent: %w", errFrame) } // with contentLength 0, it will return an empty slice. // The buffer's internal read position will not be advanced. nothing to worry about here. encryptedContent := buf.Next(contentLength) if buf.Len() < b.algorithmSuite.EncryptionSuite.AuthLen { - return frame{}, fmt.Errorf("empty buffer, cant read authenticationTag: %w", errFrame) + return nil, fmt.Errorf("empty buffer, cant read authenticationTag: %w", errFrame) } authenticationTag := buf.Next(b.algorithmSuite.EncryptionSuite.AuthLen) - return frame{ + return &frame{ isFinal: true, sequenceNumber: sequenceNumber, iV: IV, @@ -207,13 +204,13 @@ func (b *body) readFrame(buf *bytes.Buffer) (frame, error) { // 12 + N + 16 = 36 minimum bytes must be available in buffer in order to read a frame minBufferFrame := b.algorithmSuite.EncryptionSuite.IVLen + b.frameLength + b.algorithmSuite.EncryptionSuite.AuthLen if buf.Len() < minBufferFrame { - return frame{}, fmt.Errorf("empty buffer, cant read a regular frame: %w", errFrame) + return nil, fmt.Errorf("empty buffer, cant read a regular frame: %w", errFrame) } sequenceNumber := conv.FromBytes.Uint32IntBigEndian(sequenceNumberOrFinal) IV := buf.Next(b.algorithmSuite.EncryptionSuite.IVLen) encryptedContent := buf.Next(b.frameLength) authenticationTag := buf.Next(b.algorithmSuite.EncryptionSuite.AuthLen) - return frame{ + return &frame{ isFinal: false, sequenceNumber: sequenceNumber, iV: IV, @@ -224,7 +221,7 @@ func (b *body) readFrame(buf *bytes.Buffer) (frame, error) { } } -func (bf frame) len() int { +func (bf frame) Len() int { if bf.isFinal { return 4 + // isFinal 4 + // sequenceNumber @@ -242,7 +239,7 @@ func (bf frame) len() int { func (bf frame) Bytes() []byte { var buf []byte - buf = make([]byte, 0, bf.len()) + buf = make([]byte, 0, bf.Len()) if bf.isFinal { buf = append(buf, finalFrameIndicator...) } diff --git a/pkg/serialization/messagebody_test.go b/pkg/serialization/messagebody_test.go index 3c8ee58..553899c 100644 --- a/pkg/serialization/messagebody_test.go +++ b/pkg/serialization/messagebody_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" ) @@ -76,7 +77,7 @@ func Test_frame_len(t *testing.T) { encryptedContent: tt.fields.encryptedContent, authenticationTag: tt.fields.authenticationTag, } - assert.Equalf(t, tt.want, bf.len(), "len()") + assert.Equalf(t, tt.want, bf.Len(), "Len()") }) } } @@ -315,16 +316,15 @@ func Test_messageBody_NewBody(t *testing.T) { }{ {"nilAlgorithmSuite", args{algorithmSuite: nil, frameLength: 0}, nil, assert.Error}, {"zeroFrameLength", args{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 0}, nil, assert.Error}, - {"body", args{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024}, &body{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: []frame{}, sequenceNumber: 1}, assert.NoError}, + {"body", args{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024}, &body{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: []format.BodyFrame{}, sequenceNumber: 1}, assert.NoError}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - mb := messageBody{} - got, err := mb.NewBody(tt.args.algorithmSuite, tt.args.frameLength) - if !tt.wantErr(t, err, fmt.Sprintf("NewBody(%v, %v)", tt.args.algorithmSuite, tt.args.frameLength)) { + got, err := newBody(tt.args.algorithmSuite, tt.args.frameLength) + if !tt.wantErr(t, err, fmt.Sprintf("newBody(%v, %v)", tt.args.algorithmSuite, tt.args.frameLength)) { return } - assert.Equalf(t, tt.want, got, "NewBody(%v, %v)", tt.args.algorithmSuite, tt.args.frameLength) + assert.Equalf(t, tt.want, got, "newBody(%v, %v)", tt.args.algorithmSuite, tt.args.frameLength) }) } } @@ -333,7 +333,7 @@ func Test_body_len(t *testing.T) { type fields struct { algorithmSuite *suite.AlgorithmSuite frameLength int - frames []frame + frames []format.BodyFrame sequenceNumber int } tests := []struct { @@ -344,8 +344,10 @@ func Test_body_len(t *testing.T) { {"zeroBytes", fields{}, 0}, {"zeroBytes", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384}, 0}, {"zeroBytes", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024}, 0}, - {"oneFrame", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: []frame{{isFinal: true}}, sequenceNumber: 1}, 24}, - {"twoFrames", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: []frame{{isFinal: false}, {isFinal: true}}, sequenceNumber: 2}, 40}, + {"oneFrame", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: append([]format.BodyFrame{}, &frame{isFinal: true}), sequenceNumber: 1}, 24}, + //{"oneFrame", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: []frame{{isFinal: true}}, sequenceNumber: 1}, 24}, + {"twoFrames", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: append([]format.BodyFrame{}, &frame{isFinal: false}, &frame{isFinal: true}), sequenceNumber: 2}, 40}, + //{"twoFrames", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: []frame{{isFinal: false}, {isFinal: true}}, sequenceNumber: 2}, 40}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -355,7 +357,7 @@ func Test_body_len(t *testing.T) { frames: tt.fields.frames, sequenceNumber: tt.fields.sequenceNumber, } - assert.Equalf(t, tt.want, b.len(), "len()") + assert.Equalf(t, tt.want, b.Len(), "Len()") }) } } @@ -364,7 +366,7 @@ func Test_body_Bytes(t *testing.T) { type fields struct { algorithmSuite *suite.AlgorithmSuite frameLength int - frames []frame + frames []format.BodyFrame sequenceNumber int } tests := []struct { @@ -375,8 +377,8 @@ func Test_body_Bytes(t *testing.T) { {"zeroBytes", fields{}, []byte{}}, {"zeroBytes", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384}, []byte{}}, {"zeroBytes", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024}, []byte{}}, - {"oneFrame", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: []frame{{isFinal: true}}, sequenceNumber: 1}, []byte{0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, - {"twoFrames", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: []frame{{isFinal: false}, {isFinal: true}}, sequenceNumber: 2}, []byte{0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, + {"oneFrame", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: append([]format.BodyFrame{}, &frame{isFinal: true}), sequenceNumber: 1}, []byte{0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, + {"twoFrames", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: append([]format.BodyFrame{}, &frame{isFinal: false}, &frame{isFinal: true}), sequenceNumber: 2}, []byte{0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -395,19 +397,19 @@ func Test_body_Frames(t *testing.T) { type fields struct { algorithmSuite *suite.AlgorithmSuite frameLength int - frames []frame + frames []format.BodyFrame sequenceNumber int } tests := []struct { name string fields fields - want []frame + want []format.BodyFrame }{ - {"frameNil", fields{}, []frame(nil)}, - {"frameNil", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384}, []frame(nil)}, - {"frameNil", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024}, []frame(nil)}, - {"oneFrame", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: []frame{{isFinal: true}}, sequenceNumber: 1}, []frame{{isFinal: true}}}, - {"twoFrames", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: []frame{{isFinal: false}, {isFinal: true}}, sequenceNumber: 2}, []frame{{isFinal: false}, {isFinal: true}}}, + {"frameNil", fields{}, []format.BodyFrame(nil)}, + {"frameNil", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384}, []format.BodyFrame(nil)}, + {"frameNil", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024}, []format.BodyFrame(nil)}, + {"oneFrame", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: append([]format.BodyFrame{}, &frame{isFinal: true}), sequenceNumber: 1}, append([]format.BodyFrame{}, &frame{isFinal: true})}, + {"twoFrames", fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: append([]format.BodyFrame{}, &frame{isFinal: false}, &frame{isFinal: true}), sequenceNumber: 2}, append([]format.BodyFrame{}, &frame{isFinal: false}, &frame{isFinal: true})}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -426,34 +428,34 @@ func Test_body_readFrame(t *testing.T) { type fields struct { algorithmSuite *suite.AlgorithmSuite frameLength int - frames []frame + frames []format.BodyFrame sequenceNumber int } type args struct { buf *bytes.Buffer } var finalIndicator = []byte{0xff, 0xff, 0xff, 0xff} - var tFields = fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: []frame{}, sequenceNumber: 1} + var tFields = fields{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 1024, frames: []format.BodyFrame{}, sequenceNumber: 1} var bufFinal = bytes.NewBuffer([]byte{0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x4, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}) var bufFinalNoContent = bytes.NewBuffer([]byte{0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}) tests := []struct { name string fields fields args args - want frame + want *frame wantErr assert.ErrorAssertionFunc }{ - {"nilBuffer", fields{}, args{buf: nil}, frame{}, assert.Error}, - {"emptyBuffer", fields{}, args{buf: bytes.NewBuffer([]byte{})}, frame{}, assert.Error}, - {"emptyBuffer", tFields, args{buf: bytes.NewBuffer([]byte{})}, frame{}, assert.Error}, - {"emptyFinal", tFields, args{buf: bytes.NewBuffer(finalIndicator)}, frame{}, assert.Error}, - {"emptyFinal", tFields, args{buf: bytes.NewBuffer([]byte{0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1})}, frame{}, assert.Error}, - {"emptyFinal", tFields, args{buf: bytes.NewBuffer([]byte{0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1})}, frame{}, assert.Error}, - {"final", tFields, args{buf: bytes.NewBuffer([]byte{0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x5, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1})}, frame{isFinal: true, sequenceNumber: 2, iV: []uint8{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}, contentLength: 5, encryptedContent: []uint8{0x1, 0x1, 0x1, 0x1, 0x1}, authenticationTag: []uint8{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}}, assert.NoError}, - {"emptyRegular", tFields, args{buf: bytes.NewBuffer([]byte{0x0, 0x0, 0x0, 0x1})}, frame{}, assert.Error}, - {"regular", tFields, args{buf: bytes.NewBuffer([]byte{0x0, 0x0, 0x0, 0x1, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5})}, frame{isFinal: false, sequenceNumber: 1, iV: []uint8{0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3}, contentLength: 1024, encryptedContent: []uint8{0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4}, authenticationTag: []uint8{0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5}}, assert.NoError}, - {"final1024b", tFields, args{buf: bufFinal}, frame{isFinal: true, sequenceNumber: 1, iV: []uint8{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}, contentLength: 1024, encryptedContent: []uint8{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}, authenticationTag: []uint8{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}}, assert.NoError}, - {"final0b", tFields, args{buf: bufFinalNoContent}, frame{isFinal: true, sequenceNumber: 2, iV: []uint8{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}, contentLength: 0, encryptedContent: []uint8{}, authenticationTag: []uint8{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}}, assert.NoError}, + {"nilBuffer", fields{}, args{buf: nil}, nil, assert.Error}, + {"emptyBuffer", fields{}, args{buf: bytes.NewBuffer([]byte{})}, nil, assert.Error}, + {"emptyBuffer", tFields, args{buf: bytes.NewBuffer([]byte{})}, nil, assert.Error}, + {"emptyFinal", tFields, args{buf: bytes.NewBuffer(finalIndicator)}, nil, assert.Error}, + {"emptyFinal", tFields, args{buf: bytes.NewBuffer([]byte{0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1})}, nil, assert.Error}, + {"emptyFinal", tFields, args{buf: bytes.NewBuffer([]byte{0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1})}, nil, assert.Error}, + {"final", tFields, args{buf: bytes.NewBuffer([]byte{0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x5, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1})}, &frame{isFinal: true, sequenceNumber: 2, iV: []uint8{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}, contentLength: 5, encryptedContent: []uint8{0x1, 0x1, 0x1, 0x1, 0x1}, authenticationTag: []uint8{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}}, assert.NoError}, + {"emptyRegular", tFields, args{buf: bytes.NewBuffer([]byte{0x0, 0x0, 0x0, 0x1})}, nil, assert.Error}, + {"regular", tFields, args{buf: bytes.NewBuffer([]byte{0x0, 0x0, 0x0, 0x1, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5})}, &frame{isFinal: false, sequenceNumber: 1, iV: []uint8{0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3}, contentLength: 1024, encryptedContent: []uint8{0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4}, authenticationTag: []uint8{0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5}}, assert.NoError}, + {"final1024b", tFields, args{buf: bufFinal}, &frame{isFinal: true, sequenceNumber: 1, iV: []uint8{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}, contentLength: 1024, encryptedContent: []uint8{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}, authenticationTag: []uint8{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}}, assert.NoError}, + {"final0b", tFields, args{buf: bufFinalNoContent}, &frame{isFinal: true, sequenceNumber: 2, iV: []uint8{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}, contentLength: 0, encryptedContent: []uint8{}, authenticationTag: []uint8{0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}}, assert.NoError}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -492,18 +494,17 @@ func Test_messageBody_fromBuffer(t *testing.T) { {"seqNum2", assert.Error, args{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 16, bytes.NewBuffer([]byte{0x0, 0x0, 0x0, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5})}, nil}, {"seqNum13", assert.Error, args{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 16, bytes.NewBuffer([]byte{0x0, 0x0, 0x0, 0x1, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x0, 0x0, 0x0, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5})}, nil}, {"onlyRegularFrame", assert.Error, args{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 16, bytes.NewBuffer([]byte{0x0, 0x0, 0x0, 0x1, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5})}, nil}, - {"twoFrames", assert.NoError, args{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 16, bytes.NewBuffer([]byte{0x0, 0x0, 0x0, 0x1, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0x0, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5})}, &body{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 16, sequenceNumber: 3, frames: []frame{{isFinal: false, sequenceNumber: 1, iV: []uint8{0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3}, contentLength: 16, encryptedContent: []uint8{0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4}, authenticationTag: []uint8{0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5}}, {isFinal: true, sequenceNumber: 2, iV: []uint8{0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3}, contentLength: 0, encryptedContent: []uint8{}, authenticationTag: []uint8{0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5}}}}}, - {"twoFinalFrames", assert.NoError, args{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 16, bytes.NewBuffer([]byte{0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0x0, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0x0, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5})}, &body{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 16, sequenceNumber: 2, frames: []frame{{isFinal: true, sequenceNumber: 1, iV: []uint8{0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3}, contentLength: 0, encryptedContent: []uint8{}, authenticationTag: []uint8{0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5}}}}}, - {"oneFinal1b", assert.NoError, args{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 16, bytes.NewBuffer([]byte{0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0x1, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5})}, &body{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 16, sequenceNumber: 2, frames: []frame{{isFinal: true, sequenceNumber: 1, iV: []uint8{0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3}, contentLength: 1, encryptedContent: []uint8{0x04}, authenticationTag: []uint8{0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5}}}}}, + {"twoFrames", assert.NoError, args{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 16, bytes.NewBuffer([]byte{0x0, 0x0, 0x0, 0x1, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0x0, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5})}, &body{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 16, sequenceNumber: 3, frames: append([]format.BodyFrame{}, &frame{isFinal: false, sequenceNumber: 1, iV: []uint8{0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3}, contentLength: 16, encryptedContent: []uint8{0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4}, authenticationTag: []uint8{0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5}}, &frame{isFinal: true, sequenceNumber: 2, iV: []uint8{0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3}, contentLength: 0, encryptedContent: []uint8{}, authenticationTag: []uint8{0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5}})}}, + {"twoFinalFrames", assert.NoError, args{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 16, bytes.NewBuffer([]byte{0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0x0, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0x0, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5})}, &body{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 16, sequenceNumber: 2, frames: append([]format.BodyFrame{}, &frame{isFinal: true, sequenceNumber: 1, iV: []uint8{0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3}, contentLength: 0, encryptedContent: []uint8{}, authenticationTag: []uint8{0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5}})}}, + {"oneFinal1b", assert.NoError, args{suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 16, bytes.NewBuffer([]byte{0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0x1, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5})}, &body{algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, frameLength: 16, sequenceNumber: 2, frames: append([]format.BodyFrame{}, &frame{isFinal: true, sequenceNumber: 1, iV: []uint8{0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3}, contentLength: 1, encryptedContent: []uint8{0x04}, authenticationTag: []uint8{0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5}})}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - mb := messageBody{} - got, err := mb.fromBuffer(tt.args.algorithmSuite, tt.args.frameLength, tt.args.buf) - if !tt.wantErr(t, err, fmt.Sprintf("fromBuffer(%v, %v, %v)", tt.args.algorithmSuite, tt.args.frameLength, tt.args.buf)) { + got, err := deserializeBody(tt.args.algorithmSuite, tt.args.frameLength, tt.args.buf) + if !tt.wantErr(t, err, fmt.Sprintf("deserializeBody(%v, %v, %v)", tt.args.algorithmSuite, tt.args.frameLength, tt.args.buf)) { return } - assert.Equalf(t, tt.want, got, "fromBuffer(%v, %v, %v)", tt.args.algorithmSuite, tt.args.frameLength, tt.args.buf) + assert.Equalf(t, tt.want, got, "deserializeBody(%v, %v, %v)", tt.args.algorithmSuite, tt.args.frameLength, tt.args.buf) }) } } @@ -541,7 +542,7 @@ func Test_body_AddFrame(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - b, err := MessageBody.NewBody(tt.fields.algorithmSuite, tt.fields.frameLength) + b, err := newBody(tt.fields.algorithmSuite, tt.fields.frameLength) require.NoError(t, err) tt.wantErr(t, b.AddFrame(tt.args.final, tt.args.seqNum, tt.args.IV, tt.args.contentLength, tt.args.ciphertext, tt.args.authTag), fmt.Sprintf("AddFrame(%v, %v, %v, %v, %v, %v)", tt.args.final, tt.args.seqNum, tt.args.IV, tt.args.contentLength, tt.args.ciphertext, tt.args.authTag)) }) diff --git a/pkg/serialization/messagefooter.go b/pkg/serialization/messagefooter.go index 41823e7..ac797d8 100644 --- a/pkg/serialization/messagefooter.go +++ b/pkg/serialization/messagefooter.go @@ -16,32 +16,24 @@ var ( errFooter = errors.New("message footer error") ) -var MessageFooter = messageFooter{ //nolint:gochecknoglobals - lenFields: 1, -} - -type messageFooter struct { - lenFields int -} - type footer struct { algorithmSuite *suite.AlgorithmSuite // algorithmSuite in suite.AlgorithmSuite in order to check with Authentication.SignatureLen - signLen int // 2, SignLen is a length of Signature - Signature []byte // vary, length is SignLen, ECDSA Signature + signLen int // 2, SignLen is a length of signature + signature []byte // vary, length is SignLen, ECDSA signature } -func (mf messageFooter) NewFooter(alg *suite.AlgorithmSuite, signature []byte) (*footer, error) { +func newFooter(alg *suite.AlgorithmSuite, signature []byte) (*footer, error) { if alg.Authentication.SignatureLen != len(signature) { return nil, fmt.Errorf("invalid signature length, %w", errFooter) } return &footer{ algorithmSuite: alg, signLen: len(signature), - Signature: signature, + signature: signature, }, nil } -func (mf messageFooter) FromBuffer(alg *suite.AlgorithmSuite, buf *bytes.Buffer) (*footer, error) { +func deserializeFooter(alg *suite.AlgorithmSuite, buf *bytes.Buffer) (*footer, error) { signLen, err := fieldReader.ReadLenField(buf) if err != nil { return nil, fmt.Errorf("cant read signLen: %w", errors.Join(errFooter, err)) @@ -56,24 +48,31 @@ func (mf messageFooter) FromBuffer(alg *suite.AlgorithmSuite, buf *bytes.Buffer) return &footer{ algorithmSuite: alg, signLen: signLen, - Signature: signature, + signature: signature, }, nil } -func (f *footer) len() int { - return (MessageFooter.lenFields * lenFieldBytes) + - f.signLen +func (f *footer) Len() int { + return lenFieldBytes + f.signLen } func (f *footer) String() string { - return fmt.Sprintf("footer: %s, signLen: %d, Signature: %d", f.algorithmSuite, f.signLen, len(f.Signature)) + return fmt.Sprintf("footer: %s, signLen: %d, signature: %d", f.algorithmSuite, f.signLen, len(f.signature)) //return fmt.Sprintf("%#v", *f) } func (f *footer) Bytes() []byte { var buf []byte - buf = make([]byte, 0, f.len()) + buf = make([]byte, 0, f.Len()) buf = append(buf, conv.FromInt.Uint16BigEndian(f.signLen)...) - buf = append(buf, f.Signature...) + buf = append(buf, f.signature...) return buf } + +func (f *footer) SignLen() int { + return f.signLen +} + +func (f *footer) Signature() []byte { + return f.signature +} diff --git a/pkg/serialization/messagefooter_test.go b/pkg/serialization/messagefooter_test.go index 8c8135a..850a2e0 100644 --- a/pkg/serialization/messagefooter_test.go +++ b/pkg/serialization/messagefooter_test.go @@ -36,10 +36,10 @@ func Test_footer_len(t *testing.T) { t.Run(tt.name, func(t *testing.T) { f := &footer{ algorithmSuite: tt.algorithmSuite, - Signature: make([]byte, tt.algorithmSuite.Authentication.SignatureLen), + signature: make([]byte, tt.algorithmSuite.Authentication.SignatureLen), signLen: tt.algorithmSuite.Authentication.SignatureLen, } - assert.Equalf(t, tt.want, f.len(), "len()") + assert.Equalf(t, tt.want, f.Len(), "Len()") }) } } @@ -63,7 +63,7 @@ func Test_footer_Bytes(t *testing.T) { f := &footer{ algorithmSuite: tt.fields.algorithmSuite, signLen: tt.fields.signLen, - Signature: tt.fields.Signature, + signature: tt.fields.Signature, } assert.Equalf(t, tt.want, f.Bytes(), "Bytes()") }) @@ -137,7 +137,7 @@ func Test_messageFooter_FromBuffer(t *testing.T) { want: &footer{ algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY, signLen: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY.Authentication.SignatureLen, - Signature: zeroSignature, + signature: zeroSignature, }, wantErr: false, }, @@ -150,7 +150,7 @@ func Test_messageFooter_FromBuffer(t *testing.T) { want: &footer{ algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, signLen: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384.Authentication.SignatureLen, - Signature: p384Signature, + signature: p384Signature, }, wantErr: false, }, @@ -162,7 +162,7 @@ func Test_messageFooter_FromBuffer(t *testing.T) { want: &footer{ algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, signLen: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384.Authentication.SignatureLen, - Signature: p384Signature, + signature: p384Signature, }, wantErr: false, }, @@ -170,15 +170,15 @@ func Test_messageFooter_FromBuffer(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := MessageFooter.FromBuffer(tt.args.alg, tt.args.buf) + got, err := deserializeFooter(tt.args.alg, tt.args.buf) if err != nil && tt.wantErr { require.ErrorIs(t, err, errFooter) - require.Errorf(t, err, "FromBuffer() error = %v, wantErr %v", err, tt.wantErr) - require.ErrorContainsf(t, err, tt.errString, "FromBuffer() error = %v, wantErr %v", err, tt.wantErr) + require.Errorf(t, err, "deserializeFooter() error = %v, wantErr %v", err, tt.wantErr) + require.ErrorContainsf(t, err, tt.errString, "deserializeFooter() error = %v, wantErr %v", err, tt.wantErr) return } assert.NoError(t, err) - assert.Equalf(t, tt.want, got, "FromBuffer() = %v, want %v", got, tt.want) + assert.Equalf(t, tt.want, got, "deserializeFooter() = %v, want %v", got, tt.want) }) } } @@ -195,7 +195,7 @@ func TestFooterString(t *testing.T) { footer: footer{ algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY, signLen: 2, - Signature: []byte("signature1"), + signature: []byte("signature1"), }, signLen: 2, signatureLen: 10, @@ -205,7 +205,7 @@ func TestFooterString(t *testing.T) { footer: footer{ algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, signLen: 3, - Signature: []byte("signature384"), + signature: []byte("signature384"), }, signLen: 3, signatureLen: 12, @@ -214,7 +214,7 @@ func TestFooterString(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - expectedStr := fmt.Sprintf("footer: %s, signLen: %d, Signature: %d", tt.footer.algorithmSuite, tt.signLen, tt.signatureLen) + expectedStr := fmt.Sprintf("footer: %s, signLen: %d, signature: %d", tt.footer.algorithmSuite, tt.signLen, tt.signatureLen) assert.Equal(t, expectedStr, tt.footer.String()) }) } @@ -238,7 +238,7 @@ func TestNewFooter(t *testing.T) { want: &footer{ algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, signLen: len(p384Signature), - Signature: p384Signature, + signature: p384Signature, }, wantErr: false, }, @@ -249,7 +249,7 @@ func TestNewFooter(t *testing.T) { want: &footer{ algorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY, signLen: len(zeroSignature), - Signature: zeroSignature, + signature: zeroSignature, }, wantErr: false, }, @@ -265,16 +265,18 @@ func TestNewFooter(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := MessageFooter.NewFooter(tt.algorithmSuite, tt.signature) + got, err := newFooter(tt.algorithmSuite, tt.signature) if err != nil && tt.wantErr { require.ErrorIs(t, err, errFooter) - require.Errorf(t, err, "NewFooter() error = %v, wantErr %v", err, tt.wantErr) - require.ErrorContainsf(t, err, tt.errString, "NewFooter() error = %v, wantErr %v", err, tt.wantErr) + require.Errorf(t, err, "newFooter() error = %v, wantErr %v", err, tt.wantErr) + require.ErrorContainsf(t, err, tt.errString, "newFooter() error = %v, wantErr %v", err, tt.wantErr) return } assert.NoError(t, err) - assert.Equalf(t, tt.want, got, "NewFooter() = %v, want %v", got, tt.want) + assert.Equalf(t, tt.want, got, "newFooter() = %v, want %v", got, tt.want) + assert.Equal(t, len(tt.signature), got.SignLen()) + assert.Equal(t, tt.signature, got.Signature()) }) } } diff --git a/pkg/serialization/messageheader.go b/pkg/serialization/messageheader.go index f65c98e..0b669f6 100644 --- a/pkg/serialization/messageheader.go +++ b/pkg/serialization/messageheader.go @@ -54,17 +54,7 @@ type messageHeaderV2 struct { algorithmSuiteData []byte // 32 bytes, algorithmSuiteData aka commitmentKey, present only in V2 } -type HeaderParams struct { - AlgorithmSuite *suite.AlgorithmSuite - MessageID []byte - EncryptionContext suite.EncryptionContext - EncryptedDataKeys []format.MessageEDK - ContentType suite.ContentType - FrameLength int - AlgorithmSuiteData []byte -} - -func NewHeader(p HeaderParams) (format.MessageHeader, error) { +func newHeader(p format.HeaderParams) (format.MessageHeader, error) { if p.AlgorithmSuite == nil { return nil, fmt.Errorf("invalid AlgorithmSuite: %v", p.AlgorithmSuite) } @@ -222,7 +212,7 @@ func deserializeHeader(buf *bytes.Buffer) (format.MessageHeader, error) { //noli algorithmSuiteData = buf.Next(algorithmSuite.AlgorithmSuiteDataLen()) } - return NewHeader(HeaderParams{ + return newHeader(format.HeaderParams{ AlgorithmSuite: algorithmSuite, MessageID: messageID, EncryptionContext: encryptionContext, diff --git a/pkg/serialization/messageheader_test.go b/pkg/serialization/messageheader_test.go index 83f57ad..113b5e1 100644 --- a/pkg/serialization/messageheader_test.go +++ b/pkg/serialization/messageheader_test.go @@ -18,7 +18,7 @@ import ( func TestNewHeader(t *testing.T) { type args struct { - p HeaderParams + p format.HeaderParams } edk1Mock, _ := EDK.new(awsKmsProviderID, "test", []byte("test")) @@ -109,35 +109,35 @@ func TestNewHeader(t *testing.T) { wantFromBuffer format.MessageHeader wantErr bool }{ - {"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}, + {"nilAlgorithmSuite", args{format.HeaderParams{MessageID: []byte("test"), ContentType: suite.NonFramedContent, FrameLength: 10, AlgorithmSuiteData: []byte("test")}}, nil, nil, true}, + {"unsupportedAlgorithm", args{format.HeaderParams{AlgorithmSuite: &suite.AlgorithmSuite{AlgorithmID: 0x0050}, ContentType: suite.NonFramedContent, FrameLength: 10, AlgorithmSuiteData: []byte("test")}}, nil, nil, true}, + {"invalidMessageID", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, ContentType: suite.NonFramedContent, FrameLength: 10, AlgorithmSuiteData: []byte("test")}}, nil, nil, true}, + {"invalidMessageID", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, MessageID: []byte("test"), ContentType: suite.NonFramedContent, FrameLength: 10, AlgorithmSuiteData: []byte("test")}}, nil, nil, true}, + {"invalidMessageID_V1", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, MessageID: []byte("testtesttestt15"), ContentType: suite.NonFramedContent, FrameLength: 10, AlgorithmSuiteData: []byte("test")}}, nil, nil, true}, + {"invalidEncryptedDataKeys", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, MessageID: []byte("MessageID12MessageID12MessageID1"), ContentType: suite.NonFramedContent, FrameLength: 10, AlgorithmSuiteData: []byte("test")}}, nil, nil, true}, + {"invalidAlgorithmSuiteDataLen", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, MessageID: []byte("MessageID12MessageID12MessageID1"), EncryptedDataKeys: []format.MessageEDK{edk1Mock}, ContentType: suite.NonFramedContent, FrameLength: 10, AlgorithmSuiteData: []byte("test")}}, nil, nil, true}, + {"invalidAlgorithmSuiteDataLen_V1", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, MessageID: []byte("MessageMessage16"), EncryptedDataKeys: []format.MessageEDK{edk1Mock}, ContentType: suite.NonFramedContent, FrameLength: 10, AlgorithmSuiteData: []byte("test")}}, nil, nil, true}, + {"invalidFrameLength", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, MessageID: []byte("MessageID12MessageID12MessageID1"), EncryptedDataKeys: []format.MessageEDK{edk1Mock}, ContentType: suite.NonFramedContent, FrameLength: 10, AlgorithmSuiteData: []byte("Algorithm12Algorithm12Algorithm1")}}, nil, nil, true}, + {"invalidContentType", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, MessageID: []byte("MessageID12MessageID12MessageID1"), EncryptedDataKeys: []format.MessageEDK{edk1Mock}, ContentType: suite.ContentType(3), FrameLength: 1024, AlgorithmSuiteData: []byte("Algorithm12Algorithm12Algorithm1")}}, nil, nil, true}, + {"invalidContentType", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, MessageID: []byte("MessageID12MessageID12MessageID1"), EncryptedDataKeys: []format.MessageEDK{edk1Mock}, ContentType: suite.ContentType(0), FrameLength: 1024, AlgorithmSuiteData: []byte("Algorithm12Algorithm12Algorithm1")}}, nil, nil, true}, + {"invalidContentType", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, MessageID: []byte("MessageID12MessageID12MessageID1"), EncryptedDataKeys: []format.MessageEDK{edk1Mock}, ContentType: suite.NonFramedContent, FrameLength: 1024, AlgorithmSuiteData: []byte("Algorithm12Algorithm12Algorithm1")}}, nil, nil, true}, + {"valid", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, MessageID: []byte("MessageID12MessageID12MessageID1"), EncryptedDataKeys: []format.MessageEDK{edk1Mock}, ContentType: suite.FramedContent, FrameLength: 1024, AlgorithmSuiteData: []byte("Algorithm12Algorithm12Algorithm1")}}, mh1Mock, nil, false}, + {"valid", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, MessageID: []byte("MessageID12MessageID12MessageID1"), EncryptedDataKeys: []format.MessageEDK{edk1Mock}, ContentType: suite.FramedContent, FrameLength: 1024, AlgorithmSuiteData: []byte("Algorithm12Algorithm12Algorithm1")}}, mh1Mock, mh1Mock, false}, + {"valid", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, MessageID: []byte("MessageID12MessageID12MessageID1"), EncryptionContext: map[string]string{}, EncryptedDataKeys: []format.MessageEDK{edk1Mock}, ContentType: suite.FramedContent, FrameLength: 1024, AlgorithmSuiteData: []byte("Algorithm12Algorithm12Algorithm1")}}, mh2Mock, mh1Mock, false}, + {"valid", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, MessageID: []byte("MessageID12MessageID12MessageID1"), EncryptionContext: map[string]string{"test": "testing"}, EncryptedDataKeys: []format.MessageEDK{edk1Mock}, ContentType: suite.FramedContent, FrameLength: 1024, AlgorithmSuiteData: []byte("Algorithm12Algorithm12Algorithm1")}}, mh3Mock, mh3Mock, false}, + {"valid_V1", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, MessageID: []byte("MessageMessage16"), EncryptedDataKeys: []format.MessageEDK{edk1Mock}, ContentType: suite.FramedContent, FrameLength: 1024}}, mh1MockV1, nil, false}, + {"valid_V1", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, MessageID: []byte("MessageMessage16"), EncryptedDataKeys: []format.MessageEDK{edk1Mock}, ContentType: suite.FramedContent, FrameLength: 1024}}, mh1MockV1, mh1MockV1, false}, + {"valid_V1", args{format.HeaderParams{AlgorithmSuite: suite.AES_256_GCM_IV12_TAG16_HKDF_SHA256, MessageID: []byte("MessageMessage16"), EncryptionContext: map[string]string{"test": "testing"}, EncryptedDataKeys: []format.MessageEDK{edk1Mock}, ContentType: suite.FramedContent, FrameLength: 1024}}, mh3MockV1, mh3MockV1, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := NewHeader(tt.args.p) + got, err := newHeader(tt.args.p) if err != nil && tt.wantErr { - assert.Errorf(t, err, "NewHeader(%#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 } - 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.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()) diff --git a/pkg/serialization/serializer.go b/pkg/serialization/serializer.go new file mode 100644 index 0000000..dffb8a1 --- /dev/null +++ b/pkg/serialization/serializer.go @@ -0,0 +1,31 @@ +// Copyright Chainify Group LTD. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package serialization + +import ( + "github.com/chainifynet/aws-encryption-sdk-go/pkg/model/format" + "github.com/chainifynet/aws-encryption-sdk-go/pkg/suite" +) + +type Serializer struct{} + +func NewSerializer() format.Serializer { + return &Serializer{} +} + +func (s *Serializer) SerializeHeader(p format.HeaderParams) (format.MessageHeader, error) { + return newHeader(p) +} + +func (s *Serializer) SerializeHeaderAuth(v suite.MessageFormatVersion, iv, authData []byte) (format.MessageHeaderAuth, error) { + return newHeaderAuth(v, iv, authData) +} + +func (s *Serializer) SerializeBody(alg *suite.AlgorithmSuite, frameLength int) (format.MessageBody, error) { + return newBody(alg, frameLength) +} + +func (s *Serializer) SerializeFooter(alg *suite.AlgorithmSuite, signature []byte) (format.MessageFooter, error) { + return newFooter(alg, signature) +} diff --git a/pkg/version.go b/pkg/version.go index c830a49..fb110ff 100644 --- a/pkg/version.go +++ b/pkg/version.go @@ -3,4 +3,4 @@ package pkg -const Version = "0.2.2" +const Version = "0.3.0" diff --git a/test/e2e/enc_dec_test.go b/test/e2e/enc_dec_test.go index beb8424..7458c83 100644 --- a/test/e2e/enc_dec_test.go +++ b/test/e2e/enc_dec_test.go @@ -521,7 +521,10 @@ func Test_Integration_EncryptSDKDecryptCLI(t *testing.T) { cmm = tc.tEnc.tCMMi } assert.NotNil(t, cmm) - ciphertextSdk1, header1, err := c.EncryptWithParams(ctx, tf.data, tc.tEnc.tEC, cmm, tc.tAlg, tc.tEnc.tFrame) + ciphertextSdk1, header1, err := c.Encrypt(ctx, tf.data, tc.tEnc.tEC, cmm, + client.WithAlgorithm(tc.tAlg), + client.WithFrameLength(tc.tEnc.tFrame), + ) if err != nil && tc.tWantErr { require.Error(t, err) return @@ -665,7 +668,10 @@ func Test_Integration_EncryptSDK_DecryptCLI_EncryptCLI_DecryptSDK(t *testing.T) cmm = tc.tEnc.tCMMi } assert.NotNil(t, cmm) - ciphertextSdk1, header1, err := c.EncryptWithParams(ctx, tf.data, tc.tEnc.tEC, cmm, tc.tAlg, tc.tEnc.tFrame) + ciphertextSdk1, header1, err := c.Encrypt(ctx, tf.data, tc.tEnc.tEC, cmm, + client.WithAlgorithm(tc.tAlg), + client.WithFrameLength(tc.tEnc.tFrame), + ) if err != nil && tc.tWantErr { assert.ErrorIs(t, err, crypto.ErrEncryption) assert.NotErrorIs(t, err, crypto.ErrDecryption) @@ -785,7 +791,10 @@ func Test_Integration_EncryptSDK_DecryptCLI_EncryptCLI_DecryptSDK(t *testing.T) // encrypt with SDK // using cmm2 and c2 that was used to Decrypt - ciphertextSdk2, header2, err := c2.EncryptWithParams(ctx, tf.data, tc.tEnc.tEC, cmm2, tc.tAlg, tc.tEnc.tFrame) + ciphertextSdk2, header2, err := c2.Encrypt(ctx, tf.data, tc.tEnc.tEC, cmm2, + client.WithAlgorithm(tc.tAlg), + client.WithFrameLength(tc.tEnc.tFrame), + ) if err != nil && tc.tWantErr { assert.ErrorIs(t, err, crypto.ErrEncryption) assert.NotErrorIs(t, err, crypto.ErrDecryption) @@ -804,7 +813,10 @@ func Test_Integration_EncryptSDK_DecryptCLI_EncryptCLI_DecryptSDK(t *testing.T) // encrypt with SDK // using cmm and c that was used to Encrypt initially - ciphertextSdk3, header3, err := c.EncryptWithParams(ctx, tf.data, tc.tEnc.tEC, cmm, tc.tAlg, tc.tEnc.tFrame) + ciphertextSdk3, header3, err := c.Encrypt(ctx, tf.data, tc.tEnc.tEC, cmm, + client.WithAlgorithm(tc.tAlg), + client.WithFrameLength(tc.tEnc.tFrame), + ) if err != nil && tc.tWantErr { assert.ErrorIs(t, err, crypto.ErrEncryption) assert.NotErrorIs(t, err, crypto.ErrDecryption) diff --git a/test/e2e/raw_test.go b/test/e2e/raw_test.go index d033e44..d592403 100644 --- a/test/e2e/raw_test.go +++ b/test/e2e/raw_test.go @@ -51,7 +51,10 @@ func Test_Integration_StaticKeysEncrypt(t *testing.T) { log.Debug().Str("bytes", logger.FmtBytes(random32kb)).Msg("Input") // encrypt data - ciphertext1, header1, err := c.EncryptWithParams(ctx, random32kb, testEc, cmm, suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384, 4096) + ciphertext1, header1, err := c.Encrypt(ctx, random32kb, testEc, cmm, + client.WithAlgorithm(suite.AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384), + client.WithFrameLength(4096), + ) require.NoError(t, err) assert.NotNil(t, ciphertext1) assert.NotNil(t, header1)