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 import static org.junit.Assert.assertThrows; 22 23 import com.google.crypto.tink.aead.AeadConfig; 24 import com.google.crypto.tink.mac.MacConfig; 25 import java.io.ByteArrayInputStream; 26 import java.io.ByteArrayOutputStream; 27 import java.security.GeneralSecurityException; 28 import org.junit.BeforeClass; 29 import org.junit.Test; 30 import org.junit.runner.RunWith; 31 import org.junit.runners.JUnit4; 32 33 /** Tests for BinaryKeysetReader. */ 34 @RunWith(JUnit4.class) 35 public class BinaryKeysetReaderTest { 36 37 @BeforeClass setUp()38 public static void setUp() throws GeneralSecurityException { 39 MacConfig.register(); 40 AeadConfig.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 = "message".getBytes(UTF_8); 47 48 assertThat(handle2.getKeyset()).isEqualTo(handle1.getKeyset()); 49 mac2.verifyMac(mac1.computeMac(message), message); 50 } 51 52 @Test testReadWithInputStream_singleKey_shouldWork()53 public void testReadWithInputStream_singleKey_shouldWork() throws Exception { 54 KeyTemplate template = KeyTemplates.get("HMAC_SHA256_128BITTAG"); 55 KeysetHandle handle1 = KeysetHandle.generateNew(template); 56 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 57 CleartextKeysetHandle.write(handle1, BinaryKeysetWriter.withOutputStream(outputStream)); 58 KeysetHandle handle2 = 59 CleartextKeysetHandle.read( 60 BinaryKeysetReader.withInputStream( 61 new ByteArrayInputStream(outputStream.toByteArray()))); 62 63 assertKeysetHandle(handle1, handle2); 64 } 65 66 @Test testReadWithInputStream_multipleKeys_shouldWork()67 public void testReadWithInputStream_multipleKeys_shouldWork() throws Exception { 68 KeysetHandle handle1 = 69 KeysetHandle.newBuilder() 70 .addEntry( 71 KeysetHandle.generateEntryFromParametersName("HMAC_SHA256_128BITTAG") 72 .withRandomId() 73 .makePrimary()) 74 .addEntry( 75 KeysetHandle.generateEntryFromParametersName("HMAC_SHA256_128BITTAG") 76 .withRandomId()) 77 .addEntry( 78 KeysetHandle.generateEntryFromParametersName("HMAC_SHA256_128BITTAG") 79 .withRandomId()) 80 .build(); 81 82 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 83 CleartextKeysetHandle.write(handle1, BinaryKeysetWriter.withOutputStream(outputStream)); 84 KeysetHandle handle2 = 85 CleartextKeysetHandle.read( 86 BinaryKeysetReader.withInputStream( 87 new ByteArrayInputStream(outputStream.toByteArray()))); 88 89 assertKeysetHandle(handle1, handle2); 90 } 91 92 @Test testReadWithBytes_shouldWork()93 public void testReadWithBytes_shouldWork() throws Exception { 94 KeyTemplate template = KeyTemplates.get("HMAC_SHA256_128BITTAG"); 95 KeysetHandle handle1 = KeysetHandle.generateNew(template); 96 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 97 CleartextKeysetHandle.write(handle1, BinaryKeysetWriter.withOutputStream(outputStream)); 98 byte[] binaryKeyset = outputStream.toByteArray(); 99 100 KeysetReader reader = BinaryKeysetReader.withBytes(binaryKeyset); 101 KeysetHandle handle2 = CleartextKeysetHandle.read(reader); 102 assertKeysetHandle(handle1, handle2); 103 } 104 105 @Test testWithBytesReadTwice_fails()106 public void testWithBytesReadTwice_fails() throws Exception { 107 KeyTemplate template = KeyTemplates.get("HMAC_SHA256_128BITTAG"); 108 KeysetHandle handle1 = KeysetHandle.generateNew(template); 109 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 110 CleartextKeysetHandle.write(handle1, BinaryKeysetWriter.withOutputStream(outputStream)); 111 byte[] binaryKeyset = outputStream.toByteArray(); 112 113 KeysetReader reader = BinaryKeysetReader.withBytes(binaryKeyset); 114 KeysetHandle unused = CleartextKeysetHandle.read(reader); 115 116 assertThrows( 117 GeneralSecurityException.class, 118 () -> CleartextKeysetHandle.read(reader)); 119 } 120 121 @Test testReadEncrypted_singleKey_shouldWork()122 public void testReadEncrypted_singleKey_shouldWork() throws Exception { 123 Aead keysetEncryptionAead = 124 KeysetHandle.generateNew(KeyTemplates.get("AES128_EAX")) 125 .getPrimitive(RegistryConfiguration.get(), Aead.class); 126 KeysetHandle handle1 = KeysetHandle.generateNew(KeyTemplates.get("HMAC_SHA256_128BITTAG")); 127 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 128 handle1.write(BinaryKeysetWriter.withOutputStream(outputStream), keysetEncryptionAead); 129 KeysetHandle handle2 = 130 KeysetHandle.read( 131 BinaryKeysetReader.withInputStream( 132 new ByteArrayInputStream(outputStream.toByteArray())), 133 keysetEncryptionAead); 134 135 assertKeysetHandle(handle1, handle2); 136 } 137 138 @Test testReadEncrypted_multipleKeys_shouldWork()139 public void testReadEncrypted_multipleKeys_shouldWork() throws Exception { 140 KeysetHandle handle1 = 141 KeysetHandle.newBuilder() 142 .addEntry( 143 KeysetHandle.generateEntryFromParametersName("HMAC_SHA256_128BITTAG") 144 .withRandomId() 145 .makePrimary()) 146 .addEntry( 147 KeysetHandle.generateEntryFromParametersName("HMAC_SHA256_128BITTAG_RAW") 148 .withRandomId()) 149 .addEntry( 150 KeysetHandle.generateEntryFromParametersName("HMAC_SHA256_256BITTAG") 151 .withRandomId().setStatus(KeyStatus.DESTROYED)) 152 .addEntry( 153 KeysetHandle.generateEntryFromParametersName("HMAC_SHA256_256BITTAG_RAW") 154 .withRandomId().setStatus(KeyStatus.DISABLED)) 155 .addEntry( 156 KeysetHandle.generateEntryFromParametersName("AES256_CMAC") 157 .withRandomId()) 158 .build(); 159 160 Aead keysetEncryptionAead = 161 KeysetHandle.generateNew(KeyTemplates.get("AES128_EAX")) 162 .getPrimitive(RegistryConfiguration.get(), Aead.class); 163 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 164 handle1.write(BinaryKeysetWriter.withOutputStream(outputStream), keysetEncryptionAead); 165 KeysetHandle handle2 = 166 KeysetHandle.read( 167 BinaryKeysetReader.withInputStream( 168 new ByteArrayInputStream(outputStream.toByteArray())), 169 keysetEncryptionAead); 170 171 assertKeysetHandle(handle1, handle2); 172 } 173 174 } 175