xref: /aosp_15_r20/external/tink/java_src/src/main/java/com/google/crypto/tink/internal/MutablePrimitiveRegistry.java (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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 
17 package com.google.crypto.tink.internal;
18 
19 import com.google.crypto.tink.Key;
20 import com.google.crypto.tink.PrimitiveSet;
21 import com.google.crypto.tink.PrimitiveWrapper;
22 import java.security.GeneralSecurityException;
23 import java.util.concurrent.atomic.AtomicReference;
24 
25 /**
26  * A Mutable version of the {@link PrimitiveRegistry}.
27  *
28  * <p>This class probably shouldn't exist; it would be better if we had only the
29  * PrimitiveRegistry. However, at the moment, we need this, since a call to e.g.
30  *
31  * <pre> AesCmacKeyManager.register() </pre>
32  *
33  * should register such an object into a global, mutable registry.
34  */
35 public final class MutablePrimitiveRegistry {
36   private static MutablePrimitiveRegistry globalInstance =
37       new MutablePrimitiveRegistry();
38 
globalInstance()39   public static MutablePrimitiveRegistry globalInstance() {
40     return globalInstance;
41   }
42 
resetGlobalInstanceTestOnly()43   public static void resetGlobalInstanceTestOnly() {
44     globalInstance = new MutablePrimitiveRegistry();
45   }
46 
47   private final AtomicReference<PrimitiveRegistry> registry =
48       new AtomicReference<>(PrimitiveRegistry.builder().build());
49 
MutablePrimitiveRegistry()50   MutablePrimitiveRegistry() {}
51 
52   /**
53    * Registers a key primitive constructor for later use in {@link #getPrimitive}.
54    *
55    * <p>This registers a primitive constructor which can later be used to create a primitive by
56    * calling {@link #getPrimitive}. If a constructor for the pair {@code (KeyT, PrimitiveT)} has
57    * already been registered and is the same, then the call is ignored; otherwise, an exception is
58    * thrown.
59    */
registerPrimitiveConstructor( PrimitiveConstructor<KeyT, PrimitiveT> constructor)60   public synchronized <KeyT extends Key, PrimitiveT> void registerPrimitiveConstructor(
61       PrimitiveConstructor<KeyT, PrimitiveT> constructor) throws GeneralSecurityException {
62     PrimitiveRegistry newRegistry =
63         PrimitiveRegistry.builder(registry.get())
64             .registerPrimitiveConstructor(constructor)
65             .build();
66     registry.set(newRegistry);
67   }
68 
registerPrimitiveWrapper( PrimitiveWrapper<InputPrimitiveT, WrapperPrimitiveT> wrapper)69   public synchronized <InputPrimitiveT, WrapperPrimitiveT> void registerPrimitiveWrapper(
70       PrimitiveWrapper<InputPrimitiveT, WrapperPrimitiveT> wrapper)
71       throws GeneralSecurityException {
72     PrimitiveRegistry newRegistry =
73         PrimitiveRegistry.builder(registry.get()).registerPrimitiveWrapper(wrapper).build();
74     registry.set(newRegistry);
75   }
76 
77   /**
78    * Creates a primitive from a given key.
79    *
80    * <p>This will look up a previously registered constructor for the given pair of {@code (KeyT,
81    * PrimitiveT)}, and, if successful, use the registered PrimitiveConstructor object to create the
82    * requested primitive. Throws if the required constructor has not been registered, or if the
83    * primitive construction threw.
84    */
getPrimitive( KeyT key, Class<PrimitiveT> primitiveClass)85   public <KeyT extends Key, PrimitiveT> PrimitiveT getPrimitive(
86       KeyT key, Class<PrimitiveT> primitiveClass) throws GeneralSecurityException {
87     return registry.get().getPrimitive(key, primitiveClass);
88   }
89 
getInputPrimitiveClass( Class<WrapperPrimitiveT> wrapperClassObject)90   public <WrapperPrimitiveT> Class<?> getInputPrimitiveClass(
91       Class<WrapperPrimitiveT> wrapperClassObject) throws GeneralSecurityException {
92     return registry.get().getInputPrimitiveClass(wrapperClassObject);
93   }
94 
wrap( PrimitiveSet<InputPrimitiveT> primitives, Class<WrapperPrimitiveT> wrapperClassObject)95   public <InputPrimitiveT, WrapperPrimitiveT> WrapperPrimitiveT wrap(
96       PrimitiveSet<InputPrimitiveT> primitives, Class<WrapperPrimitiveT> wrapperClassObject)
97       throws GeneralSecurityException {
98     return registry.get().wrap(primitives, wrapperClassObject);
99   }
100 }
101