test/lib/jdk/test/lib/SigTestUtil.java
branchJDK-8145252-TLS13-branch
changeset 56542 56aaa6cb3693
child 56592 b1902b22005e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/lib/jdk/test/lib/SigTestUtil.java	Fri May 11 15:53:12 2018 -0700
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2018, 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.
+ */
+
+package jdk.test.lib;
+
+import java.security.*;
+import java.security.spec.*;
+import java.util.*;
+
+/*
+ * Utility class used by various Signature related regression tests for
+ * common functions such as generating the list of to-be-tested algorithms
+ * based on key size, etc. Currently, this is mostly needed by RSA
+ * signatures.
+ */
+public class SigTestUtil {
+
+    public enum SignatureType {
+        RSA("RSA"),
+        RSASSA_PSS("RSASSA-PSS")
+        ;
+
+        private String keyAlg;
+
+        SignatureType(String keyAlg) {
+            this.keyAlg = keyAlg;
+        }
+        @Override
+        public String toString() {
+            return keyAlg;
+        }
+    }    
+ 
+    // collection of all supported digest algorithms
+    // note that the entries are ordered by required key sizes
+    private static final String[] DIGEST_ALGS = {
+        "SHA-512",
+        "SHA-384",
+        "SHA-256",
+        "SHA-512/256",
+        "SHA-224",
+        "SHA-512/224",
+        "SHA-1",
+        "MD2", "MD5" // these aren't supported by RSA PSS
+    };
+
+    // indice for message digest algorithms lookup
+    // may need to be adjusted if new algorithms are added
+    private static final int PKCS1_5_INDEX_768 = 0;
+    private static final int PKCS1_5_INDEX_512 = 2;
+    private static final int PKCS1_5_INDEX_END = DIGEST_ALGS.length;
+    private static final int PSS_INDEX_2048 = 0;
+    private static final int PSS_INDEX_1024 = 1;
+    private static final int PSS_INDEX_768 = 2;
+    private static final int PSS_INDEX_512 = 4;
+    private static final int PSS_INDEX_END = 7;
+    
+    public static Iterable<String> getDigestAlgorithms(SignatureType type,
+            int keysize) throws RuntimeException {
+
+        // initialize to all, then trim based on key size
+        List<String> result = new ArrayList<>(Arrays.asList(DIGEST_ALGS));
+        int index = 0;
+        switch (type) {
+        case RSA:
+            if (keysize >= 768) {
+                index = PKCS1_5_INDEX_768;
+            } else if (keysize >= 512) {
+                index = PKCS1_5_INDEX_512;
+            } else {
+                throw new RuntimeException("Keysize too small: " + keysize);
+            }
+            result = result.subList(index, PKCS1_5_INDEX_END);
+            break;
+        case RSASSA_PSS:
+            if (keysize >= 2048) {
+                index = PSS_INDEX_2048;
+            } else if (keysize >= 1024) {
+                index = PSS_INDEX_1024;
+            } else if (keysize >= 768) {
+                index = PSS_INDEX_768;
+            } else if (keysize >= 512) {
+                index = PSS_INDEX_512;
+            } else {
+                throw new RuntimeException("Keysize too small: " + keysize);
+            }
+            result = result.subList(index, PSS_INDEX_END);
+            break;
+        default:
+            // XXX maybe just return result instead of error out?
+            throw new RuntimeException("Unsupported signature type: " + type);
+        }
+        return result;
+    }
+
+    public static AlgorithmParameterSpec generateDefaultParameter(
+            SignatureType type, String mdAlg) throws RuntimeException {
+        // only RSASSA-PSS signature uses parameters
+        switch (type) {
+        case RSASSA_PSS:
+            try {
+                MessageDigest md = MessageDigest.getInstance(mdAlg);
+                return new PSSParameterSpec(mdAlg, "MGF1",
+                    new MGF1ParameterSpec(mdAlg), md.getDigestLength(),
+                    PSSParameterSpec.TRAILER_FIELD_BC);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        default:
+            return null;
+        }
+    }
+
+    public static String generateSigAlg(SignatureType type,
+            String mdAlg) throws RuntimeException {
+        switch (type) {
+        case RSA:
+            int idx = mdAlg.indexOf("-");
+            if (idx != -1) {
+                mdAlg = mdAlg.substring(0, idx) + mdAlg.substring(idx+1);
+            }
+            return mdAlg + "with" + type.toString();
+        case RSASSA_PSS:
+            return type.toString();
+        default:
+            throw new RuntimeException("Unsupported signature type " + type );
+        }
+    }
+
+}