0N/A/*
2362N/A * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage java.security;
0N/A
0N/Aimport java.security.spec.AlgorithmParameterSpec;
0N/Aimport java.util.*;
0N/Aimport java.io.*;
0N/A
0N/Aimport java.nio.ByteBuffer;
0N/A
0N/Aimport sun.security.jca.JCAUtil;
0N/A
0N/A/**
0N/A * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
0N/A * for the <code>Signature</code> class, which is used to provide the
0N/A * functionality of a digital signature algorithm. Digital signatures are used
0N/A * for authentication and integrity assurance of digital data.
0N/A *.
0N/A * <p> All the abstract methods in this class must be implemented by each
0N/A * cryptographic service provider who wishes to supply the implementation
0N/A * of a particular signature algorithm.
0N/A *
0N/A * @author Benjamin Renaud
0N/A *
0N/A *
0N/A * @see Signature
0N/A */
0N/A
0N/Apublic abstract class SignatureSpi {
0N/A
0N/A /**
0N/A * Application-specified source of randomness.
0N/A */
0N/A protected SecureRandom appRandom = null;
0N/A
0N/A /**
0N/A * Initializes this signature object with the specified
0N/A * public key for verification operations.
0N/A *
0N/A * @param publicKey the public key of the identity whose signature is
0N/A * going to be verified.
0N/A *
0N/A * @exception InvalidKeyException if the key is improperly
0N/A * encoded, parameters are missing, and so on.
0N/A */
0N/A protected abstract void engineInitVerify(PublicKey publicKey)
0N/A throws InvalidKeyException;
0N/A
0N/A /**
0N/A * Initializes this signature object with the specified
0N/A * private key for signing operations.
0N/A *
0N/A * @param privateKey the private key of the identity whose signature
0N/A * will be generated.
0N/A *
0N/A * @exception InvalidKeyException if the key is improperly
0N/A * encoded, parameters are missing, and so on.
0N/A */
0N/A protected abstract void engineInitSign(PrivateKey privateKey)
0N/A throws InvalidKeyException;
0N/A
0N/A /**
0N/A * Initializes this signature object with the specified
0N/A * private key and source of randomness for signing operations.
0N/A *
0N/A * <p>This concrete method has been added to this previously-defined
0N/A * abstract class. (For backwards compatibility, it cannot be abstract.)
0N/A *
0N/A * @param privateKey the private key of the identity whose signature
0N/A * will be generated.
0N/A * @param random the source of randomness
0N/A *
0N/A * @exception InvalidKeyException if the key is improperly
0N/A * encoded, parameters are missing, and so on.
0N/A */
0N/A protected void engineInitSign(PrivateKey privateKey,
0N/A SecureRandom random)
0N/A throws InvalidKeyException {
0N/A this.appRandom = random;
0N/A engineInitSign(privateKey);
0N/A }
0N/A
0N/A /**
0N/A * Updates the data to be signed or verified
0N/A * using the specified byte.
0N/A *
0N/A * @param b the byte to use for the update.
0N/A *
0N/A * @exception SignatureException if the engine is not initialized
0N/A * properly.
0N/A */
0N/A protected abstract void engineUpdate(byte b) throws SignatureException;
0N/A
0N/A /**
0N/A * Updates the data to be signed or verified, using the
0N/A * specified array of bytes, starting at the specified offset.
0N/A *
0N/A * @param b the array of bytes
0N/A * @param off the offset to start from in the array of bytes
0N/A * @param len the number of bytes to use, starting at offset
0N/A *
0N/A * @exception SignatureException if the engine is not initialized
0N/A * properly
0N/A */
0N/A protected abstract void engineUpdate(byte[] b, int off, int len)
0N/A throws SignatureException;
0N/A
0N/A /**
0N/A * Updates the data to be signed or verified using the specified
0N/A * ByteBuffer. Processes the <code>data.remaining()</code> bytes
0N/A * starting at at <code>data.position()</code>.
0N/A * Upon return, the buffer's position will be equal to its limit;
0N/A * its limit will not have changed.
0N/A *
0N/A * @param input the ByteBuffer
0N/A * @since 1.5
0N/A */
0N/A protected void engineUpdate(ByteBuffer input) {
0N/A if (input.hasRemaining() == false) {
0N/A return;
0N/A }
0N/A try {
0N/A if (input.hasArray()) {
0N/A byte[] b = input.array();
0N/A int ofs = input.arrayOffset();
0N/A int pos = input.position();
0N/A int lim = input.limit();
0N/A engineUpdate(b, ofs + pos, lim - pos);
0N/A input.position(lim);
0N/A } else {
0N/A int len = input.remaining();
0N/A byte[] b = new byte[JCAUtil.getTempArraySize(len)];
0N/A while (len > 0) {
0N/A int chunk = Math.min(len, b.length);
0N/A input.get(b, 0, chunk);
0N/A engineUpdate(b, 0, chunk);
0N/A len -= chunk;
0N/A }
0N/A }
0N/A } catch (SignatureException e) {
0N/A // is specified to only occur when the engine is not initialized
0N/A // this case should never occur as it is caught in Signature.java
0N/A throw new ProviderException("update() failed", e);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Returns the signature bytes of all the data
0N/A * updated so far.
0N/A * The format of the signature depends on the underlying
0N/A * signature scheme.
0N/A *
0N/A * @return the signature bytes of the signing operation's result.
0N/A *
0N/A * @exception SignatureException if the engine is not
0N/A * initialized properly or if this signature algorithm is unable to
0N/A * process the input data provided.
0N/A */
0N/A protected abstract byte[] engineSign() throws SignatureException;
0N/A
0N/A /**
0N/A * Finishes this signature operation and stores the resulting signature
0N/A * bytes in the provided buffer <code>outbuf</code>, starting at
0N/A * <code>offset</code>.
0N/A * The format of the signature depends on the underlying
0N/A * signature scheme.
0N/A *
0N/A * <p>The signature implementation is reset to its initial state
0N/A * (the state it was in after a call to one of the
0N/A * <code>engineInitSign</code> methods)
0N/A * and can be reused to generate further signatures with the same private
0N/A * key.
0N/A *
0N/A * This method should be abstract, but we leave it concrete for
0N/A * binary compatibility. Knowledgeable providers should override this
0N/A * method.
0N/A *
0N/A * @param outbuf buffer for the signature result.
0N/A *
0N/A * @param offset offset into <code>outbuf</code> where the signature is
0N/A * stored.
0N/A *
0N/A * @param len number of bytes within <code>outbuf</code> allotted for the
0N/A * signature.
0N/A * Both this default implementation and the SUN provider do not
0N/A * return partial digests. If the value of this parameter is less
0N/A * than the actual signature length, this method will throw a
0N/A * SignatureException.
0N/A * This parameter is ignored if its value is greater than or equal to
0N/A * the actual signature length.
0N/A *
0N/A * @return the number of bytes placed into <code>outbuf</code>
0N/A *
0N/A * @exception SignatureException if the engine is not
0N/A * initialized properly, if this signature algorithm is unable to
0N/A * process the input data provided, or if <code>len</code> is less
0N/A * than the actual signature length.
0N/A *
0N/A * @since 1.2
0N/A */
0N/A protected int engineSign(byte[] outbuf, int offset, int len)
0N/A throws SignatureException {
0N/A byte[] sig = engineSign();
0N/A if (len < sig.length) {
0N/A throw new SignatureException
0N/A ("partial signatures not returned");
0N/A }
0N/A if (outbuf.length - offset < sig.length) {
0N/A throw new SignatureException
0N/A ("insufficient space in the output buffer to store the "
0N/A + "signature");
0N/A }
0N/A System.arraycopy(sig, 0, outbuf, offset, sig.length);
0N/A return sig.length;
0N/A }
0N/A
0N/A /**
0N/A * Verifies the passed-in signature.
0N/A *
0N/A * @param sigBytes the signature bytes to be verified.
0N/A *
0N/A * @return true if the signature was verified, false if not.
0N/A *
0N/A * @exception SignatureException if the engine is not
0N/A * initialized properly, the passed-in signature is improperly
0N/A * encoded or of the wrong type, if this signature algorithm is unable to
0N/A * process the input data provided, etc.
0N/A */
0N/A protected abstract boolean engineVerify(byte[] sigBytes)
0N/A throws SignatureException;
0N/A
0N/A /**
0N/A * Verifies the passed-in signature in the specified array
0N/A * of bytes, starting at the specified offset.
0N/A *
0N/A * <p> Note: Subclasses should overwrite the default implementation.
0N/A *
0N/A *
0N/A * @param sigBytes the signature bytes to be verified.
0N/A * @param offset the offset to start from in the array of bytes.
0N/A * @param length the number of bytes to use, starting at offset.
0N/A *
0N/A * @return true if the signature was verified, false if not.
0N/A *
0N/A * @exception SignatureException if the engine is not
0N/A * initialized properly, the passed-in signature is improperly
0N/A * encoded or of the wrong type, if this signature algorithm is unable to
0N/A * process the input data provided, etc.
0N/A * @since 1.4
0N/A */
0N/A protected boolean engineVerify(byte[] sigBytes, int offset, int length)
0N/A throws SignatureException {
0N/A byte[] sigBytesCopy = new byte[length];
0N/A System.arraycopy(sigBytes, offset, sigBytesCopy, 0, length);
0N/A return engineVerify(sigBytesCopy);
0N/A }
0N/A
0N/A /**
0N/A * Sets the specified algorithm parameter to the specified
0N/A * value. This method supplies a general-purpose mechanism through
0N/A * which it is possible to set the various parameters of this object.
0N/A * A parameter may be any settable parameter for the algorithm, such as
0N/A * a parameter size, or a source of random bits for signature generation
0N/A * (if appropriate), or an indication of whether or not to perform
0N/A * a specific but optional computation. A uniform algorithm-specific
0N/A * naming scheme for each parameter is desirable but left unspecified
0N/A * at this time.
0N/A *
0N/A * @param param the string identifier of the parameter.
0N/A *
0N/A * @param value the parameter value.
0N/A *
0N/A * @exception InvalidParameterException if <code>param</code> is an
0N/A * invalid parameter for this signature algorithm engine,
0N/A * the parameter is already set
0N/A * and cannot be set again, a security exception occurs, and so on.
0N/A *
0N/A * @deprecated Replaced by {@link
0N/A * #engineSetParameter(java.security.spec.AlgorithmParameterSpec)
0N/A * engineSetParameter}.
0N/A */
0N/A @Deprecated
0N/A protected abstract void engineSetParameter(String param, Object value)
0N/A throws InvalidParameterException;
0N/A
0N/A /**
0N/A * <p>This method is overridden by providers to initialize
0N/A * this signature engine with the specified parameter set.
0N/A *
0N/A * @param params the parameters
0N/A *
0N/A * @exception UnsupportedOperationException if this method is not
0N/A * overridden by a provider
0N/A *
0N/A * @exception InvalidAlgorithmParameterException if this method is
1104N/A * overridden by a provider and the given parameters
0N/A * are inappropriate for this signature engine
0N/A */
0N/A protected void engineSetParameter(AlgorithmParameterSpec params)
0N/A throws InvalidAlgorithmParameterException {
0N/A throw new UnsupportedOperationException();
0N/A }
0N/A
0N/A /**
0N/A * <p>This method is overridden by providers to return the
0N/A * parameters used with this signature engine, or null
0N/A * if this signature engine does not use any parameters.
0N/A *
0N/A * <p>The returned parameters may be the same that were used to initialize
0N/A * this signature engine, or may contain a combination of default and
0N/A * randomly generated parameter values used by the underlying signature
0N/A * implementation if this signature engine requires algorithm parameters
0N/A * but was not initialized with any.
0N/A *
0N/A * @return the parameters used with this signature engine, or null if this
0N/A * signature engine does not use any parameters
0N/A *
0N/A * @exception UnsupportedOperationException if this method is
0N/A * not overridden by a provider
0N/A * @since 1.4
0N/A */
0N/A protected AlgorithmParameters engineGetParameters() {
0N/A throw new UnsupportedOperationException();
0N/A }
0N/A
0N/A /**
0N/A * Gets the value of the specified algorithm parameter.
0N/A * This method supplies a general-purpose mechanism through which it
0N/A * is possible to get the various parameters of this object. A parameter
0N/A * may be any settable parameter for the algorithm, such as a parameter
0N/A * size, or a source of random bits for signature generation (if
0N/A * appropriate), or an indication of whether or not to perform a
0N/A * specific but optional computation. A uniform algorithm-specific
0N/A * naming scheme for each parameter is desirable but left unspecified
0N/A * at this time.
0N/A *
0N/A * @param param the string name of the parameter.
0N/A *
0N/A * @return the object that represents the parameter value, or null if
0N/A * there is none.
0N/A *
0N/A * @exception InvalidParameterException if <code>param</code> is an
0N/A * invalid parameter for this engine, or another exception occurs while
0N/A * trying to get this parameter.
0N/A *
0N/A * @deprecated
0N/A */
0N/A @Deprecated
0N/A protected abstract Object engineGetParameter(String param)
0N/A throws InvalidParameterException;
0N/A
0N/A /**
0N/A * Returns a clone if the implementation is cloneable.
0N/A *
0N/A * @return a clone if the implementation is cloneable.
0N/A *
0N/A * @exception CloneNotSupportedException if this is called
0N/A * on an implementation that does not support <code>Cloneable</code>.
0N/A */
0N/A public Object clone() throws CloneNotSupportedException {
0N/A if (this instanceof Cloneable) {
0N/A return super.clone();
0N/A } else {
0N/A throw new CloneNotSupportedException();
0N/A }
0N/A }
0N/A}