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 com.google.crypto.tink.internal.MutablePrimitiveRegistry; 20 import com.google.crypto.tink.proto.KeyTypeEntry; 21 import com.google.crypto.tink.proto.RegistryConfig; 22 import java.security.GeneralSecurityException; 23 24 /** 25 * Static methods for handling of Tink configurations. 26 * 27 * <p>Configurations, i.e., a collection of key types and their corresponding key managers supported 28 * by a specific run-time environment enable control of Tink setup via JSON-formatted config files 29 * that determine which key types are supported, and provide a mechanism for deprecation of 30 * obsolete/outdated cryptographic schemes (see <a 31 * href="https://github.com/google/tink/blob/master/proto/config.proto">config.proto</a> for more 32 * info). 33 * 34 * <h3>Usage</h3> 35 * 36 * <pre>{@code 37 * RegistryConfig registryConfig = ...; 38 * Config.register(registryConfig); 39 * }</pre> 40 * 41 * @since 1.0.0 42 */ 43 public final class Config { 44 /** Returns a {@link KeyTypeEntry} for Tink key types with the specified properties. */ getTinkKeyTypeEntry( String catalogueName, String primitiveName, String keyProtoName, int keyManagerVersion, boolean newKeyAllowed)45 public static KeyTypeEntry getTinkKeyTypeEntry( 46 String catalogueName, 47 String primitiveName, 48 String keyProtoName, 49 int keyManagerVersion, 50 boolean newKeyAllowed) { 51 return KeyTypeEntry.newBuilder() 52 .setPrimitiveName(primitiveName) 53 .setTypeUrl("type.googleapis.com/google.crypto.tink." + keyProtoName) 54 .setKeyManagerVersion(keyManagerVersion) 55 .setNewKeyAllowed(newKeyAllowed) 56 .setCatalogueName(catalogueName) 57 .build(); 58 } 59 60 /** 61 * Tries to register key managers according to the specification in {@code config}. 62 * 63 * @throws GeneralSecurityException if cannot register this config with the {@link Registry}. This 64 * usually happens when either {@code config} contains any {@link KeyTypeEntry} that is 65 * already registered or the Registry cannot find any {@link 66 * com.google.crypto.tink.KeyManager} or {@link com.google.crypto.tink.Catalogue} that can 67 * handle the entry. In both cases the error message should show how to resolve it. 68 */ register(RegistryConfig config)69 public static void register(RegistryConfig config) throws GeneralSecurityException { 70 for (KeyTypeEntry entry : config.getEntryList()) { 71 registerKeyType(entry); 72 } 73 } 74 75 /** 76 * Tries to register a key manager according to the specification in {@code entry}. 77 * 78 * @throws GeneralSecurityException if cannot register this config with the {@link Registry}. This 79 * usually happens when {@code entry} is already registered or the Registry cannot find any 80 * {@link com.google.crypto.tink.KeyManager} or {@link com.google.crypto.tink.Catalogue} that 81 * can handle the entry. In both cases the error message should show how to resolve it. 82 */ registerKeyType(KeyTypeEntry entry)83 public static void registerKeyType(KeyTypeEntry entry) throws GeneralSecurityException { 84 validate(entry); 85 // Catalogues are no longer supported; we simply return on those catalogues which have been 86 // removed, as the key managers will be registered already. 87 if (entry.getCatalogueName().equals("TinkAead") 88 || entry.getCatalogueName().equals("TinkMac") 89 || entry.getCatalogueName().equals("TinkHybridDecrypt") 90 || entry.getCatalogueName().equals("TinkHybridEncrypt") 91 || entry.getCatalogueName().equals("TinkPublicKeySign") 92 || entry.getCatalogueName().equals("TinkPublicKeyVerify") 93 || entry.getCatalogueName().equals("TinkStreamingAead") 94 || entry.getCatalogueName().equals("TinkDeterministicAead")) { 95 return; 96 } 97 Catalogue<?> catalogue = Registry.getCatalogue(entry.getCatalogueName()); 98 MutablePrimitiveRegistry.globalInstance() 99 .registerPrimitiveWrapper(catalogue.getPrimitiveWrapper()); 100 KeyManager<?> keyManager = 101 catalogue.getKeyManager( 102 entry.getTypeUrl(), entry.getPrimitiveName(), entry.getKeyManagerVersion()); 103 Registry.registerKeyManager(keyManager, entry.getNewKeyAllowed()); 104 } 105 validate(KeyTypeEntry entry)106 private static void validate(KeyTypeEntry entry) throws GeneralSecurityException { 107 if (entry.getTypeUrl().isEmpty()) { 108 throw new GeneralSecurityException("Missing type_url."); 109 } 110 if (entry.getPrimitiveName().isEmpty()) { 111 throw new GeneralSecurityException("Missing primitive_name."); 112 } 113 if (entry.getCatalogueName().isEmpty()) { 114 throw new GeneralSecurityException("Missing catalogue_name."); 115 } 116 } 117 Config()118 private Config() {} 119 } 120