Skip to content

Commit

Permalink
use Get*SymmetricKey API instead of Get*SymmetricKeys (#504)
Browse files Browse the repository at this point in the history
* use Get*SymmetricKey API instead of Get*SymmetricKeys
adapt integration test script for python3.6 that used in Centos 7/8
  • Loading branch information
Lagovas authored Feb 21, 2022
1 parent ef9aaac commit b229824
Show file tree
Hide file tree
Showing 16 changed files with 137 additions and 97 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Acra ChangeLog

## [0.92.0](https://github.com/cossacklabs/acra/releases/tag/0.92.0), February 18th 2021
## [0.92.0](https://github.com/cossacklabs/acra/releases/tag/0.92.0), February 21th 2021

This release brings stability and performance fixes to AcraServer and AcraTranslator. It officially deprecates usage
of AcraConnector in favour of TLS everywhere. Some default configuration params are changed in favour of more secure &
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG_DEV.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 0.92.0 - 2022-02-21
- Adapt python integration tests for python3.6 for tests on centos 7/8

## 0.92.0 - 2022-02-17
- Extend KeyStore interface to allow fetching single latest symmetric key for encryption purposes

Expand Down
14 changes: 4 additions & 10 deletions acrablock/dataEncryptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,11 @@ func (d *DataEncryptor) EncryptWithZoneID(zoneID, data []byte, setting config.Co
data = decrypted
}
}
keys, err := d.keyStore.GetZoneIDSymmetricKeys(zoneID)
key, err := d.keyStore.GetZoneIDSymmetricKey(zoneID)
if err != nil {
return data, err
}
if len(keys) == 0 {
return data, keystore.ErrKeysNotFound
}
return CreateAcraBlock(data, keys[0], zoneID)
return CreateAcraBlock(data, key, zoneID)
}

