diff options
Diffstat (limited to 'libraries/spongycastle/jce/src/main/java/javax/crypto/Cipher.java')
-rw-r--r-- | libraries/spongycastle/jce/src/main/java/javax/crypto/Cipher.java | 1509 |
1 files changed, 1509 insertions, 0 deletions
diff --git a/libraries/spongycastle/jce/src/main/java/javax/crypto/Cipher.java b/libraries/spongycastle/jce/src/main/java/javax/crypto/Cipher.java new file mode 100644 index 000000000..bf9fd3743 --- /dev/null +++ b/libraries/spongycastle/jce/src/main/java/javax/crypto/Cipher.java @@ -0,0 +1,1509 @@ +package javax.crypto; + +import java.util.StringTokenizer; +import java.security.Key; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.AlgorithmParameters; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.InvalidAlgorithmParameterException; +import java.security.cert.Certificate; +import java.security.spec.AlgorithmParameterSpec; + +/** + * This class provides the functionality of a cryptographic cipher for + * encryption and decryption. It forms the core of the Java Cryptographic + * Extension (JCE) framework. + * <p> + * In order to create a Cipher object, the application calls the + * Cipher's <code>getInstance</code> method, and passes the name of the + * requested <i>transformation</i> to it. Optionally, the name of a provider + * may be specified. + * <p> + * A <i>transformation</i> is a string that describes the operation (or + * set of operations) to be performed on the given input, to produce some + * output. A transformation always includes the name of a cryptographic + * algorithm (e.g., <i>DES</i>), and may be followed by a feedback mode and + * padding scheme. + * + * <p> A transformation is of the form:<p> + * + * <ul> + * <li>"<i>algorithm/mode/padding</i>" or + * <p> + * <li>"<i>algorithm</i>" + * </ul> + * + * <P> (in the latter case, + * provider-specific default values for the mode and padding scheme are used). + * For example, the following is a valid transformation:<p> + * + * <pre> + * Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>"); + * </pre> + * <p> + * When requesting a block cipher in stream cipher mode (e.g., + * <code>DES</code> in <code>CFB</code> or <code>OFB</code> mode), the user may + * optionally specify the number of bits to be + * processed at a time, by appending this number to the mode name as shown in + * the "<i>DES/CFB8/NoPadding</i>" and "<i>DES/OFB32/PKCS5Padding</i>" + * transformations. If no such number is specified, a provider-specific default + * is used. (For example, the "SunJCE" provider uses a default of 64 bits.) + */ +public class Cipher +{ + static private final int UNINITIALIZED = 0; + + static public final int ENCRYPT_MODE = 1; + static public final int DECRYPT_MODE = 2; + static public final int WRAP_MODE = 3; + static public final int UNWRAP_MODE = 4; + + static public final int PUBLIC_KEY = 1; + static public final int PRIVATE_KEY = 2; + static public final int SECRET_KEY = 3; + + private CipherSpi cipherSpi; + private Provider provider; + private String transformation; + + private int mode = UNINITIALIZED; + + /** + * Creates a Cipher object. + * + * @param cipherSpi the delegate + * @param provider the provider + * @param transformation the transformation + */ + protected Cipher( + CipherSpi cipherSpi, + Provider provider, + String transformation) + { + this.cipherSpi = cipherSpi; + this.provider = provider; + this.transformation = transformation; + } + + /** + * Generates a <code>Cipher</code> object that implements the specified + * transformation. + * <p> + * If the default provider package supplies an implementation of the + * requested transformation, an instance of <code>Cipher</code> containing + * that implementation is returned. + * If the transformation is not available in the default provider package, + * other provider packages are searched. + * + * @param transformation the name of the transformation, e.g., <i>DES/CBC/PKCS5Padding</i>. + * See Appendix A in the Java Cryptography Extension API Specification & Reference + * for information about standard transformation names. + * + * @return a cipher that implements the requested transformation + * @exception NoSuchAlgorithmException if the specified transformation is not available in the default + * provider package or any of the other provider packages that were searched. + * @exception NoSuchPaddingException if <code>transformation</code> contains a padding scheme that is + * not available. + */ + public static final Cipher getInstance( + String transformation) + throws NoSuchAlgorithmException, NoSuchPaddingException + { + try + { + JCEUtil.Implementation imp = JCEUtil.getImplementation("Cipher", transformation, (String) null); + + if (imp != null) + { + return new Cipher((CipherSpi)imp.getEngine(), imp.getProvider(), transformation); + } + + // + // try the long way + // + StringTokenizer tok = new StringTokenizer(transformation, "/"); + String algorithm = tok.nextToken(); + + imp = JCEUtil.getImplementation("Cipher", algorithm, (String) null); + + if (imp == null) + { + throw new NoSuchAlgorithmException(transformation + " not found"); + } + + CipherSpi cipherSpi = (CipherSpi)imp.getEngine(); + + // + // make sure we don't get fooled by a "//" in the string + // + if (tok.hasMoreTokens() && !transformation.regionMatches(algorithm.length(), "//", 0, 2)) + { + cipherSpi.engineSetMode(tok.nextToken()); + } + + if (tok.hasMoreTokens()) + { + cipherSpi.engineSetPadding(tok.nextToken()); + } + + return new Cipher(cipherSpi, imp.getProvider(), transformation); + } + catch (NoSuchProviderException e) + { + throw new NoSuchAlgorithmException(transformation + " not found"); + } + } + + /** + * Creates a <code>Cipher</code> object that implements the specified + * transformation, as supplied by the specified provider. + * + * @param transformation the name of the transformation, e.g., <i>DES/CBC/PKCS5Padding</i>. + * See Appendix A in the Java Cryptography Extension API Specification & Reference + * for information about standard transformation names. + * + * @param provider the provider + * @return a cipher that implements the requested transformation + * @exception NoSuchAlgorithmException if no transformation was specified, or if the specified + * transformation is not available from the specified provider. + * @exception NoSuchPaddingException if <code>transformation</code> contains a padding scheme + * that is not available. + */ + public static final Cipher getInstance( + String transformation, + Provider provider) + throws NoSuchAlgorithmException, NoSuchPaddingException + { + if (transformation == null) + { + throw new IllegalArgumentException("No transformation specified for Cipher.getInstance()"); + } + + JCEUtil.Implementation imp = JCEUtil.getImplementation("Cipher", transformation, provider); + + if (imp != null) + { + return new Cipher((CipherSpi)imp.getEngine(), imp.getProvider(), transformation); + } + + // + // try the long way + // + StringTokenizer tok = new StringTokenizer(transformation, "/"); + String algorithm = tok.nextToken(); + + imp = JCEUtil.getImplementation("Cipher", algorithm, provider); + + if (imp == null) + { + throw new NoSuchAlgorithmException(transformation + " not found"); + } + + CipherSpi cipherSpi = (CipherSpi)imp.getEngine(); + + // + // make sure we don't get fooled by a "//" in the string + // + if (tok.hasMoreTokens() && !transformation.regionMatches(algorithm.length(), "//", 0, 2)) + { + cipherSpi.engineSetMode(tok.nextToken()); + } + + if (tok.hasMoreTokens()) + { + cipherSpi.engineSetPadding(tok.nextToken()); + } + + return new Cipher(cipherSpi, imp.getProvider(), transformation); + } + + /** + * Creates a <code>Cipher</code> object that implements the specified + * transformation, as supplied by the specified provider. + * + * @param transformation the name of the transformation, e.g., <i>DES/CBC/PKCS5Padding</i>. + * See Appendix A in the Java Cryptography Extension API Specification & Reference + * for information about standard transformation names. + * + * @param provider the name of the provider + * @return a cipher that implements the requested transformation + * @exception NoSuchAlgorithmException if no transformation was specified, or if the specified + * transformation is not available from the specified provider. + * @exception NoSuchProviderException if the specified provider has not been configured. + * @exception NoSuchPaddingException if <code>transformation</code> contains a padding scheme + * that is not available. + */ + public static final Cipher getInstance( + String transformation, + String provider) + throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException + { + if (transformation == null) + { + throw new IllegalArgumentException("No transformation specified for Cipher.getInstance()"); + } + + JCEUtil.Implementation imp = JCEUtil.getImplementation("Cipher", transformation, provider); + + if (imp != null) + { + return new Cipher((CipherSpi)imp.getEngine(), imp.getProvider(), transformation); + } + + // + // try the long way + // + StringTokenizer tok = new StringTokenizer(transformation, "/"); + String algorithm = tok.nextToken(); + + imp = JCEUtil.getImplementation("Cipher", algorithm, provider); + + if (imp == null) + { + throw new NoSuchAlgorithmException(transformation + " not found"); + } + + CipherSpi cipherSpi = (CipherSpi)imp.getEngine(); + + // + // make sure we don't get fooled by a "//" in the string + // + if (tok.hasMoreTokens() && !transformation.regionMatches(algorithm.length(), "//", 0, 2)) + { + cipherSpi.engineSetMode(tok.nextToken()); + } + + if (tok.hasMoreTokens()) + { + cipherSpi.engineSetPadding(tok.nextToken()); + } + + return new Cipher(cipherSpi, imp.getProvider(), transformation); + } + + /** + * Returns the provider of this <code>Cipher</code> object. + * + * @return the provider of this <code>Cipher</code> object + */ + public final Provider getProvider() + { + return provider; + } + + /** + * Returns the algorithm name of this <code>Cipher</code> object. + * <p> + * This is the same name that was specified in one of the + * <code>getInstance</code> calls that created this <code>Cipher</code> + * object.. + * + * @return the algorithm name of this <code>Cipher</code> object. + */ + public final String getAlgorithm() + { + return transformation; + } + + /** + * Returns the block size (in bytes). + * + * @return the block size (in bytes), or 0 if the underlying algorithm is not a block cipher + */ + public final int getBlockSize() + { + return cipherSpi.engineGetBlockSize(); + } + + /** + * Returns the length in bytes that an output buffer would need to be in + * order to hold the result of the next <code>update</code> or + * <code>doFinal</code> operation, given the input length <code>inputLen</code> (in bytes). + * <p> + * This call takes into account any unprocessed (buffered) data from a + * previous <code>update</code> call, and padding. + * <p> + * The actual output length of the next <code>update</code> or + * <code>doFinal</code> call may be smaller than the length returned by + * this method. + * + * @param inputLen the input length (in bytes) + * @return the required output buffer size (in bytes) + * @exception java.lang.IllegalStateException if this cipher is in a wrong state (e.g., has not + * yet been initialized) + */ + public final int getOutputSize( + int inputLen) + throws IllegalStateException + { + if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) + { + throw new IllegalStateException("Cipher is uninitialised"); + } + + return cipherSpi.engineGetOutputSize(inputLen); + } + + /** + * Returns the initialization vector (IV) in a new buffer. + * <p> + * This is useful in the case where a random IV was created, + * or in the context of password-based encryption or decryption, where the IV + * is derived from a user-supplied password. + * + * @return the initialization vector in a new buffer, or null if the + * underlying algorithm does not use an IV, or if the IV has not yet been set. + */ + public final byte[] getIV() + { + return cipherSpi.engineGetIV(); + } + + /** + * Returns the parameters used with this cipher. + * <p> + * The returned parameters may be the same that were used to initialize + * this cipher, or may contain a combination of default and random + * parameter values used by the underlying cipher implementation if this + * cipher requires algorithm parameters but was not initialized with any. + * + * @return the parameters used with this cipher, or null if this cipher + * does not use any parameters. + */ + public final AlgorithmParameters getParameters() + { + return cipherSpi.engineGetParameters(); + } + + /** + * Returns the exemption mechanism object used with this cipher. + * + * @return the exemption mechanism object used with this cipher, or + * null if this cipher does not use any exemption mechanism. + */ + public final ExemptionMechanism getExemptionMechanism() + { + return null; + } + + /** + * Initializes this cipher with a key. + * <p> + * The cipher is initialized for one of the following four operations: + * encryption, decryption, key wrapping or key unwrapping, depending + * on the value of <code>opmode</code>. + * <p> + * If this cipher requires any algorithm parameters that cannot be + * derived from the given <code>key</code>, the underlying cipher + * implementation is supposed to generate the required parameters itself + * (using provider-specific default or random values) if it is being + * initialized for encryption or key wrapping, and raise an + * <code>InvalidKeyException</code> if it is being + * initialized for decryption or key unwrapping. + * The generated parameters can be retrieved using + * <a href = "#getParameters()">getParameters</a> or + * <a href = "#getIV()">getIV</a> (if the parameter is an IV). + * <p> + * If this cipher (including its underlying feedback or padding scheme) + * requires any random bytes (e.g., for parameter generation), it will get + * them using the <a href="http://java.sun.com/products/jdk/1.2/docs/api/java.security.SecureRandom.html"> + * <code>SecureRandom</code></a> implementation of the highest-priority + * installed provider as the source of randomness. + * (If none of the installed providers supply an implementation of + * SecureRandom, a system-provided source of randomness will be used.) + * <p> + * Note that when a Cipher object is initialized, it loses all + * previously-acquired state. In other words, initializing a Cipher is + * equivalent to creating a new instance of that Cipher and initializing + * it. + * + * @param opmode the operation mode of this cipher (this is one of the following: + * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, + * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) + * @param key the key + * @exception InvalidKeyException if the given key is inappropriate for + * initializing this cipher, or if this cipher is being initialized for + * decryption and requires algorithm parameters that cannot be + * determined from the given key, or if the given key has a keysize that + * exceeds the maximum allowable keysize (as determined from the + * configured jurisdiction policy files). Note: Jurisdiction files are ignored + * in this implementation. + */ + public final void init( + int opmode, + Key key) + throws InvalidKeyException + { + cipherSpi.engineInit(opmode, key, new SecureRandom()); + mode = opmode; + } + + /** + * Initializes this cipher with a key and a source of randomness. + * <p> + * The cipher is initialized for one of the following four operations: + * encryption, decryption, key wrapping or key unwrapping, depending + * on the value of <code>opmode</code>. + * <p> + * If this cipher requires any algorithm parameters that cannot be + * derived from the given <code>key</code>, the underlying cipher + * implementation is supposed to generate the required parameters itself + * (using provider-specific default or random values) if it is being + * initialized for encryption or key wrapping, and raise an + * <code>InvalidKeyException</code> if it is being + * initialized for decryption or key unwrapping. + * The generated parameters can be retrieved using + * <a href = "#engineGetParameters()">engineGetParameters</a> or + * <a href = "#engineGetIV()">engineGetIV</a> (if the parameter is an IV). + * <p> + * If this cipher (including its underlying feedback or padding scheme) + * requires any random bytes (e.g., for parameter generation), it will get + * them from <code>random</code>. + * <p> + * Note that when a Cipher object is initialized, it loses all + * previously-acquired state. In other words, initializing a Cipher is + * equivalent to creating a new instance of that Cipher and initializing + * it. + * @param opmode the operation mode of this cipher (this is one of the + * following: <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, + * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) + * @param key the encryption key + * @param random the source of randomness + * @exception InvalidKeyException if the given key is inappropriate for + * initializing this cipher, or if this cipher is being initialized for + * decryption and requires algorithm parameters that cannot be + * determined from the given key, or if the given key has a keysize that + * exceeds the maximum allowable keysize (as determined from the + * configured jurisdiction policy files). Note: Jurisdiction files are ignored + * in this implementation. + */ + public final void init( + int opmode, + Key key, + SecureRandom random) + throws InvalidKeyException + { + cipherSpi.engineInit(opmode, key, random); + mode = opmode; + } + + /** + * Initializes this cipher with a key and a set of algorithm parameters. + * <p> + * The cipher is initialized for one of the following four operations: + * encryption, decryption, key wrapping or key unwrapping, depending + * on the value of <code>opmode</code>. + * <p> + * If this cipher requires any algorithm parameters and + * <code>params</code> is null, the underlying cipher implementation is + * supposed to generate the required parameters itself (using + * provider-specific default or random values) if it is being + * initialized for encryption or key wrapping, and raise an + * <code>InvalidAlgorithmParameterException</code> if it is being + * initialized for decryption or key unwrapping. + * The generated parameters can be retrieved using + * <a href = "#getParameters()">getParameters</a> or + * <a href = "#getIV()">getIV</a> (if the parameter is an IV). + * <p> + * If this cipher (including its underlying feedback or padding scheme) + * requires any random bytes (e.g., for parameter generation), it will get + * them using the + * <a href="http://java.sun.com/products/jdk/1.2/docs/api/java.security.SecureRandom.html"> + * <code>SecureRandom</code></a> implementation of the highest-priority + * installed provider as the source of randomness. + * (If none of the installed providers supply an implementation of + * SecureRandom, a system-provided source of randomness will be used.) + * <p> + * Note that when a Cipher object is initialized, it loses all + * previously-acquired state. In other words, initializing a Cipher is + * equivalent to creating a new instance of that Cipher and initializing + * it. + * + * @param opmode the operation mode of this cipher (this is one of the + * following: <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, <code>WRAP_MODE</code> + * or <code>UNWRAP_MODE</code>) + * @param key the encryption key + * @param params the algorithm parameters + * @exception InvalidKeyException if the given key is inappropriate for initializing this + * cipher, or its keysize exceeds the maximum allowable keysize (as determined from the + * configured jurisdiction policy files). + * @exception InvalidAlgorithmParameterException if the given algorithm parameters are + * inappropriate for this cipher, or this cipher is being initialized for decryption and + * requires algorithm parameters and <code>params</code> is null, or the given algorithm + * parameters imply a cryptographic strength that would exceed the legal limits (as determined + * from the configured jurisdiction policy files). Note: Jurisdiction files are ignored + * in this implementation. + */ + public final void init( + int opmode, + Key key, + AlgorithmParameterSpec params) + throws InvalidKeyException, InvalidAlgorithmParameterException + { + cipherSpi.engineInit(opmode, key, params, new SecureRandom()); + mode = opmode; + } + + /** + * Initializes this cipher with a key, a set of algorithm + * parameters, and a source of randomness. + * <p> + * The cipher is initialized for one of the following four operations: + * encryption, decryption, key wrapping or key unwrapping, depending + * on the value of <code>opmode</code>. + * <p> + * If this cipher requires any algorithm parameters and + * <code>params</code> is null, the underlying cipher implementation is + * supposed to generate the required parameters itself (using + * provider-specific default or random values) if it is being + * initialized for encryption or key wrapping, and raise an + * <code>InvalidAlgorithmParameterException</code> if it is being + * initialized for decryption or key unwrapping. + * The generated parameters can be retrieved using + * <a href = "#getParameters()">getParameters</a> or + * <a href = "#getIV()">getIV</a> (if the parameter is an IV). + * <p> + * If this cipher (including its underlying feedback or padding scheme) + * requires any random bytes (e.g., for parameter generation), it will get + * them from <code>random</code>. + * <p> + * Note that when a Cipher object is initialized, it loses all + * previously-acquired state. In other words, initializing a Cipher is + * equivalent to creating a new instance of that Cipher and initializing + * it. + * + * @param opmode the operation mode of this cipher (this is one of the + * following: <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, + * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) + * @param key the encryption key + * @param params the algorithm parameters + * @param random the source of randomness + * @exception InvalidKeyException if the given key is inappropriate for + * initializing this cipher, or its keysize exceeds the maximum allowable + * keysize (as determined from the configured jurisdiction policy files). + * @exception InvalidAlgorithmParameterException if the given algorithm + * parameters are inappropriate for this cipher, + * or this cipher is being initialized for decryption and requires + * algorithm parameters and <code>params</code> is null, or the given + * algorithm parameters imply a cryptographic strength that would exceed + * the legal limits (as determined from the configured jurisdiction + * policy files). + * Note: Jurisdiction files are ignored in this implementation. + */ + public final void init( + int opmode, + Key key, + AlgorithmParameterSpec params, + SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException + { + cipherSpi.engineInit(opmode, key, params, random); + mode = opmode; + } + + /** + * Initializes this cipher with a key and a set of algorithm + * parameters. + * <p> + * The cipher is initialized for one of the following four operations: + * encryption, decryption, key wrapping or key unwrapping, depending + * on the value of <code>opmode</code>. + * <p> + * If this cipher requires any algorithm parameters and + * <code>params</code> is null, the underlying cipher implementation is + * supposed to generate the required parameters itself (using + * provider-specific default or random values) if it is being + * initialized for encryption or key wrapping, and raise an + * <code>InvalidAlgorithmParameterException</code> if it is being + * initialized for decryption or key unwrapping. + * The generated parameters can be retrieved using + * <a href = "#getParameters()">getParameters</a> or + * <a href = "#getIV()">getIV</a> (if the parameter is an IV). + * <p> + * If this cipher (including its underlying feedback or padding scheme) + * requires any random bytes (e.g., for parameter generation), it will get + * them using the + * <a href="http://java.sun.com/products/jdk/1.2/docs/api/java.security.SecureRandom.html"> + * <code>SecureRandom</code></a> implementation of the highest-priority + * installed provider as the source of randomness. + * (If none of the installed providers supply an implementation of + * SecureRandom, a system-provided source of randomness will be used.) + * <p> + * Note that when a Cipher object is initialized, it loses all + * previously-acquired state. In other words, initializing a Cipher is + * equivalent to creating a new instance of that Cipher and initializing + * it. + * + * @param opmode the operation mode of this cipher (this is one of the + * following: <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, <code>WRAP_MODE</code> + * or <code>UNWRAP_MODE</code>) + * @param key the encryption key + * @param params the algorithm parameters + * @exception InvalidKeyException if the given key is inappropriate for + * initializing this cipher, or its keysize exceeds the maximum allowable + * keysize (as determined from the configured jurisdiction policy files). + * @exception InvalidAlgorithmParameterException if the given algorithm + * parameters are inappropriate for this cipher, + * or this cipher is being initialized for decryption and requires + * algorithm parameters and <code>params</code> is null, or the given + * algorithm parameters imply a cryptographic strength that would exceed + * the legal limits (as determined from the configured jurisdiction + * policy files). + * Note: Jurisdiction files are ignored in this implementation. + */ + public final void init( + int opmode, + Key key, + AlgorithmParameters params) + throws InvalidKeyException, InvalidAlgorithmParameterException + { + cipherSpi.engineInit(opmode, key, params, new SecureRandom()); + mode = opmode; + } + + /** + * Initializes this cipher with a key, a set of algorithm + * parameters, and a source of randomness. + * <p> + * The cipher is initialized for one of the following four operations: + * encryption, decryption, key wrapping or key unwrapping, depending + * on the value of <code>opmode</code>. + * <p> + * If this cipher requires any algorithm parameters and + * <code>params</code> is null, the underlying cipher implementation is + * supposed to generate the required parameters itself (using + * provider-specific default or random values) if it is being + * initialized for encryption or key wrapping, and raise an + * <code>InvalidAlgorithmParameterException</code> if it is being + * initialized for decryption or key unwrapping. + * The generated parameters can be retrieved using + * <a href = "#getParameters()">getParameters</a> or + * <a href = "#getIV()">getIV</a> (if the parameter is an IV). + * <p> + * If this cipher (including its underlying feedback or padding scheme) + * requires any random bytes (e.g., for parameter generation), it will get + * them from <code>random</code>. + * <p> + * Note that when a Cipher object is initialized, it loses all + * previously-acquired state. In other words, initializing a Cipher is + * equivalent to creating a new instance of that Cipher and initializing + * it. + * + * @param opmode the operation mode of this cipher (this is one of the + * following: <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, <code>WRAP_MODE</code> + * or <code>UNWRAP_MODE</code>) + * @param key the encryption key + * @param params the algorithm parameters + * @param random the source of randomness + * @exception InvalidKeyException if the given key is inappropriate for + * initializing this cipher, or its keysize exceeds the maximum allowable + * keysize (as determined from the configured jurisdiction policy files). + * @exception InvalidAlgorithmParameterException if the given algorithm + * parameters are inappropriate for this cipher, + * or this cipher is being initialized for decryption and requires + * algorithm parameters and <code>params</code> is null, or the given + * algorithm parameters imply a cryptographic strength that would exceed + * the legal limits (as determined from the configured jurisdiction + * policy files). + * Note: Jurisdiction files are ignored in this implementation. + */ + public final void init( + int opmode, + Key key, + AlgorithmParameters params, + SecureRandom random) + throws InvalidKeyException, InvalidAlgorithmParameterException + { + cipherSpi.engineInit(opmode, key, params, random); + mode = opmode; + } + + /** + * Initializes this cipher with the public key from the given certificate. + * <p> + * The cipher is initialized for one of the following four operations: + * encryption, decryption, key wrapping or key unwrapping, depending + * on the value of <code>opmode</code>. + * <p> + * If the certificate is of type X.509 and has a <i>key usage</i> + * extension field marked as critical, and the value of the <i>key usage</i> + * extension field implies that the public key in + * the certificate and its corresponding private key are not + * supposed to be used for the operation represented by the value + * of <code>opmode</code>, + * an <code>InvalidKeyException</code> + * is thrown. + * <p> + * If this cipher requires any algorithm parameters that cannot be + * derived from the public key in the given certificate, the underlying + * cipher + * implementation is supposed to generate the required parameters itself + * (using provider-specific default or ramdom values) if it is being + * initialized for encryption or key wrapping, and raise an <code> + * InvalidKeyException</code> if it is being initialized for decryption or + * key unwrapping. + * The generated parameters can be retrieved using + * <a href = "#getParameters()">getParameters</a> or + * <a href = "#getIV()">getIV</a> (if the parameter is an IV). + * <p> + * If this cipher (including its underlying feedback or padding scheme) + * requires any random bytes (e.g., for parameter generation), it will get + * them using the + * <a href="http://java.sun.com/products/jdk/1.2/docs/api/java.security.SecureRandom.html"> + * <code>SecureRandom</code></a> + * implementation of the highest-priority installed provider as the source of randomness. + * (If none of the installed providers supply an implementation of + * SecureRandom, a system-provided source of randomness will be used.) + * <p> + * Note that when a Cipher object is initialized, it loses all + * previously-acquired state. In other words, initializing a Cipher is + * equivalent to creating a new instance of that Cipher and initializing + * it. + * @param opmode the operation mode of this cipher (this is one of the + * following: + * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, + * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) + * @param certificate the certificate + * @exception InvalidKeyException if the public key in the given + * certificate is inappropriate for initializing this cipher, or this + * cipher is being initialized for decryption or unwrapping keys and + * requires algorithm parameters that cannot be determined from the + * public key in the given certificate, or the keysize of the public key + * in the given certificate has a keysize that exceeds the maximum + * allowable keysize (as determined by the configured jurisdiction policy + * files). + * Note: Jurisdiction files are ignored in this implementation. + */ + public final void init( + int opmode, + Certificate certificate) + throws InvalidKeyException + { + cipherSpi.engineInit(opmode, certificate.getPublicKey(), new SecureRandom()); + mode = opmode; + } + + /** + * Initializes this cipher with the public key from the given certificate + * and a source of randomness. + * <p>The cipher is initialized for one of the following four operations: + * encryption, decryption, key wrapping + * or key unwrapping, depending on + * the value of <code>opmode</code>. + * <p> + * If the certificate is of type X.509 and has a <i>key usage</i> + * extension field marked as critical, and the value of the <i>key usage</i> + * extension field implies that the public key in + * the certificate and its corresponding private key are not + * supposed to be used for the operation represented by the value of + * <code>opmode</code>, + * an <code>InvalidKeyException</code> + * is thrown. + * <p> + * If this cipher requires any algorithm parameters that cannot be + * derived from the public key in the given <code>certificate</code>, + * the underlying cipher + * implementation is supposed to generate the required parameters itself + * (using provider-specific default or random values) if it is being + * initialized for encryption or key wrapping, and raise an + * <code>InvalidKeyException</code> if it is being + * initialized for decryption or key unwrapping. + * The generated parameters can be retrieved using + * <a href = "#engineGetParameters()">engineGetParameters</a> or + * <a href = "#engineGetIV()">engineGetIV</a> (if the parameter is an IV). + * <p> + * If this cipher (including its underlying feedback or padding scheme) + * requires any random bytes (e.g., for parameter generation), it will get + * them from <code>random</code>. + * <p> + * Note that when a Cipher object is initialized, it loses all + * previously-acquired state. In other words, initializing a Cipher is + * equivalent to creating a new instance of that Cipher and initializing + * it. + * + * @param opmode the operation mode of this cipher (this is one of the + * following: <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, + * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) + * @param certificate the certificate + * @param random the source of randomness + * @exception InvalidKeyException if the public key in the given + * certificate is inappropriate for initializing this cipher, or this + * cipher is being initialized for decryption or unwrapping keys and + * requires algorithm parameters that cannot be determined from the + * public key in the given certificate, or the keysize of the public key + * in the given certificate has a keysize that exceeds the maximum + * allowable keysize (as determined by the configured jurisdiction policy + * files). + */ + public final void init( + int opmode, + Certificate certificate, + SecureRandom random) + throws InvalidKeyException + { + cipherSpi.engineInit(opmode, certificate.getPublicKey(), random); + mode = opmode; + } + + /** + * Continues a multiple-part encryption or decryption operation + * (depending on how this cipher was initialized), processing another data + * part. + * <p> + * The bytes in the <code>input</code> buffer are processed, and the + * result is stored in a new buffer. + * <p> + * If <code>input</code> has a length of zero, this method returns + * <code>null</code>. + * + * @param input the input buffer + * @return the new buffer with the result, or null if the underlying + * cipher is a block cipher and the input data is too short to result in a + * new block. + * @exception IllegalStateException if this cipher is in a wrong state + * (e.g., has not been initialized) + */ + public final byte[] update( + byte[] input) + throws IllegalStateException + { + if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) + { + throw new IllegalStateException("Cipher is uninitialised"); + } + + if (input == null) + { + throw new IllegalArgumentException("Null input buffer"); + } + + if (input.length == 0) + { + return null; + } + + return cipherSpi.engineUpdate(input, 0, input.length); + } + + /** + * Continues a multiple-part encryption or decryption operation + * (depending on how this cipher was initialized), processing another data + * part. + * <p> + * The first <code>inputLen</code> bytes in the <code>input</code> + * buffer, starting at <code>inputOffset</code> inclusive, are processed, + * and the result is stored in a new buffer. + * <p> + * If <code>inputLen</code> is zero, this method returns + * <code>null</code>. + * + * @param input the input buffer + * @param inputOffset the offset in <code>input</code> where the input + * starts + * @param inputLen the input length + * @return the new buffer with the result, or null if the underlying + * cipher is a block cipher and the input data is too short to result in a + * new block. + * @exception IllegalStateException if this cipher is in a wrong state + * (e.g., has not been initialized) + */ + public final byte[] update( + byte[] input, + int inputOffset, + int inputLen) + throws IllegalStateException + { + if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) + { + throw new IllegalStateException("Cipher is uninitialised"); + } + + if (input == null) + { + throw new IllegalArgumentException("Null input passed"); + } + + if (inputLen < 0 || inputOffset < 0 + || inputLen > (input.length - inputOffset)) + { + throw new IllegalArgumentException("Bad inputOffset/inputLen"); + } + + if (inputLen == 0) + { + return null; + } + + return cipherSpi.engineUpdate(input, inputOffset, inputLen); + } + + /** + * Continues a multiple-part encryption or decryption operation + * (depending on how this cipher was initialized), processing another data + * part. + * <p> + * The first <code>inputLen</code> bytes in the <code>input</code> + * buffer, starting at <code>inputOffset</code> inclusive, are processed, + * and the result is stored in the <code>output</code> buffer. + * <p> + * If the <code>output</code> buffer is too small to hold the result, + * a <code>ShortBufferException</code> is thrown. In this case, repeat this + * call with a larger output buffer. Use + * <a href = "#getOutputSize(int)">getOutputSize</a> to determine how big + * the output buffer should be. + * <p> + * If <code>inputLen</code> is zero, this method returns + * a length of zero. + * + * @param input the input buffer + * @param inputOffset the offset in <code>input</code> where the input starts + * @param inputLen the input length + * @param output the buffer for the result + * @return the number of bytes stored in <code>output</code> + * @exception IllegalStateException if this cipher is in a wrong state + * (e.g., has not been initialized) + * @exception ShortBufferException if the given output buffer is too small + * to hold the result + */ + public final int update( + byte[] input, + int inputOffset, + int inputLen, + byte[] output) + throws IllegalStateException, ShortBufferException + { + if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) + { + throw new IllegalStateException("Cipher is uninitialised"); + } + + if (input == null) + { + throw new IllegalArgumentException("Null input passed"); + } + + if (inputLen < 0 || inputOffset < 0 + || inputLen > (input.length - inputOffset)) + { + throw new IllegalArgumentException("Bad inputOffset/inputLen"); + } + + if (output == null) + { + throw new IllegalArgumentException("Null output passed"); + } + + if (inputLen == 0) + { + return 0; + } + + return cipherSpi.engineUpdate(input, inputOffset, inputLen, output, 0); + } + + /** + * Continues a multiple-part encryption or decryption operation + * (depending on how this cipher was initialized), processing another data + * part. + * <p> + * The first <code>inputLen</code> bytes in the <code>input</code> + * buffer, starting at <code>inputOffset</code> inclusive, are processed, + * and the result is stored in the <code>output</code> buffer, starting at + * <code>outputOffset</code> inclusive. + * <p> + * If the <code>output</code> buffer is too small to hold the result, + * a <code>ShortBufferException</code> is thrown. In this case, repeat this + * call with a larger output buffer. Use + * <a href = "#getOutputSize(int)">getOutputSize</a> to determine how big + * the output buffer should be. + * <p> + * If <code>inputLen</code> is zero, this method returns + * a length of zero. + * + * @param input the input buffer + * @param inputOffset the offset in <code>input</code> where the input starts + * @param inputLen the input length + * @param output the buffer for the result + * @param outputOffset the offset in <code>output</code> where the result + * is stored + * @return the number of bytes stored in <code>output</code> + * @exception IllegalStateException if this cipher is in a wrong state + * (e.g., has not been initialized) + * @exception ShortBufferException if the given output buffer is too small + * to hold the result + */ + public final int update( + byte[] input, + int inputOffset, + int inputLen, + byte[] output, + int outputOffset) + throws IllegalStateException, ShortBufferException + { + if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) + { + throw new IllegalStateException("Cipher is uninitialised"); + } + + if (input == null) + { + throw new IllegalArgumentException("Null input passed"); + } + + if (inputLen < 0 || inputOffset < 0 + || inputLen > (input.length - inputOffset)) + { + throw new IllegalArgumentException("Bad inputOffset/inputLen"); + } + + if (output == null) + { + throw new IllegalArgumentException("Null output passed"); + } + + if (outputOffset < 0 || outputOffset >= output.length) + { + throw new IllegalArgumentException("Bad outputOffset"); + } + + if (inputLen == 0) + { + return 0; + } + + return cipherSpi.engineUpdate(input, inputOffset, inputLen, output, outputOffset); + } + + /** + * Finishes a multiple-part encryption or decryption operation, depending + * on how this cipher was initialized. + * <p> + * Input data that may have been buffered during a previous + * <code>update</code> operation is processed, with padding (if requested) + * being applied. + * The result is stored in a new buffer. + * <p> + * A call to this method resets this cipher object to the state + * it was in when previously initialized via a call to <code>init</code>. + * That is, the object is reset and available to encrypt or decrypt + * (depending on the operation mode that was specified in the call to + * <code>init</code>) more data. + * @return the new buffer with the result + * @exception IllegalStateException if this cipher is in a wrong state + * (e.g., has not been initialized) + * @exception IllegalBlockSizeException if this cipher is a block cipher, + * no padding has been requested (only in encryption mode), and the total + * input length of the data processed by this cipher is not a multiple of + * block size + * @exception BadPaddingException if this cipher is in decryption mode, + * and (un)padding has been requested, but the decrypted data is not + * bounded by the appropriate padding bytes + */ + public final byte[] doFinal() + throws java.lang.IllegalStateException, IllegalBlockSizeException, + BadPaddingException + { + if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) + { + throw new IllegalStateException("Cipher is uninitialised"); + } + + return cipherSpi.engineDoFinal(null, 0, 0); + } + + /** + * Finishes a multiple-part encryption or decryption operation, depending + * on how this cipher was initialized. + * <p> + * Input data that may have been buffered during a previous + * <code>update</code> operation is processed, with padding (if requested) + * being applied. + * The result is stored in the <code>output</code> buffer, starting at + * <code>outputOffset</code> inclusive. + * <p> + * If the <code>output</code> buffer is too small to hold the result, + * a <code>ShortBufferException</code> is thrown. In this case, repeat this + * call with a larger output buffer. Use + * <a href = "#getOutputSize(int)">getOutputSize</a> to determine how big + * the output buffer should be. + * <p> + * A call to this method resets this cipher object to the state + * it was in when previously initialized via a call to <code>init</code>. + * That is, the object is reset and available to encrypt or decrypt + * (depending on the operation mode that was specified in the call to + * <code>init</code>) more data. + * + * @param output the buffer for the result + * @param outputOffset the offset in <code>output</code> where the result + * is stored + * @return the number of bytes stored in <code>output</code> + * @exception IllegalStateException if this cipher is in a wrong state + * (e.g., has not been initialized) + * @exception IllegalBlockSizeException if this cipher is a block cipher, + * no padding has been requested (only in encryption mode), and the total + * input length of the data processed by this cipher is not a multiple of + * block size + * @exception ShortBufferException if the given output buffer is too small + * to hold the result + * @exception BadPaddingException if this cipher is in decryption mode, + * and (un)padding has been requested, but the decrypted data is not + * bounded by the appropriate padding bytes + */ + public final int doFinal( + byte[] output, + int outputOffset) + throws IllegalStateException, IllegalBlockSizeException, + ShortBufferException, BadPaddingException + { + if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) + { + throw new IllegalStateException("Cipher is uninitialised"); + } + + if (output == null) + { + throw new IllegalArgumentException("Null output passed"); + } + + if (outputOffset < 0 || outputOffset >= output.length) + { + throw new IllegalArgumentException("Bad outputOffset"); + } + + return cipherSpi.engineDoFinal(null, 0, 0, output, outputOffset); + } + + /** + * Encrypts or decrypts data in a single-part operation, or finishes a + * multiple-part operation. The data is encrypted or decrypted, + * depending on how this cipher was initialized. + * <p> + * The bytes in the <code>input</code> buffer, and any input bytes that + * may have been buffered during a previous <code>update</code> operation, + * are processed, with padding (if requested) being applied. + * The result is stored in a new buffer. + * <p> + * A call to this method resets this cipher object to the state + * it was in when previously initialized via a call to <code>init</code>. + * That is, the object is reset and available to encrypt or decrypt + * (depending on the operation mode that was specified in the call to + * <code>init</code>) more data. + * + * @param input the input buffer + * @return the new buffer with the result + * @exception IllegalStateException if this cipher is in a wrong state + * (e.g., has not been initialized) + * @exception IllegalBlockSizeException if this cipher is a block cipher, + * no padding has been requested (only in encryption mode), and the total + * input length of the data processed by this cipher is not a multiple of + * block size + * @exception BadPaddingException if this cipher is in decryption mode, + * and (un)padding has been requested, but the decrypted data is not + * bounded by the appropriate padding bytes + */ + public final byte[] doFinal( + byte[] input) + throws java.lang.IllegalStateException, IllegalBlockSizeException, BadPaddingException + { + if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) + { + throw new IllegalStateException("Cipher is uninitialised"); + } + + if (input == null) + { + throw new IllegalArgumentException("Null input passed"); + } + + return cipherSpi.engineDoFinal(input, 0, input.length); + } + + /** + * Encrypts or decrypts data in a single-part operation, or finishes a + * multiple-part operation. The data is encrypted or decrypted, + * depending on how this cipher was initialized. + * <p> + * The first <code>inputLen</code> bytes in the <code>input</code> + * buffer, starting at <code>inputOffset</code> inclusive, and any input + * bytes that may have been buffered during a previous <code>update</code> + * operation, are processed, with padding (if requested) being applied. + * The result is stored in a new buffer. + * <p>A call to this method resets this cipher object to the state + * it was in when previously initialized via a call to <code>init</code>. + * That is, the object is reset and available to encrypt or decrypt + * (depending on the operation mode that was specified in the call to + * <code>init</code>) more data. + * + * @param input the input buffer + * @param inputOffset the offset in <code>input</code> where the input starts + * @param inputLen the input length + * @return the new buffer with the result + * @exception IllegalStateException if this cipher is in a wrong state + * (e.g., has not been initialized) + * @exception IllegalBlockSizeException if this cipher is a block cipher, + * no padding has been requested (only in encryption mode), and the total + * input length of the data processed by this cipher is not a multiple of + * block size + * @exception BadPaddingException if this cipher is in decryption mode, + * and (un)padding has been requested, but the decrypted data is not + * bounded by the appropriate padding bytes + */ + public final byte[] doFinal( + byte[] input, + int inputOffset, + int inputLen) + throws IllegalStateException, IllegalBlockSizeException, BadPaddingException + { + if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) + { + throw new IllegalStateException("Cipher is uninitialised"); + } + + if (input == null) + { + throw new IllegalArgumentException("Null input passed"); + } + + if (inputLen < 0 || inputOffset < 0 + || inputLen > (input.length - inputOffset)) + { + throw new IllegalArgumentException("Bad inputOffset/inputLen"); + } + + return cipherSpi.engineDoFinal(input, inputOffset, inputLen); + } + + /** + * Encrypts or decrypts data in a single-part operation, or finishes a + * multiple-part operation. The data is encrypted or decrypted, + * depending on how this cipher was initialized. + * <p> + * The first <code>inputLen</code> bytes in the <code>input</code> + * buffer, starting at <code>inputOffset</code> inclusive, and any input + * bytes that may have been buffered during a previous <code>update</code> + * operation, are processed, with padding (if requested) being applied. + * The result is stored in the <code>output</code> buffer. + * <p> + * If the <code>output</code> buffer is too small to hold the result, + * a <code>ShortBufferException</code> is thrown. In this case, repeat this + * call with a larger output buffer. Use + * <a href = "#getOutputSize(int)">getOutputSize</a> to determine how big + * the output buffer should be. + * <p> + * A call to this method resets this cipher object to the state + * it was in when previously initialized via a call to <code>init</code>. + * That is, the object is reset and available to encrypt or decrypt + * (depending on the operation mode that was specified in the call to + * <code>init</code>) more data. + * @param input the input buffer + * @param inputOffset the offset in <code>input</code> where the input starts + * @param inputLen the input length + * @param output the buffer for the result + * @return the number of bytes stored in <code>output</code> + * @exception IllegalStateException if this cipher is in a wrong state + * (e.g., has not been initialized) + * @exception IllegalBlockSizeException if this cipher is a block cipher, + * no padding has been requested (only in encryption mode), and the total + * input length of the data processed by this cipher is not a multiple of + * block size + * @exception ShortBufferException if the given output buffer is too small + * to hold the result + * @exception BadPaddingException if this cipher is in decryption mode, + * and (un)padding has been requested, but the decrypted data is not + * bounded by the appropriate padding bytes + */ + public final int doFinal( + byte[] input, + int inputOffset, + int inputLen, + byte[] output) + throws IllegalStateException, ShortBufferException, + IllegalBlockSizeException, BadPaddingException + { + if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) + { + throw new IllegalStateException("Cipher is uninitialised"); + } + + if (input == null) + { + throw new IllegalArgumentException("Null input passed"); + } + + if (inputLen < 0 || inputOffset < 0 + || inputLen > (input.length - inputOffset)) + { + throw new IllegalArgumentException("Bad inputOffset/inputLen"); + } + + if (output == null) + { + throw new IllegalArgumentException("Null output passed"); + } + + return cipherSpi.engineDoFinal(input, inputOffset, inputLen, output, 0); + } + + /** + * Encrypts or decrypts data in a single-part operation, or finishes a + * multiple-part operation. The data is encrypted or decrypted, + * depending on how this cipher was initialized. + * <p> + * The first <code>inputLen</code> bytes in the <code>input</code> + * buffer, starting at <code>inputOffset</code> inclusive, and any input + * bytes that may have been buffered during a previous + * <code>update</code> operation, are processed, with padding + * (if requested) being applied. + * The result is stored in the <code>output</code> buffer, starting at + * <code>outputOffset</code> inclusive. + * <p> + * If the <code>output</code> buffer is too small to hold the result, + * a <code>ShortBufferException</code> is thrown. In this case, repeat this + * call with a larger output buffer. Use + * <a href = "#getOutputSize(int)">getOutputSize</a> to determine how big + * the output buffer should be. + * <p> + * A call to this method resets this cipher object to the state + * it was in when previously initialized via a call to <code>init</code>. + * That is, the object is reset and available to encrypt or decrypt + * (depending on the operation mode that was specified in the call to + * <code>init</code>) more data. + * + * @param input the input buffer + * @param inputOffset the offset in <code>input</code> where the input starts + * @param inputLen the input length + * @param output the buffer for the result + * @param outputOffset the offset in <code>output</code> where the result is + * stored + * @return the number of bytes stored in <code>output</code> + * @exception IllegalStateException if this cipher is in a wrong state + * (e.g., has not been initialized) + * @exception IllegalBlockSizeException if this cipher is a block cipher, + * no padding has been requested (only in encryption mode), and the total + * input length of the data processed by this cipher is not a multiple of + * block size + * @exception ShortBufferException if the given output buffer is too small + * to hold the result + * @exception BadPaddingException if this cipher is in decryption mode, + * and (un)padding has been requested, but the decrypted data is not + * bounded by the appropriate padding bytes + */ + public final int doFinal( + byte[] input, + int inputOffset, + int inputLen, + byte[] output, + int outputOffset) + throws IllegalStateException, ShortBufferException, + IllegalBlockSizeException, BadPaddingException + { + if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) + { + throw new IllegalStateException("Cipher is uninitialised"); + } + + if (input == null) + { + throw new IllegalArgumentException("Null input passed"); + } + + if (inputLen < 0 || inputOffset < 0 + || inputLen > (input.length - inputOffset)) + { + throw new IllegalArgumentException("Bad inputOffset/inputLen"); + } + + if (output == null) + { + throw new IllegalArgumentException("Null output passed"); + } + + if (outputOffset < 0 || outputOffset >= output.length) + { + throw new IllegalArgumentException("Bad outputOffset"); + } + + return cipherSpi.engineDoFinal(input, inputOffset, inputLen, output, outputOffset); + } + + /** + * Wrap a key. + * + * @param key the key to be wrapped. + * @return the wrapped key. + * @exception IllegalStateException if this cipher is in a wrong state (e.g., has not + * been initialized). + * @exception IllegalBlockSizeException if this cipher is a block cipher, no padding + * has been requested, and the length of the encoding of the key to be wrapped is not a + * multiple of the block size. + * @exception <DD>java.security.InvalidKeyException - if it is impossible or unsafe to + * wrap the key with this cipher (e.g., a hardware protected key is being passed to a + * software-only cipher). + */ + public final byte[] wrap( + Key key) + throws IllegalStateException, IllegalBlockSizeException, InvalidKeyException + { + if (mode != WRAP_MODE) + { + throw new IllegalStateException("Cipher is not initialised for wrapping"); + } + + if (key == null) + { + throw new IllegalArgumentException("Null key passed"); + } + + return cipherSpi.engineWrap(key); + } + + /** + * Unwrap a previously wrapped key. + * + * @param wrappedKey the key to be unwrapped. + * @param wrappedKeyAlgorithm the algorithm associated with the wrapped key. + * @param wrappedKeyType the type of the wrapped key. This must be one of + * <code>SECRET_KEY</code>, <code>PRIVATE_KEY</code>, or <code>PUBLIC_KEY</code>. + * @return the unwrapped key. + * @exception IllegalStateException if this cipher is in a wrong state + * (e.g., has not been initialized). + * @exception InvalidKeyException if <code>wrappedKey</code> does not + * represent a wrapped key, or if the algorithm associated with the + * wrapped key is different from <code>wrappedKeyAlgorithm</code> + * and/or its key type is different from <code>wrappedKeyType</code>. + * @exception NoSuchAlgorithmException - if no installed providers + * can create keys for the <code>wrappedKeyAlgorithm</code>. + */ + public final Key unwrap( + byte[] wrappedKey, + String wrappedKeyAlgorithm, + int wrappedKeyType) + throws IllegalStateException, InvalidKeyException, NoSuchAlgorithmException + { + if (mode != UNWRAP_MODE) + { + throw new IllegalStateException("Cipher is not initialised for unwrapping"); + } + + if (wrappedKeyType != SECRET_KEY && wrappedKeyType != PUBLIC_KEY + && wrappedKeyType != PRIVATE_KEY) + { + throw new IllegalArgumentException("Invalid key type argument"); + } + + if (wrappedKey == null) + { + throw new IllegalArgumentException("Null wrappedKey passed"); + } + + if (wrappedKeyAlgorithm == null) + { + throw new IllegalArgumentException("Null wrappedKeyAlgorithm string passed"); + } + + return cipherSpi.engineUnwrap(wrappedKey, wrappedKeyAlgorithm, wrappedKeyType); + } +} |