• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 Google Inc.
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 java.nio.charset.StandardCharsets.UTF_8;
21 
22 import com.google.crypto.tink.aead.PredefinedAeadParameters;
23 import com.google.crypto.tink.config.TinkConfig;
24 import com.google.crypto.tink.mac.PredefinedMacParameters;
25 import com.google.crypto.tink.proto.Keyset;
26 import com.google.crypto.tink.subtle.Random;
27 import java.io.ByteArrayInputStream;
28 import java.io.ByteArrayOutputStream;
29 import java.security.GeneralSecurityException;
30 import org.junit.BeforeClass;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 import org.junit.runners.JUnit4;
34 
35 /** Tests for JsonKeysetWriter. */
36 @RunWith(JUnit4.class)
37 public class JsonKeysetWriterTest {
38   @BeforeClass
setUp()39   public static void setUp() throws GeneralSecurityException {
40     TinkConfig.register();
41   }
42 
assertKeysetHandle(KeysetHandle handle1, KeysetHandle handle2)43   private void assertKeysetHandle(KeysetHandle handle1, KeysetHandle handle2) throws Exception {
44     Mac mac1 = handle1.getPrimitive(RegistryConfiguration.get(), Mac.class);
45     Mac mac2 = handle2.getPrimitive(RegistryConfiguration.get(), Mac.class);
46     byte[] message = Random.randBytes(20);
47 
48     assertThat(handle2.getKeyset()).isEqualTo(handle1.getKeyset());
49     mac2.verifyMac(mac1.computeMac(message), message);
50   }
51 
testWrite_shouldWork(KeysetHandle handle1)52   private void testWrite_shouldWork(KeysetHandle handle1) throws Exception {
53     ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
54     CleartextKeysetHandle.write(handle1, JsonKeysetWriter.withOutputStream(outputStream));
55     KeysetHandle handle2 =
56         CleartextKeysetHandle.read(
57             JsonKeysetReader.withInputStream(new ByteArrayInputStream(outputStream.toByteArray())));
58 
59     assertKeysetHandle(handle1, handle2);
60   }
61 
62   @Test
testWrite_singleKey_shouldWork()63   public void testWrite_singleKey_shouldWork() throws Exception {
64     KeysetHandle handle1 = KeysetHandle.generateNew(PredefinedMacParameters.HMAC_SHA256_128BITTAG);
65 
66     testWrite_shouldWork(handle1);
67   }
68 
69   @Test
testWrite_multipleKeys_shouldWork()70   public void testWrite_multipleKeys_shouldWork() throws Exception {
71     KeysetHandle handle1 =
72         KeysetHandle.newBuilder()
73             .addEntry(
74                 KeysetHandle.generateEntryFromParametersName("HMAC_SHA256_128BITTAG")
75                     .withRandomId()
76                     .makePrimary())
77             .addEntry(
78                 KeysetHandle.generateEntryFromParametersName("HMAC_SHA256_128BITTAG")
79                     .withRandomId())
80             .addEntry(
81                 KeysetHandle.generateEntryFromParametersName("HMAC_SHA256_128BITTAG")
82                     .withRandomId())
83             .build();
84     testWrite_shouldWork(handle1);
85   }
86 
testWriteEncrypted_shouldWork(KeysetHandle handle1)87   private void testWriteEncrypted_shouldWork(KeysetHandle handle1) throws Exception {
88     // Encrypt the keyset with an AeadKey.
89     Aead masterKey =
90         KeysetHandle.generateNew(PredefinedAeadParameters.AES128_EAX)
91             .getPrimitive(RegistryConfiguration.get(), Aead.class);
92     ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
93     handle1.write(JsonKeysetWriter.withOutputStream(outputStream), masterKey);
94     KeysetHandle handle2 =
95         KeysetHandle.read(
96             JsonKeysetReader.withInputStream(new ByteArrayInputStream(outputStream.toByteArray())),
97             masterKey);
98 
99     assertKeysetHandle(handle1, handle2);
100   }
101 
102   @Test
testWriteEncrypted_singleKey_shouldWork()103   public void testWriteEncrypted_singleKey_shouldWork() throws Exception {
104     // Encrypt the keyset with an AeadKey.
105     KeysetHandle handle1 = KeysetHandle.generateNew(PredefinedMacParameters.HMAC_SHA256_128BITTAG);
106 
107     testWriteEncrypted_shouldWork(handle1);
108   }
109 
110   @Test
testWriteEncrypted_multipleKeys_shouldWork()111   public void testWriteEncrypted_multipleKeys_shouldWork() throws Exception {
112     // Encrypt the keyset with an AeadKey.
113     KeysetHandle handle1 =
114         KeysetHandle.newBuilder()
115             .addEntry(
116                 KeysetHandle.generateEntryFromParametersName("HMAC_SHA256_128BITTAG")
117                     .withRandomId()
118                     .makePrimary())
119             .addEntry(
120                 KeysetHandle.generateEntryFromParametersName("HMAC_SHA256_128BITTAG")
121                     .withRandomId())
122             .addEntry(
123                 KeysetHandle.generateEntryFromParametersName("HMAC_SHA256_128BITTAG")
124                     .withRandomId())
125             .build();
126     testWriteEncrypted_shouldWork(handle1);
127   }
128 
129   @Test
testWrite_writesNegativeIdAsPositive()130   public void testWrite_writesNegativeIdAsPositive() throws Exception {
131     int magicKeyId = -19230912;
132     Keyset unmodified =
133         CleartextKeysetHandle.getKeyset(
134             KeysetHandle.generateNew(PredefinedMacParameters.HMAC_SHA256_128BITTAG));
135     Keyset modified =
136         Keyset.newBuilder(unmodified)
137             .setPrimaryKeyId(magicKeyId)
138             .setKey(0, Keyset.Key.newBuilder(unmodified.getKey(0)).setKeyId(magicKeyId).build())
139             .build();
140     KeysetHandle modifiedHandle =
141         TinkProtoKeysetFormat.parseKeyset(modified.toByteArray(), InsecureSecretKeyAccess.get());
142 
143     // Write cleartext keyset
144     ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
145     CleartextKeysetHandle.write(modifiedHandle, JsonKeysetWriter.withOutputStream(outputStream));
146     String cleartextKeysetInJson = new String(outputStream.toByteArray(), UTF_8);
147 
148     assertThat(cleartextKeysetInJson).contains("\"primaryKeyId\":4275736384");
149     assertThat(cleartextKeysetInJson).contains("\"keyId\":4275736384");
150 
151     // Write encrypted keyset
152     Aead keysetEncryptionAead =
153         KeysetHandle.generateNew(KeyTemplates.get("AES128_EAX"))
154             .getPrimitive(RegistryConfiguration.get(), Aead.class);
155     ByteArrayOutputStream outputStream2 = new ByteArrayOutputStream();
156     modifiedHandle.write(JsonKeysetWriter.withOutputStream(outputStream2), keysetEncryptionAead);
157     String encryptedKeysetInJson = new String(outputStream2.toByteArray(), UTF_8);
158 
159     assertThat(encryptedKeysetInJson).contains("\"primaryKeyId\":4275736384");
160     assertThat(encryptedKeysetInJson).contains("\"keyId\":4275736384");
161   }
162 
163 }
164