• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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