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.hybrid; 18 19 import com.google.crypto.tink.aead.AeadConfig; 20 import com.google.crypto.tink.config.TinkFips; 21 import com.google.crypto.tink.daead.DeterministicAeadConfig; 22 import com.google.crypto.tink.hybrid.internal.HpkePrivateKeyManager; 23 import com.google.crypto.tink.proto.RegistryConfig; 24 import com.google.errorprone.annotations.CanIgnoreReturnValue; 25 import java.security.GeneralSecurityException; 26 27 /** 28 * Static methods and constants for registering with the {@link com.google.crypto.tink.Registry} all 29 * instances of {@link com.google.crypto.tink.HybridEncrypt} and {@link 30 * com.google.crypto.tink.HybridDecrypt} key types supported in a particular release of Tink. 31 * 32 * <p>To register all HybridEncrypt and HybridDecrypt key types provided in the latest Tink version 33 * one can do: 34 * 35 * <pre>{@code 36 * HybridConfig.register(); 37 * }</pre> 38 * 39 * <p>For more information on how to obtain and use instances of HybridEncrypt or HybridDecrypt, see 40 * {@link HybridEncryptFactory} or {@link HybridDecryptFactory}. 41 * 42 * @since 1.0.0 43 */ 44 public final class HybridConfig { 45 public static final String ECIES_AEAD_HKDF_PUBLIC_KEY_TYPE_URL = 46 initializeClassReturnInput("type.googleapis.com/google.crypto.tink.EciesAeadHkdfPublicKey"); 47 public static final String ECIES_AEAD_HKDF_PRIVATE_KEY_TYPE_URL = 48 initializeClassReturnInput("type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey"); 49 50 /** 51 * @deprecated 52 */ 53 @Deprecated 54 public static final RegistryConfig TINK_1_0_0 = RegistryConfig.getDefaultInstance(); 55 /** 56 * @deprecated 57 * @since 1.1.0 58 */ 59 @Deprecated 60 public static final RegistryConfig TINK_1_1_0 = RegistryConfig.getDefaultInstance(); 61 62 /** 63 * @deprecated 64 * @since 1.2.0 65 */ 66 @Deprecated 67 public static final RegistryConfig LATEST = RegistryConfig.getDefaultInstance(); 68 69 static { 70 try { init()71 init(); 72 } catch (GeneralSecurityException e) { 73 throw new ExceptionInInitializerError(e); 74 } 75 } 76 77 /** 78 * Returns the input, but crucially also calls the static initializer just above. 79 * 80 * <p>Before some refactorings, the string constants in this class were defined as: <code> 81 * private final static string AES_CTR_HMAC_AEAD_TYPE_URL = new SomeKeyMananger().get(); 82 * </code>. After the refactorings, it would be tempting to define them as <code> 83 * AES_CTR_HMAC_AEAD_TYPE_URL = "...";</code> However, this would change the behavior. By the JLS 84 * §12.4.1, the static initializer of the class is called if "A static field declared by T is used 85 * and the field is not a constant variable". The §4.12.4 explains that a constant variable is a 86 * "final variable of type String which is initialized with a constant expression". Hence, after 87 * the above refactoring the initializer wouldn't be called anymore. 88 * 89 * <p>Because of this, we always call this function here to enforce calling the static 90 * initializer, i.e. to enforce that when a user accesses any of the variables here, the class is 91 * initialized. 92 */ 93 @CanIgnoreReturnValue initializeClassReturnInput(String s)94 private static String initializeClassReturnInput(String s) { 95 return s; 96 } 97 98 /** 99 * Tries to register with the {@link com.google.crypto.tink.Registry} all instances of {@link 100 * com.google.crypto.tink.Catalogue} needed to handle HybridDecrypt and HybridEncrypt key types 101 * supported in Tink. 102 * 103 * <p>Because HybridDecrypt and HybridEncrypt key types depend on {@link 104 * com.google.crypto.tink.Aead} and {@link com.google.crypto.tink.Mac} key types, this method also 105 * registers all Aead and Mac catalogues. 106 * 107 * @deprecated use {@link #register} 108 */ 109 @Deprecated init()110 public static void init() throws GeneralSecurityException { 111 register(); 112 } 113 114 /** 115 * Tries to register with the {@link com.google.crypto.tink.Registry} all instances of {@link 116 * com.google.crypto.tink.Catalogue} needed to handle HybridDecrypt and HybridEncrypt key types 117 * supported in Tink. 118 * 119 * <p>Because HybridDecrypt and HybridEncrypt key types depend on {@link 120 * com.google.crypto.tink.Aead} and {@link com.google.crypto.tink.Mac} key types, this method also 121 * registers all Aead and Mac catalogues. 122 * 123 * @since 1.2.0 124 */ register()125 public static void register() throws GeneralSecurityException { 126 HybridDecryptWrapper.register(); 127 HybridEncryptWrapper.register(); 128 129 AeadConfig.register(); 130 DeterministicAeadConfig.register(); 131 132 if (TinkFips.useOnlyFips()) { 133 // If Tink is built in FIPS-mode do not register algorithms which are not compatible. 134 // Currently there is no hybrid encryption scheme which is part of FIPS 140-2, therefore 135 // we do not register any in FIPS-mode. 136 return; 137 } 138 139 EciesAeadHkdfPrivateKeyManager.registerPair(/*newKeyAllowed=*/true); 140 HpkePrivateKeyManager.registerPair(/*newKeyAllowed=*/true); 141 } 142 HybridConfig()143 private HybridConfig() {} 144 } 145