• 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.internal.LegacyProtoParameters;
23 import com.google.crypto.tink.internal.ProtoParametersSerialization;
24 import com.google.crypto.tink.mac.AesCmacParameters;
25 import com.google.crypto.tink.mac.MacConfig;
26 import com.google.crypto.tink.proto.AesCmacKeyFormat;
27 import com.google.crypto.tink.proto.AesCmacParams;
28 import com.google.crypto.tink.proto.KeyTemplate;
29 import com.google.crypto.tink.proto.OutputPrefixType;
30 import com.google.crypto.tink.subtle.Hex;
31 import com.google.protobuf.ByteString;
32 import com.google.protobuf.ExtensionRegistryLite;
33 import java.security.GeneralSecurityException;
34 import org.junit.BeforeClass;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 import org.junit.runners.JUnit4;
38 
39 @RunWith(JUnit4.class)
40 public final class TinkProtoParametersFormatTest {
41 
42   @BeforeClass
setUp()43   public static void setUp() throws GeneralSecurityException {
44     MacConfig.register();
45   }
46 
47   @Test
testParseAesCmacFormat()48   public void testParseAesCmacFormat() throws GeneralSecurityException {
49     AesCmacKeyFormat format =
50         AesCmacKeyFormat.newBuilder()
51             .setKeySize(32)
52             .setParams(AesCmacParams.newBuilder().setTagSize(16))
53             .build();
54     KeyTemplate template =
55         KeyTemplate.newBuilder()
56             .setValue(format.toByteString())
57             .setOutputPrefixType(OutputPrefixType.TINK)
58             .setTypeUrl("type.googleapis.com/google.crypto.tink.AesCmacKey")
59             .build();
60     assertThat(TinkProtoParametersFormat.parse(template.toByteArray()))
61         .isEqualTo(
62             AesCmacParameters.builder()
63                 .setKeySizeBytes(32)
64                 .setTagSizeBytes(16)
65                 .setVariant(AesCmacParameters.Variant.TINK)
66                 .build());
67   }
68 
69   @Test
testParseInvalidAesCmacFormat_throws()70   public void testParseInvalidAesCmacFormat_throws() throws GeneralSecurityException {
71     AesCmacKeyFormat format =
72         AesCmacKeyFormat.newBuilder()
73             .setKeySize(37) // Invalid Key Size
74             .setParams(AesCmacParams.newBuilder().setTagSize(16))
75             .build();
76     KeyTemplate template =
77         KeyTemplate.newBuilder()
78             .setValue(format.toByteString())
79             .setOutputPrefixType(OutputPrefixType.TINK)
80             .setTypeUrl("type.googleapis.com/google.crypto.tink.AesCmacKey")
81             .build();
82     assertThrows(
83         GeneralSecurityException.class,
84         () -> TinkProtoParametersFormat.parse(template.toByteArray()));
85   }
86 
87   @Test
testSerializeAesCmacFormat()88   public void testSerializeAesCmacFormat() throws Exception {
89     AesCmacParameters params =
90         AesCmacParameters.builder()
91             .setKeySizeBytes(32)
92             .setTagSizeBytes(16)
93             .setVariant(AesCmacParameters.Variant.TINK)
94             .build();
95 
96     byte[] serialized = TinkProtoParametersFormat.serialize(params);
97 
98     KeyTemplate template =
99         KeyTemplate.parseFrom(serialized, ExtensionRegistryLite.getEmptyRegistry());
100 
101     assertThat(template.getOutputPrefixType()).isEqualTo(OutputPrefixType.TINK);
102     assertThat(template.getTypeUrl())
103         .isEqualTo("type.googleapis.com/google.crypto.tink.AesCmacKey");
104     assertThat(AesCmacKeyFormat.parseFrom(template.getValue()))
105         .isEqualTo(
106             AesCmacKeyFormat.newBuilder()
107                 .setKeySize(32)
108                 .setParams(AesCmacParams.newBuilder().setTagSize(16))
109                 .build());
110   }
111 
112   /** When parsing, if a TypeURL is not recognized we currently always parse into a Legacy object */
113   @Test
testParseToLegacyFormat()114   public void testParseToLegacyFormat() throws Exception {
115     KeyTemplate template =
116         KeyTemplate.newBuilder()
117             .setValue(ByteString.copyFrom(Hex.decode("80")))
118             .setOutputPrefixType(OutputPrefixType.TINK)
119             .setTypeUrl("SomeInvalidTypeURL")
120             .build();
121     Parameters parsed = TinkProtoParametersFormat.parse(template.toByteArray());
122 
123     LegacyProtoParameters expected =
124         new LegacyProtoParameters(ProtoParametersSerialization.create(template));
125 
126     assertThat(parsed).isEqualTo(expected);
127   }
128 
129   /** When serializing a legacy object, we always succeed, even if an object is registered. */
130   @Test
testSerializeFromLegacyFormat()131   public void testSerializeFromLegacyFormat() throws Exception {
132     KeyTemplate template =
133         KeyTemplate.newBuilder()
134             .setValue(ByteString.copyFrom(Hex.decode("80")))
135             .setOutputPrefixType(OutputPrefixType.TINK)
136             .setTypeUrl("SomeInvalidTypeURL")
137             .build();
138     LegacyProtoParameters legacyParameters =
139         new LegacyProtoParameters(ProtoParametersSerialization.create(template));
140 
141     byte[] serialized = TinkProtoParametersFormat.serialize(legacyParameters);
142 
143     assertThat(KeyTemplate.parseFrom(serialized, ExtensionRegistryLite.getEmptyRegistry()))
144         .isEqualTo(template);
145   }
146 
147   @Test
testParseWithSpaceTypeUrl_throws()148   public void testParseWithSpaceTypeUrl_throws() throws Exception {
149     KeyTemplate template =
150         KeyTemplate.newBuilder()
151             .setValue(ByteString.EMPTY)
152             .setOutputPrefixType(OutputPrefixType.TINK)
153             .setTypeUrl("SomeTypeUrlWhichHas OneSpace")
154             .build();
155     assertThrows(
156         GeneralSecurityException.class,
157         () -> TinkProtoParametersFormat.parse(template.toByteArray()));
158   }
159 }
160