1 // Copyright 2022 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.internal; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.junit.Assert.assertThrows; 21 import static org.junit.Assume.assumeFalse; 22 import static org.junit.Assume.assumeTrue; 23 24 import com.google.crypto.tink.Aead; 25 import com.google.crypto.tink.KeyManager; 26 import com.google.crypto.tink.config.internal.TinkFipsUtil; 27 import com.google.crypto.tink.proto.KeyData; 28 import com.google.protobuf.ByteString; 29 import java.security.GeneralSecurityException; 30 import org.junit.Test; 31 import org.junit.runner.RunWith; 32 import org.junit.runners.JUnit4; 33 34 /** Tests for {@link KeyManagerRegistry}. */ 35 @RunWith(JUnit4.class) 36 public final class KeyManagerRegistryTest { 37 private static class Primitive1 {} 38 39 private static class TestKeyManager implements KeyManager<Primitive1> { TestKeyManager(String typeUrl)40 public TestKeyManager(String typeUrl) { 41 this.typeUrl = typeUrl; 42 } 43 44 private final String typeUrl; 45 46 @Override getPrimitive(ByteString serializedKey)47 public Primitive1 getPrimitive(ByteString serializedKey) throws GeneralSecurityException { 48 throw new UnsupportedOperationException("Not needed for test"); 49 } 50 51 @Override newKeyData(ByteString serializedKeyFormat)52 public KeyData newKeyData(ByteString serializedKeyFormat) throws GeneralSecurityException { 53 throw new UnsupportedOperationException("Not needed for test"); 54 } 55 56 @Override getKeyType()57 public String getKeyType() { 58 return this.typeUrl; 59 } 60 61 @Override getPrimitiveClass()62 public Class<Primitive1> getPrimitiveClass() { 63 return Primitive1.class; 64 } 65 } 66 67 @Test testEmptyRegistry()68 public void testEmptyRegistry() throws Exception { 69 KeyManagerRegistry registry = new KeyManagerRegistry(); 70 assertThrows( 71 GeneralSecurityException.class, () -> registry.getKeyManager("customTypeUrl", Aead.class)); 72 assertThrows( 73 GeneralSecurityException.class, () -> registry.getUntypedKeyManager("customTypeUrl")); 74 assertThat(registry.typeUrlExists("customTypeUrl")).isFalse(); 75 } 76 77 @Test testRegisterKeyManager_works()78 public void testRegisterKeyManager_works() throws Exception { 79 assumeFalse("Unable to test KeyManagers in Fips mode", TinkFipsUtil.useOnlyFips()); 80 KeyManagerRegistry registry = new KeyManagerRegistry(); 81 TestKeyManager manager = new TestKeyManager("customTypeUrl"); 82 registry.registerKeyManager(manager, true); 83 84 assertThat(registry.getKeyManager("customTypeUrl", Primitive1.class)).isSameInstanceAs(manager); 85 assertThat(registry.typeUrlExists("customTypeUrl")).isTrue(); 86 } 87 88 @Test testRegisterKeyManager_twice_works()89 public void testRegisterKeyManager_twice_works() throws Exception { 90 assumeFalse("Unable to test KeyManagers in Fips mode", TinkFipsUtil.useOnlyFips()); 91 KeyManagerRegistry registry = new KeyManagerRegistry(); 92 TestKeyManager manager1 = new TestKeyManager("customTypeUrl"); 93 TestKeyManager manager2 = new TestKeyManager("customTypeUrl"); 94 registry.registerKeyManager(manager1, true); 95 registry.registerKeyManager(manager2, true); 96 97 assertThat(registry.getKeyManager("customTypeUrl", Primitive1.class)) 98 .isAnyOf(manager1, manager2); 99 } 100 101 @Test testRegisterKeyManager_differentManagersSameKeyType_failsAndDoesnotChangeState()102 public void testRegisterKeyManager_differentManagersSameKeyType_failsAndDoesnotChangeState() 103 throws Exception { 104 assumeFalse("Unable to test KeyManagers in Fips mode", TinkFipsUtil.useOnlyFips()); 105 KeyManagerRegistry registry = new KeyManagerRegistry(); 106 TestKeyManager testKeyManager = new TestKeyManager("customTypeUrl"); 107 registry.registerKeyManager(testKeyManager, true); 108 109 assertThat(registry.isNewKeyAllowed("customTypeUrl")).isTrue(); 110 assertThat(registry.getUntypedKeyManager("customTypeUrl")).isSameInstanceAs(testKeyManager); 111 112 // Adding {} at the end makes this an anonymous subclass, hence a different class, so this 113 // throws. 114 assertThrows( 115 GeneralSecurityException.class, 116 () -> registry.registerKeyManager(new TestKeyManager("customTypeUrl") {}, true)); 117 118 assertThat(registry.isNewKeyAllowed("customTypeUrl")).isTrue(); 119 assertThat(registry.getUntypedKeyManager("customTypeUrl")).isSameInstanceAs(testKeyManager); 120 } 121 122 @Test testRegisterKeyManager_twoKeyTypes_works()123 public void testRegisterKeyManager_twoKeyTypes_works() throws Exception { 124 assumeFalse("Unable to test KeyManagers in Fips mode", TinkFipsUtil.useOnlyFips()); 125 KeyManagerRegistry registry = new KeyManagerRegistry(); 126 TestKeyManager manager1 = new TestKeyManager("customTypeUrl1"); 127 TestKeyManager manager2 = new TestKeyManager("customTypeUrl2"); 128 registry.registerKeyManager(manager1, true); 129 registry.registerKeyManager(manager2, true); 130 assertThat(registry.getKeyManager("customTypeUrl1", Primitive1.class)) 131 .isSameInstanceAs(manager1); 132 assertThat(registry.getKeyManager("customTypeUrl2", Primitive1.class)) 133 .isSameInstanceAs(manager2); 134 } 135 136 @Test testFipsCompatibleKeyManager_works()137 public void testFipsCompatibleKeyManager_works() throws Exception { 138 if (TinkFipsUtil.useOnlyFips()) { 139 assumeTrue( 140 "If FIPS is required, we can only register managers if the fips module is available", 141 TinkFipsUtil.fipsModuleAvailable()); 142 } 143 144 KeyManagerRegistry registry = new KeyManagerRegistry(); 145 TestKeyManager manager = new TestKeyManager("customTypeUrl1"); 146 assertThrows( 147 GeneralSecurityException.class, () -> registry.getUntypedKeyManager("customTypeUrl1")); 148 registry.registerKeyManagerWithFipsCompatibility( 149 manager, TinkFipsUtil.AlgorithmFipsCompatibility.ALGORITHM_REQUIRES_BORINGCRYPTO, true); 150 assertThat(registry.isNewKeyAllowed("customTypeUrl1")).isTrue(); 151 assertThat(registry.getKeyManager("customTypeUrl1", Primitive1.class)) 152 .isSameInstanceAs(manager); 153 assertThat(registry.getUntypedKeyManager("customTypeUrl1")).isSameInstanceAs(manager); 154 } 155 156 @Test testFipsCompatibleKeyManager_noFipsAvailable_failsAndDoesNotRegister()157 public void testFipsCompatibleKeyManager_noFipsAvailable_failsAndDoesNotRegister() 158 throws Exception { 159 assumeTrue(TinkFipsUtil.useOnlyFips()); 160 assumeFalse(TinkFipsUtil.fipsModuleAvailable()); 161 162 KeyManagerRegistry registry = new KeyManagerRegistry(); 163 TestKeyManager manager = new TestKeyManager("customTypeUrl1"); 164 assertThrows( 165 GeneralSecurityException.class, 166 () -> 167 registry.registerKeyManagerWithFipsCompatibility( 168 manager, 169 TinkFipsUtil.AlgorithmFipsCompatibility.ALGORITHM_REQUIRES_BORINGCRYPTO, 170 true)); 171 assertThat(registry.typeUrlExists("customTypeUrl1")).isFalse(); 172 assertThrows( 173 GeneralSecurityException.class, 174 () -> registry.getKeyManager("customTypeUrl1", Primitive1.class)); 175 assertThrows( 176 GeneralSecurityException.class, () -> registry.getUntypedKeyManager("customTypeUrl1")); 177 } 178 179 @Test testTypeUrlExists()180 public void testTypeUrlExists() throws Exception { 181 assumeFalse("Unable to test with KeyManagers in Fips mode", TinkFipsUtil.useOnlyFips()); 182 KeyManagerRegistry registry = new KeyManagerRegistry(); 183 TestKeyManager manager1 = new TestKeyManager("customTypeUrl1"); 184 TestKeyManager manager2 = new TestKeyManager("customTypeUrl2"); 185 registry.registerKeyManager(manager1, true); 186 registry.registerKeyManager(manager2, true); 187 assertThat(registry.typeUrlExists("customTypeUrl1")).isTrue(); 188 assertThat(registry.typeUrlExists("customTypeUrl2")).isTrue(); 189 assertThat(registry.typeUrlExists("unknownTypeUrl")).isFalse(); 190 } 191 192 @Test testGetKeyManager_works()193 public void testGetKeyManager_works() throws Exception { 194 assumeFalse("Unable to test KeyManagers in Fips mode", TinkFipsUtil.useOnlyFips()); 195 KeyManagerRegistry registry = new KeyManagerRegistry(); 196 KeyManager<?> registered = new TestKeyManager("typeUrl"); 197 registry.registerKeyManager(registered, true); 198 KeyManager<Primitive1> aeadManager1 = registry.getKeyManager("typeUrl", Primitive1.class); 199 KeyManager<?> manager = registry.getUntypedKeyManager("typeUrl"); 200 assertThat(aeadManager1).isSameInstanceAs(registered); 201 assertThat(manager).isSameInstanceAs(registered); 202 } 203 204 @Test testIsNewKeyAllowed_works()205 public void testIsNewKeyAllowed_works() throws Exception { 206 // Skip test if in FIPS mode, as registerKeyManager() is not allowed in FipsMode. 207 assumeFalse("Unable to test KeyManagers in Fips mode", TinkFipsUtil.useOnlyFips()); 208 KeyManagerRegistry registry = new KeyManagerRegistry(); 209 TestKeyManager manager1 = new TestKeyManager("customTypeUrlAllow"); 210 registry.registerKeyManager(manager1, true); 211 TestKeyManager manager2 = new TestKeyManager("customTypeUrlDisallow"); 212 registry.registerKeyManager(manager2, false); 213 assertThat(registry.isNewKeyAllowed("customTypeUrlAllow")).isTrue(); 214 assertThat(registry.isNewKeyAllowed("customTypeUrlDisallow")).isFalse(); 215 } 216 217 @Test testRegisterKeyManager_sameNewKeyAllowed_shouldWork()218 public void testRegisterKeyManager_sameNewKeyAllowed_shouldWork() throws Exception { 219 // Skip test if in FIPS mode, as registerKeyManager() is not allowed in FipsMode. 220 assumeFalse("Unable to test KeyManagers in Fips mode", TinkFipsUtil.useOnlyFips()); 221 KeyManagerRegistry registry = new KeyManagerRegistry(); 222 TestKeyManager manager = new TestKeyManager("customTypeUrl"); 223 registry.registerKeyManager(manager, false); 224 225 assertThat(registry.isNewKeyAllowed("customTypeUrl")).isFalse(); 226 assertThat(registry.getKeyManager("customTypeUrl", Primitive1.class)).isSameInstanceAs(manager); 227 assertThat(registry.getUntypedKeyManager("customTypeUrl")).isSameInstanceAs(manager); 228 229 registry.registerKeyManager(manager, false); 230 231 assertThat(registry.isNewKeyAllowed("customTypeUrl")).isFalse(); 232 assertThat(registry.getKeyManager("customTypeUrl", Primitive1.class)).isSameInstanceAs(manager); 233 assertThat(registry.getUntypedKeyManager("customTypeUrl")).isSameInstanceAs(manager); 234 } 235 236 @Test testRegisterKeyManager_moreRestrictedNewKeyAllowed_shouldWorkAndChangeState()237 public void testRegisterKeyManager_moreRestrictedNewKeyAllowed_shouldWorkAndChangeState() 238 throws Exception { 239 // Skip test if in FIPS mode, as registerKeyManager() is not allowed in FipsMode. 240 assumeFalse("Unable to test KeyManagers in Fips mode", TinkFipsUtil.useOnlyFips()); 241 KeyManagerRegistry registry = new KeyManagerRegistry(); 242 TestKeyManager manager = new TestKeyManager("customTypeUrl"); 243 registry.registerKeyManager(manager, true); 244 245 assertThat(registry.isNewKeyAllowed("customTypeUrl")).isTrue(); 246 assertThat(registry.getKeyManager("customTypeUrl", Primitive1.class)).isSameInstanceAs(manager); 247 assertThat(registry.getUntypedKeyManager("customTypeUrl")).isSameInstanceAs(manager); 248 249 registry.registerKeyManager(manager, false); 250 251 assertThat(registry.isNewKeyAllowed("customTypeUrl")).isFalse(); 252 assertThat(registry.getKeyManager("customTypeUrl", Primitive1.class)).isSameInstanceAs(manager); 253 assertThat(registry.getUntypedKeyManager("customTypeUrl")).isSameInstanceAs(manager); 254 } 255 256 @Test 257 public void testRegisterKeyManager_lessRestrictedNewKeyAllowed_shouldThrowExceptionAndNotChangeState()258 testRegisterKeyManager_lessRestrictedNewKeyAllowed_shouldThrowExceptionAndNotChangeState() 259 throws Exception { 260 // Skip test if in FIPS mode, as registerKeyManager() is not allowed in FipsMode. 261 assumeFalse("Unable to test KeyManagers in Fips mode", TinkFipsUtil.useOnlyFips()); 262 KeyManagerRegistry registry = new KeyManagerRegistry(); 263 TestKeyManager manager = new TestKeyManager("customTypeUrl"); 264 registry.registerKeyManager(manager, false); 265 266 assertThat(registry.isNewKeyAllowed("customTypeUrl")).isFalse(); 267 assertThat(registry.getKeyManager("customTypeUrl", Primitive1.class)).isSameInstanceAs(manager); 268 assertThat(registry.getUntypedKeyManager("customTypeUrl")).isSameInstanceAs(manager); 269 270 assertThrows(GeneralSecurityException.class, () -> registry.registerKeyManager(manager, true)); 271 272 assertThat(registry.isNewKeyAllowed("customTypeUrl")).isFalse(); 273 assertThat(registry.getKeyManager("customTypeUrl", Primitive1.class)).isSameInstanceAs(manager); 274 assertThat(registry.getUntypedKeyManager("customTypeUrl")).isSameInstanceAs(manager); 275 } 276 } 277