24
24
import com .google .crypto .tink .KeyTemplate ;
25
25
import com .google .crypto .tink .KeyTemplates ;
26
26
import com .google .crypto .tink .KeysetHandle ;
27
+ import com .google .crypto .tink .KmsClient ;
28
+ import com .google .crypto .tink .KmsClients ;
27
29
import com .google .crypto .tink .internal .KeyTemplateProtoConverter ;
28
30
import com .google .crypto .tink .mac .HmacKeyManager ;
31
+ import com .google .crypto .tink .subtle .Random ;
32
+ import com .google .crypto .tink .testing .FakeKmsClient ;
29
33
import java .security .GeneralSecurityException ;
30
34
import org .junit .BeforeClass ;
31
35
import org .junit .Test ;
@@ -50,6 +54,33 @@ private Aead generateNewRemoteAead() throws GeneralSecurityException {
50
54
return keysetHandle .getPrimitive (Aead .class );
51
55
}
52
56
57
+ @ DataPoints ("dekParameters" )
58
+ public static final AeadParameters [] DEK_PARAMETERS =
59
+ new AeadParameters [] {
60
+ PredefinedAeadParameters .AES128_GCM ,
61
+ PredefinedAeadParameters .AES256_GCM ,
62
+ PredefinedAeadParameters .AES128_EAX ,
63
+ PredefinedAeadParameters .AES256_EAX ,
64
+ PredefinedAeadParameters .AES128_CTR_HMAC_SHA256 ,
65
+ PredefinedAeadParameters .AES256_CTR_HMAC_SHA256 ,
66
+ PredefinedAeadParameters .CHACHA20_POLY1305 ,
67
+ PredefinedAeadParameters .XCHACHA20_POLY1305 ,
68
+ };
69
+
70
+ @ Theory
71
+ public void createEncryptDecrypt_works (
72
+ @ FromDataPoints ("dekParameters" ) AeadParameters dekParameters ) throws Exception {
73
+ Aead remoteAead = this .generateNewRemoteAead ();
74
+ Aead envAead = KmsEnvelopeAead .create (dekParameters , remoteAead );
75
+ byte [] plaintext = "plaintext" .getBytes (UTF_8 );
76
+ byte [] associatedData = "associatedData" .getBytes (UTF_8 );
77
+ byte [] ciphertext = envAead .encrypt (plaintext , associatedData );
78
+ assertThat (envAead .decrypt (ciphertext , associatedData )).isEqualTo (plaintext );
79
+
80
+ assertThat (envAead .decrypt (envAead .encrypt (plaintext , EMPTY_ADD ), EMPTY_ADD ))
81
+ .isEqualTo (plaintext );
82
+ }
83
+
53
84
@ DataPoints ("tinkDekTemplates" )
54
85
public static final String [] TINK_DEK_TEMPLATES =
55
86
new String [] {
@@ -65,10 +96,10 @@ private Aead generateNewRemoteAead() throws GeneralSecurityException {
65
96
};
66
97
67
98
@ Theory
68
- public void encryptDecrypt_works ( @ FromDataPoints ( "tinkDekTemplates" ) String dekTemplateName )
69
- throws Exception {
99
+ public void legacyConstructorEncryptDecrypt_works (
100
+ @ FromDataPoints ( "tinkDekTemplates" ) String dekTemplateName ) throws Exception {
70
101
Aead remoteAead = this .generateNewRemoteAead ();
71
- KmsEnvelopeAead envAead =
102
+ Aead envAead =
72
103
new KmsEnvelopeAead (
73
104
KeyTemplateProtoConverter .toProto (KeyTemplates .get (dekTemplateName )), remoteAead );
74
105
byte [] plaintext = "plaintext" .getBytes (UTF_8 );
@@ -94,9 +125,7 @@ public void createKeyFormatWithInvalidDekTemplate_fails() throws Exception {
94
125
@ Test
95
126
public void decryptWithInvalidAssociatedData_fails () throws GeneralSecurityException {
96
127
Aead remoteAead = this .generateNewRemoteAead ();
97
- KmsEnvelopeAead envAead =
98
- new KmsEnvelopeAead (
99
- KeyTemplateProtoConverter .toProto (KeyTemplates .get ("AES128_EAX" )), remoteAead );
128
+ Aead envAead = KmsEnvelopeAead .create (PredefinedAeadParameters .AES128_EAX , remoteAead );
100
129
byte [] plaintext = "plaintext" .getBytes (UTF_8 );
101
130
byte [] associatedData = "associatedData" .getBytes (UTF_8 );
102
131
byte [] ciphertext = envAead .encrypt (plaintext , associatedData );
@@ -109,9 +138,7 @@ public void decryptWithInvalidAssociatedData_fails() throws GeneralSecurityExcep
109
138
@ Test
110
139
public void corruptedCiphertext_fails () throws GeneralSecurityException {
111
140
Aead remoteAead = this .generateNewRemoteAead ();
112
- KmsEnvelopeAead envAead =
113
- new KmsEnvelopeAead (
114
- KeyTemplateProtoConverter .toProto (KeyTemplates .get ("AES128_EAX" )), remoteAead );
141
+ Aead envAead = KmsEnvelopeAead .create (PredefinedAeadParameters .AES128_EAX , remoteAead );
115
142
byte [] associatedData = "envelope_ad" .getBytes (UTF_8 );
116
143
byte [] plaintext = "helloworld" .getBytes (UTF_8 );
117
144
byte [] ciphertext = envAead .encrypt (plaintext , associatedData );
@@ -124,9 +151,7 @@ public void corruptedCiphertext_fails() throws GeneralSecurityException {
124
151
@ Test
125
152
public void corruptedDek_fails () throws GeneralSecurityException {
126
153
Aead remoteAead = this .generateNewRemoteAead ();
127
- KmsEnvelopeAead envAead =
128
- new KmsEnvelopeAead (
129
- KeyTemplateProtoConverter .toProto (KeyTemplates .get ("AES128_EAX" )), remoteAead );
154
+ Aead envAead = KmsEnvelopeAead .create (PredefinedAeadParameters .AES128_EAX , remoteAead );
130
155
byte [] plaintext = "helloworld" .getBytes (UTF_8 );
131
156
byte [] associatedData = "envelope_ad" .getBytes (UTF_8 );
132
157
byte [] ciphertext = envAead .encrypt (plaintext , associatedData );
@@ -139,9 +164,7 @@ public void corruptedDek_fails() throws GeneralSecurityException {
139
164
@ Test
140
165
public void ciphertextTooShort_fails () throws GeneralSecurityException {
141
166
Aead remoteAead = this .generateNewRemoteAead ();
142
- KmsEnvelopeAead envAead =
143
- new KmsEnvelopeAead (
144
- KeyTemplateProtoConverter .toProto (KeyTemplates .get ("AES128_EAX" )), remoteAead );
167
+ Aead envAead = KmsEnvelopeAead .create (PredefinedAeadParameters .AES128_EAX , remoteAead );
145
168
assertThrows (
146
169
GeneralSecurityException .class ,
147
170
() -> envAead .decrypt ("foo" .getBytes (UTF_8 ), "envelope_ad" .getBytes (UTF_8 )));
@@ -150,9 +173,7 @@ public void ciphertextTooShort_fails() throws GeneralSecurityException {
150
173
@ Test
151
174
public void malformedDekLength_fails () throws GeneralSecurityException {
152
175
Aead remoteAead = this .generateNewRemoteAead ();
153
- KmsEnvelopeAead envAead =
154
- new KmsEnvelopeAead (
155
- KeyTemplateProtoConverter .toProto (KeyTemplates .get ("AES128_EAX" )), remoteAead );
176
+ Aead envAead = KmsEnvelopeAead .create (PredefinedAeadParameters .AES128_EAX , remoteAead );
156
177
157
178
byte [] plaintext = "helloworld" .getBytes (UTF_8 );
158
179
byte [] associatedData = "envelope_ad" .getBytes (UTF_8 );
@@ -174,6 +195,53 @@ public void malformedDekLength_fails() throws GeneralSecurityException {
174
195
GeneralSecurityException .class ,
175
196
() -> envAead .decrypt (corruptedCiphertext2 , associatedData ));
176
197
}
198
+
199
+ @ Test
200
+ public void create_isCompatibleWithOldConstructor () throws Exception {
201
+ String kekUri = FakeKmsClient .createFakeKeyUri ();
202
+ Aead remoteAead = new FakeKmsClient ().getAead (kekUri );
203
+
204
+ Aead aead1 =
205
+ new KmsEnvelopeAead (
206
+ KeyTemplateProtoConverter .toProto (
207
+ AesCtrHmacAeadKeyManager .aes128CtrHmacSha256Template ()),
208
+ remoteAead );
209
+ Aead aead2 =
210
+ KmsEnvelopeAead .create (PredefinedAeadParameters .AES128_CTR_HMAC_SHA256 , remoteAead );
211
+
212
+ byte [] plaintext = Random .randBytes (20 );
213
+ byte [] associatedData = Random .randBytes (20 );
214
+ assertThat (aead1 .decrypt (aead2 .encrypt (plaintext , associatedData ), associatedData ))
215
+ .isEqualTo (plaintext );
216
+ assertThat (aead2 .decrypt (aead1 .encrypt (plaintext , associatedData ), associatedData ))
217
+ .isEqualTo (plaintext );
218
+ }
219
+
220
+ @ Test
221
+ public void create_isCompatibleWithKmsEnvelopeAeadKey () throws Exception {
222
+ String kekUri = FakeKmsClient .createFakeKeyUri ();
223
+ KeyTemplate dekTemplate = AesCtrHmacAeadKeyManager .aes128CtrHmacSha256Template ();
224
+
225
+ // Register kmsClient and create a keyset with a KmsEnvelopeAeadKey key.
226
+ KmsClient kmsClient1 = new FakeKmsClient (kekUri );
227
+ KmsClients .add (kmsClient1 );
228
+ KeysetHandle handle1 =
229
+ KeysetHandle .generateNew (KmsEnvelopeAeadKeyManager .createKeyTemplate (kekUri , dekTemplate ));
230
+ Aead aead1 = handle1 .getPrimitive (Aead .class );
231
+
232
+ // Get Aead object from the kmsClient, and create the envelope AEAD without the registry.
233
+ Aead remoteAead = new FakeKmsClient ().getAead (kekUri );
234
+ Aead aead2 =
235
+ KmsEnvelopeAead .create (PredefinedAeadParameters .AES128_CTR_HMAC_SHA256 , remoteAead );
236
+
237
+ // Check that aead1 and aead2 implement the same primitive
238
+ byte [] plaintext = Random .randBytes (20 );
239
+ byte [] associatedData = Random .randBytes (20 );
240
+ assertThat (aead1 .decrypt (aead2 .encrypt (plaintext , associatedData ), associatedData ))
241
+ .isEqualTo (plaintext );
242
+ assertThat (aead2 .decrypt (aead1 .encrypt (plaintext , associatedData ), associatedData ))
243
+ .isEqualTo (plaintext );
244
+ }
177
245
}
178
246
179
247
0 commit comments