1 // Copyright 2017 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.signature; 18 19 import com.google.crypto.tink.PublicKeySign; 20 import com.google.crypto.tink.internal.LegacyProtoKey; 21 import com.google.crypto.tink.internal.MonitoringClient; 22 import com.google.crypto.tink.internal.MonitoringKeysetInfo; 23 import com.google.crypto.tink.internal.MonitoringUtil; 24 import com.google.crypto.tink.internal.MutableMonitoringRegistry; 25 import com.google.crypto.tink.internal.MutablePrimitiveRegistry; 26 import com.google.crypto.tink.internal.PrimitiveConstructor; 27 import com.google.crypto.tink.internal.PrimitiveRegistry; 28 import com.google.crypto.tink.internal.PrimitiveSet; 29 import com.google.crypto.tink.internal.PrimitiveWrapper; 30 import com.google.crypto.tink.signature.internal.LegacyFullSign; 31 import java.security.GeneralSecurityException; 32 33 /** 34 * The implementation of {@code PrimitiveWrapper<PublicKeySign>}. 35 * 36 * <p>The returned primitive works with a keyset (rather than a single key). To sign a message, it 37 * uses the primary key in the keyset, and prepends to the signature a certain prefix associated 38 * with the primary key. 39 */ 40 public class PublicKeySignWrapper implements PrimitiveWrapper<PublicKeySign, PublicKeySign> { 41 42 private static final PublicKeySignWrapper WRAPPER = new PublicKeySignWrapper(); 43 private static final PrimitiveConstructor<LegacyProtoKey, PublicKeySign> 44 LEGACY_PRIMITIVE_CONSTRUCTOR = 45 PrimitiveConstructor.create( 46 LegacyFullSign::create, LegacyProtoKey.class, PublicKeySign.class); 47 48 private static class WrappedPublicKeySign implements PublicKeySign { 49 private final PrimitiveSet<PublicKeySign> primitives; 50 51 private final MonitoringClient.Logger logger; 52 WrappedPublicKeySign(final PrimitiveSet<PublicKeySign> primitives)53 public WrappedPublicKeySign(final PrimitiveSet<PublicKeySign> primitives) { 54 this.primitives = primitives; 55 if (primitives.hasAnnotations()) { 56 MonitoringClient client = MutableMonitoringRegistry.globalInstance().getMonitoringClient(); 57 MonitoringKeysetInfo keysetInfo = MonitoringUtil.getMonitoringKeysetInfo(primitives); 58 this.logger = client.createLogger(keysetInfo, "public_key_sign", "sign"); 59 } else { 60 this.logger = MonitoringUtil.DO_NOTHING_LOGGER; 61 } 62 } 63 64 @Override sign(final byte[] data)65 public byte[] sign(final byte[] data) throws GeneralSecurityException { 66 try { 67 byte[] output = primitives.getPrimary().getFullPrimitive().sign(data); 68 logger.log(primitives.getPrimary().getKeyId(), data.length); 69 return output; 70 } catch (GeneralSecurityException e) { 71 logger.logFailure(); 72 throw e; 73 } 74 } 75 } 76 PublicKeySignWrapper()77 PublicKeySignWrapper() {} 78 79 @Override wrap(final PrimitiveSet<PublicKeySign> primitives)80 public PublicKeySign wrap(final PrimitiveSet<PublicKeySign> primitives) { 81 return new WrappedPublicKeySign(primitives); 82 } 83 84 @Override getPrimitiveClass()85 public Class<PublicKeySign> getPrimitiveClass() { 86 return PublicKeySign.class; 87 } 88 89 @Override getInputPrimitiveClass()90 public Class<PublicKeySign> getInputPrimitiveClass() { 91 return PublicKeySign.class; 92 } 93 94 /** 95 * Register the wrapper within the registry. 96 * 97 * <p>This is required for calls to {@link Keyset.getPrimitive} with a {@link PublicKeySign} 98 * argument. 99 */ register()100 public static void register() throws GeneralSecurityException { 101 MutablePrimitiveRegistry.globalInstance().registerPrimitiveWrapper(WRAPPER); 102 MutablePrimitiveRegistry.globalInstance() 103 .registerPrimitiveConstructor(LEGACY_PRIMITIVE_CONSTRUCTOR); 104 } 105 106 /** 107 * registerToInternalPrimitiveRegistry is a non-public method (it takes an argument of an 108 * internal-only type) registering an instance of {@code PublicKeySignWrapper} to the provided 109 * {@code PrimitiveRegistry#Builder}. 110 */ registerToInternalPrimitiveRegistry( PrimitiveRegistry.Builder primitiveRegistryBuilder)111 public static void registerToInternalPrimitiveRegistry( 112 PrimitiveRegistry.Builder primitiveRegistryBuilder) throws GeneralSecurityException { 113 primitiveRegistryBuilder.registerPrimitiveWrapper(WRAPPER); 114 } 115 } 116