• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 Google LLC
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.testing.Asserts.assertEqualWhenValueParsed;
21 import static org.junit.Assert.assertThrows;
22 
23 import com.google.crypto.tink.Key;
24 import com.google.crypto.tink.Parameters;
25 import com.google.crypto.tink.aead.internal.AesGcmSivProtoSerialization;
26 import com.google.crypto.tink.internal.MutableSerializationRegistry;
27 import com.google.crypto.tink.internal.ProtoKeySerialization;
28 import com.google.crypto.tink.internal.ProtoParametersSerialization;
29 import com.google.crypto.tink.mac.MacConfig;
30 import com.google.crypto.tink.proto.AesCmacKeyFormat;
31 import com.google.crypto.tink.proto.AesCmacParams;
32 import com.google.crypto.tink.proto.AesCtrHmacAeadKeyFormat;
33 import com.google.crypto.tink.proto.AesCtrKeyFormat;
34 import com.google.crypto.tink.proto.AesCtrParams;
35 import com.google.crypto.tink.proto.AesEaxKeyFormat;
36 import com.google.crypto.tink.proto.AesEaxParams;
37 import com.google.crypto.tink.proto.AesGcmKeyFormat;
38 import com.google.crypto.tink.proto.AesGcmSivKeyFormat;
39 import com.google.crypto.tink.proto.HashType;
40 import com.google.crypto.tink.proto.HmacKeyFormat;
41 import com.google.crypto.tink.proto.HmacParams;
42 import com.google.crypto.tink.proto.KeyData.KeyMaterialType;
43 import com.google.crypto.tink.proto.KeyTemplate;
44 import com.google.crypto.tink.proto.KmsEnvelopeAeadKey;
45 import com.google.crypto.tink.proto.KmsEnvelopeAeadKeyFormat;
46 import com.google.crypto.tink.proto.OutputPrefixType;
47 import java.security.GeneralSecurityException;
48 import org.junit.BeforeClass;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 import org.junit.runners.JUnit4;
52 
53 @RunWith(JUnit4.class)
54 public final class LegacyKmsEnvelopeAeadProtoSerializationTest {
55   private static final AeadParameters CHACHA20POLY1305_PARAMETERS =
56       ChaCha20Poly1305Parameters.create(ChaCha20Poly1305Parameters.Variant.NO_PREFIX);
57 
58   private static final KeyTemplate CHACHA20POLY1305_RAW_TEMPLATE =
59       KeyTemplate.newBuilder()
60           .setTypeUrl("type.googleapis.com/google.crypto.tink.ChaCha20Poly1305Key")
61           .setOutputPrefixType(OutputPrefixType.RAW)
62           .build();
63 
64   private static final String TYPE_URL =
65       "type.googleapis.com/google.crypto.tink.KmsEnvelopeAeadKey";
66 
67   private static final MutableSerializationRegistry registry = new MutableSerializationRegistry();
68 
69   @BeforeClass
setUp()70   public static void setUp() throws Exception {
71     MacConfig.register();
72     AeadConfig.register();
73     LegacyKmsEnvelopeAeadProtoSerialization.register(registry);
74     // Also register the AesGcmSivProtoSerialization if we don't have conscrypt.
75     // We anyhow only want to parse and serialize.
76     AesGcmSivProtoSerialization.register();
77   }
78 
79   @Test
registerTwice()80   public void registerTwice() throws Exception {
81     MutableSerializationRegistry registry = new MutableSerializationRegistry();
82     LegacyKmsAeadProtoSerialization.register(registry);
83     LegacyKmsAeadProtoSerialization.register(registry);
84   }
85 
86   @Test
serializeParseParameters_aesGcm_works()87   public void serializeParseParameters_aesGcm_works() throws Exception {
88     LegacyKmsEnvelopeAeadParameters parameters =
89         LegacyKmsEnvelopeAeadParameters.builder()
90             .setKekUri("someOtherKeyUri")
91             .setDekParsingStrategy(
92                 LegacyKmsEnvelopeAeadParameters.DekParsingStrategy.ASSUME_AES_GCM)
93             .setDekParametersForNewKeys(
94                 AesGcmParameters.builder()
95                     .setIvSizeBytes(12)
96                     .setKeySizeBytes(16)
97                     .setTagSizeBytes(16)
98                     .setVariant(AesGcmParameters.Variant.NO_PREFIX)
99                     .build())
100             .build();
101 
102     ProtoParametersSerialization serialization =
103         ProtoParametersSerialization.create(
104             TYPE_URL,
105             OutputPrefixType.RAW,
106             KmsEnvelopeAeadKeyFormat.newBuilder()
107                 .setKekUri("someOtherKeyUri")
108                 .setDekTemplate(
109                     KeyTemplate.newBuilder()
110                         .setTypeUrl("type.googleapis.com/google.crypto.tink.AesGcmKey")
111                         .setValue(
112                             AesGcmKeyFormat.newBuilder().setKeySize(16).build().toByteString())
113                         .setOutputPrefixType(OutputPrefixType.RAW)
114                         .build())
115                 .build());
116 
117     ProtoParametersSerialization serialized =
118         registry.serializeParameters(parameters, ProtoParametersSerialization.class);
119     assertEqualWhenValueParsed(KmsEnvelopeAeadKeyFormat.parser(), serialized, serialization);
120 
121     Parameters parsed = registry.parseParameters(serialization);
122     assertThat(parsed).isEqualTo(parameters);
123   }
124 
125   @Test
serializeParseParameters_xChaCha20Poly1305_works()126   public void serializeParseParameters_xChaCha20Poly1305_works() throws Exception {
127     LegacyKmsEnvelopeAeadParameters parameters =
128         LegacyKmsEnvelopeAeadParameters.builder()
129             .setKekUri("someOtherKeyUriForAnXChaChaKey")
130             .setDekParsingStrategy(
131                 LegacyKmsEnvelopeAeadParameters.DekParsingStrategy.ASSUME_XCHACHA20POLY1305)
132             .setDekParametersForNewKeys(XChaCha20Poly1305Parameters.create())
133             .build();
134 
135     ProtoParametersSerialization serialization =
136         ProtoParametersSerialization.create(
137             TYPE_URL,
138             OutputPrefixType.RAW,
139             KmsEnvelopeAeadKeyFormat.newBuilder()
140                 .setKekUri("someOtherKeyUriForAnXChaChaKey")
141                 .setDekTemplate(
142                     KeyTemplate.newBuilder()
143                         .setTypeUrl("type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
144                         .setOutputPrefixType(OutputPrefixType.RAW)
145                         .build())
146                 .build());
147 
148     ProtoParametersSerialization serialized =
149         registry.serializeParameters(parameters, ProtoParametersSerialization.class);
150     assertEqualWhenValueParsed(KmsEnvelopeAeadKeyFormat.parser(), serialized, serialization);
151 
152     Parameters parsed = registry.parseParameters(serialization);
153     assertThat(parsed).isEqualTo(parameters);
154   }
155 
156   @Test
serializeParseParameters_chaCha20Poly1305_works()157   public void serializeParseParameters_chaCha20Poly1305_works() throws Exception {
158     LegacyKmsEnvelopeAeadParameters parameters =
159         LegacyKmsEnvelopeAeadParameters.builder()
160             .setKekUri("someArbitrarykeyUri723")
161             .setDekParsingStrategy(
162                 LegacyKmsEnvelopeAeadParameters.DekParsingStrategy.ASSUME_CHACHA20POLY1305)
163             .setDekParametersForNewKeys(CHACHA20POLY1305_PARAMETERS)
164             .build();
165 
166     ProtoParametersSerialization serialization =
167         ProtoParametersSerialization.create(
168             TYPE_URL,
169             OutputPrefixType.RAW,
170             KmsEnvelopeAeadKeyFormat.newBuilder()
171                 .setKekUri("someArbitrarykeyUri723")
172                 .setDekTemplate(CHACHA20POLY1305_RAW_TEMPLATE)
173                 .build());
174 
175     ProtoParametersSerialization serialized =
176         registry.serializeParameters(parameters, ProtoParametersSerialization.class);
177     assertEqualWhenValueParsed(KmsEnvelopeAeadKeyFormat.parser(), serialized, serialization);
178 
179     Parameters parsed = registry.parseParameters(serialization);
180     assertThat(parsed).isEqualTo(parameters);
181   }
182 
183   @Test
serializeParseParameters_aesCtrHmac_works()184   public void serializeParseParameters_aesCtrHmac_works() throws Exception {
185     LegacyKmsEnvelopeAeadParameters parameters =
186         LegacyKmsEnvelopeAeadParameters.builder()
187             .setKekUri("someEaxOtherKeyUri")
188             .setDekParsingStrategy(
189                 LegacyKmsEnvelopeAeadParameters.DekParsingStrategy.ASSUME_AES_CTR_HMAC)
190             .setDekParametersForNewKeys(
191                 AesCtrHmacAeadParameters.builder()
192                     .setAesKeySizeBytes(16)
193                     .setHmacKeySizeBytes(32)
194                     .setTagSizeBytes(32)
195                     .setIvSizeBytes(16)
196                     .setHashType(AesCtrHmacAeadParameters.HashType.SHA256)
197                     .setVariant(AesCtrHmacAeadParameters.Variant.NO_PREFIX)
198                     .build())
199             .build();
200 
201     AesCtrKeyFormat aesCtrKeyFormat =
202         AesCtrKeyFormat.newBuilder()
203             .setParams(AesCtrParams.newBuilder().setIvSize(16).build())
204             .setKeySize(16)
205             .build();
206     HmacKeyFormat hmacKeyFormat =
207         HmacKeyFormat.newBuilder()
208             .setParams(HmacParams.newBuilder().setHash(HashType.SHA256).setTagSize(32).build())
209             .setKeySize(32)
210             .build();
211     AesCtrHmacAeadKeyFormat format =
212         AesCtrHmacAeadKeyFormat.newBuilder()
213             .setAesCtrKeyFormat(aesCtrKeyFormat)
214             .setHmacKeyFormat(hmacKeyFormat)
215             .build();
216 
217     ProtoParametersSerialization serialization =
218         ProtoParametersSerialization.create(
219             TYPE_URL,
220             OutputPrefixType.RAW,
221             KmsEnvelopeAeadKeyFormat.newBuilder()
222                 .setKekUri("someEaxOtherKeyUri")
223                 .setDekTemplate(
224                     KeyTemplate.newBuilder()
225                         .setTypeUrl("type.googleapis.com/google.crypto.tink.AesCtrHmacAeadKey")
226                         .setOutputPrefixType(OutputPrefixType.RAW)
227                         .setValue(format.toByteString())
228                         .build())
229                 .build());
230     Parameters parsed = registry.parseParameters(serialization);
231     assertThat(parsed).isEqualTo(parameters);
232 
233     ProtoParametersSerialization serialized =
234         registry.serializeParameters(parameters, ProtoParametersSerialization.class);
235     assertEqualWhenValueParsed(KmsEnvelopeAeadKeyFormat.parser(), serialized, serialization);
236   }
237 
238   @Test
serializeParseParameters_aesEax_works()239   public void serializeParseParameters_aesEax_works() throws Exception {
240     LegacyKmsEnvelopeAeadParameters parameters =
241         LegacyKmsEnvelopeAeadParameters.builder()
242             .setKekUri("someEaxOtherKeyUri")
243             .setDekParsingStrategy(
244                 LegacyKmsEnvelopeAeadParameters.DekParsingStrategy.ASSUME_AES_EAX)
245             .setDekParametersForNewKeys(
246                 AesEaxParameters.builder()
247                     .setIvSizeBytes(12)
248                     .setKeySizeBytes(16)
249                     .setTagSizeBytes(16)
250                     .setVariant(AesEaxParameters.Variant.NO_PREFIX)
251                     .build())
252             .build();
253 
254     ProtoParametersSerialization serialization =
255         ProtoParametersSerialization.create(
256             TYPE_URL,
257             OutputPrefixType.RAW,
258             KmsEnvelopeAeadKeyFormat.newBuilder()
259                 .setKekUri("someEaxOtherKeyUri")
260                 .setDekTemplate(
261                     KeyTemplate.newBuilder()
262                         .setTypeUrl("type.googleapis.com/google.crypto.tink.AesEaxKey")
263                         .setValue(
264                             AesEaxKeyFormat.newBuilder()
265                                 .setKeySize(16)
266                                 .setParams(AesEaxParams.newBuilder().setIvSize(12))
267                                 .build()
268                                 .toByteString())
269                         .setOutputPrefixType(OutputPrefixType.RAW)
270                         .build())
271                 .build());
272 
273     ProtoParametersSerialization serialized =
274         registry.serializeParameters(parameters, ProtoParametersSerialization.class);
275     assertEqualWhenValueParsed(KmsEnvelopeAeadKeyFormat.parser(), serialized, serialization);
276 
277     Parameters parsed = registry.parseParameters(serialization);
278     assertThat(parsed).isEqualTo(parameters);
279   }
280 
281   @Test
serializeParseParameters_aesGcmSiv_works()282   public void serializeParseParameters_aesGcmSiv_works() throws Exception {
283     LegacyKmsEnvelopeAeadParameters parameters =
284         LegacyKmsEnvelopeAeadParameters.builder()
285             .setKekUri("someEaxOtherKeyUri")
286             .setDekParsingStrategy(
287                 LegacyKmsEnvelopeAeadParameters.DekParsingStrategy.ASSUME_AES_GCM_SIV)
288             .setDekParametersForNewKeys(
289                 AesGcmSivParameters.builder()
290                     .setKeySizeBytes(16)
291                     .setVariant(AesGcmSivParameters.Variant.NO_PREFIX)
292                     .build())
293             .build();
294 
295     ProtoParametersSerialization serialization =
296         ProtoParametersSerialization.create(
297             TYPE_URL,
298             OutputPrefixType.RAW,
299             KmsEnvelopeAeadKeyFormat.newBuilder()
300                 .setKekUri("someEaxOtherKeyUri")
301                 .setDekTemplate(
302                     KeyTemplate.newBuilder()
303                         .setTypeUrl("type.googleapis.com/google.crypto.tink.AesGcmSivKey")
304                         .setValue(
305                             AesGcmSivKeyFormat.newBuilder().setKeySize(16).build().toByteString())
306                         .setOutputPrefixType(OutputPrefixType.RAW)
307                         .build())
308                 .build());
309 
310     ProtoParametersSerialization serialized =
311         registry.serializeParameters(parameters, ProtoParametersSerialization.class);
312     assertEqualWhenValueParsed(KmsEnvelopeAeadKeyFormat.parser(), serialized, serialization);
313 
314     Parameters parsed = registry.parseParameters(serialization);
315     assertThat(parsed).isEqualTo(parameters);
316   }
317 
318   @Test
serializeParseParameters_withTinkPrefix_works()319   public void serializeParseParameters_withTinkPrefix_works() throws Exception {
320     LegacyKmsEnvelopeAeadParameters parameters =
321         LegacyKmsEnvelopeAeadParameters.builder()
322             .setVariant(LegacyKmsEnvelopeAeadParameters.Variant.TINK)
323             .setKekUri("kekUri")
324             .setDekParsingStrategy(
325                 LegacyKmsEnvelopeAeadParameters.DekParsingStrategy.ASSUME_AES_GCM)
326             .setDekParametersForNewKeys(
327                 AesGcmParameters.builder()
328                     .setIvSizeBytes(12)
329                     .setKeySizeBytes(16)
330                     .setTagSizeBytes(16)
331                     .setVariant(AesGcmParameters.Variant.NO_PREFIX)
332                     .build())
333             .build();
334 
335     ProtoParametersSerialization serialization =
336         ProtoParametersSerialization.create(
337             TYPE_URL,
338             OutputPrefixType.TINK,
339             KmsEnvelopeAeadKeyFormat.newBuilder()
340                 .setKekUri("kekUri")
341                 .setDekTemplate(
342                     KeyTemplate.newBuilder()
343                         .setTypeUrl("type.googleapis.com/google.crypto.tink.AesGcmKey")
344                         .setValue(
345                             AesGcmKeyFormat.newBuilder().setKeySize(16).build().toByteString())
346                         .setOutputPrefixType(OutputPrefixType.RAW)
347                         .build())
348                 .build());
349 
350     ProtoParametersSerialization serialized =
351         registry.serializeParameters(parameters, ProtoParametersSerialization.class);
352     assertEqualWhenValueParsed(KmsEnvelopeAeadKeyFormat.parser(), serialized, serialization);
353 
354     Parameters parsed = registry.parseParameters(serialization);
355     assertThat(parsed).isEqualTo(parameters);
356   }
357 
358   @Test
parseParameters_macTypeUrl_throws()359   public void parseParameters_macTypeUrl_throws() throws Exception {
360     ProtoParametersSerialization serialization =
361         ProtoParametersSerialization.create(
362             TYPE_URL,
363             OutputPrefixType.RAW,
364             KmsEnvelopeAeadKeyFormat.newBuilder()
365                 .setKekUri("someEaxOtherKeyUri")
366                 .setDekTemplate(
367                     KeyTemplate.newBuilder()
368                         .setTypeUrl("type.googleapis.com/google.crypto.tink.AesCmacParams")
369                         .setValue(
370                             AesCmacKeyFormat.newBuilder()
371                                 .setKeySize(32)
372                                 .setParams(AesCmacParams.newBuilder().setTagSize(16).build())
373                                 .build()
374                                 .toByteString())
375                         .setOutputPrefixType(OutputPrefixType.RAW)
376                         .build())
377                 .build());
378 
379     GeneralSecurityException thrown =
380         assertThrows(GeneralSecurityException.class, () -> registry.parseParameters(serialization));
381     // Check the message to ensure that the exception is not thrown when parsing the key template
382     // but instead when computing the DekParsingStrategy from the class.
383     assertThat(thrown).hasMessageThat().contains("Unsupported DEK parameters when");
384   }
385 
386   /**
387    * Tests that when parsing, the OutputPrefixType of the template in DekKeyTemplate is ignored and
388    * RAW is used instead.
389    */
390   @Test
parseParameters_dekOutputPrefixUnknown_isIgnored()391   public void parseParameters_dekOutputPrefixUnknown_isIgnored() throws Exception {
392     LegacyKmsEnvelopeAeadParameters parameters =
393         LegacyKmsEnvelopeAeadParameters.builder()
394             .setKekUri("someEaxOtherKeyUri")
395             .setDekParsingStrategy(
396                 LegacyKmsEnvelopeAeadParameters.DekParsingStrategy.ASSUME_XCHACHA20POLY1305)
397             .setDekParametersForNewKeys(XChaCha20Poly1305Parameters.create())
398             .build();
399 
400     ProtoParametersSerialization serialization =
401         ProtoParametersSerialization.create(
402             TYPE_URL,
403             OutputPrefixType.RAW,
404             KmsEnvelopeAeadKeyFormat.newBuilder()
405                 .setKekUri("someEaxOtherKeyUri")
406                 .setDekTemplate(
407                     KeyTemplate.newBuilder()
408                         .setTypeUrl("type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
409                         .setOutputPrefixType(OutputPrefixType.UNKNOWN_PREFIX)
410                         .build())
411                 .build());
412 
413     Parameters parsed = registry.parseParameters(serialization);
414     assertThat(parsed).isEqualTo(parameters);
415   }
416 
417   /**
418    * Tests that when parsing, the OutputPrefixType of the template in DekKeyTemplate is ignored and
419    * RAW is used instead.
420    */
421   @Test
parseParameters_dekOutputPrefixTink_isIgnored()422   public void parseParameters_dekOutputPrefixTink_isIgnored() throws Exception {
423     LegacyKmsEnvelopeAeadParameters parameters =
424         LegacyKmsEnvelopeAeadParameters.builder()
425             .setKekUri("someEaxOtherKeyUri")
426             .setDekParsingStrategy(
427                 LegacyKmsEnvelopeAeadParameters.DekParsingStrategy.ASSUME_XCHACHA20POLY1305)
428             .setDekParametersForNewKeys(XChaCha20Poly1305Parameters.create())
429             .build();
430 
431     ProtoParametersSerialization serialization =
432         ProtoParametersSerialization.create(
433             TYPE_URL,
434             OutputPrefixType.RAW,
435             KmsEnvelopeAeadKeyFormat.newBuilder()
436                 .setKekUri("someEaxOtherKeyUri")
437                 .setDekTemplate(
438                     KeyTemplate.newBuilder()
439                         .setTypeUrl("type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
440                         .setOutputPrefixType(OutputPrefixType.TINK)
441                         .build())
442                 .build());
443 
444     Parameters parsed = registry.parseParameters(serialization);
445     assertThat(parsed).isEqualTo(parameters);
446   }
447 
448   @Test
serializeParseKey_works()449   public void serializeParseKey_works() throws Exception {
450     LegacyKmsEnvelopeAeadParameters parameters =
451         LegacyKmsEnvelopeAeadParameters.builder()
452             .setKekUri("someKeyUriForKeyTests")
453             .setDekParsingStrategy(
454                 LegacyKmsEnvelopeAeadParameters.DekParsingStrategy.ASSUME_XCHACHA20POLY1305)
455             .setDekParametersForNewKeys(XChaCha20Poly1305Parameters.create())
456             .build();
457     LegacyKmsEnvelopeAeadKey key = LegacyKmsEnvelopeAeadKey.create(parameters);
458 
459     KmsEnvelopeAeadKeyFormat format =
460         KmsEnvelopeAeadKeyFormat.newBuilder()
461             .setKekUri("someKeyUriForKeyTests")
462             .setDekTemplate(
463                 KeyTemplate.newBuilder()
464                     .setTypeUrl("type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
465                     .setOutputPrefixType(OutputPrefixType.RAW))
466             .build();
467 
468     ProtoKeySerialization serialization =
469         ProtoKeySerialization.create(
470             TYPE_URL,
471             KmsEnvelopeAeadKey.newBuilder().setParams(format).build().toByteString(),
472             KeyMaterialType.REMOTE,
473             OutputPrefixType.RAW,
474             /* idRequirement= */ null);
475 
476     ProtoKeySerialization serialized =
477         registry.serializeKey(key, ProtoKeySerialization.class, /* access= */ null);
478     assertEqualWhenValueParsed(KmsEnvelopeAeadKey.parser(), serialized, serialization);
479 
480     Key parsed = registry.parseKey(serialization, /* access= */ null);
481     assertThat(parsed.equalsKey(key)).isTrue();
482   }
483 
484   @Test
serializeParseKeyWithTinkPrefix_works()485   public void serializeParseKeyWithTinkPrefix_works() throws Exception {
486     LegacyKmsEnvelopeAeadParameters parameters =
487         LegacyKmsEnvelopeAeadParameters.builder()
488             .setVariant(LegacyKmsEnvelopeAeadParameters.Variant.TINK)
489             .setKekUri("someKeyUriForKeyTests")
490             .setDekParsingStrategy(
491                 LegacyKmsEnvelopeAeadParameters.DekParsingStrategy.ASSUME_XCHACHA20POLY1305)
492             .setDekParametersForNewKeys(XChaCha20Poly1305Parameters.create())
493             .build();
494     LegacyKmsEnvelopeAeadKey key =
495         LegacyKmsEnvelopeAeadKey.create(parameters, /* idRequirement= */ 0x11223344);
496 
497     KmsEnvelopeAeadKeyFormat format =
498         KmsEnvelopeAeadKeyFormat.newBuilder()
499             .setKekUri("someKeyUriForKeyTests")
500             .setDekTemplate(
501                 KeyTemplate.newBuilder()
502                     .setTypeUrl("type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
503                     .setOutputPrefixType(OutputPrefixType.RAW))
504             .build();
505 
506     ProtoKeySerialization serialization =
507         ProtoKeySerialization.create(
508             TYPE_URL,
509             KmsEnvelopeAeadKey.newBuilder().setParams(format).build().toByteString(),
510             KeyMaterialType.REMOTE,
511             OutputPrefixType.TINK,
512             /* idRequirement= */ 0x11223344);
513 
514     ProtoKeySerialization serialized =
515         registry.serializeKey(key, ProtoKeySerialization.class, /* access= */ null);
516     assertEqualWhenValueParsed(KmsEnvelopeAeadKey.parser(), serialized, serialization);
517 
518     Key parsed = registry.parseKey(serialization, /* access= */ null);
519     assertThat(parsed.equalsKey(key)).isTrue();
520   }
521 
522   @Test
parseKey_wrongVersion_throws()523   public void parseKey_wrongVersion_throws() throws Exception {
524     KmsEnvelopeAeadKeyFormat format =
525         KmsEnvelopeAeadKeyFormat.newBuilder()
526             .setKekUri("someKeyUriForKeyTests")
527             .setDekTemplate(
528                 KeyTemplate.newBuilder()
529                     .setTypeUrl("type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
530                     .setOutputPrefixType(OutputPrefixType.RAW))
531             .build();
532 
533     ProtoKeySerialization serialization =
534         ProtoKeySerialization.create(
535             TYPE_URL,
536             KmsEnvelopeAeadKey.newBuilder().setVersion(1).setParams(format).build().toByteString(),
537             KeyMaterialType.REMOTE,
538             OutputPrefixType.RAW,
539             /* idRequirement= */ null);
540 
541     assertThrows(
542         GeneralSecurityException.class, () -> registry.parseKey(serialization, /* access= */ null));
543   }
544 
545   @Test
parseKey_invalidOutputPrefixType_throws()546   public void parseKey_invalidOutputPrefixType_throws() throws Exception {
547     KmsEnvelopeAeadKeyFormat format =
548         KmsEnvelopeAeadKeyFormat.newBuilder()
549             .setKekUri("someKeyUriForKeyTests")
550             .setDekTemplate(
551                 KeyTemplate.newBuilder()
552                     .setTypeUrl("type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key")
553                     .setOutputPrefixType(OutputPrefixType.RAW))
554             .build();
555 
556     ProtoKeySerialization serialization =
557         ProtoKeySerialization.create(
558             TYPE_URL,
559             KmsEnvelopeAeadKey.newBuilder().setParams(format).build().toByteString(),
560             KeyMaterialType.REMOTE,
561             OutputPrefixType.LEGACY,
562             /* idRequirement= */ 123);
563 
564     assertThrows(
565         GeneralSecurityException.class, () -> registry.parseKey(serialization, /* access= */ null));
566   }
567 }
568