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 package com.google.crypto.tink; 17 18 import static java.lang.annotation.ElementType.FIELD; 19 import static java.lang.annotation.ElementType.LOCAL_VARIABLE; 20 import static java.lang.annotation.ElementType.METHOD; 21 import static java.lang.annotation.ElementType.TYPE; 22 23 import java.lang.annotation.Retention; 24 import java.lang.annotation.RetentionPolicy; 25 import java.lang.annotation.Target; 26 27 /** 28 * Annotates methods and classes which access parts of keys. 29 * 30 * <p>In Tink, a key is a representation of a mathematical function (e.g. the function {@code 31 * Encrypt}, or the function {@code Sign}). These functions typically require all fields in the 32 * corresponding objects to be specified. A common mistake is to extract only parts of such a 33 * description. This can lead to incompatibilities. 34 * 35 * <p>For example, suppose a user want to export an RSASSA-PSS key public key from Tink for use with 36 * a different library. These keys consist of the modulus {@code n}, the public exponent {@code e}, 37 * as well as the specification of two hash functions, and the length of salt used internally in the 38 * algorithm. When exporting such a key, often users ignore the hash functions and the salt length. 39 * However, this would be a mistake: even if it works at the moment, if later Tink is configured to 40 * use a different hash function, and the resulting key is exported using such a method, the 41 * signatures will not be compatible. 42 * 43 * <p>Hence, when users access a function which requires this annotation, they should ensure that 44 * they will not get compatibility bugs in the future. In most cases, they probably should call the 45 * other methods on the corresponding class too. 46 * 47 * <p>In order to use a function which calls such a method, the function using it has to be 48 * annotated with {@code AccessesPartialKey}: 49 * 50 * <pre> 51 * class KeyExporter { 52 * ... 53 * {@literal @}AccessesPartialKey 54 * public static SecretBytes exportHmacKey(HmacKey key) { 55 * // The caller of this method can only handle keys without prefix, SHA256, 20 byte tags, 56 * // and 32 byte keys. 57 * if (key.getParameters().getVariant() != HmacParameters.Variant.NO_PREFIX || 58 * key.getParameters().getHashType() != HMacParameters.Hash.SHA_256 || 59 * key.getParameters().getTagSizeBytes() != 20 || 60 * key.getParameters().getKeySizeBytes() != 32) { 61 * throw new IllegalArgumentException("Parameters not supported by receiver."); 62 * } 63 * return key.getKeyBytes(); 64 * } 65 * } 66 * </pre> 67 */ 68 @Target({TYPE, METHOD, FIELD, LOCAL_VARIABLE}) 69 @Retention(RetentionPolicy.CLASS) 70 public @interface AccessesPartialKey {} 71