/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 javax.crypto; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; import java.security.spec.AlgorithmParameterSpec; import java.util.Arrays; import org.apache.harmony.security.fortress.Engine; /** * This class implements the functionality of an exemption mechanism such as * <i>key recovery</i>, <i>key weakening</i>, or <i>key escrow</i>. */ public class ExemptionMechanism { // Used to access common engine functionality private static final Engine ENGINE = new Engine("ExemptionMechanism"); // Store used provider private final Provider provider; // Store used spi implementation private final ExemptionMechanismSpi spiImpl; // Store mechanism name private final String mechanism; // Store state (initialized or not) private boolean isInit; // Store initKey value private Key initKey; // Indicates if blob generated successfully private boolean generated; /** * Creates a {@code ExemptionMechanism} instance. * * @param exmechSpi * the implementation delegate. * @param provider * the associated provider. * @param mechanism * the name of the mechanism. */ protected ExemptionMechanism(ExemptionMechanismSpi exmechSpi, Provider provider, String mechanism) { this.mechanism = mechanism; this.spiImpl = exmechSpi; this.provider = provider; isInit = false; } /** * Returns the name of this {@code ExemptionMechanism}. * * @return the name of this {@code ExemptionMechanism}. */ public final String getName() { return mechanism; } /** * Returns a new {@code ExemptionMechanism} instance that provides the * specified exemption mechanism algorithm. * * @param algorithm * the name of the requested exemption mechanism. * @return the new {@code ExemptionMechanism} instance. * @throws NoSuchAlgorithmException * if the specified algorithm is not available by any provider. * @throws NullPointerException * if the algorithm parameter is {@code null}. */ public static final ExemptionMechanism getInstance(String algorithm) throws NoSuchAlgorithmException { if (algorithm == null) { throw new NullPointerException("algorithm == null"); } Engine.SpiAndProvider sap = ENGINE.getInstance(algorithm, null); return new ExemptionMechanism((ExemptionMechanismSpi) sap.spi, sap.provider, algorithm); } /** * Returns a new {@code ExemptionMechansm} instance that provides the * specified exemption mechanism algorithm from the specified provider. * * @param algorithm * the name of the requested exemption mechanism. * @param provider * the name of the provider that is providing the algorithm. * @return the new {@code ExemptionMechanism} instance. * @throws NoSuchAlgorithmException * if the specified algorithm is not provided by the specified * provider. * @throws NoSuchProviderException * if the specified provider is not available. * @throws NullPointerException * if the algorithm parameter is {@code null}. * @throws IllegalArgumentException * if the provider parameter is {@code null}. */ public static final ExemptionMechanism getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { throw new IllegalArgumentException("provider == null"); } Provider impProvider = Security.getProvider(provider); if (impProvider == null) { throw new NoSuchProviderException(provider); } if (algorithm == null) { throw new NullPointerException("algorithm == null"); } return getInstance(algorithm, impProvider); } /** * Returns a new {@code ExemptionMechanism} instance that provides the * specified exemption mechanism algorithm from the specified provider. * * @param algorithm * the name of the requested exemption mechanism. * @param provider * the provider that is providing the algorithm. * @return the new {@code ExemptionMechanism} instance. * @throws NoSuchAlgorithmException * if the specified algorithm is not provided by the specified * provider. * @throws NullPointerException * if the algorithm parameter is {@code null}. * @throws IllegalArgumentException * if the provider parameter is {@code null}. */ public static final ExemptionMechanism getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException { if (algorithm == null) { throw new NullPointerException("algorithm == null"); } if (provider == null) { throw new IllegalArgumentException("provider == null"); } Object spi = ENGINE.getInstance(algorithm, provider, null); return new ExemptionMechanism((ExemptionMechanismSpi) spi, provider, algorithm); } /** * Returns the provider of this {@code ExemptionMechanism} instance. * * @return the provider of this {@code ExemptionMechanism} instance. */ public final Provider getProvider() { return provider; } /** * Returns whether the result blob for this {@code ExemptionMechanism} * instance has been generated successfully and that the specified key is * the same as the one that was used to initialize and generate. * * @param key * the key to verify. * @return whether the result blob for this {@code ExemptionMechanism} * instance has been generated successfully. * @throws ExemptionMechanismException * if an error occurs while determining whether the result blob * has been generated successfully. */ public final boolean isCryptoAllowed(Key key) throws ExemptionMechanismException { if (generated && (initKey.equals(key) || Arrays.equals(initKey.getEncoded(), key.getEncoded()))) { return true; } return false; } /** * Returns the size in bytes for the output buffer needed to hold the output * of the next {@link #genExemptionBlob} call, given the specified {@code * inputLen} (in bytes). * * @param inputLen * the specified input length (in bytes). * @return the size in bytes for the output buffer. * @throws IllegalStateException * if this {@code ExemptionMechanism} instance is not * initialized. */ public final int getOutputSize(int inputLen) throws IllegalStateException { if (!isInit) { throw new IllegalStateException("ExemptionMechanism is not initialized"); } return spiImpl.engineGetOutputSize(inputLen); } /** * Initializes this {@code ExemptionMechanism} instance with the * specified key. * * @param key * the key to initialize this instance with. * @throws InvalidKeyException * if the key cannot be used to initialize this mechanism. * @throws ExemptionMechanismException * if error(s) occur during initialization. */ public final void init(Key key) throws InvalidKeyException, ExemptionMechanismException { generated = false; spiImpl.engineInit(key); initKey = key; isInit = true; } /** * Initializes this {@code ExemptionMechanism} instance with the * specified key and algorithm parameters. * * @param key * the key to initialize this instance with. * @param param * the parameters for this exemption mechanism algorithm. * @throws InvalidKeyException * if the key cannot be used to initialize this mechanism. * @throws InvalidAlgorithmParameterException * if the parameters cannot be used to initialize this * mechanism. * @throws ExemptionMechanismException * if error(s) occur during initialization. */ public final void init(Key key, AlgorithmParameters param) throws InvalidKeyException, InvalidAlgorithmParameterException, ExemptionMechanismException { generated = false; spiImpl.engineInit(key, param); initKey = key; isInit = true; } /** * Initializes this {@code ExemptionMechanism} instance with the * specified key and algorithm parameters. * * @param key * the key to initialize this instance with. * @param param * the parameters for this exemption mechanism algorithm. * @throws InvalidKeyException * if the key cannot be used to initialize this mechanism. * @throws InvalidAlgorithmParameterException * the the parameters cannot be used to initialize this * mechanism. * @throws ExemptionMechanismException * if error(s) occur during initialization. */ public final void init(Key key, AlgorithmParameterSpec param) throws InvalidKeyException, InvalidAlgorithmParameterException, ExemptionMechanismException { generated = false; spiImpl.engineInit(key, param); initKey = key; isInit = true; } /** * Generates the result key blob for this exemption mechanism. * * @return the result key blob for this exemption mechanism. * @throws IllegalStateException * if this {@code ExemptionMechanism} instance is not * initialized. * @throws ExemptionMechanismException * if error(s) occur during generation. */ public final byte[] genExemptionBlob() throws IllegalStateException, ExemptionMechanismException { if (!isInit) { throw new IllegalStateException("ExemptionMechanism is not initialized"); } generated = false; byte[] result = spiImpl.engineGenExemptionBlob(); generated = true; return result; } /** * Generates the result key blob for this exemption mechanism and stores it * into the {@code output} buffer. * * @param output * the output buffer for the result key blob. * @return the number of bytes written to the {@code output} buffer. * @throws IllegalStateException * if this {@code ExemptionMechanism} instance is not * initialized. * @throws ShortBufferException * if the provided buffer is too small for the result key blob. * @throws ExemptionMechanismException * if error(s) occur during generation. */ public final int genExemptionBlob(byte[] output) throws IllegalStateException, ShortBufferException, ExemptionMechanismException { return genExemptionBlob(output, 0); } /** * Generates the result key blob for this exemption mechanism and stores it * into the {@code output} buffer at offset {@code outputOffset}. * * @param output * the output buffer for the result key blob. * @param outputOffset * the offset in the output buffer to start. * @return the number of bytes written to the {@code output} buffer. * @throws IllegalStateException * if this {@code ExemptionMechanism} instance is not * initialized. * @throws ShortBufferException * if the provided buffer is too small for the result key blob. * @throws ExemptionMechanismException * if error(s) occur during generation. */ public final int genExemptionBlob(byte[] output, int outputOffset) throws IllegalStateException, ShortBufferException, ExemptionMechanismException { if (!isInit) { throw new IllegalStateException("ExemptionMechanism is not initialized"); } generated = false; int len = spiImpl.engineGenExemptionBlob(output, outputOffset); generated = true; return len; } /** * Override to clear any key state in the instance. */ @Override protected void finalize() { try { super.finalize(); } catch (Throwable t) { // for consistency with the RI, we must override Object.finalize() to // remove the throws clause. throw new AssertionError(t); } } }