| /* |
| * 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(); |
| } |
| } |