open-vault/builtin/logical/transit/path_decrypt_test.go
Marco Rieger b634e1964d
fix missing plaintext in bulk decrypt response (#9991)
Decrypting an ciphertext where its corresponding value equals empty, the payload property "plaintext" is missing in the response object. This fixes the problem by adding a new, distinct struct for decrypt batch response items where "omitempty" is not set.
2020-09-22 09:43:07 -04:00

137 lines
4.1 KiB
Go

package transit
import (
"context"
"encoding/json"
"github.com/hashicorp/vault/sdk/logical"
"testing"
)
func TestTransit_BatchDecryption(t *testing.T) {
var resp *logical.Response
var err error
b, s := createBackendWithStorage(t)
batchEncryptionInput := []interface{}{
map[string]interface{}{"plaintext": ""}, // empty string
map[string]interface{}{"plaintext": "Cg=="}, // newline
map[string]interface{}{"plaintext": "dGhlIHF1aWNrIGJyb3duIGZveA=="},
}
batchEncryptionData := map[string]interface{}{
"batch_input": batchEncryptionInput,
}
batchEncryptionReq := &logical.Request{
Operation: logical.CreateOperation,
Path: "encrypt/upserted_key",
Storage: s,
Data: batchEncryptionData,
}
resp, err = b.HandleRequest(context.Background(), batchEncryptionReq)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%v resp:%#v", err, resp)
}
batchResponseItems := resp.Data["batch_results"].([]EncryptBatchResponseItem)
batchDecryptionInput := make([]interface{}, len(batchResponseItems))
for i, item := range batchResponseItems {
batchDecryptionInput[i] = map[string]interface{}{"ciphertext": item.Ciphertext}
}
batchDecryptionData := map[string]interface{}{
"batch_input": batchDecryptionInput,
}
batchDecryptionReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "decrypt/upserted_key",
Storage: s,
Data: batchDecryptionData,
}
resp, err = b.HandleRequest(context.Background(), batchDecryptionReq)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%v resp:%#v", err, resp)
}
batchDecryptionResponseItems := resp.Data["batch_results"].([]DecryptBatchResponseItem)
expectedResult := "[{\"plaintext\":\"\"},{\"plaintext\":\"Cg==\"},{\"plaintext\":\"dGhlIHF1aWNrIGJyb3duIGZveA==\"}]"
jsonResponse, err := json.Marshal(batchDecryptionResponseItems)
if err != nil || err == nil && string(jsonResponse) != expectedResult {
t.Fatalf("bad: expected json response [%s]", jsonResponse)
}
}
func TestTransit_BatchDecryption_DerivedKey(t *testing.T) {
var resp *logical.Response
var err error
b, s := createBackendWithStorage(t)
policyData := map[string]interface{}{
"derived": true,
}
policyReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "keys/existing_key",
Storage: s,
Data: policyData,
}
resp, err = b.HandleRequest(context.Background(), policyReq)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%v resp:%#v", err, resp)
}
batchInput := []interface{}{
map[string]interface{}{"plaintext": "dGhlIHF1aWNrIGJyb3duIGZveA==", "context": "dGVzdGNvbnRleHQ="},
map[string]interface{}{"plaintext": "dGhlIHF1aWNrIGJyb3duIGZveA==", "context": "dGVzdGNvbnRleHQ="},
}
batchData := map[string]interface{}{
"batch_input": batchInput,
}
batchReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "encrypt/existing_key",
Storage: s,
Data: batchData,
}
resp, err = b.HandleRequest(context.Background(), batchReq)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%v resp:%#v", err, resp)
}
batchDecryptionInputItems := resp.Data["batch_results"].([]EncryptBatchResponseItem)
batchDecryptionInput := make([]interface{}, len(batchDecryptionInputItems))
for i, item := range batchDecryptionInputItems {
batchDecryptionInput[i] = map[string]interface{}{"ciphertext": item.Ciphertext, "context": "dGVzdGNvbnRleHQ="}
}
batchDecryptionData := map[string]interface{}{
"batch_input": batchDecryptionInput,
}
batchDecryptionReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "decrypt/existing_key",
Storage: s,
Data: batchDecryptionData,
}
resp, err = b.HandleRequest(context.Background(), batchDecryptionReq)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%v resp:%#v", err, resp)
}
batchDecryptionResponseItems := resp.Data["batch_results"].([]DecryptBatchResponseItem)
plaintext := "dGhlIHF1aWNrIGJyb3duIGZveA=="
for _, item := range batchDecryptionResponseItems {
if item.Plaintext != plaintext {
t.Fatalf("bad: plaintext. Expected: %q, Actual: %q", plaintext, item.Plaintext)
}
}
}