• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ////////////////////////////////////////////////////////////////////////////////
16 
17 package com.google.crypto.tink.aead;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static com.google.crypto.tink.internal.Util.isPrefix;
21 import static org.junit.Assert.assertThrows;
22 
23 import com.google.crypto.tink.Aead;
24 import com.google.crypto.tink.KeysetHandle;
25 import com.google.crypto.tink.KmsClients;
26 import com.google.crypto.tink.RegistryConfiguration;
27 import com.google.crypto.tink.TinkProtoKeysetFormat;
28 import com.google.crypto.tink.internal.KeyManagerRegistry;
29 import com.google.crypto.tink.subtle.Random;
30 import com.google.crypto.tink.testing.FakeKmsClient;
31 import com.google.crypto.tink.testing.TestUtil;
32 import java.security.GeneralSecurityException;
33 import java.util.Arrays;
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 import org.junit.runners.JUnit4;
38 
39 /** Tests for KmsAeadKeyManager. */
40 @RunWith(JUnit4.class)
41 public class KmsAeadKeyManagerTest {
42   @Before
setUp()43   public void setUp() throws Exception {
44     KmsClients.add(new FakeKmsClient());
45     AeadConfig.register();
46   }
47 
48   @Test
testKeyManagerRegistered()49   public void testKeyManagerRegistered() throws Exception {
50     assertThat(
51             KeyManagerRegistry.globalInstance()
52                 .getKeyManager("type.googleapis.com/google.crypto.tink.KmsAeadKey", Aead.class))
53         .isNotNull();
54   }
55 
56   @Test
testKmsAead_success()57   public void testKmsAead_success() throws Exception {
58     String keyUri = FakeKmsClient.createFakeKeyUri();
59     KeysetHandle keysetHandle =
60         KeysetHandle.generateNew(KmsAeadKeyManager.createKeyTemplate(keyUri));
61     TestUtil.runBasicAeadTests(keysetHandle.getPrimitive(RegistryConfiguration.get(), Aead.class));
62   }
63 
64   @Test
createAeadFromLegacyKmsAeadKey_works()65   public void createAeadFromLegacyKmsAeadKey_works() throws Exception {
66     String keyUri = FakeKmsClient.createFakeKeyUri();
67     LegacyKmsAeadParameters parameters = LegacyKmsAeadParameters.create(keyUri);
68     LegacyKmsAeadKey key = LegacyKmsAeadKey.create(parameters);
69     KeysetHandle keysetHandle =
70         KeysetHandle.newBuilder()
71             .addEntry(KeysetHandle.importKey(key).withRandomId().makePrimary())
72             .build();
73 
74     Aead aead = keysetHandle.getPrimitive(RegistryConfiguration.get(), Aead.class);
75     TestUtil.runBasicAeadTests(aead);
76 
77     Aead clientAead = new FakeKmsClient().getAead(keyUri);
78     byte[] plaintext = Random.randBytes(20);
79     byte[] associatedData = Random.randBytes(20);
80     byte[] ciphertext = aead.encrypt(plaintext, associatedData);
81     byte[] decrypted = clientAead.decrypt(ciphertext, associatedData);
82     assertThat(decrypted).isEqualTo(plaintext);
83   }
84 
85   @Test
createAeadFromLegacyKmsAeadKeyWithTinkPrefix_works()86   public void createAeadFromLegacyKmsAeadKeyWithTinkPrefix_works() throws Exception {
87     String keyUri = FakeKmsClient.createFakeKeyUri();
88     LegacyKmsAeadParameters parameters =
89         LegacyKmsAeadParameters.create(keyUri, LegacyKmsAeadParameters.Variant.TINK);
90     LegacyKmsAeadKey key = LegacyKmsAeadKey.create(parameters, 0x11223344);
91     KeysetHandle keysetHandle =
92         KeysetHandle.newBuilder()
93             .addEntry(KeysetHandle.importKey(key).withFixedId(0x11223344).makePrimary())
94             .build();
95 
96     Aead aead = keysetHandle.getPrimitive(RegistryConfiguration.get(), Aead.class);
97     TestUtil.runBasicAeadTests(aead);
98 
99     byte[] plaintext = Random.randBytes(20);
100     byte[] associatedData = Random.randBytes(20);
101     byte[] ciphertext = aead.encrypt(plaintext, associatedData);
102     assertThat(
103             isPrefix(
104                 new byte[] {(byte) 0x01, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44},
105                 ciphertext))
106         .isTrue();
107 
108     Aead clientAead = new FakeKmsClient().getAead(keyUri);
109     // test that clientAead can decrypt ciphertext if the 5 byte prefix is removed.
110     byte[] ciphertextWithoutPrefix = Arrays.copyOfRange(ciphertext, 5, ciphertext.length);
111     byte[] decrypted = clientAead.decrypt(ciphertextWithoutPrefix, associatedData);
112     assertThat(decrypted).isEqualTo(plaintext);
113   }
114 
115   @Test
createAeadInvalidUri_throws()116   public void createAeadInvalidUri_throws() throws Exception {
117     LegacyKmsAeadParameters parameters = LegacyKmsAeadParameters.create("wrong uri");
118     LegacyKmsAeadKey key = LegacyKmsAeadKey.create(parameters);
119     KeysetHandle keysetHandle =
120         KeysetHandle.newBuilder()
121             .addEntry(KeysetHandle.importKey(key).withRandomId().makePrimary())
122             .build();
123 
124     assertThrows(
125         GeneralSecurityException.class,
126         () -> keysetHandle.getPrimitive(RegistryConfiguration.get(), Aead.class));
127   }
128 
129   @Test
createKeyTemplateGenerateNewGetPrimitive_isSameAs_clientGetAead()130   public void createKeyTemplateGenerateNewGetPrimitive_isSameAs_clientGetAead()
131       throws Exception {
132     String keyUri = FakeKmsClient.createFakeKeyUri();
133 
134     // Create Aead primitive using createKeyTemplate, generateNew, and getPrimitive.
135     // This requires that a KmsClient that supports keyUri is registered.
136     KeysetHandle keysetHandle =
137         KeysetHandle.generateNew(KmsAeadKeyManager.createKeyTemplate(keyUri));
138     Aead aead1 = keysetHandle.getPrimitive(RegistryConfiguration.get(), Aead.class);
139 
140     // Create Aead using FakeKmsClient.getAead.
141     // No KmsClient needs to be registered.
142     Aead aead2 = new FakeKmsClient().getAead(keyUri);
143 
144     // Test that aead1 and aead2 are the same.
145     byte[] plaintext = Random.randBytes(20);
146     byte[] associatedData = Random.randBytes(20);
147     byte[] ciphertext = aead1.encrypt(plaintext, associatedData);
148     byte[] decrypted = aead2.decrypt(ciphertext, associatedData);
149     assertThat(decrypted).isEqualTo(plaintext);
150   }
151 
152   @Test
createKeyTemplate()153   public void createKeyTemplate() throws Exception {
154     String keyUri = "some example KEK URI";
155     assertThat(KmsAeadKeyManager.createKeyTemplate(keyUri).toParameters())
156         .isEqualTo(LegacyKmsAeadParameters.create(keyUri));
157   }
158 
159   @Test
generateNewFromParams_works()160   public void generateNewFromParams_works() throws Exception {
161     LegacyKmsAeadParameters parameters = LegacyKmsAeadParameters.create("some example KEK URI");
162     KeysetHandle keysetHandle1 = KeysetHandle.generateNew(parameters);
163     KeysetHandle keysetHandle2 = KeysetHandle.generateNew(parameters);
164     // For LegacyKmsAeadParameters we expect both keysets to be the same -- however, the ID of the
165     // keys may differ.
166     assertThat(keysetHandle1.getAt(0).getKey().equalsKey(keysetHandle2.getAt(0).getKey())).isTrue();
167   }
168 
169   @Test
serializeAndParse_works()170   public void serializeAndParse_works() throws Exception {
171     LegacyKmsAeadParameters parameters = LegacyKmsAeadParameters.create("some example KEK URI");
172     KeysetHandle keysetHandle1 = KeysetHandle.generateNew(parameters);
173     byte[] serialized = TinkProtoKeysetFormat.serializeKeysetWithoutSecret(keysetHandle1);
174     KeysetHandle keysetHandle2 = TinkProtoKeysetFormat.parseKeysetWithoutSecret(serialized);
175     assertThat(keysetHandle1.equalsKeyset(keysetHandle2)).isTrue();
176   }
177 }
178