blob: 27be30cb8df8914d9f43dabfda173bba1774f9e5 [file] [log] [blame]
/*
* 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 java.security;
import java.nio.ByteBuffer;
import java.security.spec.AlgorithmParameterSpec;
/**
* {@code SignatureSpi} is the <i>Service Provider Interface</i> (<b>SPI</b>)
* definition for {@link Signature}.
*
* @see Signature
*/
public abstract class SignatureSpi {
/**
* Implementation specific source of randomness.
*/
protected SecureRandom appRandom;
/**
* Initializes this {@code SignatureSpi} instance for signature
* verification, using the public key of the identity whose signature is
* going to be verified.
*
* @param publicKey
* the public key.
* @throws InvalidKeyException
* if {@code publicKey} is not valid.
*/
protected abstract void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException;
/**
* Initializes this {@code SignatureSpi} instance for signing, using the
* private key of the identity whose signature is going to be generated.
*
* @param privateKey
* the private key.
* @throws InvalidKeyException
* if {@code privateKey} is not valid.
*/
protected abstract void engineInitSign(PrivateKey privateKey)
throws InvalidKeyException;
/**
* Initializes this {@code SignatureSpi} instance for signing, using the
* private key of the identity whose signature is going to be generated and
* the specified source of randomness.
*
* @param privateKey
* the private key.
* @param random
* the {@code SecureRandom} to use.
* @throws InvalidKeyException
* if {@code privateKey} is not valid.
*/
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException {
appRandom = random;
engineInitSign(privateKey);
}
/**
* Updates the data to be verified or to be signed, using the specified
* {@code byte}.
*
* @param b
* the byte to update with.
* @throws SignatureException
* if this {@code SignatureSpi} instance is not initialized
* properly.
*/
protected abstract void engineUpdate(byte b) throws SignatureException;
/**
* Updates the data to be verified or to be signed, using the given {@code
* byte[]}, starting form the specified index for the specified length.
*
* @param b
* the byte array to update with.
* @param off
* the start index in {@code b} of the data.
* @param len
* the number of bytes to use.
* @throws SignatureException
* if this {@code SignatureSpi} instance is not initialized
* properly.
*/
protected abstract void engineUpdate(byte[] b, int off, int len)
throws SignatureException;
/**
* Updates the data to be verified or to be signed, using the specified
* {@code ByteBuffer}.
*
* @param input
* the {@code ByteBuffer} to update with.
* @throws RuntimeException
* since {@code SignatureException} is not specified for this
* method it throws a {@code RuntimeException} if underlying
* {@link #engineUpdate(byte[], int, int)} throws {@code
* SignatureException}.
*/
protected void engineUpdate(ByteBuffer input) {
if (!input.hasRemaining()) {
return;
}
byte[] tmp;
if (input.hasArray()) {
tmp = input.array();
int offset = input.arrayOffset();
int position = input.position();
int limit = input.limit();
try {
engineUpdate(tmp, offset + position, limit - position);
} catch (SignatureException e) {
throw new RuntimeException(e); //Wrap SignatureException
}
input.position(limit);
} else {
tmp = new byte[input.limit() - input.position()];
input.get(tmp);
try {
engineUpdate(tmp, 0, tmp.length);
} catch (SignatureException e) {
throw new RuntimeException(e); //Wrap SignatureException
}
}
}
/**
* Generates and returns the signature of all updated data.
* <p>
* This {@code SignatureSpi} instance is reset to the state of its last
* initialization for signing and thus can be used for another signature
* from the same identity.
*
* @return the signature of all updated data.
* @throws SignatureException
* if this {@code SignatureSpi} instance is not initialized
* properly.
*/
protected abstract byte[] engineSign() throws SignatureException;
/**
* Generates and stores the signature of all updated data in the provided
* {@code byte[]} at the specified position with the specified length.
* <p>
* This {@code SignatureSpi} instance is reset to the state of its last
* initialization for signing and thus can be used for another signature
* from the same identity.
*
* @param outbuf
* the buffer to store the signature.
* @param offset
* the index of the first byte in {@code outbuf} to store.
* @param len
* the number of bytes allocated for the signature.
* @return the number of bytes stored in {@code outbuf}.
* @throws SignatureException
* if this {@code SignatureSpi} instance is not initialized
* properly.
* @throws IllegalArgumentException
* if {@code offset} or {@code len} are not valid in respect to
* {@code outbuf}.
*/
protected int engineSign(byte[] outbuf, int offset, int len) throws SignatureException {
byte[] tmp = engineSign();
if (tmp == null) {
return 0;
}
if (len < tmp.length) {
throw new SignatureException("The value of len parameter is less than the actual signature length");
}
if (offset < 0) {
throw new SignatureException("offset < 0");
}
if (offset + len > outbuf.length) {
throw new SignatureException("offset + len > outbuf.length");
}
System.arraycopy(tmp, 0, outbuf, offset, tmp.length);
return tmp.length;
}
/**
* Indicates whether the given {@code sigBytes} can be verified using the
* public key or a certificate of the signer.
* <p>
* This {@code SignatureSpi} instance is reset to the state of its last
* initialization for verifying and thus can be used to verify another
* signature of the same signer.
*
* @param sigBytes
* the signature to verify.
* @return {@code true} if the signature was verified, {@code false}
* otherwise.
* @throws SignatureException
* if this {@code SignatureSpi} instance is not initialized
* properly.
*/
protected abstract boolean engineVerify(byte[] sigBytes)
throws SignatureException;
/**
* Indicates whether the given {@code sigBytes} starting at index {@code
* offset} with {@code length} bytes can be verified using the public key or
* a certificate of the signer.
* <p>
* This {@code SignatureSpi} instance is reset to the state of its last
* initialization for verifying and thus can be used to verify another
* signature of the same signer.
*
* @param sigBytes
* the {@code byte[]} containing the signature to verify.
* @param offset
* the start index in {@code sigBytes} of the signature
* @param length
* the number of bytes allocated for the signature.
* @return {@code true} if the signature was verified, {@code false}
* otherwise.
* @throws SignatureException
* if this {@code SignatureSpi} instance is not initialized
* properly.
* @throws IllegalArgumentException
* if {@code offset} or {@code length} are not valid in respect
* to {@code sigBytes}.
*/
protected boolean engineVerify(byte[] sigBytes, int offset, int length)
throws SignatureException {
byte[] tmp = new byte[length];
System.arraycopy(sigBytes, offset, tmp, 0, length);
return engineVerify(tmp);
}
/**
* Sets the specified parameter to the given value.
*
* @param param
* the name of the parameter.
* @param value
* the parameter value.
* @throws InvalidParameterException
* if the parameter is invalid, already set or is not allowed to
* be changed.
* @deprecated Use {@link #engineSetParameter(AlgorithmParameterSpec)}
*/
@Deprecated
protected abstract void engineSetParameter(String param, Object value)
throws InvalidParameterException;
/**
* Sets the specified {@code AlgorithmParameterSpec}.
*
* @param params
* the parameter to set.
* @throws InvalidAlgorithmParameterException
* if the parameter is invalid, already set or is not allowed to
* be changed.
*/
protected void engineSetParameter(AlgorithmParameterSpec params)
throws InvalidAlgorithmParameterException {
throw new UnsupportedOperationException();
}
/**
* Returns the {@code AlgorithmParameters} of this {@link SignatureSpi}
* instance.
*
* @return the {@code AlgorithmParameters} of this {@link SignatureSpi}
* instance, maybe {@code null}.
*/
protected AlgorithmParameters engineGetParameters() {
throw new UnsupportedOperationException();
}
/**
* Returns the value of the parameter with the specified name.
*
* @param param
* the name of the requested parameter value.
* @return the value of the parameter with the specified name, maybe {@code
* null}.
* @throws InvalidParameterException
* if {@code param} is not a valid parameter for this {@code
* SignatureSpi} or an other error occurs.
* @deprecated There is no generally accepted parameter naming convention.
*/
@Deprecated
protected abstract Object engineGetParameter(String param)
throws InvalidParameterException;
@Override
public Object clone() throws CloneNotSupportedException {
if (this instanceof Cloneable) {
return super.clone();
}
throw new CloneNotSupportedException();
}
}