OpenJDK / jdk / jdk12
changeset 26203:0030579ec361
8050370: Need new regressions tests for messageDigest with DigestIOStream
Reviewed-by: weijun
Contributed-by: Zaiyao Liu <zaiyao.liu@oracle.com>
author | weijun |
---|---|
date | Tue, 26 Aug 2014 15:10:29 +0800 |
parents | 6f45f1d6688a |
children | 77df35747ce7 |
files | jdk/test/java/security/MessageDigest/TestDigestIOStream.java |
diffstat | 1 files changed, 335 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/MessageDigest/TestDigestIOStream.java Tue Aug 26 15:10:29 2014 +0800 @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.security.DigestInputStream; +import java.security.DigestOutputStream; +import java.security.MessageDigest; +import java.util.Arrays; +import java.util.Random; +import static java.lang.System.out; + +/** + * @test + * @bug 8050370 + * @summary MessageDigest tests with DigestIOStream + * @author Kevin Liu + */ + +enum ReadModel { + READ, BUFFER_READ, MIX_READ +} + +public class TestDigestIOStream { + + private static final int[] DATA_LEN_ARRAY = { + 1, 50, 2500, 125000, 6250000 + }; + private static final String[] ALGORITHM_ARRAY = { + "MD2", "MD5", "SHA1", "SHA-224", "SHA-256", "SHA-384", "SHA-512" + }; + + private static byte[] data; + + private static MessageDigest md = null; + + public static void main(String argv[]) throws Exception { + TestDigestIOStream test = new TestDigestIOStream(); + test.run(); + } + + public void run() throws Exception { + for (String algorithm: ALGORITHM_ARRAY) { + + md = MessageDigest.getInstance(algorithm); + + for (int length: DATA_LEN_ARRAY) { + + Random rdm = new Random(); + data = new byte[length]; + rdm.nextBytes(data); + + if (!testMDChange(algorithm, length)) { + throw new RuntimeException("testMDChange failed at:" + + algorithm + "/" + length); + } + if (!testMDShare(algorithm, length)) { + throw new RuntimeException("testMDShare failed at:" + + algorithm + "/" + length); + } + for (ReadModel readModel: ReadModel.values()) { + // test Digest function when digest switch on + if (!testDigestOnOff(algorithm, readModel, true, length)) { + throw new RuntimeException("testDigestOn failed at:" + + algorithm + "/" + length + "/" + readModel); + } + // test Digest function when digest switch off + if (!testDigestOnOff(algorithm, readModel, false, length)) { + throw new RuntimeException("testDigestOff failed at:" + + algorithm + "/" + length + "/" + readModel); + } + } + } + } + int testNumber = ALGORITHM_ARRAY.length * ReadModel.values().length + * DATA_LEN_ARRAY.length * 2 + ALGORITHM_ARRAY.length + * DATA_LEN_ARRAY.length * 2; + out.println("All " + testNumber + " Tests Passed"); + } + + /** + * Test DigestInputStream and DigestOutputStream digest function when digest + * set on and off + * + * @param algo + * Message Digest algorithm + * @param readModel + * which read method used(READ, BUFFER_READ, MIX_READ) + * @param on + * digest switch(on and off) + * @param dataLength + * plain test data length. + * @exception Exception + * throw unexpected exception + */ + public boolean testDigestOnOff(String algo, ReadModel readModel, + boolean on, int dataLength) throws Exception { + + // Generate the DigestInputStream/DigestOutputStream object + try (ByteArrayInputStream bais = new ByteArrayInputStream(data); + DigestInputStream dis = new DigestInputStream(bais, + MessageDigest.getInstance(algo)); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DigestOutputStream dos = new DigestOutputStream(baos, + MessageDigest.getInstance(algo)); + ByteArrayOutputStream baOut = new ByteArrayOutputStream();) { + + // Perform the update using all available/possible update methods + int k = 0; + byte[] buffer = new byte[5]; + boolean enDigest = true; + // Make sure the digest function is on (default) + dis.on(enDigest); + dos.on(enDigest); + + switch (readModel) { + case READ: // use only read() + while ((k = dis.read()) != -1) { + if (on) { + dos.write(k); + } else { + dos.write(k); + if (enDigest) { + baOut.write(k); + } + enDigest = !enDigest; + dos.on(enDigest); + dis.on(enDigest); + } + } + break; + case BUFFER_READ: // use only read(byte[], int, int) + while ((k = dis.read(buffer, 0, buffer.length)) != -1) { + if (on) { + dos.write(buffer, 0, k); + } else { + dos.write(buffer, 0, k); + if (enDigest) { + baOut.write(buffer, 0, k); + } + enDigest = !enDigest; + dis.on(enDigest); + dos.on(enDigest); + } + } + break; + case MIX_READ: // use both read() and read(byte[], int, int) + while ((k = dis.read()) != -1) { + if (on) { + dos.write(k); + if ((k = dis.read(buffer, 0, buffer.length)) != -1) { + dos.write(buffer, 0, k); + } + } else { + dos.write(k); + if (enDigest) { + baOut.write(k); + } + enDigest = !enDigest; + dis.on(enDigest); + dos.on(enDigest); + if ((k = dis.read(buffer, 0, buffer.length)) != -1) { + dos.write(buffer, 0, k); + if (enDigest) { + baOut.write(buffer, 0, k); + } + enDigest = !enDigest; + dis.on(enDigest); + dos.on(enDigest); + } + } + } + break; + default: + out.println("ERROR: Invalid read/write combination choice!"); + return false; + } + + // Get the output and the "correct" digest values + byte[] output1 = dis.getMessageDigest().digest(); + byte[] output2 = dos.getMessageDigest().digest(); + byte[] standard; + if (on) { + standard = md.digest(data); + } else { + byte[] dataDigested = baOut.toByteArray(); + standard = md.digest(dataDigested); + } + + // Compare the output byte array value to the input data + if (!MessageDigest.isEqual(data, baos.toByteArray())) { + out.println("ERROR of " + readModel + + ": output and input data unexpectedly changed"); + return false; + } + // Compare generated digest values + if (!MessageDigest.isEqual(output1, standard) + || !MessageDigest.isEqual(output2, standard)) { + out.println("ERROR" + readModel + + ": generated digest data unexpectedly changed"); + return false; + } + + return true; + } catch (Exception ex) { + out.println("testDigestOnOff failed at:" + algo + "/" + readModel + + "/" + dataLength + " with unexpected exception"); + throw ex; + } + } + + /** + * Test DigestInputStream and DigestOutputStream digest function when Swap + * the message digest engines between DigestIn/OutputStream + * + * @param algo + * Message Digest algorithm + * @param dataLength + * plain test data length. + * @exception Exception + * throw unexpected exception + */ + public boolean testMDChange(String algo, int dataLength) throws Exception { + // Generate the DigestInputStream/DigestOutputStream object + MessageDigest mdIn = MessageDigest.getInstance(algo); + MessageDigest mdOut = MessageDigest.getInstance(algo); + try (ByteArrayInputStream bais = new ByteArrayInputStream(data); + DigestInputStream dis = new DigestInputStream(bais, mdIn); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DigestOutputStream dos = new DigestOutputStream(baos, mdOut);) { + + // Perform the update using all available/possible update methods + int k = 0; + byte[] buffer = new byte[10]; + + // use both read() and read(byte[], int, int) + while ((k = dis.read()) != -1) { + dos.write(k); + if ((k = dis.read(buffer, 0, buffer.length)) != -1) { + dos.write(buffer, 0, k); + } + + // Swap the message digest engines between + // DigestIn/OutputStream objects + dis.setMessageDigest(mdOut); + dos.setMessageDigest(mdIn); + mdIn = dis.getMessageDigest(); + mdOut = dos.getMessageDigest(); + } + + // Get the output and the "correct" digest values + byte[] output1 = mdIn.digest(); + byte[] output2 = mdOut.digest(); + byte[] standard = md.digest(data); + + // Compare generated digest values + return MessageDigest.isEqual(output1, standard) + && MessageDigest.isEqual(output2, standard); + } catch (Exception ex) { + out.println("testMDChange failed at:" + algo + "/" + dataLength + + " with unexpected exception"); + throw ex; + } + } + + /** + * Test DigestInputStream and DigestOutputStream digest function when use + * same message digest object. + * + * @param algo + * Message Digest algorithm + * @param dataLength + * plain test data length. + * @exception Exception + * throw unexpected exception + */ + public boolean testMDShare(String algo, int dataLength) throws Exception { + MessageDigest mdCommon = MessageDigest.getInstance(algo); + // Generate the DigestInputStream/DigestOutputStream object + try (ByteArrayInputStream bais = new ByteArrayInputStream(data); + DigestInputStream dis = new DigestInputStream(bais, mdCommon); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DigestOutputStream dos = new DigestOutputStream(baos, mdCommon);) { + + // Perform the update using all available/possible update methods + int k = 0; + byte[] buffer = new byte[10]; + + // use both read() and read(byte[], int, int) + while (k < data.length) { + int len = dis.read(buffer, 0, buffer.length); + if (len != -1) { + k += len; + if (k < data.length) { + dos.write(data[k]); + k++; + dis.skip(1); + } + } + } + + // Get the output and the "correct" digest values + byte[] output = mdCommon.digest(); + byte[] standard = md.digest(data); + + // Compare generated digest values + return MessageDigest.isEqual(output, standard); + } catch (Exception ex) { + out.println("TestMDShare failed at:" + algo + "/" + dataLength + + " with unexpected exception"); + throw ex; + } + } +}