changeset 11645:c4eca15ee640

8050371: More MessageDigest tests Reviewed-by: xuelei
author msolovie
date Thu, 21 Apr 2016 17:01:02 +0300
parents 43eac338b248
children b99f001f70a7
files test/java/security/MessageDigest/TestSameLength.java test/java/security/MessageDigest/TestSameValue.java
diffstat 2 files changed, 453 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/MessageDigest/TestSameLength.java	Thu Apr 21 17:01:02 2016 +0300
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2015, 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 static java.lang.System.out;
+
+import java.nio.ByteBuffer;
+import java.security.MessageDigest;
+import java.util.Random;
+
+/**
+ * @test
+ * @bug 8050371
+ * @summary Check md.getDigestLength() equal digest output length with various
+ *          algorithm/dataLen/(update,digest methods).
+ * @author Kevin Liu
+ */
+
+public class TestSameLength {
+
+    public static void main(String[] args) throws Exception {
+        TestSameLength test = new TestSameLength();
+        test.run();
+    }
+
+    private void run() throws Exception {
+        String[] algorithmArr = {
+                "SHA", "Sha", "SHA-1", "sha-1", "SHA1", "sha1", "MD5", "md5",
+                "SHA-224", "SHA-256", "SHA-384", "SHA-512"
+        };
+        int[] nUpdatesArr = {
+                0, 1, 2, 3
+        };
+        int[] dataLenArr = {
+                1, 50, 2500, 125000, 6250000
+        };
+
+        for (String algorithm: algorithmArr) {
+            for (UpdateMethod update: UpdateMethod.values()) {
+                for (int dataLen: dataLenArr) {
+                    if (!runTest(algorithm, dataLen, update)) {
+                        throw new RuntimeException(
+                                "Test failed at algorithm/dataLen/numUpdate:"
+                                        + algorithm + "/" + dataLen + "/"
+                                        + update.toString());
+                    }
+                }
+            }
+        }
+
+        out.println("All " + algorithmArr.length * nUpdatesArr.length
+                * dataLenArr.length + " tests Passed");
+    }
+
+    private boolean runTest(String algo, long dataLen,
+            UpdateMethod whichUpdate) throws Exception {
+        try {
+            // Do initialization
+            byte[] data = new byte[(int) dataLen];
+            new Random().nextBytes(data);
+            MessageDigest md = MessageDigest.getInstance(algo);
+            int outputLen = md.getDigestLength();
+
+            // Perform the update using all available/possible update methods
+            whichUpdate.updateDigest(data, md, dataLen);
+            // Get the output
+            byte[] output = md.digest();
+
+            // Compare input and output
+            return outputLen == output.length;
+        } catch (Exception ex) {
+            System.err.println("Testing: " + algo + "/" + dataLen + "/"
+                    + whichUpdate.toString()
+                    + " failed with unexpected exception");
+            ex.printStackTrace();
+            throw ex;
+        }
+    }
+
+    private static enum UpdateMethod {
+        UPDATE_BYTE {
+            @Override
+            public void updateDigest(byte[] data,
+                    MessageDigest md, long dataLen) {
+
+                for (int i = 0; i < dataLen; i++) {
+                    md.update(data[i]);
+                }
+            }
+        },
+
+        UPDATE_BUFFER {
+            @Override
+            public void updateDigest(byte[] data,
+                    MessageDigest md, long dataLen) {
+
+                md.update(data);
+            }
+        },
+
+        UPDATE_BUFFER_LEN {
+            @Override
+            public void updateDigest(byte[] data,
+                    MessageDigest md, long dataLen) {
+
+                for (int i = 0; i < dataLen; i++) {
+                    md.update(data, i, 1);
+                }
+            }
+        },
+
+        UPDATE_BYTE_BUFFER {
+            @Override
+            public void updateDigest(byte[] data,
+                    MessageDigest md, long dataLen) {
+
+                md.update(ByteBuffer.wrap(data));
+            }
+        };
+
+        public abstract void updateDigest(byte[] data,
+                    MessageDigest md, long dataLen);
+        }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/security/MessageDigest/TestSameValue.java	Thu Apr 21 17:01:02 2016 +0300
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2015, 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 static java.lang.System.out;
+
+import java.nio.ByteBuffer;
+import java.security.DigestException;
+import java.security.MessageDigest;
+import java.util.Random;
+
+/**
+ * @test
+ * @bug 8050371
+ * @summary Check md.digest(data) value whether same with digest output value
+ *          with various update/digest methods.
+ * @author Kevin Liu
+ */
+
+public class TestSameValue {
+
+    public static void main(String[] args) throws Exception {
+        TestSameValue test1 = new TestSameValue();
+        test1.run();
+    }
+
+    private void run() throws Exception {
+
+        byte[] data = new byte[6706];
+        MessageDigest md = null;
+        // Initialize input data
+        new Random().nextBytes(data);
+
+        String[] providers = {
+                null, "SUN"
+        };
+        String[] algorithmArr = {
+                "SHA", "Sha", "MD5", "md5", "SHA-224", "SHA-256", "SHA-384",
+                "SHA-512"
+        };
+
+        for (String algorithm: algorithmArr) {
+            for (String provider: providers) {
+                if (provider != null) {
+                    md = MessageDigest.getInstance(algorithm, provider);
+                } else {
+                    md = MessageDigest.getInstance(algorithm);
+                }
+                for (UpdateDigestMethod updateMethod: UpdateDigestMethod
+                        .values()) {
+                    byte[] output = updateMethod.updateDigest(data, md);
+                    // Get the output and the "correct" one
+                    byte[] standard = md.digest(data);
+                    // Compare input and output
+                    if (!MessageDigest.isEqual(output, standard)) {
+                        throw new RuntimeException(
+                                "Test failed at algorithm/provider/numUpdate:"
+                                        + algorithm + "/" + provider + "/"
+                                        + updateMethod);
+                    }
+                }
+            }
+        }
+
+        out.println("All " + algorithmArr.length
+                * UpdateDigestMethod.values().length * providers.length
+                + " tests Passed");
+    }
+
+    private static enum UpdateDigestMethod {
+
+        /*
+         * update the data one by one using method update(byte input) then
+         * do digest (giving the output buffer, offset, and the number of
+         * bytes to put in the output buffer)
+         */
+        UPDATE_DIGEST_BUFFER {
+            @Override
+            public byte[] updateDigest(byte[] data, MessageDigest md)
+                    throws DigestException {
+                for (byte element: data) {
+                    md.update(element);
+                }
+                byte[] output = new byte[md.getDigestLength()];
+                int len = md.digest(output, 0, output.length);
+                if (len != output.length) {
+                    throw new RuntimeException(
+                        "ERROR" + ": digest length differs!");
+                }
+                return output;
+            }
+        },
+
+        /*
+         * update the data one by one using method update(byte input)
+         * then do digest
+         */
+        UPDATE_DIGEST {
+            @Override
+            public byte[] updateDigest(byte[] data, MessageDigest md) {
+                for (byte element: data) {
+                    md.update(element);
+                }
+                return md.digest();
+            }
+        },
+
+        /*
+         * update all the data at once as a block, then do digest ( giving the
+         * output buffer, offset, and the number of bytes to put in the output
+         * buffer)
+         */
+        UPDATE_BLOCK_DIGEST_BUFFER {
+            @Override
+            public byte[] updateDigest(byte[] data, MessageDigest md)
+                    throws DigestException {
+                md.update(data);
+                byte[] output = new byte[md.getDigestLength()];
+                int len = md.digest(output, 0, output.length);
+                if (len != output.length) {
+                    throw new RuntimeException(
+                        "ERROR" + ": digest length differs!");
+                }
+                return output;
+            }
+        },
+
+        // update all the data at once as a block, then do digest
+        UPDATE_BLOCK_DIGEST {
+            @Override
+            public byte[] updateDigest(byte[] data, MessageDigest md) {
+                md.update(data);
+                return md.digest();
+            }
+        },
+
+        /*
+         * update the leading bytes (length is "data.length-LASTNBYTES")
+         * at once as a block, then do digest (do a final update using
+         * the left LASTNBYTES bytes which is passed as a parameter for
+         * the digest method, then complete the digest)
+         */
+        UPDATE_LEADING_BLOCK_DIGEST_REMAIN {
+            @Override
+            public byte[] updateDigest(byte[] data, MessageDigest md) {
+                byte[] mainPart = new byte[data.length - LASTNBYTES];
+                for (int i = 0; i < mainPart.length; i++) {
+                    mainPart[i] = data[i];
+                }
+                for (int j = 0; j < LASTNBYTES; j++) {
+                    REMAIN[j] = data[data.length - LASTNBYTES + j];
+                }
+                md.update(mainPart);
+                return md.digest(REMAIN);
+            }
+        },
+
+        /*
+         * update the data 2 bytes each time, after finishing updating,
+         * do digest (giving the output buffer, offset, and the number
+         * of bytes to put in the output buffer)
+         */
+        UPDATE_BYTES_DIGEST_BUFFER {
+            @Override
+            public byte[] updateDigest(byte[] data, MessageDigest md)
+                    throws DigestException {
+
+                for (int i = 0; i < data.length / 2; i++) {
+                    md.update(data, i * 2, 2);
+                }
+                byte[] output = new byte[md.getDigestLength()];
+                int len = md.digest(output, 0, output.length);
+                if (len != output.length) {
+                    throw new RuntimeException(
+                        "ERROR" + ": digest length differs!");
+                }
+                return output;
+            }
+        },
+
+        /*
+         * update the data 2 bytes each time, after finishing updating,
+         * do digest
+         */
+        UPDATE_BYTES_DIGEST {
+            @Override
+            public byte[] updateDigest(byte[] data, MessageDigest md) {
+                for (int i=0;i<data.length/2;i++){
+                    md.update(data,i*2,2);
+                }
+                return md.digest();
+            }
+        },
+
+        /*
+         * update the data one by one using method update(byte[] input,
+         * int offset, int len) for the leading bytes (length is
+         * "data.length-LASTNBYTES"), then do digest (do a final
+         * update using the left LASTNBYTES bytes which is passed
+         * as a parameter for digest method then complete the digest)
+         */
+        UPDATE_BUFFER_LEADING_DIGEST_REMAIN {
+            @Override
+            public byte[] updateDigest(byte[] data, MessageDigest md) {
+                for (int i = 0; i < data.length - LASTNBYTES; i++) {
+                    md.update(data, i, 1);
+                }
+                for (int j = 0; j < LASTNBYTES; j++) {
+                    REMAIN[j] = data[data.length - LASTNBYTES + j];
+                }
+                return md.digest(REMAIN);
+            }
+        },
+
+        /*
+         * update the data one by one using method update(byte input)
+         * for the leading bytes (length is "data.length-LASTNBYTES"),
+         * then do digest (do a final update using the left LASTNBYTES
+         * bytes which is passed as a parameter for digest method,
+         * then complete the digest)
+         */
+        UPDATE_LEADING_DIGEST_REMAIN {
+            @Override
+            public byte[] updateDigest(byte[] data, MessageDigest md) {
+                for (int i = 0; i < data.length - LASTNBYTES; i++) {
+                    md.update(data[i]);
+                }
+                for (int j = 0; j < LASTNBYTES; j++) {
+                    REMAIN[j] = data[data.length - LASTNBYTES + j];
+                }
+                return md.digest(REMAIN);
+            }
+        },
+
+        /*
+         * update all the data at once as a ByteBuffer, then do digest
+         * (giving the output buffer, offset, and the number of bytes
+         * to put in the output buffer)
+         */
+        UPDATE_BYTE_BUFFER_DIGEST_BUFFER {
+            @Override
+            public byte[] updateDigest(byte[] data, MessageDigest md)
+                    throws DigestException {
+                md.update(ByteBuffer.wrap(data));
+                byte[] output = new byte[md.getDigestLength()];
+                int len = md.digest(output, 0, output.length);
+                if (len != output.length) {
+                    throw new RuntimeException(
+                          "ERROR" + ": digest length differs!");
+                }
+                return output;
+            }
+        },
+
+        // update all the data at once as a ByteBuffer, then do digest
+        UPDATE_BYTE_BUFFER_DIGEST {
+            @Override
+            public byte[] updateDigest(byte[] data, MessageDigest md) {
+                md.update(ByteBuffer.wrap(data));
+                return md.digest();
+            }
+        },
+
+        /*
+         * update the leading bytes (length is "data.length-LASTNBYTES")
+         * at once as a ByteBuffer, then do digest (do a final update
+         * using the left LASTNBYTES bytes which is passed as a parameter
+         * for the digest method, then complete the digest)
+         */
+        UPDATE_BYTE_BUFFER_LEADING_DIGEST_REMAIN {
+            @Override
+            public byte[] updateDigest(byte[] data, MessageDigest md) {
+                byte[] mainPart = new byte[data.length - LASTNBYTES];
+                for (int i = 0; i < mainPart.length; i++) {
+                    mainPart[i] = data[i];
+                }
+                for (int j = 0; j < LASTNBYTES; j++) {
+                    REMAIN[j] = data[data.length - LASTNBYTES + j];
+                }
+                md.update(ByteBuffer.wrap(mainPart));
+                return md.digest(REMAIN);
+            }
+        };
+
+        private static final int LASTNBYTES = 5;
+        private static final byte[] REMAIN = new byte[LASTNBYTES];
+
+        public abstract byte[] updateDigest(byte[] data, MessageDigest md)
+                throws DigestException;
+    }
+}