// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// package keyset_test import ( "bytes" "testing" "google.golang.org/protobuf/proto" "github.com/google/tink/go/aead" "github.com/google/tink/go/keyset" "github.com/google/tink/go/mac" "github.com/google/tink/go/signature" "github.com/google/tink/go/testkeyset" "github.com/google/tink/go/testutil" tinkpb "github.com/google/tink/go/proto/tink_go_proto" ) func TestNewHandle(t *testing.T) { template := mac.HMACSHA256Tag128KeyTemplate() handle, err := keyset.NewHandle(template) if err != nil { t.Errorf("keyset.NewHandle(template) = %v, want nil", err) } ks := testkeyset.KeysetMaterial(handle) if len(ks.Key) != 1 { t.Errorf("len(ks.Key) = %d, want 1", len(ks.Key)) } key := ks.Key[0] if ks.PrimaryKeyId != key.KeyId { t.Errorf("ks.PrimaryKeyId = %d, want %d", ks.PrimaryKeyId, key.KeyId) } if key.KeyData.TypeUrl != template.TypeUrl { t.Errorf("key.KeyData.TypeUrl = %v, want %v", key.KeyData.TypeUrl, template.TypeUrl) } if _, err = mac.New(handle); err != nil { t.Errorf("mac.New(handle) err = %v, want nil", err) } } func TestNewHandleWithInvalidTypeURLFails(t *testing.T) { // template with unknown TypeURL invalidTemplate := mac.HMACSHA256Tag128KeyTemplate() invalidTemplate.TypeUrl = "some unknown TypeURL" if _, err := keyset.NewHandle(invalidTemplate); err == nil { t.Errorf("keyset.NewHandle(invalidTemplate) err = nil, want error") } } func TestNewHandleWithNilTemplateFails(t *testing.T) { if _, err := keyset.NewHandle(nil); err == nil { t.Error("keyset.NewHandle(nil) err = nil, want error") } } func TestWriteAndReadInBinary(t *testing.T) { keysetEncryptionHandle, err := keyset.NewHandle(aead.AES128GCMKeyTemplate()) if err != nil { t.Errorf("keyset.NewHandle(aead.AES128GCMKeyTemplate()) err = %v, want nil", err) } keysetEncryptionAead, err := aead.New(keysetEncryptionHandle) if err != nil { t.Errorf("aead.New(keysetEncryptionHandle) err = %v, want nil", err) } handle, err := keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) if err != nil { t.Fatalf("keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) err = %v, want nil", err) } buff := &bytes.Buffer{} err = handle.Write(keyset.NewBinaryWriter(buff), keysetEncryptionAead) if err != nil { t.Fatalf("handle.Write(keyset.NewBinaryWriter(buff), keysetEncryptionAead) err = %v, want nil", err) } encrypted := buff.Bytes() gotHandle, err := keyset.Read(keyset.NewBinaryReader(bytes.NewBuffer(encrypted)), keysetEncryptionAead) if err != nil { t.Fatalf("keyset.Read() err = %v, want nil", err) } if !proto.Equal(testkeyset.KeysetMaterial(gotHandle), testkeyset.KeysetMaterial(handle)) { t.Fatalf("keyset.Read() = %v, want %v", gotHandle, handle) } } func TestWriteAndReadInJSON(t *testing.T) { keysetEncryptionHandle, err := keyset.NewHandle(aead.AES128GCMKeyTemplate()) if err != nil { t.Errorf("keyset.NewHandle(aead.AES128GCMKeyTemplate()) err = %v, want nil", err) } keysetEncryptionAead, err := aead.New(keysetEncryptionHandle) if err != nil { t.Errorf("aead.New(keysetEncryptionHandle) err = %v, want nil", err) } handle, err := keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) if err != nil { t.Fatalf("keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) err = %v, want nil", err) } buff := &bytes.Buffer{} err = handle.Write(keyset.NewJSONWriter(buff), keysetEncryptionAead) if err != nil { t.Fatalf("h.Write(keyset.NewJSONWriter(buff), keysetEncryptionAead) err = %v, want nil", err) } encrypted := buff.Bytes() gotHandle, err := keyset.Read(keyset.NewJSONReader(bytes.NewBuffer(encrypted)), keysetEncryptionAead) if err != nil { t.Fatalf("keyset.Read() err = %v, want nil", err) } if !proto.Equal(testkeyset.KeysetMaterial(gotHandle), testkeyset.KeysetMaterial(handle)) { t.Fatalf("keyset.Read() = %v, want %v", gotHandle, handle) } } func TestWriteAndReadWithAssociatedData(t *testing.T) { keysetEncryptionHandle, err := keyset.NewHandle(aead.AES128GCMKeyTemplate()) if err != nil { t.Errorf("keyset.NewHandle(aead.AES128GCMKeyTemplate()) err = %v, want nil", err) } keysetEncryptionAead, err := aead.New(keysetEncryptionHandle) if err != nil { t.Errorf("aead.New(keysetEncryptionHandle) err = %v, want nil", err) } handle, err := keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) if err != nil { t.Fatalf("keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) err = %v, want nil", err) } associatedData := []byte{0x01, 0x02} buff := &bytes.Buffer{} err = handle.WriteWithAssociatedData(keyset.NewBinaryWriter(buff), keysetEncryptionAead, associatedData) if err != nil { t.Fatalf("handle.WriteWithAssociatedData() err = %v, want nil", err) } encrypted := buff.Bytes() handle2, err := keyset.ReadWithAssociatedData(keyset.NewBinaryReader(bytes.NewBuffer(encrypted)), keysetEncryptionAead, associatedData) if err != nil { t.Fatalf("keyset.ReadWithAssociatedData() err = %v, want nil", err) } if !proto.Equal(testkeyset.KeysetMaterial(handle), testkeyset.KeysetMaterial(handle2)) { t.Errorf("keyset.ReadWithAssociatedData() = %v, want %v", handle2, handle) } } func TestReadWithMismatchedAssociatedData(t *testing.T) { keysetEncryptionHandle, err := keyset.NewHandle(aead.AES128GCMKeyTemplate()) if err != nil { t.Errorf("keyset.NewHandle(aead.AES128GCMKeyTemplate()) err = %v, want nil", err) } keysetEncryptionAead, err := aead.New(keysetEncryptionHandle) if err != nil { t.Errorf("aead.New(keysetEncryptionHandle) err = %v, want nil", err) } handle, err := keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) if err != nil { t.Fatalf("keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) err = %v, want nil", err) } associatedData := []byte{0x01, 0x02} buff := &bytes.Buffer{} err = handle.WriteWithAssociatedData(keyset.NewBinaryWriter(buff), keysetEncryptionAead, associatedData) if err != nil { t.Fatalf("handle.WriteWithAssociatedData() err = %v, want nil", err) } encrypted := buff.Bytes() invalidAssociatedData := []byte{0x01, 0x03} _, err = keyset.ReadWithAssociatedData(keyset.NewBinaryReader(bytes.NewBuffer(encrypted)), keysetEncryptionAead, invalidAssociatedData) if err == nil { t.Errorf("keyset.ReadWithAssociatedData() err = nil, want err") } } func TestWriteAndReadWithNoSecrets(t *testing.T) { // Create a keyset that contains a public key. privateHandle, err := keyset.NewHandle(signature.ECDSAP256KeyTemplate()) if err != nil { t.Fatalf("keyset.NewHandle(signature.ECDSAP256KeyTemplate()) err = %v, want nil", err) } handle, err := privateHandle.Public() if err != nil { t.Fatalf("privateHandle.Public() err = %v, want nil", err) } buff := &bytes.Buffer{} err = handle.WriteWithNoSecrets(keyset.NewBinaryWriter(buff)) if err != nil { t.Fatalf("handle.WriteWithAssociatedData(keyset.NewBinaryWriter(buff), masterKey, associatedData) err = %v, want nil", err) } serialized := buff.Bytes() handle2, err := keyset.ReadWithNoSecrets(keyset.NewBinaryReader(bytes.NewBuffer(serialized))) if err != nil { t.Fatalf("keyset.ReadWithNoSecrets() err = %v, want nil", err) } if !proto.Equal(testkeyset.KeysetMaterial(handle), testkeyset.KeysetMaterial(handle2)) { t.Fatalf("keyset.ReadWithNoSecrets() = %v, want %v", handle2, handle) } } func TestWriteWithNoSecretsFailsWithSymmetricSecretKey(t *testing.T) { // Create a keyset that contains a symmetric secret key. handle, err := keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) if err != nil { t.Fatalf("keyset.NewHandle(aead.AES256GCMKeyTemplate()) err = %v, want nil", err) } buff := &bytes.Buffer{} err = handle.WriteWithNoSecrets(keyset.NewBinaryWriter(buff)) if err == nil { t.Error("handle.WriteWithNoSecrets() = nil, want error") } } func TestReadWithNoSecretsFailsWithSymmetricSecretKey(t *testing.T) { // Create a keyset that contains a symmetric secret key. handle, err := keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) if err != nil { t.Fatalf("keyset.NewHandle(aead.AES256GCMKeyTemplate()) err = %v, want nil", err) } buff := &bytes.Buffer{} err = testkeyset.Write(handle, keyset.NewBinaryWriter(buff)) if err != nil { t.Fatalf("insecurecleartextkeyset.Write(handle, keyset.NewBinaryWriter(buff)) err = %v, want nil", err) } serialized := buff.Bytes() _, err = keyset.ReadWithNoSecrets(keyset.NewBinaryReader(bytes.NewBuffer(serialized))) if err == nil { t.Error("keyset.ReadWithNoSecrets() = nil, want error") } } func TestWriteWithNoSecretsFailsWithPrivateKey(t *testing.T) { // Create a keyset that contains a private key. handle, err := keyset.NewHandle(signature.ECDSAP256KeyTemplate()) if err != nil { t.Fatalf("keyset.NewHandle(signature.ECDSAP256KeyTemplate()) err = %v, want nil", err) } buff := &bytes.Buffer{} if err := handle.WriteWithNoSecrets(keyset.NewBinaryWriter(buff)); err == nil { t.Error("handle.WriteWithNoSecrets() = nil, want error") } } func TestReadWithNoSecretsFailsWithPrivateKey(t *testing.T) { // Create a keyset that contains a private key. handle, err := keyset.NewHandle(signature.ECDSAP256KeyTemplate()) if err != nil { t.Fatalf("keyset.NewHandle(signature.ECDSAP256KeyTemplate()) err = %v, want nil", err) } buff := &bytes.Buffer{} err = testkeyset.Write(handle, keyset.NewBinaryWriter(buff)) if err != nil { t.Fatalf("insecurecleartextkeyset.Write(handle, keyset.NewBinaryWriter(buff)) err = %v, want nil", err) } serialized := buff.Bytes() _, err = keyset.ReadWithNoSecrets(keyset.NewBinaryReader(bytes.NewBuffer(serialized))) if err == nil { t.Error("keyset.ReadWithNoSecrets() = nil, want error") } } func TestWriteAndReadWithNoSecretsFailsWithUnknownKeyMaterial(t *testing.T) { // Create a keyset that contains unknown key material. keyData := testutil.NewKeyData("some type url", []byte{0}, tinkpb.KeyData_UNKNOWN_KEYMATERIAL) key := testutil.NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 1, tinkpb.OutputPrefixType_TINK) ks := testutil.NewKeyset(1, []*tinkpb.Keyset_Key{key}) handle, err := testkeyset.NewHandle(ks) if err != nil { t.Fatal(err) } serialized, err := proto.Marshal(ks) if err != nil { t.Fatal(err) } buff := &bytes.Buffer{} err = handle.WriteWithNoSecrets(keyset.NewBinaryWriter(buff)) if err == nil { t.Error("handle.WriteWithNoSecrets() = nil, want error") } _, err = keyset.ReadWithNoSecrets(keyset.NewBinaryReader(bytes.NewBuffer(serialized))) if err == nil { t.Error("handle.ReadWithNoSecrets() = nil, want error") } } func TestKeysetInfo(t *testing.T) { kt := mac.HMACSHA256Tag128KeyTemplate() kh, err := keyset.NewHandle(kt) if err != nil { t.Errorf("unexpected error: %s", err) } info := kh.KeysetInfo() if info.PrimaryKeyId != info.KeyInfo[0].KeyId { t.Errorf("Expected primary key id: %d, but got: %d", info.KeyInfo[0].KeyId, info.PrimaryKeyId) } }