• 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.jwt;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.junit.Assert.assertThrows;
21 
22 import com.google.crypto.tink.InsecureSecretKeyAccess;
23 import com.google.crypto.tink.internal.KeyTester;
24 import com.google.crypto.tink.mac.HmacKey;
25 import com.google.crypto.tink.mac.HmacParameters;
26 import com.google.crypto.tink.util.SecretBytes;
27 import java.security.GeneralSecurityException;
28 import java.util.Optional;
29 import org.junit.Test;
30 import org.junit.runner.RunWith;
31 import org.junit.runners.JUnit4;
32 
33 @RunWith(JUnit4.class)
34 public final class JwtHmacKeyTest {
35   @Test
buildSimpleVariantCheckProperties()36   public void buildSimpleVariantCheckProperties() throws Exception {
37     JwtHmacParameters parameters =
38         JwtHmacParameters.builder()
39             .setKeySizeBytes(16)
40             .setAlgorithm(JwtHmacParameters.Algorithm.HS256)
41             .setKidStrategy(JwtHmacParameters.KidStrategy.IGNORED)
42             .build();
43     SecretBytes keyBytes = SecretBytes.randomBytes(16);
44     JwtHmacKey key = JwtHmacKey.builder().setParameters(parameters).setKeyBytes(keyBytes).build();
45     assertThat(key.getParameters()).isEqualTo(parameters);
46     assertThat(key.getKeyBytes()).isEqualTo(keyBytes);
47     assertThat(key.getKid()).isEqualTo(Optional.empty());
48   }
49 
50   @Test
buildWithoutKeyBytes_throws()51   public void buildWithoutKeyBytes_throws() throws Exception {
52     JwtHmacParameters parameters =
53         JwtHmacParameters.builder()
54             .setKeySizeBytes(16)
55             .setAlgorithm(JwtHmacParameters.Algorithm.HS256)
56             .setKidStrategy(JwtHmacParameters.KidStrategy.IGNORED)
57             .build();
58     JwtHmacKey.Builder builder = JwtHmacKey.builder().setParameters(parameters);
59     assertThrows(GeneralSecurityException.class, builder::build);
60   }
61 
62   @Test
build_kidStrategyIgnored_WithCustomKid_throws()63   public void build_kidStrategyIgnored_WithCustomKid_throws() throws Exception {
64     JwtHmacParameters parameters =
65         JwtHmacParameters.builder()
66             .setKeySizeBytes(16)
67             .setAlgorithm(JwtHmacParameters.Algorithm.HS256)
68             .setKidStrategy(JwtHmacParameters.KidStrategy.IGNORED)
69             .build();
70     SecretBytes keyBytes = SecretBytes.randomBytes(16);
71     JwtHmacKey.Builder builder =
72         JwtHmacKey.builder()
73             .setParameters(parameters)
74             .setCustomKid("customKid")
75             .setKeyBytes(keyBytes);
76     assertThrows(GeneralSecurityException.class, builder::build);
77   }
78 
79   @Test
build_kidStrategyIgnored_withIdRequirement_throws()80   public void build_kidStrategyIgnored_withIdRequirement_throws() throws Exception {
81     JwtHmacParameters parameters =
82         JwtHmacParameters.builder()
83             .setKeySizeBytes(16)
84             .setAlgorithm(JwtHmacParameters.Algorithm.HS256)
85             .setKidStrategy(JwtHmacParameters.KidStrategy.IGNORED)
86             .build();
87     SecretBytes keyBytes = SecretBytes.randomBytes(16);
88     JwtHmacKey.Builder builder =
89         JwtHmacKey.builder().setParameters(parameters).setIdRequirement(120).setKeyBytes(keyBytes);
90     assertThrows(GeneralSecurityException.class, builder::build);
91   }
92 
93   @Test
build_kidStrategyCustom()94   public void build_kidStrategyCustom() throws Exception {
95     JwtHmacParameters parameters =
96         JwtHmacParameters.builder()
97             .setKeySizeBytes(16)
98             .setAlgorithm(JwtHmacParameters.Algorithm.HS384)
99             .setKidStrategy(JwtHmacParameters.KidStrategy.CUSTOM)
100             .build();
101     SecretBytes keyBytes = SecretBytes.randomBytes(16);
102     JwtHmacKey key =
103         JwtHmacKey.builder()
104             .setParameters(parameters)
105             .setKeyBytes(keyBytes)
106             .setCustomKid("CustomKid")
107             .build();
108     assertThat(key.getParameters()).isEqualTo(parameters);
109     assertThat(key.getKeyBytes()).isEqualTo(keyBytes);
110     assertThat(key.getKid()).isEqualTo(Optional.of("CustomKid"));
111   }
112 
113   @Test
build_kidStrategyCustom_differentAlgorithmAndKeyId_works()114   public void build_kidStrategyCustom_differentAlgorithmAndKeyId_works() throws Exception {
115     JwtHmacParameters parameters =
116         JwtHmacParameters.builder()
117             .setKeySizeBytes(16)
118             .setAlgorithm(JwtHmacParameters.Algorithm.HS256)
119             .setKidStrategy(JwtHmacParameters.KidStrategy.CUSTOM)
120             .build();
121     SecretBytes keyBytes = SecretBytes.randomBytes(16);
122     JwtHmacKey key =
123         JwtHmacKey.builder()
124             .setParameters(parameters)
125             .setKeyBytes(keyBytes)
126             .setCustomKid("myCustomTestKid")
127             .build();
128     assertThat(key.getParameters()).isEqualTo(parameters);
129     assertThat(key.getKeyBytes()).isEqualTo(keyBytes);
130     assertThat(key.getKid()).isEqualTo(Optional.of("myCustomTestKid"));
131   }
132 
133   @Test
build_kidStrategyCustom_doNotSetCustomKid_throws()134   public void build_kidStrategyCustom_doNotSetCustomKid_throws() throws Exception {
135     JwtHmacParameters parameters =
136         JwtHmacParameters.builder()
137             .setKeySizeBytes(16)
138             .setAlgorithm(JwtHmacParameters.Algorithm.HS256)
139             .setKidStrategy(JwtHmacParameters.KidStrategy.CUSTOM)
140             .build();
141     SecretBytes keyBytes = SecretBytes.randomBytes(16);
142     JwtHmacKey.Builder builder =
143         JwtHmacKey.builder().setParameters(parameters).setKeyBytes(keyBytes);
144     assertThrows(GeneralSecurityException.class, builder::build);
145   }
146 
147   @Test
build_kidStrategyCustom_setIdRequirement_throws()148   public void build_kidStrategyCustom_setIdRequirement_throws() throws Exception {
149     JwtHmacParameters parameters =
150         JwtHmacParameters.builder()
151             .setKeySizeBytes(16)
152             .setAlgorithm(JwtHmacParameters.Algorithm.HS256)
153             .setKidStrategy(JwtHmacParameters.KidStrategy.CUSTOM)
154             .build();
155     SecretBytes keyBytes = SecretBytes.randomBytes(16);
156     JwtHmacKey.Builder builder =
157         JwtHmacKey.builder()
158             .setParameters(parameters)
159             .setCustomKid("myCustomTestKid")
160             .setKeyBytes(keyBytes)
161             .setIdRequirement(2930);
162     assertThrows(GeneralSecurityException.class, builder::build);
163   }
164 
165   @Test
build_kidStrategyBase64_works()166   public void build_kidStrategyBase64_works() throws Exception {
167     JwtHmacParameters parameters =
168         JwtHmacParameters.builder()
169             .setKeySizeBytes(16)
170             .setAlgorithm(JwtHmacParameters.Algorithm.HS384)
171             .setKidStrategy(JwtHmacParameters.KidStrategy.BASE64_ENCODED_KEY_ID)
172             .build();
173     SecretBytes keyBytes = SecretBytes.randomBytes(16);
174     JwtHmacKey key =
175         JwtHmacKey.builder()
176             .setParameters(parameters)
177             .setKeyBytes(keyBytes)
178             .setIdRequirement(0x1ac6a944)
179             .build();
180     assertThat(key.getParameters()).isEqualTo(parameters);
181     assertThat(key.getKeyBytes()).isEqualTo(keyBytes);
182     assertThat(key.getIdRequirementOrNull()).isEqualTo(0x1ac6a944);
183     // See JwtFormatTest.getKidFromTinkOutputPrefixType_success
184     assertThat(key.getKid()).isEqualTo(Optional.of("GsapRA"));
185   }
186 
187   @Test
build_kidStrategyBase64_setCustomKeyId_throws()188   public void build_kidStrategyBase64_setCustomKeyId_throws() throws Exception {
189     JwtHmacParameters parameters =
190         JwtHmacParameters.builder()
191             .setKeySizeBytes(16)
192             .setAlgorithm(JwtHmacParameters.Algorithm.HS384)
193             .setKidStrategy(JwtHmacParameters.KidStrategy.BASE64_ENCODED_KEY_ID)
194             .build();
195     SecretBytes keyBytes = SecretBytes.randomBytes(16);
196     JwtHmacKey.Builder builder =
197         JwtHmacKey.builder()
198             .setParameters(parameters)
199             .setKeyBytes(keyBytes)
200             .setIdRequirement(0x89abcdef)
201             .setCustomKid("customKeyId");
202     assertThrows(GeneralSecurityException.class, builder::build);
203   }
204 
205   @Test
build_kidStrategyBase64_omitIdRequirement_throws()206   public void build_kidStrategyBase64_omitIdRequirement_throws() throws Exception {
207     JwtHmacParameters parameters =
208         JwtHmacParameters.builder()
209             .setKeySizeBytes(16)
210             .setAlgorithm(JwtHmacParameters.Algorithm.HS384)
211             .setKidStrategy(JwtHmacParameters.KidStrategy.BASE64_ENCODED_KEY_ID)
212             .build();
213     SecretBytes keyBytes = SecretBytes.randomBytes(16);
214     JwtHmacKey.Builder builder =
215         JwtHmacKey.builder().setParameters(parameters).setKeyBytes(keyBytes);
216     assertThrows(GeneralSecurityException.class, builder::build);
217   }
218 
219   @Test
testEqualities()220   public void testEqualities() throws Exception {
221     SecretBytes keyBytes16 = SecretBytes.randomBytes(16);
222     SecretBytes keyBytes16Copy =
223         SecretBytes.copyFrom(
224             keyBytes16.toByteArray(InsecureSecretKeyAccess.get()), InsecureSecretKeyAccess.get());
225     SecretBytes keyBytes16B = SecretBytes.randomBytes(16);
226     SecretBytes keyBytes32 = SecretBytes.randomBytes(32);
227 
228     JwtHmacParameters parametersIgnoredKidStrategy =
229         JwtHmacParameters.builder()
230             .setKeySizeBytes(16)
231             .setAlgorithm(JwtHmacParameters.Algorithm.HS256)
232             .setKidStrategy(JwtHmacParameters.KidStrategy.IGNORED)
233             .build();
234     JwtHmacParameters parametersIgnoredKidStrategyCopy =
235         JwtHmacParameters.builder()
236             .setKeySizeBytes(16)
237             .setAlgorithm(JwtHmacParameters.Algorithm.HS256)
238             .setKidStrategy(JwtHmacParameters.KidStrategy.IGNORED)
239             .build();
240     JwtHmacParameters parametersHS384 =
241         JwtHmacParameters.builder()
242             .setKeySizeBytes(16)
243             .setAlgorithm(JwtHmacParameters.Algorithm.HS384)
244             .setKidStrategy(JwtHmacParameters.KidStrategy.IGNORED)
245             .build();
246     JwtHmacParameters parametersHS512 =
247         JwtHmacParameters.builder()
248             .setKeySizeBytes(16)
249             .setAlgorithm(JwtHmacParameters.Algorithm.HS512)
250             .setKidStrategy(JwtHmacParameters.KidStrategy.IGNORED)
251             .build();
252     JwtHmacParameters parametersKeySize32 =
253         JwtHmacParameters.builder()
254             .setKeySizeBytes(32)
255             .setAlgorithm(JwtHmacParameters.Algorithm.HS256)
256             .setKidStrategy(JwtHmacParameters.KidStrategy.IGNORED)
257             .build();
258     JwtHmacParameters parametersKidStrategyCustom =
259         JwtHmacParameters.builder()
260             .setKeySizeBytes(16)
261             .setAlgorithm(JwtHmacParameters.Algorithm.HS256)
262             .setKidStrategy(JwtHmacParameters.KidStrategy.CUSTOM)
263             .build();
264     JwtHmacParameters parametersKidStrategyBase64 =
265         JwtHmacParameters.builder()
266             .setKeySizeBytes(16)
267             .setAlgorithm(JwtHmacParameters.Algorithm.HS256)
268             .setKidStrategy(JwtHmacParameters.KidStrategy.BASE64_ENCODED_KEY_ID)
269             .build();
270     new KeyTester()
271         .addEqualityGroup(
272             "StrategyKidIgnored",
273             JwtHmacKey.builder()
274                 .setParameters(parametersIgnoredKidStrategy)
275                 .setKeyBytes(keyBytes16)
276                 .build(),
277             // the same key built twice must be equal
278             JwtHmacKey.builder()
279                 .setParameters(parametersIgnoredKidStrategy)
280                 .setKeyBytes(keyBytes16)
281                 .build(),
282             // the same key built with a copy of key bytes and parameters must be equal
283             JwtHmacKey.builder()
284                 .setParameters(parametersIgnoredKidStrategyCopy)
285                 .setKeyBytes(keyBytes16Copy)
286                 .build())
287         .addEqualityGroup(
288             "keyBytes16B",
289             JwtHmacKey.builder()
290                 .setParameters(parametersIgnoredKidStrategy)
291                 .setKeyBytes(keyBytes16B)
292                 .build())
293         .addEqualityGroup(
294             "parametersHS384",
295             JwtHmacKey.builder().setParameters(parametersHS384).setKeyBytes(keyBytes16).build())
296         .addEqualityGroup(
297             "parametersHS512",
298             JwtHmacKey.builder().setParameters(parametersHS512).setKeyBytes(keyBytes16).build())
299         .addEqualityGroup(
300             "parameters32BytesKey",
301             JwtHmacKey.builder().setParameters(parametersKeySize32).setKeyBytes(keyBytes32).build())
302         .addEqualityGroup(
303             "custom Kid 1",
304             JwtHmacKey.builder()
305                 .setParameters(parametersKidStrategyCustom)
306                 .setKeyBytes(keyBytes16)
307                 .setCustomKid("myCustomKid1")
308                 .build())
309         .addEqualityGroup(
310             "custom Kid 2",
311             JwtHmacKey.builder()
312                 .setParameters(parametersKidStrategyCustom)
313                 .setKeyBytes(keyBytes16)
314                 .setCustomKid("myCustomKid2")
315                 .build())
316         .addEqualityGroup(
317             "base64Id101",
318             JwtHmacKey.builder()
319                 .setParameters(parametersKidStrategyBase64)
320                 .setKeyBytes(keyBytes16)
321                 .setIdRequirement(101)
322                 .build())
323         .addEqualityGroup(
324             "base64Id102",
325             JwtHmacKey.builder()
326                 .setParameters(parametersKidStrategyBase64)
327                 .setKeyBytes(keyBytes16)
328                 .setIdRequirement(102)
329                 .build())
330         .doTests();
331   }
332 
333   @Test
testDifferentKeyTypesEquality_fails()334   public void testDifferentKeyTypesEquality_fails() throws Exception {
335     JwtHmacParameters parameters =
336         JwtHmacParameters.builder()
337             .setKeySizeBytes(16)
338             .setAlgorithm(JwtHmacParameters.Algorithm.HS256)
339             .setKidStrategy(JwtHmacParameters.KidStrategy.IGNORED)
340             .build();
341     SecretBytes keyBytes = SecretBytes.randomBytes(16);
342     JwtHmacKey key = JwtHmacKey.builder().setParameters(parameters).setKeyBytes(keyBytes).build();
343 
344     HmacParameters hmacParameters =
345         HmacParameters.builder()
346             .setKeySizeBytes(16)
347             .setTagSizeBytes(10)
348             .setHashType(HmacParameters.HashType.SHA256)
349             .setVariant(HmacParameters.Variant.NO_PREFIX)
350             .build();
351     HmacKey hmacKey = HmacKey.builder().setParameters(hmacParameters).setKeyBytes(keyBytes).build();
352 
353     assertThat(key.equalsKey(hmacKey)).isFalse();
354   }
355 }
356