123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446 |
- /* CipherSpi.java -- The cipher service provider interface.
- Copyright (C) 2004, 2006 Free Software Foundation, Inc.
- This file is part of GNU Classpath.
- GNU Classpath is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
- GNU Classpath is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GNU Classpath; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA.
- Linking this library statically or dynamically with other modules is
- making a combined work based on this library. Thus, the terms and
- conditions of the GNU General Public License cover the whole
- combination.
- As a special exception, the copyright holders of this library give you
- permission to link this library with independent modules to produce an
- executable, regardless of the license terms of these independent
- modules, and to copy and distribute the resulting executable under
- terms of your choice, provided that you also meet, for each linked
- independent module, the terms and conditions of the license of that
- module. An independent module is a module which is not derived from
- or based on this library. If you modify this library, you may extend
- this exception to your version of the library, but you are not
- obligated to do so. If you do not wish to do so, delete this
- exception statement from your version. */
- package javax.crypto;
- import java.nio.ByteBuffer;
- import java.security.AlgorithmParameters;
- import java.security.InvalidAlgorithmParameterException;
- import java.security.InvalidKeyException;
- import java.security.Key;
- import java.security.NoSuchAlgorithmException;
- import java.security.SecureRandom;
- import java.security.spec.AlgorithmParameterSpec;
- /**
- * <p>This class represents the <i>Service Provider Interface</i>
- * (<b>SPI</b>) for cryptographic ciphers.</p>
- *
- * <p>Providers of cryptographic ciphers must subclass this for every
- * cipher they implement, implementing the abstract methods as
- * appropriate, then provide an entry that points to the subclass in
- * their implementation of {@link java.security.Provider}.</p>
- *
- * <p>CipherSpi objects are instantiated along with {@link Cipher}s when
- * the {@link Cipher#getInstance(java.lang.String)} methods are invoked.
- * Particular ciphers are referenced by a <i>transformation</i>, which
- * is a String consisting of the cipher's name or the ciper's name
- * followed by a mode and a padding. Transformations all follow the
- * general form:</p>
- *
- * <ul>
- * <li><i>algorithm</i>, or</li>
- * <li><i>algorithm</i>/<i>mode</i>/<i>padding</i>
- * </ul>
- *
- * <p>Cipher names in the master {@link java.security.Provider} class
- * may be:</p>
- *
- * <ol>
- * <li>The algorithm's name, which uses a pluggable mode and padding:
- * <code>Cipher.<i>algorithm</i></code></li>
- * <li>The algorithm's name and the mode, which uses pluggable padding:
- * <code>Cipher.<i>algorithm</i>/<i>mode</i></code></li>
- * <li>The algorithm's name and the padding, which uses a pluggable
- * mode: <code>Cipher.<i>algorithm</i>//<i>padding</i></code></li>
- * <li>The algorihtm's name, the mode, and the padding:
- * <code>Cipher.<i>algorithm</i>/<i>mode</i>/<i>padding</i></code></li>
- * </ol>
- *
- * <p>When any {@link Cipher#getInstance(java.lang.String)} method is
- * invoked, the following happens if the transformation is simply
- * <i>algorithm</i>:</p>
- *
- * <ol>
- * <li>If the provider defines a <code>CipherSpi</code> implementation
- * for "<i>algorithm</i>", return it. Otherwise throw a {@link
- * java.security.NoSuchAlgorithmException}.</li>
- * </ol>
- *
- * <p>If the transformation is of the form
- * <i>algorithm</i>/<i>mode</i>/<i>padding</i>:</p>
- *
- * <ol>
- * <li>If the provider defines a <code>CipherSpi</code> subclass for
- * "<i>algorithm</i>/<i>mode</i>/<i>padding</i>", return it. Otherwise
- * go to step 2.</li>
- *
- * <li>If the provider defines a <code>CipherSpi</code> subclass for
- * "<i>algorithm</i>/<i>mode</i>", instatiate it, call {@link
- * #engineSetPadding(java.lang.String)} for the padding name, and return
- * it. Otherwise go to step 3.</li>
- *
- * <li>If the provider defines a <code>CipherSpi</code> subclass for
- * "<i>algorithm</i>//<i>padding</i>", instatiate it, call {@link
- * #engineSetMode(java.lang.String)} for the mode name, and return
- * it. Otherwise go to step 4.</li>
- *
- * <li>If the provider defines a <code>CipherSpi</code> subclass for
- * "<i>algorithm</i>", instatiate it, call {@link
- * #engineSetMode(java.lang.String)} for the mode name, call {@link
- * #engineSetPadding(java.lang.String)} for the padding name, and return
- * it. Otherwise throw a {@link java.security.NoSuchAlgorithmException}.</li>
- * </ol>
- *
- * @author Casey Marshall (csm@gnu.org)
- * @since 1.4
- */
- public abstract class CipherSpi
- {
- // Constructors.
- // ------------------------------------------------------------------------
- /**
- * Create a new CipherSpi.
- */
- public CipherSpi()
- {
- }
- // Abstract methods to be implemented by providers.
- // ------------------------------------------------------------------------
- /**
- * Finishes a multi-part transformation or transforms a portion of a
- * byte array, and returns the transformed bytes.
- *
- * @param input The input bytes.
- * @param inputOffset The index in the input at which to start.
- * @param inputLength The number of bytes to transform.
- * @return The transformed bytes in a new array.
- * @throws javax.crypto.IllegalBlockSizeException If this instance has
- * no padding and the input size is not a multiple of the
- * block size.
- * @throws javax.crypto.BadPaddingException If this instance is being
- * used for decryption and the padding is not appropriate for
- * this instance's padding scheme.
- */
- protected abstract byte[]
- engineDoFinal(byte[] input, int inputOffset, int inputLength)
- throws IllegalBlockSizeException, BadPaddingException;
- /**
- * Finishes a multi-part transformation or transforms a portion of a
- * byte array, and stores the transformed bytes in the supplied array.
- *
- * @param input The input bytes.
- * @param inputOffset The index in the input at which to start.
- * @param inputLength The number of bytes to transform.
- * @param output The output byte array.
- * @param outputOffset The index in the output array at which to start.
- * @return The number of transformed bytes stored in the output array.
- * @throws javax.crypto.IllegalBlockSizeException If this instance has
- * no padding and the input size is not a multiple of the
- * block size.
- * @throws javax.crypto.BadPaddingException If this instance is being
- * used for decryption and the padding is not appropriate for
- * this instance's padding scheme.
- * @throws javax.crypto.ShortBufferException If there is not enough
- * space in the output array for the transformed bytes.
- */
- protected abstract int
- engineDoFinal(byte[] input, int inputOffset, int inputLength,
- byte[] output, int outputOffset)
- throws IllegalBlockSizeException, BadPaddingException, ShortBufferException;
- /**
- * @since 1.5
- */
- protected int engineDoFinal (ByteBuffer input, ByteBuffer output)
- throws BadPaddingException, IllegalBlockSizeException,
- ShortBufferException
- {
- int total = 0;
- byte[] inbuf = new byte[256];
- while (input.hasRemaining ())
- {
- int in = Math.min (inbuf.length, input.remaining ());
- input.get (inbuf, 0, in);
- byte[] outbuf = new byte[engineGetOutputSize (in)];
- int out = 0;
- if (input.hasRemaining ()) // i.e., we have more 'update' calls
- out = engineUpdate (inbuf, 0, in, outbuf, 0);
- else
- out = engineDoFinal (inbuf, 0, in, outbuf, 0);
- output.put (outbuf, 0, out);
- total += out;
- }
- return total;
- }
- /**
- * Returns the block size of the underlying cipher.
- *
- * @return The block size.
- */
- protected abstract int engineGetBlockSize();
- /**
- * Returns the initializaiton vector this cipher was initialized with,
- * if any.
- *
- * @return The IV, or null if this cipher uses no IV or if this
- * instance has not been initialized yet.
- */
- protected abstract byte[] engineGetIV();
- /**
- * <p>Return the length of the given key in bits.</p>
- *
- * <p>For compatibility this method is not declared
- * <code>abstract</code>, and the default implementation will throw an
- * {@link java.lang.UnsupportedOperationException}. Concrete
- * subclasses should override this method to return the correct
- * value.</p>
- *
- * @param key The key to get the size for.
- * @return The size of the key, in bits.
- * @throws java.security.InvalidKeyException If the key's length
- * cannot be determined by this implementation.
- */
- protected int engineGetKeySize(Key key) throws InvalidKeyException
- {
- throw new UnsupportedOperationException();
- }
- /**
- * <p>Returns the size, in bytes, an output buffer must be for a call
- * to {@link #engineUpdate(byte[],int,int,byte[],int)} or {@link
- * #engineDoFinal(byte[],int,int,byte[],int)} to succeed.</p>
- *
- * <p>The actual output length may be smaller than the value returned
- * by this method, as it considers the padding length as well. The
- * length considered is the argument plus the length of any buffered,
- * unprocessed bytes.</p>
- *
- * @param inputLength The input length, in bytes.
- * @return The size an output buffer must be.
- */
- protected abstract int engineGetOutputSize(int inputLength);
- /**
- * Returns the parameters that this cipher is using. This may be the
- * parameters used to initialize this cipher, or it may be parameters
- * that have been initialized with random values.
- *
- * @return This cipher's parameters, or <code>null</code> if this
- * cipher does not use parameters.
- */
- protected abstract AlgorithmParameters engineGetParameters();
- /**
- * Initializes this cipher with an operation mode, key, and source of
- * randomness. If this cipher requires any other initializing data,
- * for example an initialization vector, then it should generate it
- * from the provided source of randomness.
- *
- * @param opmode The operation mode, one of {@link
- * Cipher#DECRYPT_MODE}, {@link Cipher#ENCRYPT_MODE}, {@link
- * Cipher#UNWRAP_MODE}, or {@link Cipher#WRAP_MODE}.
- * @param key The key to initialize this cipher with.
- * @param random The source of random bytes to use.
- * @throws java.security.InvalidKeyException If the given key is not
- * acceptable for this implementation.
- */
- protected abstract void engineInit(int opmode, Key key, SecureRandom random)
- throws InvalidKeyException;
- /**
- * Initializes this cipher with an operation mode, key, parameters,
- * and source of randomness. If this cipher requires any other
- * initializing data, for example an initialization vector, then it should
- * generate it from the provided source of randomness.
- *
- * @param opmode The operation mode, one of {@link
- * Cipher#DECRYPT_MODE}, {@link Cipher#ENCRYPT_MODE}, {@link
- * Cipher#UNWRAP_MODE}, or {@link Cipher#WRAP_MODE}.
- * @param key The key to initialize this cipher with.
- * @param params The algorithm parameters to initialize with.
- * @param random The source of random bytes to use.
- * @throws java.security.InvalidAlgorithmParameterException If the
- * given parameters are not appropriate for this
- * implementation.
- * @throws java.security.InvalidKeyException If the given key is not
- * acceptable for this implementation.
- */
- protected abstract void
- engineInit(int opmode, Key key, AlgorithmParameters params,
- SecureRandom random)
- throws InvalidAlgorithmParameterException, InvalidKeyException;
- /**
- * Initializes this cipher with an operation mode, key, parameters,
- * and source of randomness. If this cipher requires any other
- * initializing data, for example an initialization vector, then it should
- * generate it from the provided source of randomness.
- *
- * @param opmode The operation mode, one of {@link
- * Cipher#DECRYPT_MODE}, {@link Cipher#ENCRYPT_MODE}, {@link
- * Cipher#UNWRAP_MODE}, or {@link Cipher#WRAP_MODE}.
- * @param key The key to initialize this cipher with.
- * @param params The algorithm parameters to initialize with.
- * @param random The source of random bytes to use.
- * @throws java.security.InvalidAlgorithmParameterException If the
- * given parameters are not appropriate for this
- * implementation.
- * @throws java.security.InvalidKeyException If the given key is not
- * acceptable for this implementation.
- */
- protected abstract void
- engineInit(int opmode, Key key, AlgorithmParameterSpec params,
- SecureRandom random)
- throws InvalidAlgorithmParameterException, InvalidKeyException;
- /**
- * Set the mode in which this cipher is to run.
- *
- * @param mode The name of the mode to use.
- * @throws java.security.NoSuchAlgorithmException If the mode is
- * not supported by this cipher's provider.
- */
- protected abstract void engineSetMode(String mode)
- throws NoSuchAlgorithmException;
- /**
- * Set the method with which the input is to be padded.
- *
- * @param padding The name of the padding to use.
- * @throws javax.crypto.NoSuchPaddingException If the padding is not
- * supported by this cipher's provider.
- */
- protected abstract void engineSetPadding(String padding)
- throws NoSuchPaddingException;
- /**
- * <p>Unwraps a previously-wrapped key.</p>
- *
- * <p>For compatibility this method is not declared
- * <code>abstract</code>, and the default implementation will throw an
- * {@link java.lang.UnsupportedOperationException}.</p>
- *
- * @param wrappedKey The wrapped key.
- * @param wrappedKeyAlgorithm The name of the algorithm used to wrap
- * this key.
- * @param wrappedKeyType The type of wrapped key; one of
- * {@link Cipher#PRIVATE_KEY},
- * {@link Cipher#PUBLIC_KEY}, or
- * {@link Cipher#SECRET_KEY}.
- * @return The unwrapped key.
- * @throws java.security.InvalidKeyException If the key cannot be
- * unwrapped, or if <code>wrappedKeyType</code> is an
- * inappropriate type for the unwrapped key.
- * @throws java.security.NoSuchAlgorithmException If the
- * <code>wrappedKeyAlgorithm</code> is unknown.
- */
- protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
- int wrappedKeyType)
- throws InvalidKeyException, NoSuchAlgorithmException
- {
- throw new UnsupportedOperationException();
- }
- /**
- * Continue with a multi-part transformation, returning a new array of
- * the transformed bytes.
- *
- * @param input The next input bytes.
- * @param inputOffset The index in the input array from which to start.
- * @param inputLength The number of bytes to input.
- * @return The transformed bytes.
- */
- protected abstract byte[]
- engineUpdate(byte[] input, int inputOffset, int inputLength);
- /**
- * Continue with a multi-part transformation, storing the transformed
- * bytes into the specified array.
- *
- * @param input The next input bytes.
- * @param inputOffset The index in the input from which to start.
- * @param inputLength The number of bytes to input.
- * @param output The output buffer.
- * @param outputOffset The index in the output array from which to start.
- * @return The transformed bytes.
- * @throws javax.crypto.ShortBufferException If there is not enough
- * space in the output array to store the transformed bytes.
- */
- protected abstract int
- engineUpdate(byte[] input, int inputOffset, int inputLength,
- byte[] output, int outputOffset)
- throws ShortBufferException;
- /**
- * @since 1.5
- */
- protected int engineUpdate (ByteBuffer input, ByteBuffer output)
- throws ShortBufferException
- {
- int total = 0;
- byte[] inbuf = new byte[256];
- while (input.hasRemaining ())
- {
- int in = Math.min (inbuf.length, input.remaining ());
- input.get (inbuf, 0, in);
- byte[] outbuf = new byte[engineGetOutputSize (in)];
- int out = engineUpdate (inbuf, 0, in, outbuf, 0);
- output.put (outbuf, 0, out);
- total += out;
- }
- return total;
- }
- /**
- * <p>Wrap a key.</p>
- *
- * <p>For compatibility this method is not declared
- * <code>abstract</code>, and the default implementation will throw an
- * {@link java.lang.UnsupportedOperationException}.</p>
- *
- * @param key The key to wrap.
- * @return The wrapped key.
- * @throws java.security.InvalidKeyException If the key cannot be
- * wrapped.
- */
- protected byte[] engineWrap(Key key) throws InvalidKeyException, IllegalBlockSizeException
- {
- throw new UnsupportedOperationException();
- }
- }
|