// EncryptWithClientID encrypt data using AcraBlock
Expand All @@ -88,12 +85,9 @@ func (d *DataEncryptor) EncryptWithClientID(clientID, data []byte, setting confi
data = decrypted
}
}
keys, err := d.keyStore.GetClientIDSymmetricKeys(clientID)
keys, err := d.keyStore.GetClientIDSymmetricKey(clientID)
if err != nil {
return data, err
}
if len(keys) == 0 {
return data, keystore.ErrKeysNotFound
}
return CreateAcraBlock(data, keys[0], nil)
return CreateAcraBlock(data, keys, nil)
}
49 changes: 27 additions & 22 deletions acrablock/dataEncryptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ func TestSuccessDataEncryptionWithClientID(t *testing.T) {
if err != nil {
t.Fatal(err)
}
symKey := [][]byte{[]byte(`some key`)}
symKey := []byte(`some key`)
clientID := []byte(`clientid`)
keyStore.On("GetClientIDSymmetricKeys", clientID).Return(symKey, nil)
keyStore.On("GetClientIDSymmetricKey", clientID).Return(symKey, nil)
envelopeType := config.CryptoEnvelopeTypeAcraBlock
setting := &config.BasicColumnEncryptionSetting{CryptoEnvelope: &envelopeType}
testData := []byte(`test data`)
Expand All @@ -42,7 +42,7 @@ func TestSuccessDataEncryptionWithClientID(t *testing.T) {
if n != len(acraBlock) {
t.Fatal("Took invalid AcraBlock with extra data")
}
decrypted, err := acraBlock.Decrypt(symKey, nil)
decrypted, err := acraBlock.Decrypt([][]byte{symKey}, nil)
if err != nil {
t.Fatal(err)
}
Expand All @@ -66,9 +66,10 @@ func TestSuccessAcraStructReEncryptionWithClientID(t *testing.T) {
if err != nil {
t.Fatal(err)
}
symKey := [][]byte{[]byte(`some key`)}
symKey := []byte(`some key`)
clientID := []byte(`clientid`)
keyStore.On("GetClientIDSymmetricKeys", clientID).Return(symKey, nil)
keyStore.On("GetClientIDSymmetricKeys", clientID).Return([][]byte{symKey}, nil)
keyStore.On("GetClientIDSymmetricKey", clientID).Return(symKey, nil)
keyStore.On("GetServerDecryptionPrivateKeys", clientID).Return([]*keys.PrivateKey{keyPair.Private}, nil)

envelopeType := config.CryptoEnvelopeTypeAcraBlock
Expand All @@ -91,7 +92,7 @@ func TestSuccessAcraStructReEncryptionWithClientID(t *testing.T) {
if n != len(acraBlock) {
t.Fatal("Took invalid AcraBlock with extra data")
}
decrypted, err := acraBlock.Decrypt(symKey, nil)
decrypted, err := acraBlock.Decrypt([][]byte{symKey}, nil)
if err != nil {
t.Fatal(err)
}
Expand All @@ -115,9 +116,10 @@ func TestSuccessIgnoringAcraStructReEncryptionWithClientID(t *testing.T) {
if err != nil {
t.Fatal(err)
}
symKey := [][]byte{[]byte(`some key`)}
symKey := []byte(`some key`)
clientID := []byte(`clientid`)
keyStore.On("GetClientIDSymmetricKeys", clientID).Return(symKey, nil)
keyStore.On("GetClientIDSymmetricKeys", clientID).Return([][]byte{symKey}, nil)
keyStore.On("GetClientIDSymmetricKey", clientID).Return(symKey, nil)
keyStore.On("GetServerDecryptionPrivateKeys", clientID).Return([]*keys.PrivateKey{keyPair.Private}, nil)

envelopeType := config.CryptoEnvelopeTypeAcraBlock
Expand All @@ -140,7 +142,7 @@ func TestSuccessIgnoringAcraStructReEncryptionWithClientID(t *testing.T) {
if n != len(acraBlock) {
t.Fatal("Took invalid AcraBlock with extra data")
}
decrypted, err := acraBlock.Decrypt(symKey, nil)
decrypted, err := acraBlock.Decrypt([][]byte{symKey}, nil)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -190,9 +192,10 @@ func TestSuccessDataEncryptionWithZoneID(t *testing.T) {
if err != nil {
t.Fatal(err)
}
symKey := [][]byte{[]byte(`some key`)}
symKey := []byte(`some key`)
zoneID := zone.GenerateZoneID()
keyStore.On("GetZoneIDSymmetricKeys", zoneID).Return(symKey, nil)
keyStore.On("GetZoneIDSymmetricKeys", zoneID).Return([][]byte{symKey}, nil)
keyStore.On("GetZoneIDSymmetricKey", zoneID).Return(symKey, nil)
envelopeType := config.CryptoEnvelopeTypeAcraBlock
setting := &config.BasicColumnEncryptionSetting{CryptoEnvelope: &envelopeType}
testData := []byte(`test data`)
Expand All @@ -215,7 +218,7 @@ func TestSuccessDataEncryptionWithZoneID(t *testing.T) {
t.Fatal("Took invalid AcraBlock with extra data")
}

decrypted, err := acraBlock.Decrypt(symKey, zoneID)
decrypted, err := acraBlock.Decrypt([][]byte{symKey}, zoneID)
if err != nil {
t.Fatal(err)
}
Expand All @@ -241,8 +244,9 @@ func TestSuccessAcraStructReEncryptionWithZoneID(t *testing.T) {
if err != nil {
t.Fatal(err)
}
symKey := [][]byte{[]byte(`some key`)}
keyStore.On("GetZoneIDSymmetricKeys", zoneID).Return(symKey, nil)
symKey := []byte(`some key`)
keyStore.On("GetZoneIDSymmetricKeys", zoneID).Return([][]byte{symKey}, nil)
keyStore.On("GetZoneIDSymmetricKey", zoneID).Return(symKey, nil)
keyStore.On("GetZonePrivateKeys", zoneID).Return([]*keys.PrivateKey{keyPair.Private}, nil)
envelopeType := config.CryptoEnvelopeTypeAcraBlock
reEncrypt := true
Expand All @@ -266,7 +270,7 @@ func TestSuccessAcraStructReEncryptionWithZoneID(t *testing.T) {
t.Fatal("Took invalid AcraBlock with extra data")
}

decrypted, err := acraBlock.Decrypt(symKey, zoneID)
decrypted, err := acraBlock.Decrypt([][]byte{symKey}, zoneID)
if err != nil {
t.Fatal(err)
}
Expand All @@ -292,8 +296,9 @@ func TestSuccessIgnoringAcraStructReEncryptionWithZoneID(t *testing.T) {
if err != nil {
t.Fatal(err)
}
symKey := [][]byte{[]byte(`some key`)}
keyStore.On("GetZoneIDSymmetricKeys", zoneID).Return(symKey, nil)
symKey := []byte(`some key`)
keyStore.On("GetZoneIDSymmetricKeys", zoneID).Return([][]byte{symKey}, nil)
keyStore.On("GetZoneIDSymmetricKey", zoneID).Return(symKey, nil)
keyStore.On("GetZonePrivateKeys", zoneID).Return([]*keys.PrivateKey{keyPair.Private}, nil)
envelopeType := config.CryptoEnvelopeTypeAcraBlock
reEncrypt := false
Expand All @@ -317,7 +322,7 @@ func TestSuccessIgnoringAcraStructReEncryptionWithZoneID(t *testing.T) {
t.Fatal("Took invalid AcraBlock with extra data")
}

decrypted, err := acraBlock.Decrypt(symKey, zoneID)
decrypted, err := acraBlock.Decrypt([][]byte{symKey}, zoneID)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -436,8 +441,8 @@ func TestFailedDataEncryptionWithErrorFromKeystore(t *testing.T) {
expectedError := errors.New("some error")
zoneID := zone.GenerateZoneID()
clientID := []byte(`clientid`)
keyStore.On("GetZoneIDSymmetricKeys", zoneID).Return(nil, expectedError)
keyStore.On("GetClientIDSymmetricKeys", clientID).Return(nil, expectedError)
keyStore.On("GetZoneIDSymmetricKey", zoneID).Return(nil, expectedError)
keyStore.On("GetClientIDSymmetricKey", clientID).Return(nil, expectedError)
envelopeType := config.CryptoEnvelopeTypeAcraBlock
setting := &config.BasicColumnEncryptionSetting{CryptoEnvelope: &envelopeType}
testData := []byte(`test data`)
Expand Down Expand Up @@ -468,8 +473,8 @@ func TestFailedDataEncryptionOnEmptyKeys(t *testing.T) {
}
zoneID := zone.GenerateZoneID()
clientID := []byte(`clientid`)
keyStore.On("GetZoneIDSymmetricKeys", zoneID).Return(nil, nil)
keyStore.On("GetClientIDSymmetricKeys", clientID).Return(nil, nil)
keyStore.On("GetZoneIDSymmetricKey", zoneID).Return(nil, keystore.ErrKeysNotFound)
keyStore.On("GetClientIDSymmetricKey", clientID).Return(nil, keystore.ErrKeysNotFound)
envelopeType := config.CryptoEnvelopeTypeAcraBlock
setting := &config.BasicColumnEncryptionSetting{CryptoEnvelope: &envelopeType}
testData := []byte(`test data`)
Expand Down
16 changes: 4 additions & 12 deletions cmd/acra-keys/keys/read-key.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,28 +244,20 @@ func ReadKeyBytes(params ReadKeyParams, keyStore keystore.ServerKeyStore) ([]byt
return key.Value, nil

case KeySymmetric:
keys, err := keyStore.GetClientIDSymmetricKeys(params.ClientID())
key, err := keyStore.GetClientIDSymmetricKey(params.ClientID())
if err != nil {
log.WithError(err).Error("Cannot read client symmetric key")
return nil, err
}
if len(keys) == 0 {
log.WithError(err).Error("Empty symmetric keys list")
return nil, keystore.ErrKeysNotFound
}
return keys[0], nil
return key, nil

case KeyZoneSymmetric:
keys, err := keyStore.GetZoneIDSymmetricKeys(params.ZoneID())
key, err := keyStore.GetZoneIDSymmetricKey(params.ZoneID())
if err != nil {
log.WithError(err).Error("Cannot read client symmetric key")
return nil, err
}
if len(keys) == 0 {
log.WithError(err).Error("Empty symmetric keys list")
return nil, keystore.ErrKeysNotFound
}
return keys[0], nil
return key, nil

default:
log.WithField("expected", SupportedReadKeyKinds).Errorf("Unknown key kind: %s", kind)
Expand Down
12 changes: 5 additions & 7 deletions cmd/acra-translator/grpc_api/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,21 +253,19 @@ func (service *TranslatorService) EncryptSymSearchable(ctx context.Context, requ
logger.Errorln("Empty ClientID")
return nil, ErrEmptyClientID
}
var symKeys [][]byte
var symKey []byte
var err error
logger.Debugln("Load encryption symmetric key from KeyStore")
if request.ZoneId != nil {
symKeys, err = service.data.Keystorage.GetZoneIDSymmetricKeys(request.ZoneId)
symKey, err = service.data.Keystorage.GetZoneIDSymmetricKey(request.ZoneId)
} else {
symKeys, err = service.data.Keystorage.GetClientIDSymmetricKeys(request.ClientId)
symKey, err = service.data.Keystorage.GetClientIDSymmetricKey(request.ClientId)
}
if err != nil {
logger.WithError(err).Errorln("Can't load symmetric keys")
return nil, ErrKeysNotFound
}
if len(symKeys) == 0 {
return nil, ErrKeysNotFound
}

logger.Debugln("Load secret key for HMAC from KeyStore")
hmacKey, err := service.data.Keystorage.GetHMACSecretKey(request.ClientId)
if err != nil {
Expand All @@ -277,7 +275,7 @@ func (service *TranslatorService) EncryptSymSearchable(ctx context.Context, requ
logger.Debugln("Generate HMAC")
dataHash := hmac.GenerateHMAC(hmacKey, request.Data)
logger.Debugln("Create AcraBlock")
acrastruct, err := acrablock.CreateAcraBlock(request.Data, symKeys[0], request.ZoneId)
acrastruct, err := acrablock.CreateAcraBlock(request.Data, symKey, request.ZoneId)
if err != nil {
logger.WithError(err).Errorln("Can't create AcraBlock")
return nil, ErrEncryptionFailed
Expand Down
38 changes: 38 additions & 0 deletions cmd/acra-translator/grpc_api/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,21 @@ func TestTranslatorService_SearchSym(t *testing.T) {
return [][]byte{append([]byte{}, zoneIDSymKey...)}
},
nil)
keystore.On("GetZoneIDSymmetricKey", mock.MatchedBy(func([]byte) bool { return true })).Return(
func([]byte) []byte {
return append([]byte{}, zoneIDSymKey...)
},
nil)
keystore.On("GetClientIDSymmetricKeys", mock.MatchedBy(func([]byte) bool { return true })).Return(
func([]byte) [][]byte {
return [][]byte{append([]byte{}, clientIDSymKey...)}
},
nil)
keystore.On("GetClientIDSymmetricKey", mock.MatchedBy(func([]byte) bool { return true })).Return(
func([]byte) []byte {
return append([]byte{}, clientIDSymKey...)
},
nil)

translatorData := &translatorCommon.TranslatorData{Keystorage: keystore}
serviceImplementation, err := translatorCommon.NewTranslatorService(translatorData)
Expand Down Expand Up @@ -369,6 +379,7 @@ func TestTranslatorService_DecryptionPoisonRecord(t *testing.T) {
keyStorage := &mocks.ServerKeyStore{}
// everytime return copy of value because it will be zeroized after each call
keyStorage.On("GetPoisonSymmetricKeys").Return(func() [][]byte { return [][]byte{append([]byte{}, poisonSymKey...)} }, nil)
keyStorage.On("GetPoisonSymmetricKey").Return(func() []byte { return append([]byte{}, poisonSymKey...) }, nil)
callbackStorage := poison.NewCallbackStorage()
callback := &testPoisonCallback{}
callbackStorage.AddCallback(callback)
Expand All @@ -394,17 +405,28 @@ func TestTranslatorService_DecryptionPoisonRecord(t *testing.T) {
// reset all .On registered callbacks
keyStorage.ExpectedCalls = nil
keyStorage.On("GetPoisonSymmetricKeys").Return(func() [][]byte { return [][]byte{append([]byte{}, poisonSymKey...)} }, nil)
keyStorage.On("GetPoisonSymmetricKey").Return(func() []byte { return append([]byte{}, poisonSymKey...) }, nil)
keyStorage.On("GetHMACSecretKey", mock.MatchedBy(func([]byte) bool { return true })).Return(func([]byte) []byte { return append([]byte{}, hmacKey...) }, nil)
keyStorage.On("GetZoneIDSymmetricKeys", mock.MatchedBy(func([]byte) bool { return true })).Return(
func([]byte) [][]byte {
return [][]byte{append([]byte{}, someSymKey...)}
},
nil)
keyStorage.On("GetZoneIDSymmetricKey", mock.MatchedBy(func([]byte) bool { return true })).Return(
func([]byte) []byte {
return append([]byte{}, someSymKey...)
},
nil)
keyStorage.On("GetClientIDSymmetricKeys", mock.MatchedBy(func([]byte) bool { return true })).Return(
func([]byte) [][]byte {
return [][]byte{append([]byte{}, someSymKey...)}
},
nil)
keyStorage.On("GetClientIDSymmetricKey", mock.MatchedBy(func([]byte) bool { return true })).Return(
func([]byte) []byte {
return append([]byte{}, someSymKey...)
},
nil)
for _, tcase := range testCases {
// reset value in loop to re-use
callback.called = false
Expand All @@ -424,16 +446,27 @@ func TestTranslatorService_DecryptionPoisonRecord(t *testing.T) {
// reset all .On registered callbacks
keyStorage.ExpectedCalls = nil
keyStorage.On("GetPoisonSymmetricKeys").Return(func() [][]byte { return [][]byte{append([]byte{}, poisonSymKey...)} }, nil)
keyStorage.On("GetPoisonSymmetricKey").Return(func() []byte { return append([]byte{}, poisonSymKey...) }, nil)
keyStorage.On("GetZoneIDSymmetricKeys", mock.MatchedBy(func([]byte) bool { return true })).Return(
func([]byte) [][]byte {
return [][]byte{append([]byte{}, someSymKey...)}
},
nil)
keyStorage.On("GetZoneIDSymmetricKey", mock.MatchedBy(func([]byte) bool { return true })).Return(
func([]byte) []byte {
return append([]byte{}, someSymKey...)
},
nil)
keyStorage.On("GetClientIDSymmetricKeys", mock.MatchedBy(func([]byte) bool { return true })).Return(
func([]byte) [][]byte {
return [][]byte{append([]byte{}, someSymKey...)}
},
nil)
keyStorage.On("GetClientIDSymmetricKey", mock.MatchedBy(func([]byte) bool { return true })).Return(
func([]byte) []byte {
return append([]byte{}, someSymKey...)
},
nil)
for _, tcase := range testCases {
// reset value in loop to re-use
callback.called = false
Expand Down Expand Up @@ -614,6 +647,11 @@ func testgRPCServiceFlow(ctx context.Context, expectedClientID []byte, conn *grp
return [][]byte{append([]byte{}, testSymmetricKey...)}
},
nil)
keystorage.On("GetClientIDSymmetricKey", mock.Anything).Return(
func([]byte) []byte {
return append([]byte{}, testSymmetricKey...)
},
nil)
symWriterClient := NewWriterSymClient(conn)
symEncryptResponse, err := symWriterClient.EncryptSym(ctx, &EncryptSymRequest{Data: testData})
if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions cmd/acra-translator/http_api/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ func initKeyStore(clientID, zoneID []byte, keyStorage *mocks.ServerKeyStore, t *
keyStorage.On("GetClientIDSymmetricKeys", mock.MatchedBy(func(id []byte) bool {
return bytes.Equal(id, clientID)
})).Return(func([]byte) [][]byte { return [][]byte{append([]byte{}, acraBlockSymKey...)} }, nil)
keyStorage.On("GetClientIDSymmetricKey", mock.MatchedBy(func(id []byte) bool {
return bytes.Equal(id, clientID)
})).Return(func([]byte) []byte { return append([]byte{}, acraBlockSymKey...) }, nil)
keyStorage.On("GetHMACSecretKey", mock.MatchedBy(func(id []byte) bool {
return bytes.Equal(id, clientID)
})).Return(func([]byte) []byte { return append([]byte{}, hmacSymKey...) }, nil)
Expand All @@ -146,6 +149,9 @@ func initKeyStore(clientID, zoneID []byte, keyStorage *mocks.ServerKeyStore, t *
keyStorage.On("GetZoneIDSymmetricKeys", mock.MatchedBy(func(id []byte) bool {
return bytes.Equal(id, zoneID)
})).Return(func([]byte) [][]byte { return [][]byte{append([]byte{}, acraBlockZoneKey...)} }, nil)
keyStorage.On("GetZoneIDSymmetricKey", mock.MatchedBy(func(id []byte) bool {
return bytes.Equal(id, zoneID)
})).Return(func([]byte) []byte { return append([]byte{}, acraBlockZoneKey...) }, nil)
keyStorage.On("GetClientIDEncryptionPublicKey", mock.MatchedBy(func(id []byte) bool {
return bytes.Equal(id, clientID)
})).Return(AcraStructKeyPair.Public, nil)
Expand Down
Loading

0 comments on commit b229824

Please sign in to comment.