blob: c682d86b9684daf11354ba83fd08236f46ac210a [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;
/**
* {@code MessageDigestSpi} is the Service Provider Interface (SPI) definition
* for {@link MessageDigest}. Examples of digest algorithms are MD5 and SHA. A
* digest is a secure one way hash function for a stream of bytes. It acts like
* a fingerprint for a stream of bytes.
*
* @see MessageDigest
*/
public abstract class MessageDigestSpi {
/**
* Returns the engine digest length in bytes. If the implementation does not
* implement this function {@code 0} is returned.
*
* @return the digest length in bytes, or {@code 0}.
*/
protected int engineGetDigestLength() {
return 0;
}
/**
* Updates this {@code MessageDigestSpi} using the given {@code byte}.
*
* @param input
* the {@code byte} to update this {@code MessageDigestSpi} with.
* @see #engineReset()
*/
protected abstract void engineUpdate(byte input);
/**
* Updates this {@code MessageDigestSpi} using the given {@code byte[]}.
*
* @param input
* the {@code byte} array.
* @param offset
* the index of the first byte in {@code input} to update from.
* @param len
* the number of bytes in {@code input} to update from.
* @throws IllegalArgumentException
* if {@code offset} or {@code len} are not valid in respect to
* {@code input}.
*/
protected abstract void engineUpdate(byte[] input, int offset, int len);
/**
* Updates this {@code MessageDigestSpi} using the given {@code input}.
*
* @param input
* the {@code ByteBuffer}.
*/
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();
engineUpdate(tmp, offset+position, limit - position);
input.position(limit);
} else {
tmp = new byte[input.limit() - input.position()];
input.get(tmp);
engineUpdate(tmp, 0, tmp.length);
}
}
/**
* Computes and returns the final hash value for this
* {@link MessageDigestSpi}. After the digest is computed the receiver is
* reset.
*
* @return the computed one way hash value.
* @see #engineReset()
*/
protected abstract byte[] engineDigest();
/**
* Computes and stores the final hash value for this
* {@link MessageDigestSpi}. After the digest is computed the receiver is
* reset.
*
* @param buf
* the buffer to store the result in.
* @param offset
* the index of the first byte in {@code buf} to store in.
* @param len
* the number of bytes allocated for the digest.
* @return the number of bytes written to {@code buf}.
* @throws DigestException
* if an error occures.
* @throws IllegalArgumentException
* if {@code offset} or {@code len} are not valid in respect to
* {@code buf}.
* @see #engineReset()
*/
protected int engineDigest(byte[] buf, int offset, int len) throws DigestException {
if (len < engineGetDigestLength()) {
engineReset();
throw new DigestException("The value of len parameter is less than the actual digest length");
}
if (offset < 0) {
engineReset();
throw new DigestException("offset < 0");
}
if (offset + len > buf.length) {
engineReset();
throw new DigestException("offset + len > buf.length");
}
byte[] tmp = engineDigest();
if (len < tmp.length) {
throw new DigestException("The value of len parameter is less than the actual digest length");
}
System.arraycopy(tmp, 0, buf, offset, tmp.length);
return tmp.length;
}
/**
* Puts this {@code MessageDigestSpi} back in an initial state, such that it
* is ready to compute a one way hash value.
*/
protected abstract void engineReset();
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}