Path: blob/master/src/java.base/share/classes/javax/crypto/ExemptionMechanism.java
41152 views
/*1* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.crypto;2627import java.security.AlgorithmParameters;28import java.security.Provider;29import java.security.Key;30import java.security.Security;31import java.security.NoSuchAlgorithmException;32import java.security.NoSuchProviderException;33import java.security.InvalidKeyException;34import java.security.InvalidAlgorithmParameterException;35import java.security.spec.AlgorithmParameterSpec;36import java.util.Objects;3738import sun.security.jca.GetInstance.Instance;3940/**41* This class provides the functionality of an exemption mechanism, examples42* of which are <i>key recovery</i>, <i>key weakening</i>, and43* <i>key escrow</i>.44*45* <p>Applications or applets that use an exemption mechanism may be granted46* stronger encryption capabilities than those which don't.47*48* @since 1.449*/5051public class ExemptionMechanism {5253// The provider54private Provider provider;5556// The provider implementation (delegate)57private ExemptionMechanismSpi exmechSpi;5859// The name of the exemption mechanism.60private String mechanism;6162// Flag which indicates whether this ExemptionMechanism63// result is generated successfully.64private boolean done = false;6566// State information67private boolean initialized = false;6869// Store away the key at init() time for later comparison.70private Key keyStored = null;7172/**73* Creates a ExemptionMechanism object.74*75* @param exmechSpi the delegate76* @param provider the provider77* @param mechanism the exemption mechanism78*/79protected ExemptionMechanism(ExemptionMechanismSpi exmechSpi,80Provider provider,81String mechanism) {82this.exmechSpi = exmechSpi;83this.provider = provider;84this.mechanism = mechanism;85}8687/**88* Returns the exemption mechanism name of this89* <code>ExemptionMechanism</code> object.90*91* <p>This is the same name that was specified in one of the92* <code>getInstance</code> calls that created this93* <code>ExemptionMechanism</code> object.94*95* @return the exemption mechanism name of this96* <code>ExemptionMechanism</code> object.97*/98public final String getName() {99return this.mechanism;100}101102/**103* Returns an <code>ExemptionMechanism</code> object that implements the104* specified exemption mechanism algorithm.105*106* <p> This method traverses the list of registered security Providers,107* starting with the most preferred Provider.108* A new ExemptionMechanism object encapsulating the109* ExemptionMechanismSpi implementation from the first110* Provider that supports the specified algorithm is returned.111*112* <p> Note that the list of registered providers may be retrieved via113* the {@link Security#getProviders() Security.getProviders()} method.114*115* @implNote116* The JDK Reference Implementation additionally uses the117* {@code jdk.security.provider.preferred}118* {@link Security#getProperty(String) Security} property to determine119* the preferred provider order for the specified algorithm. This120* may be different than the order of providers returned by121* {@link Security#getProviders() Security.getProviders()}.122*123* @param algorithm the standard name of the requested exemption124* mechanism.125* See the ExemptionMechanism section in the126* <a href=127* "{@docRoot}/../specs/security/standard-names.html#exemption-mechanisms">128* Java Security Standard Algorithm Names Specification</a>129* for information about standard exemption mechanism names.130*131* @return the new {@code ExemptionMechanism} object132*133* @throws NoSuchAlgorithmException if no {@code Provider} supports an134* {@code ExemptionMechanismSpi} implementation for the135* specified algorithm136*137* @throws NullPointerException if {@code algorithm} is {@code null}138*139* @see java.security.Provider140*/141public static final ExemptionMechanism getInstance(String algorithm)142throws NoSuchAlgorithmException {143Objects.requireNonNull(algorithm, "null algorithm name");144Instance instance = JceSecurity.getInstance("ExemptionMechanism",145ExemptionMechanismSpi.class, algorithm);146return new ExemptionMechanism((ExemptionMechanismSpi)instance.impl,147instance.provider, algorithm);148}149150151/**152* Returns an <code>ExemptionMechanism</code> object that implements the153* specified exemption mechanism algorithm.154*155* <p> A new ExemptionMechanism object encapsulating the156* ExemptionMechanismSpi implementation from the specified provider157* is returned. The specified provider must be registered158* in the security provider list.159*160* <p> Note that the list of registered providers may be retrieved via161* the {@link Security#getProviders() Security.getProviders()} method.162*163* @param algorithm the standard name of the requested exemption mechanism.164* See the ExemptionMechanism section in the165* <a href=166* "{@docRoot}/../specs/security/standard-names.html#exemption-mechanisms">167* Java Security Standard Algorithm Names Specification</a>168* for information about standard exemption mechanism names.169*170* @param provider the name of the provider.171*172* @return the new {@code ExemptionMechanism} object173*174* @throws IllegalArgumentException if the {@code provider}175* is {@code null} or empty176*177* @throws NoSuchAlgorithmException if an {@code ExemptionMechanismSpi}178* implementation for the specified algorithm is not179* available from the specified provider180*181* @throws NoSuchProviderException if the specified provider is not182* registered in the security provider list183*184* @throws NullPointerException if {@code algorithm} is {@code null}185*186* @see java.security.Provider187*/188public static final ExemptionMechanism getInstance(String algorithm,189String provider) throws NoSuchAlgorithmException,190NoSuchProviderException {191Objects.requireNonNull(algorithm, "null algorithm name");192Instance instance = JceSecurity.getInstance("ExemptionMechanism",193ExemptionMechanismSpi.class, algorithm, provider);194return new ExemptionMechanism((ExemptionMechanismSpi)instance.impl,195instance.provider, algorithm);196}197198/**199* Returns an <code>ExemptionMechanism</code> object that implements the200* specified exemption mechanism algorithm.201*202* <p> A new ExemptionMechanism object encapsulating the203* ExemptionMechanismSpi implementation from the specified Provider204* object is returned. Note that the specified Provider object205* does not have to be registered in the provider list.206*207* @param algorithm the standard name of the requested exemption mechanism.208* See the ExemptionMechanism section in the209* <a href=210* "{@docRoot}/../specs/security/standard-names.html#exemption-mechanisms">211* Java Security Standard Algorithm Names Specification</a>212* for information about standard exemption mechanism names.213*214* @param provider the provider.215*216* @return the new {@code ExemptionMechanism} object217*218* @throws IllegalArgumentException if the {@code provider}219* is null220*221* @throws NoSuchAlgorithmException if an {@code ExemptionMechanismSpi}222* implementation for the specified algorithm is not available223* from the specified {@code Provider object}224*225* @exception NullPointerException if {@code algorithm} is {@code null}226*227* @see java.security.Provider228*/229public static final ExemptionMechanism getInstance(String algorithm,230Provider provider) throws NoSuchAlgorithmException {231Objects.requireNonNull(algorithm, "null algorithm name");232Instance instance = JceSecurity.getInstance("ExemptionMechanism",233ExemptionMechanismSpi.class, algorithm, provider);234return new ExemptionMechanism((ExemptionMechanismSpi)instance.impl,235instance.provider, algorithm);236}237238/**239* Returns the provider of this <code>ExemptionMechanism</code> object.240*241* @return the provider of this <code>ExemptionMechanism</code> object.242*/243public final Provider getProvider() {244return this.provider;245}246247/**248* Returns whether the result blob has been generated successfully by this249* exemption mechanism.250*251* <p>The method also makes sure that the key passed in is the same as252* the one this exemption mechanism used in initializing and generating253* phases.254*255* @param key the key the crypto is going to use.256*257* @return whether the result blob of the same key has been generated258* successfully by this exemption mechanism; false if <code>key</code>259* is null.260*261* @exception ExemptionMechanismException if problem(s) encountered262* while determining whether the result blob has been generated successfully263* by this exemption mechanism object.264*/265public final boolean isCryptoAllowed(Key key)266throws ExemptionMechanismException {267boolean ret = false;268if (done && (key != null)) {269// Check if the key passed in is the same as the one270// this exemption mechanism used.271ret = keyStored.equals(key);272}273return ret;274}275276/**277* Returns the length in bytes that an output buffer would need to be in278* order to hold the result of the next279* {@link #genExemptionBlob(byte[]) genExemptionBlob}280* operation, given the input length <code>inputLen</code> (in bytes).281*282* <p>The actual output length of the next283* {@link #genExemptionBlob(byte[]) genExemptionBlob}284* call may be smaller than the length returned by this method.285*286* @param inputLen the input length (in bytes)287*288* @return the required output buffer size (in bytes)289*290* @exception IllegalStateException if this exemption mechanism is in a291* wrong state (e.g., has not yet been initialized)292*/293public final int getOutputSize(int inputLen) throws IllegalStateException {294if (!initialized) {295throw new IllegalStateException(296"ExemptionMechanism not initialized");297}298if (inputLen < 0) {299throw new IllegalArgumentException(300"Input size must be equal to " + "or greater than zero");301}302return exmechSpi.engineGetOutputSize(inputLen);303}304305/**306* Initializes this exemption mechanism with a key.307*308* <p>If this exemption mechanism requires any algorithm parameters309* that cannot be derived from the given <code>key</code>, the310* underlying exemption mechanism implementation is supposed to311* generate the required parameters itself (using provider-specific312* default values); in the case that algorithm parameters must be313* specified by the caller, an <code>InvalidKeyException</code> is raised.314*315* @param key the key for this exemption mechanism316*317* @exception InvalidKeyException if the given key is inappropriate for318* this exemption mechanism.319* @exception ExemptionMechanismException if problem(s) encountered in the320* process of initializing.321*/322public final void init(Key key)323throws InvalidKeyException, ExemptionMechanismException {324done = false;325initialized = false;326327keyStored = key;328exmechSpi.engineInit(key);329initialized = true;330}331332/**333* Initializes this exemption mechanism with a key and a set of algorithm334* parameters.335*336* <p>If this exemption mechanism requires any algorithm parameters337* and <code>params</code> is null, the underlying exemption338* mechanism implementation is supposed to generate the required339* parameters itself (using provider-specific default values); in the case340* that algorithm parameters must be specified by the caller, an341* <code>InvalidAlgorithmParameterException</code> is raised.342*343* @param key the key for this exemption mechanism344* @param params the algorithm parameters345*346* @exception InvalidKeyException if the given key is inappropriate for347* this exemption mechanism.348* @exception InvalidAlgorithmParameterException if the given algorithm349* parameters are inappropriate for this exemption mechanism.350* @exception ExemptionMechanismException if problem(s) encountered in the351* process of initializing.352*/353public final void init(Key key, AlgorithmParameterSpec params)354throws InvalidKeyException, InvalidAlgorithmParameterException,355ExemptionMechanismException {356done = false;357initialized = false;358359keyStored = key;360exmechSpi.engineInit(key, params);361initialized = true;362}363364/**365* Initializes this exemption mechanism with a key and a set of algorithm366* parameters.367*368* <p>If this exemption mechanism requires any algorithm parameters369* and <code>params</code> is null, the underlying exemption mechanism370* implementation is supposed to generate the required parameters itself371* (using provider-specific default values); in the case that algorithm372* parameters must be specified by the caller, an373* <code>InvalidAlgorithmParameterException</code> is raised.374*375* @param key the key for this exemption mechanism376* @param params the algorithm parameters377*378* @exception InvalidKeyException if the given key is inappropriate for379* this exemption mechanism.380* @exception InvalidAlgorithmParameterException if the given algorithm381* parameters are inappropriate for this exemption mechanism.382* @exception ExemptionMechanismException if problem(s) encountered in the383* process of initializing.384*/385public final void init(Key key, AlgorithmParameters params)386throws InvalidKeyException, InvalidAlgorithmParameterException,387ExemptionMechanismException {388done = false;389initialized = false;390391keyStored = key;392exmechSpi.engineInit(key, params);393initialized = true;394}395396/**397* Generates the exemption mechanism key blob.398*399* @return the new buffer with the result key blob.400*401* @exception IllegalStateException if this exemption mechanism is in402* a wrong state (e.g., has not been initialized).403* @exception ExemptionMechanismException if problem(s) encountered in the404* process of generating.405*/406public final byte[] genExemptionBlob() throws IllegalStateException,407ExemptionMechanismException {408if (!initialized) {409throw new IllegalStateException(410"ExemptionMechanism not initialized");411}412byte[] blob = exmechSpi.engineGenExemptionBlob();413done = true;414return blob;415}416417/**418* Generates the exemption mechanism key blob, and stores the result in419* the <code>output</code> buffer.420*421* <p>If the <code>output</code> buffer is too small to hold the result,422* a <code>ShortBufferException</code> is thrown. In this case, repeat this423* call with a larger output buffer. Use424* {@link #getOutputSize(int) getOutputSize} to determine how big425* the output buffer should be.426*427* @param output the buffer for the result428*429* @return the number of bytes stored in <code>output</code>430*431* @exception IllegalStateException if this exemption mechanism is in432* a wrong state (e.g., has not been initialized).433* @exception ShortBufferException if the given output buffer is too small434* to hold the result.435* @exception ExemptionMechanismException if problem(s) encountered in the436* process of generating.437*/438public final int genExemptionBlob(byte[] output)439throws IllegalStateException, ShortBufferException,440ExemptionMechanismException {441if (!initialized) {442throw new IllegalStateException443("ExemptionMechanism not initialized");444}445int n = exmechSpi.engineGenExemptionBlob(output, 0);446done = true;447return n;448}449450/**451* Generates the exemption mechanism key blob, and stores the result in452* the <code>output</code> buffer, starting at <code>outputOffset</code>453* inclusive.454*455* <p>If the <code>output</code> buffer is too small to hold the result,456* a <code>ShortBufferException</code> is thrown. In this case, repeat this457* call with a larger output buffer. Use458* {@link #getOutputSize(int) getOutputSize} to determine how big459* the output buffer should be.460*461* @param output the buffer for the result462* @param outputOffset the offset in <code>output</code> where the result463* is stored464*465* @return the number of bytes stored in <code>output</code>466*467* @exception IllegalStateException if this exemption mechanism is in468* a wrong state (e.g., has not been initialized).469* @exception ShortBufferException if the given output buffer is too small470* to hold the result.471* @exception ExemptionMechanismException if problem(s) encountered in the472* process of generating.473*/474public final int genExemptionBlob(byte[] output, int outputOffset)475throws IllegalStateException, ShortBufferException,476ExemptionMechanismException {477if (!initialized) {478throw new IllegalStateException479("ExemptionMechanism not initialized");480}481int n = exmechSpi.engineGenExemptionBlob(output, outputOffset);482done = true;483return n;484}485}486487488