com.google.crypto.tink.internal.MutablePrimitiveRegistry Maven / Gradle / Ivy
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package com.google.crypto.tink.internal;
import com.google.crypto.tink.Key;
import com.google.crypto.tink.PrimitiveSet;
import com.google.crypto.tink.PrimitiveWrapper;
import java.security.GeneralSecurityException;
import java.util.concurrent.atomic.AtomicReference;
/**
* A Mutable version of the {@link PrimitiveRegistry}.
*
* This class probably shouldn't exist; it would be better if we had only the
* PrimitiveRegistry. However, at the moment, we need this, since a call to e.g.
*
*
AesCmacKeyManager.register()
*
* should register such an object into a global, mutable registry.
*/
public final class MutablePrimitiveRegistry {
private static MutablePrimitiveRegistry globalInstance =
new MutablePrimitiveRegistry();
public static MutablePrimitiveRegistry globalInstance() {
return globalInstance;
}
public static void resetGlobalInstanceTestOnly() {
globalInstance = new MutablePrimitiveRegistry();
}
private final AtomicReference registry =
new AtomicReference<>(PrimitiveRegistry.builder().build());
MutablePrimitiveRegistry() {}
/**
* Registers a key primitive constructor for later use in {@link #getPrimitive}.
*
* This registers a primitive constructor which can later be used to create a primitive by
* calling {@link #getPrimitive}. If a constructor for the pair {@code (KeyT, PrimitiveT)} has
* already been registered and is the same, then the call is ignored; otherwise, an exception is
* thrown.
*/
public synchronized void registerPrimitiveConstructor(
PrimitiveConstructor constructor) throws GeneralSecurityException {
PrimitiveRegistry newRegistry =
PrimitiveRegistry.builder(registry.get())
.registerPrimitiveConstructor(constructor)
.build();
registry.set(newRegistry);
}
public synchronized void registerPrimitiveWrapper(
PrimitiveWrapper wrapper)
throws GeneralSecurityException {
PrimitiveRegistry newRegistry =
PrimitiveRegistry.builder(registry.get()).registerPrimitiveWrapper(wrapper).build();
registry.set(newRegistry);
}
/**
* Creates a primitive from a given key.
*
* This will look up a previously registered constructor for the given pair of {@code (KeyT,
* PrimitiveT)}, and, if successful, use the registered PrimitiveConstructor object to create the
* requested primitive. Throws if the required constructor has not been registered, or if the
* primitive construction threw.
*/
public PrimitiveT getPrimitive(
KeyT key, Class primitiveClass) throws GeneralSecurityException {
return registry.get().getPrimitive(key, primitiveClass);
}
public Class getInputPrimitiveClass(
Class wrapperClassObject) throws GeneralSecurityException {
return registry.get().getInputPrimitiveClass(wrapperClassObject);
}
public WrapperPrimitiveT wrap(
PrimitiveSet primitives, Class wrapperClassObject)
throws GeneralSecurityException {
return registry.get().wrap(primitives, wrapperClassObject);
}
}