Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/security/MessageDigest/TestDigestIOStream.java
38811 views
/*1* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.ByteArrayInputStream;24import java.io.ByteArrayOutputStream;25import java.io.PrintStream;26import java.security.DigestInputStream;27import java.security.DigestOutputStream;28import java.security.MessageDigest;29import java.util.Arrays;30import java.util.Random;31import static java.lang.System.out;3233/**34* @test35* @bug 805037036* @summary MessageDigest tests with DigestIOStream37* @author Kevin Liu38* @key randomness39*/4041enum ReadModel {42READ, BUFFER_READ, MIX_READ43}4445public class TestDigestIOStream {4647private static final int[] DATA_LEN_ARRAY = {481, 50, 2500, 125000, 625000049};50private static final String[] ALGORITHM_ARRAY = {51"MD2", "MD5", "SHA1", "SHA-224", "SHA-256", "SHA-384", "SHA-512"52};5354private static byte[] data;5556private static MessageDigest md = null;5758public static void main(String argv[]) throws Exception {59TestDigestIOStream test = new TestDigestIOStream();60test.run();61}6263public void run() throws Exception {64for (String algorithm: ALGORITHM_ARRAY) {6566md = MessageDigest.getInstance(algorithm);6768for (int length: DATA_LEN_ARRAY) {6970Random rdm = new Random();71data = new byte[length];72rdm.nextBytes(data);7374if (!testMDChange(algorithm, length)) {75throw new RuntimeException("testMDChange failed at:"76+ algorithm + "/" + length);77}78if (!testMDShare(algorithm, length)) {79throw new RuntimeException("testMDShare failed at:"80+ algorithm + "/" + length);81}82for (ReadModel readModel: ReadModel.values()) {83// test Digest function when digest switch on84if (!testDigestOnOff(algorithm, readModel, true, length)) {85throw new RuntimeException("testDigestOn failed at:"86+ algorithm + "/" + length + "/" + readModel);87}88// test Digest function when digest switch off89if (!testDigestOnOff(algorithm, readModel, false, length)) {90throw new RuntimeException("testDigestOff failed at:"91+ algorithm + "/" + length + "/" + readModel);92}93}94}95}96int testNumber = ALGORITHM_ARRAY.length * ReadModel.values().length97* DATA_LEN_ARRAY.length * 2 + ALGORITHM_ARRAY.length98* DATA_LEN_ARRAY.length * 2;99out.println("All " + testNumber + " Tests Passed");100}101102/**103* Test DigestInputStream and DigestOutputStream digest function when digest104* set on and off105*106* @param algo107* Message Digest algorithm108* @param readModel109* which read method used(READ, BUFFER_READ, MIX_READ)110* @param on111* digest switch(on and off)112* @param dataLength113* plain test data length.114* @exception Exception115* throw unexpected exception116*/117public boolean testDigestOnOff(String algo, ReadModel readModel,118boolean on, int dataLength) throws Exception {119120// Generate the DigestInputStream/DigestOutputStream object121try (ByteArrayInputStream bais = new ByteArrayInputStream(data);122DigestInputStream dis = new DigestInputStream(bais,123MessageDigest.getInstance(algo));124ByteArrayOutputStream baos = new ByteArrayOutputStream();125DigestOutputStream dos = new DigestOutputStream(baos,126MessageDigest.getInstance(algo));127ByteArrayOutputStream baOut = new ByteArrayOutputStream();) {128129// Perform the update using all available/possible update methods130int k = 0;131byte[] buffer = new byte[5];132boolean enDigest = true;133// Make sure the digest function is on (default)134dis.on(enDigest);135dos.on(enDigest);136137switch (readModel) {138case READ: // use only read()139while ((k = dis.read()) != -1) {140if (on) {141dos.write(k);142} else {143dos.write(k);144if (enDigest) {145baOut.write(k);146}147enDigest = !enDigest;148dos.on(enDigest);149dis.on(enDigest);150}151}152break;153case BUFFER_READ: // use only read(byte[], int, int)154while ((k = dis.read(buffer, 0, buffer.length)) != -1) {155if (on) {156dos.write(buffer, 0, k);157} else {158dos.write(buffer, 0, k);159if (enDigest) {160baOut.write(buffer, 0, k);161}162enDigest = !enDigest;163dis.on(enDigest);164dos.on(enDigest);165}166}167break;168case MIX_READ: // use both read() and read(byte[], int, int)169while ((k = dis.read()) != -1) {170if (on) {171dos.write(k);172if ((k = dis.read(buffer, 0, buffer.length)) != -1) {173dos.write(buffer, 0, k);174}175} else {176dos.write(k);177if (enDigest) {178baOut.write(k);179}180enDigest = !enDigest;181dis.on(enDigest);182dos.on(enDigest);183if ((k = dis.read(buffer, 0, buffer.length)) != -1) {184dos.write(buffer, 0, k);185if (enDigest) {186baOut.write(buffer, 0, k);187}188enDigest = !enDigest;189dis.on(enDigest);190dos.on(enDigest);191}192}193}194break;195default:196out.println("ERROR: Invalid read/write combination choice!");197return false;198}199200// Get the output and the "correct" digest values201byte[] output1 = dis.getMessageDigest().digest();202byte[] output2 = dos.getMessageDigest().digest();203byte[] standard;204if (on) {205standard = md.digest(data);206} else {207byte[] dataDigested = baOut.toByteArray();208standard = md.digest(dataDigested);209}210211// Compare the output byte array value to the input data212if (!MessageDigest.isEqual(data, baos.toByteArray())) {213out.println("ERROR of " + readModel214+ ": output and input data unexpectedly changed");215return false;216}217// Compare generated digest values218if (!MessageDigest.isEqual(output1, standard)219|| !MessageDigest.isEqual(output2, standard)) {220out.println("ERROR" + readModel221+ ": generated digest data unexpectedly changed");222return false;223}224225return true;226} catch (Exception ex) {227out.println("testDigestOnOff failed at:" + algo + "/" + readModel228+ "/" + dataLength + " with unexpected exception");229throw ex;230}231}232233/**234* Test DigestInputStream and DigestOutputStream digest function when Swap235* the message digest engines between DigestIn/OutputStream236*237* @param algo238* Message Digest algorithm239* @param dataLength240* plain test data length.241* @exception Exception242* throw unexpected exception243*/244public boolean testMDChange(String algo, int dataLength) throws Exception {245// Generate the DigestInputStream/DigestOutputStream object246MessageDigest mdIn = MessageDigest.getInstance(algo);247MessageDigest mdOut = MessageDigest.getInstance(algo);248try (ByteArrayInputStream bais = new ByteArrayInputStream(data);249DigestInputStream dis = new DigestInputStream(bais, mdIn);250ByteArrayOutputStream baos = new ByteArrayOutputStream();251DigestOutputStream dos = new DigestOutputStream(baos, mdOut);) {252253// Perform the update using all available/possible update methods254int k = 0;255byte[] buffer = new byte[10];256257// use both read() and read(byte[], int, int)258while ((k = dis.read()) != -1) {259dos.write(k);260if ((k = dis.read(buffer, 0, buffer.length)) != -1) {261dos.write(buffer, 0, k);262}263264// Swap the message digest engines between265// DigestIn/OutputStream objects266dis.setMessageDigest(mdOut);267dos.setMessageDigest(mdIn);268mdIn = dis.getMessageDigest();269mdOut = dos.getMessageDigest();270}271272// Get the output and the "correct" digest values273byte[] output1 = mdIn.digest();274byte[] output2 = mdOut.digest();275byte[] standard = md.digest(data);276277// Compare generated digest values278return MessageDigest.isEqual(output1, standard)279&& MessageDigest.isEqual(output2, standard);280} catch (Exception ex) {281out.println("testMDChange failed at:" + algo + "/" + dataLength282+ " with unexpected exception");283throw ex;284}285}286287/**288* Test DigestInputStream and DigestOutputStream digest function when use289* same message digest object.290*291* @param algo292* Message Digest algorithm293* @param dataLength294* plain test data length.295* @exception Exception296* throw unexpected exception297*/298public boolean testMDShare(String algo, int dataLength) throws Exception {299MessageDigest mdCommon = MessageDigest.getInstance(algo);300// Generate the DigestInputStream/DigestOutputStream object301try (ByteArrayInputStream bais = new ByteArrayInputStream(data);302DigestInputStream dis = new DigestInputStream(bais, mdCommon);303ByteArrayOutputStream baos = new ByteArrayOutputStream();304DigestOutputStream dos = new DigestOutputStream(baos, mdCommon);) {305306// Perform the update using all available/possible update methods307int k = 0;308byte[] buffer = new byte[10];309310// use both read() and read(byte[], int, int)311while (k < data.length) {312int len = dis.read(buffer, 0, buffer.length);313if (len != -1) {314k += len;315if (k < data.length) {316dos.write(data[k]);317k++;318dis.skip(1);319}320}321}322323// Get the output and the "correct" digest values324byte[] output = mdCommon.digest();325byte[] standard = md.digest(data);326327// Compare generated digest values328return MessageDigest.isEqual(output, standard);329} catch (Exception ex) {330out.println("TestMDShare failed at:" + algo + "/" + dataLength331+ " with unexpected exception");332throw ex;333}334}335}336337338