/* * 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.nio.ByteBuffer; import java.security.AlgorithmParameters; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.SecureRandom; import java.security.Security; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.security.spec.AlgorithmParameterSpec; import java.util.Set; import org.apache.harmony.crypto.internal.NullCipherSpi; import org.apache.harmony.security.fortress.Engine; /** * This class provides access to implementations of cryptographic ciphers for * encryption and decryption. Cipher classes can not be instantiated directly, * one has to call the Cipher's {@code getInstance} method with the name of a * requested transformation, optionally with a provider. A transformation * specifies an operation (or a set of operations) as a string in the form: *
* A valid transformation would be: *
* This is the name of the transformation argument used in the * {@code getInstance} call creating this object. * * @return the name of the algorithm of this cipher instance. */ public final String getAlgorithm() { return transformation; } /** * Returns this ciphers block size (in bytes). * * @return this ciphers block size. */ public final int getBlockSize() { return spiImpl.engineGetBlockSize(); } /** * Returns the length in bytes an output buffer needs to be when this cipher * is updated with {@code inputLen} bytes. * * @param inputLen * the number of bytes of the input. * @return the output buffer length for the input length. * @throws IllegalStateException * if this cipher instance is in an invalid state. */ public final int getOutputSize(int inputLen) { if (mode == 0) { throw new IllegalStateException("Cipher has not yet been initialized"); } return spiImpl.engineGetOutputSize(inputLen); } /** * Returns the initialization vector for this cipher instance. * * @return the initialization vector for this cipher instance. */ public final byte[] getIV() { return spiImpl.engineGetIV(); } /** * Returns the parameters that where used to create this cipher instance. *
* These may be a the same parameters that were used to create this cipher * instance, or may be a combination of default and random parameters, * depending on the underlying cipher implementation. * * @return the parameters that where used to create this cipher instance, or * {@code null} if this cipher instance does not have any * parameters. */ public final AlgorithmParameters getParameters() { return spiImpl.engineGetParameters(); } /** * Returns the exemption mechanism associated with this cipher. * * @return currently {@code null} */ public final ExemptionMechanism getExemptionMechanism() { //FIXME implement getExemptionMechanism // try { // return ExemptionMechanism.getInstance(transformation, provider); // } catch (NoSuchAlgorithmException e) { return null; // } } /** * Initializes this cipher instance with the specified key. *
* The cipher is initialized for the specified operational mode (one of: * encryption, decryption, key wrapping or key unwrapping) depending on * {@code opmode}. *
* If this cipher instance needs any algorithm parameters or random values * that the specified key can not provide, the underlying implementation of * this cipher is supposed to generate the required parameters (using its * provider or random values). *
* When a cipher instance is initialized by a call to any of the {@code * init} methods, the state of the instance is overridden, meaning that it * is equivalent to creating a new instance and calling its {@code init} * method. * * @param opmode * the operation this cipher instance should be initialized for * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code * WRAP_MODE} or {@code UNWRAP_MODE}). * @param key * the input key for the operation. * @throws InvalidKeyException * if the specified key can not be used to initialize this * cipher instance. */ public final void init(int opmode, Key key) throws InvalidKeyException { if (secureRandom == null) { // In theory it might be thread-unsafe but in the given case it's OK // since it does not matter which SecureRandom instance is passed // to the init() secureRandom = new SecureRandom(); } init(opmode, key, secureRandom); } /** * Initializes this cipher instance with the specified key and a source of * randomness. *
* The cipher is initialized for the specified operational mode (one of: * encryption, decryption, key wrapping or key unwrapping) depending on * {@code opmode}. *
* If this cipher instance needs any algorithm parameters or random values * that the specified key can not provide, the underlying implementation of * this cipher is supposed to generate the required parameters (using its * provider or random values). Random values are generated using {@code * random}; *
* When a cipher instance is initialized by a call to any of the {@code * init} methods, the state of the instance is overridden, means it is * equivalent to creating a new instance and calling it {@code init} method. * * @param opmode * the operation this cipher instance should be initialized for * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code * WRAP_MODE} or {@code UNWRAP_MODE}). * @param key * the input key for the operation. * @param random * the source of randomness to use. * @throws InvalidKeyException * if the specified key can not be used to initialize this * cipher instance. * @throws InvalidParameterException * if the specified opmode is invalid. */ public final void init(int opmode, Key key, SecureRandom random) throws InvalidKeyException { checkMode(opmode); // FIXME InvalidKeyException // if keysize exceeds the maximum allowable keysize // (jurisdiction policy files) spiImpl.engineInit(opmode, key, random); mode = opmode; } private void checkMode(int mode) { if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE && mode != UNWRAP_MODE && mode != WRAP_MODE) { throw new InvalidParameterException("Invalid mode: " + mode); } } /** * Initializes this cipher instance with the specified key and algorithm * parameters. *
* The cipher is initialized for the specified operational mode (one of: * encryption, decryption, key wrapping or key unwrapping). *
* If this cipher instance needs any algorithm parameters and {@code params} * is {@code null}, the underlying implementation of this cipher is supposed * to generate the required parameters (using its provider or random * values). *
* When a cipher instance is initialized by a call to any of the {@code * init} methods, the state of the instance is overridden, means it is * equivalent to creating a new instance and calling it {@code init} method. * * @param opmode * the operation this cipher instance should be initialized for * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code * WRAP_MODE} or {@code UNWRAP_MODE}). * @param key * the input key for the operation. * @param params * the algorithm parameters. * @throws InvalidKeyException * if the specified key can not be used to initialize this * cipher instance. * @throws InvalidAlgorithmParameterException * it the specified parameters are inappropriate for this * cipher. */ public final void init(int opmode, Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { if (secureRandom == null) { secureRandom = new SecureRandom(); } init(opmode, key, params, secureRandom); } /** * Initializes this cipher instance with the specified key, algorithm * parameters and a source of randomness. *
* The cipher is initialized for the specified operational mode (one of: * encryption, decryption, key wrapping or key unwrapping) depending on * {@code opmode}. *
* If this cipher instance needs any algorithm parameters and {@code params} * is {@code null}, the underlying implementation of this cipher is supposed * to generate the required parameters (using its provider or random * values). Random values are generated using {@code random}; *
* When a cipher instance is initialized by a call to any of the {@code * init} methods, the state of the instance is overridden, meaning that it * is equivalent to creating a new instance and calling it {@code init} * method. * * @param opmode * the operation this cipher instance should be initialized for * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code * WRAP_MODE} or {@code UNWRAP_MODE}). * @param key * the input key for the operation. * @param params * the algorithm parameters. * @param random * the source of randomness to use. * @throws InvalidKeyException * if the specified key can not be used to initialize this * cipher instance. * @throws InvalidAlgorithmParameterException * it the specified parameters are inappropriate for this * cipher. * @throws InvalidParameterException * if the specified {@code opmode} is invalid. */ public final void init(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { checkMode(opmode); // FIXME InvalidKeyException // if keysize exceeds the maximum allowable keysize // (jurisdiction policy files) // FIXME InvalidAlgorithmParameterException // cryptographic strength exceed the legal limits // (jurisdiction policy files) spiImpl.engineInit(opmode, key, params, random); mode = opmode; } /** * Initializes this cipher instance with the specified key and algorithm * parameters. *
* The cipher is initialized for the specified operation (one of: * encryption, decryption, key wrapping or key unwrapping) depending on * {@code opmode}. *
* If this cipher instance needs any algorithm parameters and {@code params} * is {@code null}, the underlying implementation of this cipher is supposed * to generate the required parameters (using its provider or random * values). *
* When a cipher instance is initialized by a call to any of the {@code * init} methods, the state of the instance is overridden, meaning that it * is equivalent to creating a new instance and calling it {@code init} * method. * * @param opmode * the operation this cipher instance should be initialized for * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code * WRAP_MODE} or {@code UNWRAP_MODE}). * @param key * the input key for the operation. * @param params * the algorithm parameters. * @throws InvalidKeyException * if the specified key can not be used to initialize this * cipher instance. * @throws InvalidAlgorithmParameterException * it the specified parameters are inappropriate for this * cipher. */ public final void init(int opmode, Key key, AlgorithmParameters params) throws InvalidKeyException, InvalidAlgorithmParameterException { if (secureRandom == null) { secureRandom = new SecureRandom(); } init(opmode, key, params, secureRandom); } /** * Initializes this cipher instance with the specified key, algorithm * parameters and a source of randomness. *
* The cipher will be initialized for the specified operation (one of: * encryption, decryption, key wrapping or key unwrapping) depending on * {@code opmode}. *
* If this cipher instance needs any algorithm parameters and {@code params} * is {@code null}, the underlying implementation of this cipher is supposed * to generate the required parameters (using its provider or random * values). Random values are generated using {@code random}. *
* When a cipher instance is initialized by a call to any of the {@code * init} methods, the state of the instance is overridden, means it is * equivalent to creating a new instance and calling it {@code init} method. * * @param opmode * the operation this cipher instance should be initialized for * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code * WRAP_MODE} or {@code UNWRAP_MODE}). * @param key * the input key for the operation. * @param params * the algorithm parameters. * @param random * the source of randomness to use. * @throws InvalidKeyException * if the specified key can not be used to initialize this * cipher instance. * @throws InvalidAlgorithmParameterException * if the specified parameters are inappropriate for this * cipher. * @throws InvalidParameterException * if the specified {@code opmode} is invalid. */ public final void init(int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { checkMode(opmode); // FIXME InvalidKeyException // if keysize exceeds the maximum allowable keysize // (jurisdiction policy files) // FIXME InvalidAlgorithmParameterException // cryptographic strength exceed the legal limits // (jurisdiction policy files) spiImpl.engineInit(opmode, key, params, random); mode = opmode; } /** * Initializes this cipher instance with the public key from the specified * certificate. *
* The cipher will be initialized for the specified operation (one of: * encryption, decryption, key wrapping or key unwrapping) depending on * {@code opmode}. *
* It the type of the certificate is X.509 and the certificate has a key * usage extension field marked as critical, the specified {@code * opmode} has the be enabled for this key, otherwise an {@code * InvalidKeyException} is thrown. *
* If this cipher instance needs any algorithm parameters that the key in * the certificate can not provide, the underlying implementation of this * cipher is supposed to generate the required parameters (using its * provider or random values). *
* When a cipher instance is initialized by a call to any of the {@code * init} methods, the state of the instance is overridden, means it is * equivalent to creating a new instance and calling it {@code init} method. * * @param opmode * the operation this cipher instance should be initialized for * (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code * WRAP_MODE} or {@code UNWRAP_MODE}). * @param certificate * the certificate. * @throws InvalidKeyException * if the public key in the certificate can not be used to * initialize this cipher instance. */ public final void init(int opmode, Certificate certificate) throws InvalidKeyException { if (secureRandom == null) { secureRandom = new SecureRandom(); } init(opmode, certificate, secureRandom); } /** * Initializes this cipher instance with the public key from the specified * certificate and a source of randomness. *
* The cipher will be initialized for the specified operation (one of: * encryption, decryption, key wrapping or key unwrapping) depending on * {@code opmode}. *
* It the type of the certificate is X.509 and the certificate has a key * usage extension field marked as critical, the specified {@code * opmode} has the be enabled for this key, otherwise an {@code * InvalidKeyException} is thrown. *
* If this cipher instance needs any algorithm parameters that the key in * the certificate can not provide, the underlying implementation of this * cipher is supposed to generate the required parameters (using its * provider or random values). Random values are generated using {@code * random}. *
* When a cipher instance is initialized by a call to any of the {@code
* init} methods, the state of the instance is overridden, means it is
* equivalent to creating a new instance and calling it {@code init} method.
*
* @param opmode
* the operation this cipher instance should be initialized for
* (one of: {@code ENCRYPT_MODE}, {@code DECRYPT_MODE}, {@code
* WRAP_MODE} or {@code UNWRAP_MODE}).
* @param certificate
* the certificate.
* @param random
* the source of randomness to be used.
* @throws InvalidKeyException
* if the public key in the certificate can not be used to
* initialize this cipher instance.
*/
public final void init(int opmode, Certificate certificate,
SecureRandom random) throws InvalidKeyException {
checkMode(opmode);
if (certificate instanceof X509Certificate) {
Set
* If the size of the {@code output} buffer is too small to hold the result,
* a {@code ShortBufferException} is thrown. Use
* {@link Cipher#getOutputSize getOutputSize} to check for the size of the
* output buffer.
*
* @param input
* the input bytes to transform.
* @param inputOffset
* the offset in the input to start.
* @param inputLen
* the length of the input to transform.
* @param output
* the output buffer.
* @return the number of bytes placed in output.
* @throws ShortBufferException
* if the size of the {@code output} buffer is too small.
* @throws IllegalStateException
* if this cipher instance is not initialized for encryption or
* decryption.
* @throws IllegalArgumentException
* if the input is {@code null}, the output is {@code null}, or
* if {@code inputOffset} and {@code inputLen} do not specify a
* valid chunk in the input buffer.
*/
public final int update(byte[] input, int inputOffset, int inputLen,
byte[] output) throws ShortBufferException {
return update(input, inputOffset, inputLen, output, 0);
}
/**
* Continues a multi-part transformation (encryption or decryption). The
* transformed bytes are stored in the {@code output} buffer.
*
* If the size of the {@code output} buffer is too small to hold the result,
* a {@code ShortBufferException} is thrown. Use
* {@link Cipher#getOutputSize getOutputSize} to check for the size of the
* output buffer.
*
* @param input
* the input bytes to transform.
* @param inputOffset
* the offset in the input to start.
* @param inputLen
* the length of the input to transform.
* @param output
* the output buffer.
* @param outputOffset
* the offset in the output buffer.
* @return the number of bytes placed in output.
* @throws ShortBufferException
* if the size of the {@code output} buffer is too small.
* @throws IllegalStateException
* if this cipher instance is not initialized for encryption or
* decryption.
* @throws IllegalArgumentException
* if the input is {@code null}, the output is {@code null}, or
* if {@code inputOffset} and {@code inputLen} do not specify a
* valid chunk in the input buffer.
*/
public final int update(byte[] input, int inputOffset, int inputLen,
byte[] output, int outputOffset) throws ShortBufferException {
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
throw new IllegalStateException();
}
if (input == null) {
throw new IllegalArgumentException("input == null");
}
if (output == null) {
throw new IllegalArgumentException("output == null");
}
if (outputOffset < 0) {
throw new IllegalArgumentException("outputOffset < 0. outputOffset=" + outputOffset);
}
checkInputOffsetAndCount(input.length, inputOffset, inputLen);
if (input.length == 0) {
return 0;
}
return spiImpl.engineUpdate(input, inputOffset, inputLen, output,
outputOffset);
}
/**
* Continues a multi-part transformation (encryption or decryption). The
* {@code input.remaining()} bytes starting at {@code input.position()} are
* transformed and stored in the {@code output} buffer.
*
* If the {@code output.remaining()} is too small to hold the transformed
* bytes a {@code ShortBufferException} is thrown. Use
* {@link Cipher#getOutputSize getOutputSize} to check for the size of the
* output buffer.
*
* @param input
* the input buffer to transform.
* @param output
* the output buffer to store the result within.
* @return the number of bytes stored in the output buffer.
* @throws ShortBufferException
* if the size of the {@code output} buffer is too small.
* @throws IllegalStateException
* if this cipher instance is not initialized for encryption or
* decryption.
* @throws IllegalArgumentException
* if the input buffer and the output buffer are the identical
* object.
*/
public final int update(ByteBuffer input, ByteBuffer output)
throws ShortBufferException {
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
throw new IllegalStateException();
}
if (input == output) {
throw new IllegalArgumentException("input == output");
}
return spiImpl.engineUpdate(input, output);
}
/**
* Finishes a multi-part transformation (encryption or decryption).
*
* Processes any bytes that may have been buffered in previous {@code
* update} calls.
*
* @return the final bytes from the transformation.
* @throws IllegalBlockSizeException
* if the size of the resulting bytes is not a multiple of the
* cipher block size.
* @throws BadPaddingException
* if the padding of the data does not match the padding scheme.
* @throws IllegalStateException
* if this cipher instance is not initialized for encryption or
* decryption.
*/
public final byte[] doFinal() throws IllegalBlockSizeException,
BadPaddingException {
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
throw new IllegalStateException();
}
return spiImpl.engineDoFinal(null, 0, 0);
}
/**
* Finishes a multi-part transformation (encryption or decryption).
*
* Processes any bytes that may have been buffered in previous {@code
* update} calls.
*
* The final transformed bytes are stored in the {@code output} buffer.
*
* @param output
* the output buffer.
* @param outputOffset
* the offset in the output buffer.
* @return the number of bytes placed in the output buffer.
* @throws IllegalBlockSizeException
* if the size of the resulting bytes is not a multiple of the
* cipher block size.
* @throws ShortBufferException
* if the size of the {@code output} buffer is too small.
* @throws BadPaddingException
* if the padding of the data does not match the padding scheme.
* @throws IllegalStateException
* if this cipher instance is not initialized for encryption or
* decryption.
*/
public final int doFinal(byte[] output, int outputOffset)
throws IllegalBlockSizeException, ShortBufferException,
BadPaddingException {
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
throw new IllegalStateException();
}
if (outputOffset < 0) {
throw new IllegalArgumentException("outputOffset < 0. outputOffset=" + outputOffset);
}
return spiImpl.engineDoFinal(null, 0, 0, output, outputOffset);
}
/**
* Finishes a multi-part transformation (encryption or decryption).
*
* Processes the bytes in {@code input} buffer, and any bytes that have been
* buffered in previous {@code update} calls.
*
* @param input
* the input buffer.
* @return the final bytes from the transformation.
* @throws IllegalBlockSizeException
* if the size of the resulting bytes is not a multiple of the
* cipher block size.
* @throws BadPaddingException
* if the padding of the data does not match the padding scheme.
* @throws IllegalStateException
* if this cipher instance is not initialized for encryption or
* decryption.
*/
public final byte[] doFinal(byte[] input) throws IllegalBlockSizeException,
BadPaddingException {
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
throw new IllegalStateException();
}
return spiImpl.engineDoFinal(input, 0, input.length);
}
/**
* Finishes a multi-part transformation (encryption or decryption).
*
* Processes the {@code inputLen} bytes in {@code input} buffer at {@code
* inputOffset}, and any bytes that have been buffered in previous {@code
* update} calls.
*
* @param input
* the input buffer.
* @param inputOffset
* the offset in the input buffer.
* @param inputLen
* the length of the input
* @return the final bytes from the transformation.
* @throws IllegalBlockSizeException
* if the size of the resulting bytes is not a multiple of the
* cipher block size.
* @throws BadPaddingException
* if the padding of the data does not match the padding scheme.
* @throws IllegalStateException
* if this cipher instance is not initialized for encryption or
* decryption.
* @throws IllegalArgumentException
* if {@code inputOffset} and {@code inputLen} do not specify an
* valid chunk in the input buffer.
*/
public final byte[] doFinal(byte[] input, int inputOffset, int inputLen)
throws IllegalBlockSizeException, BadPaddingException {
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
throw new IllegalStateException();
}
checkInputOffsetAndCount(input.length, inputOffset, inputLen);
return spiImpl.engineDoFinal(input, inputOffset, inputLen);
}
/**
* Finishes a multi-part transformation (encryption or decryption).
*
* Processes the {@code inputLen} bytes in {@code input} buffer at {@code
* inputOffset}, and any bytes that have been buffered in previous {@code
* update} calls.
*
* @param input
* the input buffer.
* @param inputOffset
* the offset in the input buffer.
* @param inputLen
* the length of the input.
* @param output
* the output buffer for the transformed bytes.
* @return the number of bytes placed in the output buffer.
* @throws ShortBufferException
* if the size of the {@code output} buffer is too small.
* @throws IllegalBlockSizeException
* if the size of the resulting bytes is not a multiple of the
* cipher block size.
* @throws BadPaddingException
* if the padding of the data does not match the padding scheme.
* @throws IllegalStateException
* if this cipher instance is not initialized for encryption or
* decryption.
* @throws IllegalArgumentException
* if {@code inputOffset} and {@code inputLen} do not specify an
* valid chunk in the input buffer.
*/
public final int doFinal(byte[] input, int inputOffset, int inputLen,
byte[] output) throws ShortBufferException,
IllegalBlockSizeException, BadPaddingException {
return doFinal(input, inputOffset, inputLen, output, 0);
}
/**
* Finishes a multi-part transformation (encryption or decryption).
*
* Processes the {@code inputLen} bytes in {@code input} buffer at {@code
* inputOffset}, and any bytes that have been buffered in previous {@code
* update} calls.
*
* @param input
* the input buffer.
* @param inputOffset
* the offset in the input buffer.
* @param inputLen
* the length of the input.
* @param output
* the output buffer for the transformed bytes.
* @param outputOffset
* the offset in the output buffer.
* @return the number of bytes placed in the output buffer.
* @throws ShortBufferException
* if the size of the {@code output} buffer is too small.
* @throws IllegalBlockSizeException
* if the size of the resulting bytes is not a multiple of the
* cipher block size.
* @throws BadPaddingException
* if the padding of the data does not match the padding scheme.
* @throws IllegalStateException
* if this cipher instance is not initialized for encryption or
* decryption.
* @throws IllegalArgumentException
* if {@code inputOffset} and {@code inputLen} do not specify an
* valid chunk in the input buffer.
*/
public final int doFinal(byte[] input, int inputOffset, int inputLen,
byte[] output, int outputOffset) throws ShortBufferException,
IllegalBlockSizeException, BadPaddingException {
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
throw new IllegalStateException();
}
checkInputOffsetAndCount(input.length, inputOffset, inputLen);
return spiImpl.engineDoFinal(input, inputOffset, inputLen, output,
outputOffset);
}
/**
* Finishes a multi-part transformation (encryption or decryption).
*
* Processes the {@code input.remaining()} bytes in {@code input} buffer at
* {@code input.position()}, and any bytes that have been buffered in
* previous {@code update} calls. The transformed bytes are placed into
* {@code output} buffer.
*
* @param input
* the input buffer.
* @param output
* the output buffer.
* @return the number of bytes placed into the output buffer.
* @throws ShortBufferException
* if the size of the {@code output} buffer is too small.
* @throws IllegalBlockSizeException
* if the size of the resulting bytes is not a multiple of the
* cipher block size.
* @throws BadPaddingException
* if the padding of the data does not match the padding scheme.
* @throws IllegalArgumentException
* if the input buffer and the output buffer are the same
* object.
* @throws IllegalStateException
* if this cipher instance is not initialized for encryption or
* decryption.
*/
public final int doFinal(ByteBuffer input, ByteBuffer output)
throws ShortBufferException, IllegalBlockSizeException,
BadPaddingException {
if (mode != ENCRYPT_MODE && mode != DECRYPT_MODE) {
throw new IllegalStateException();
}
if (input == output) {
throw new IllegalArgumentException("input == output");
}
return spiImpl.engineDoFinal(input, output);
}
/**
* Wraps a key using this cipher instance.
*
* @param key
* the key to wrap.
* @return the wrapped key.
* @throws IllegalBlockSizeException
* if the size of the resulting bytes is not a multiple of the
* cipher block size.
* @throws InvalidKeyException
* if this cipher instance can not wrap this key.
* @throws IllegalStateException
* if this cipher instance is not initialized for wrapping.
*/
public final byte[] wrap(Key key) throws IllegalBlockSizeException,
InvalidKeyException {
if (mode != WRAP_MODE) {
throw new IllegalStateException();
}
return spiImpl.engineWrap(key);
}
/**
* Unwraps a key using this cipher instance.
*
* @param wrappedKey
* the wrapped key to unwrap.
* @param wrappedKeyAlgorithm
* the algorithm for the wrapped key.
* @param wrappedKeyType
* the type of the wrapped key (one of: {@code SECRET_KEY
* ,
PRIVATE_KEY} or {@code PUBLIC_KEY})
* @return the unwrapped key
* @throws InvalidKeyException
* if the {@code wrappedKey} can not be unwrapped to a key of
* type {@code wrappedKeyType} for the {@code
* wrappedKeyAlgorithm}.
* @throws NoSuchAlgorithmException
* if no provider can be found that can create a key of type
* {@code wrappedKeyType} for the {@code wrappedKeyAlgorithm}.
* @throws IllegalStateException
* if this cipher instance is not initialized for unwrapping.
*/
public final Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
int wrappedKeyType) throws InvalidKeyException,
NoSuchAlgorithmException {
if (mode != UNWRAP_MODE) {
throw new IllegalStateException();
}
return spiImpl.engineUnwrap(wrappedKey, wrappedKeyAlgorithm,
wrappedKeyType);
}
/**
* Returns the maximum key length for the specified transformation.
*
* @param transformation
* the transformation name.
* @return the maximum key length, currently {@code Integer.MAX_VALUE}.
* @throws NoSuchAlgorithmException
* if no provider for the specified {@code transformation} can
* be found.
* @throws NullPointerException
* if {@code transformation} is {@code null}.
*/
public static final int getMaxAllowedKeyLength(String transformation)
throws NoSuchAlgorithmException {
if (transformation == null) {
throw new NullPointerException();
}
checkTransformation(transformation);
//FIXME jurisdiction policy files
return Integer.MAX_VALUE;
}
/**
* Returns the maximum cipher parameter value for the specified
* transformation. If there is no maximum limit, {@code null} is returned.
*
* @param transformation
* the transformation name.
* @return a parameter spec holding the maximum value or {@code null}.
* Currently {@code null}.
* @throws NoSuchAlgorithmException
* if no provider for the specified {@code transformation} can
* be found.
* @throws NullPointerException
* if {@code transformation} is {@code null}.
*/
public static final AlgorithmParameterSpec getMaxAllowedParameterSpec(
String transformation) throws NoSuchAlgorithmException {
if (transformation == null) {
throw new NullPointerException();
}
checkTransformation(transformation);
//FIXME jurisdiction policy files
return null;
}
}