Add unit tests for convergence in non-context mode

This commit is contained in:
Jeff Mitchell 2016-08-07 15:16:36 -04:00
parent 8b1d47037e
commit 1976bc0534
1 changed files with 156 additions and 38 deletions

View File

@ -56,19 +56,6 @@ func TestBackend_upsert(t *testing.T) {
})
}
func TestBackend_upsert_convergent(t *testing.T) {
decryptData := make(map[string]interface{})
logicaltest.Test(t, logicaltest.TestCase{
Factory: Factory,
Steps: []logicaltest.TestStep{
testAccStepReadPolicy(t, "test", true, false),
testAccStepEncryptUpsertConvergent(t, "test", testPlaintext, decryptData),
testAccStepReadPolicy(t, "test", false, false),
testAccStepDecrypt(t, "test", testPlaintext, decryptData),
},
})
}
func TestBackend_datakey(t *testing.T) {
dataKeyInfo := make(map[string]interface{})
logicaltest.Test(t, logicaltest.TestCase{
@ -243,6 +230,7 @@ func testAccStepReadPolicy(t *testing.T, name string, expectNone, derived bool)
KDFMode string `mapstructure:"kdf_mode"`
DeletionAllowed bool `mapstructure:"deletion_allowed"`
ConvergentEncryption bool `mapstructure:"convergent_encryption"`
ContextAsNonce bool `mapstructure:"context_as_nonce"`
}
if err := mapstructure.Decode(resp.Data, &d); err != nil {
return err
@ -323,30 +311,6 @@ func testAccStepEncryptUpsert(
}
}
func testAccStepEncryptUpsertConvergent(
t *testing.T, name, plaintext string, decryptData map[string]interface{}) logicaltest.TestStep {
return logicaltest.TestStep{
Operation: logical.CreateOperation,
Path: "encrypt/" + name,
Data: map[string]interface{}{
"plaintext": base64.StdEncoding.EncodeToString([]byte(plaintext)),
},
Check: func(resp *logical.Response) error {
var d struct {
Ciphertext string `mapstructure:"ciphertext"`
}
if err := mapstructure.Decode(resp.Data, &d); err != nil {
return err
}
if d.Ciphertext == "" {
return fmt.Errorf("missing ciphertext")
}
decryptData["ciphertext"] = d.Ciphertext
return nil
},
}
}
func testAccStepEncryptContext(
t *testing.T, name, plaintext, context string, decryptData map[string]interface{}) logicaltest.TestStep {
return logicaltest.TestStep{
@ -594,6 +558,160 @@ func TestConvergentEncryption(t *testing.T) {
System: sysView,
})
req := &logical.Request{
Storage: storage,
Operation: logical.UpdateOperation,
Path: "keys/testkeynonderived",
Data: map[string]interface{}{
"derived": false,
"convergent_encryption": true,
},
}
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("expected non-nil response")
}
if !resp.IsError() {
t.Fatalf("bad: expected error response, got %#v", *resp)
}
req.Path = "keys/testkey"
req.Data = map[string]interface{}{
"derived": true,
"convergent_encryption": true,
}
resp, err = b.HandleRequest(req)
if err != nil {
t.Fatal(err)
}
if resp != nil {
t.Fatalf("bad: got resp %#v", *resp)
}
// First, test using an invalid length of nonce
req.Path = "encrypt/testkey"
req.Data = map[string]interface{}{
"plaintext": "emlwIHphcA==", // "zip zap"
"nonce": "Zm9vIGJhcg==", // "foo bar"
"context": "pWZ6t/im3AORd0lVYE0zBdKpX6Bl3/SvFtoVTPWbdkzjG788XmMAnOlxandSdd7S",
}
resp, err = b.HandleRequest(req)
if resp == nil {
t.Fatal("expected non-nil response")
}
if !resp.IsError() {
t.Fatalf("expected error response, got %#v", *resp)
}
// Now test encrypting the same value twice
req.Data = map[string]interface{}{
"plaintext": "emlwIHphcA==", // "zip zap"
"nonce": "b25ldHdvdGhyZWVl", // "onetwothreee"
"context": "pWZ6t/im3AORd0lVYE0zBdKpX6Bl3/SvFtoVTPWbdkzjG788XmMAnOlxandSdd7S",
}
resp, err = b.HandleRequest(req)
if resp == nil {
t.Fatal("expected non-nil response")
}
if resp.IsError() {
t.Fatalf("got error response: %#v", *resp)
}
ciphertext1 := resp.Data["ciphertext"].(string)
resp, err = b.HandleRequest(req)
if resp == nil {
t.Fatal("expected non-nil response")
}
if resp.IsError() {
t.Fatalf("got error response: %#v", *resp)
}
ciphertext2 := resp.Data["ciphertext"].(string)
if ciphertext1 != ciphertext2 {
t.Fatalf("expected the same ciphertext but got %s and %s", ciphertext1, ciphertext2)
}
// For sanity, also check a different nonce value...
req.Data = map[string]interface{}{
"plaintext": "emlwIHphcA==", // "zip zap"
"nonce": "dHdvdGhyZWVmb3Vy", // "twothreefour"
"context": "pWZ6t/im3AORd0lVYE0zBdKpX6Bl3/SvFtoVTPWbdkzjG788XmMAnOlxandSdd7S",
}
resp, err = b.HandleRequest(req)
if resp == nil {
t.Fatal("expected non-nil response")
}
if resp.IsError() {
t.Fatalf("got error response: %#v", *resp)
}
ciphertext3 := resp.Data["ciphertext"].(string)
resp, err = b.HandleRequest(req)
if resp == nil {
t.Fatal("expected non-nil response")
}
if resp.IsError() {
t.Fatalf("got error response: %#v", *resp)
}
ciphertext4 := resp.Data["ciphertext"].(string)
if ciphertext3 != ciphertext4 {
t.Fatalf("expected the same ciphertext but got %s and %s", ciphertext3, ciphertext4)
}
if ciphertext1 == ciphertext3 {
t.Fatalf("expected different ciphertexts")
}
// ...and a different context value
req.Data = map[string]interface{}{
"plaintext": "emlwIHphcA==", // "zip zap"
"nonce": "dHdvdGhyZWVmb3Vy", // "twothreefour"
"context": "qV4h9iQyvn+raODOer4JNAsOhkXBwdT4HZ677Ql4KLqXSU+Jk4C/fXBWbv6xkSYT",
}
resp, err = b.HandleRequest(req)
if resp == nil {
t.Fatal("expected non-nil response")
}
if resp.IsError() {
t.Fatalf("got error response: %#v", *resp)
}
ciphertext5 := resp.Data["ciphertext"].(string)
resp, err = b.HandleRequest(req)
if resp == nil {
t.Fatal("expected non-nil response")
}
if resp.IsError() {
t.Fatalf("got error response: %#v", *resp)
}
ciphertext6 := resp.Data["ciphertext"].(string)
if ciphertext5 != ciphertext6 {
t.Fatalf("expected the same ciphertext but got %s and %s", ciphertext5, ciphertext6)
}
if ciphertext1 == ciphertext5 {
t.Fatalf("expected different ciphertexts")
}
if ciphertext3 == ciphertext5 {
t.Fatalf("expected different ciphertexts")
}
}
func TestConvergentEncryptionContextAsNonce(t *testing.T) {
var b *backend
sysView := logical.TestSystemView()
storage := &logical.InmemStorage{}
b = Backend(&logical.BackendConfig{
StorageView: storage,
System: sysView,
})
req := &logical.Request{
Storage: storage,
Operation: logical.UpdateOperation,
@ -696,7 +814,7 @@ func TestConvergentEncryption(t *testing.T) {
ciphertext4 := resp.Data["ciphertext"].(string)
if ciphertext3 != ciphertext4 {
t.Fatalf("expected the same ciphertext but got %s and %s", ciphertext1, ciphertext2)
t.Fatalf("expected the same ciphertext but got %s and %s", ciphertext3, ciphertext4)
}
if ciphertext1 == ciphertext3 {
t.Fatalf("expected different ciphertexts")