• 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;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.junit.Assert.assertThrows;
21 
22 import com.google.crypto.tink.aead.AeadConfig;
23 import com.google.crypto.tink.aead.AesGcmParameters;
24 import com.google.crypto.tink.aead.PredefinedAeadParameters;
25 import com.google.crypto.tink.internal.LegacyProtoParameters;
26 import com.google.crypto.tink.internal.MutableSerializationRegistry;
27 import com.google.crypto.tink.internal.ParametersSerializer;
28 import com.google.crypto.tink.internal.ProtoParametersSerialization;
29 import com.google.crypto.tink.proto.AesGcmKeyFormat;
30 import com.google.crypto.tink.proto.OutputPrefixType;
31 import com.google.protobuf.ByteString;
32 import java.security.GeneralSecurityException;
33 import org.junit.BeforeClass;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.junit.runners.JUnit4;
37 
38 @RunWith(JUnit4.class)
39 public final class KeyTemplateTest {
40   private static final String AES_GCM_TYPE_URL = "type.googleapis.com/google.crypto.tink.AesGcmKey";
41 
42   @BeforeClass
setUpClass()43   public static void setUpClass() throws Exception {
44     AeadConfig.register();
45   }
46 
47   @Test
testToParameters_aesGcm_works()48   public void testToParameters_aesGcm_works() throws Exception {
49     AesGcmKeyFormat format = AesGcmKeyFormat.newBuilder().setKeySize(16).build();
50 
51     assertThat(
52             KeyTemplate.create(
53                     AES_GCM_TYPE_URL, format.toByteArray(), KeyTemplate.OutputPrefixType.RAW)
54                 .toParameters())
55         .isEqualTo(
56             AesGcmParameters.builder()
57                 .setKeySizeBytes(16)
58                 .setIvSizeBytes(12)
59                 .setTagSizeBytes(16)
60                 .setVariant(AesGcmParameters.Variant.NO_PREFIX)
61                 .build());
62 
63     assertThat(
64             KeyTemplate.create(
65                     AES_GCM_TYPE_URL, format.toByteArray(), KeyTemplate.OutputPrefixType.TINK)
66                 .toParameters())
67         .isEqualTo(
68             AesGcmParameters.builder()
69                 .setKeySizeBytes(16)
70                 .setIvSizeBytes(12)
71                 .setTagSizeBytes(16)
72                 .setVariant(AesGcmParameters.Variant.TINK)
73                 .build());
74   }
75 
76   @Test
testToParameters_unParseableAesGcm_fails()77   public void testToParameters_unParseableAesGcm_fails() throws Exception {
78     // Invalid Key size
79     AesGcmKeyFormat format = AesGcmKeyFormat.newBuilder().setKeySize(17).build();
80     KeyTemplate template =
81         KeyTemplate.create(
82             AES_GCM_TYPE_URL, format.toByteArray(), KeyTemplate.OutputPrefixType.RAW);
83     assertThrows(GeneralSecurityException.class, template::toParameters);
84   }
85 
86   @Test
testToParameters_notRegisteredTypeUrl_givesLegacy()87   public void testToParameters_notRegisteredTypeUrl_givesLegacy() throws Exception {
88     Parameters p =
89         KeyTemplate.create("nonexistenttypeurl", new byte[] {1}, KeyTemplate.OutputPrefixType.TINK)
90             .toParameters();
91     assertThat(p).isInstanceOf(LegacyProtoParameters.class);
92     LegacyProtoParameters parameters = (LegacyProtoParameters) p;
93     assertThat(parameters.getSerialization().getKeyTemplate().getTypeUrl())
94         .isEqualTo("nonexistenttypeurl");
95     assertThat(parameters.getSerialization().getKeyTemplate().getValue())
96         .isEqualTo(ByteString.copyFrom(new byte[] {1}));
97     assertThat(parameters.getSerialization().getKeyTemplate().getOutputPrefixType())
98         .isEqualTo(OutputPrefixType.TINK);
99   }
100 
101   @Test
testCreateFromParameters_works()102   public void testCreateFromParameters_works() throws Exception {
103     assertThat(KeyTemplate.createFrom(PredefinedAeadParameters.AES128_GCM).toParameters())
104         .isEqualTo(PredefinedAeadParameters.AES128_GCM);
105   }
106 
107   @Test
testCreateFromParameters_unparseable_throws()108   public void testCreateFromParameters_unparseable_throws() throws Exception {
109     Parameters p =
110         new Parameters() {
111           @Override
112           public boolean hasIdRequirement() {
113             return false;
114           }
115         };
116     KeyTemplate t = KeyTemplate.createFrom(p);
117     assertThrows(RuntimeException.class, () -> t.getTypeUrl());
118   }
119 
120   private static class ParametersSubclass extends Parameters {
ParametersSubclass()121     ParametersSubclass() {}
122 
123     @Override
hasIdRequirement()124     public boolean hasIdRequirement() {
125       return false;
126     }
127   }
128 
129   private static ParametersSerializer<ParametersSubclass, ProtoParametersSerialization>
130       PARAMETERS_SUBCLASS_SERIALIZER =
131           ParametersSerializer.create(
132               (ParametersSubclass p) ->
133                   ProtoParametersSerialization.create(
134                       "sometypeurl", OutputPrefixType.RAW, AesGcmKeyFormat.getDefaultInstance()),
135               ParametersSubclass.class,
136               ProtoParametersSerialization.class);
137 
138   @Test
testCreateFromParameters_unserializableAtCreationButLaterYes_works()139   public void testCreateFromParameters_unserializableAtCreationButLaterYes_works()
140       throws Exception {
141     Parameters p = new ParametersSubclass();
142     KeyTemplate t = KeyTemplate.createFrom(p);
143     // We only do this in this test, and never use it elsewhere -- hence this global state does not
144     // break anything.
145     MutableSerializationRegistry.globalInstance()
146         .registerParametersSerializer(PARAMETERS_SUBCLASS_SERIALIZER);
147     assertThat(t.getTypeUrl()).isEqualTo("sometypeurl");
148   }
149 }
150