1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package jdk.test.lib; 25 26 import java.security.*; 27 import java.security.spec.*; 28 import java.util.*; 29 30 /* 31 * Utility class used by various Signature related regression tests for 32 * common functions such as generating the list of to-be-tested algorithms 33 * based on key size, etc. Currently, this is mostly needed by RSA 34 * signatures. 35 */ 36 public class SigTestUtil { 37 38 public enum SignatureType { 39 RSA("RSA"), 40 RSASSA_PSS("RSASSA-PSS") 41 ; 42 43 private String keyAlg; 44 45 SignatureType(String keyAlg) { 46 this.keyAlg = keyAlg; 47 } 48 @Override 49 public String toString() { 50 return keyAlg; 51 } 52 } 53 54 // collection of all supported digest algorithms 55 // note that the entries are ordered by required key sizes 56 private static final String[] DIGEST_ALGS = { 57 "SHA-512", 58 "SHA-384", 59 "SHA-256", 60 "SHA-512/256", 61 "SHA-224", 62 "SHA-512/224", 63 "SHA-1", 64 "MD2", "MD5" // these aren't supported by RSA PSS 65 }; 66 67 // indice for message digest algorithms lookup 68 // may need to be adjusted if new algorithms are added 69 private static final int PKCS1_5_INDEX_768 = 0; 70 private static final int PKCS1_5_INDEX_512 = 2; 71 private static final int PKCS1_5_INDEX_END = DIGEST_ALGS.length; 72 private static final int PSS_INDEX_2048 = 0; 73 private static final int PSS_INDEX_1024 = 1; 74 private static final int PSS_INDEX_768 = 2; 75 private static final int PSS_INDEX_512 = 4; 76 private static final int PSS_INDEX_END = 7; 77 78 public static Iterable<String> getDigestAlgorithms(SignatureType type, 79 int keysize) throws RuntimeException { 80 81 // initialize to all, then trim based on key size 82 List<String> result = new ArrayList<>(Arrays.asList(DIGEST_ALGS)); 83 int index = 0; 84 switch (type) { 85 case RSA: 86 if (keysize >= 768) { 87 index = PKCS1_5_INDEX_768; 88 } else if (keysize >= 512) { 89 index = PKCS1_5_INDEX_512; 90 } else { 91 throw new RuntimeException("Keysize too small: " + keysize); 92 } 93 result = result.subList(index, PKCS1_5_INDEX_END); 94 break; 95 case RSASSA_PSS: 96 if (keysize >= 2048) { 97 index = PSS_INDEX_2048; 98 } else if (keysize >= 1024) { 99 index = PSS_INDEX_1024; 100 } else if (keysize >= 768) { 101 index = PSS_INDEX_768; 102 } else if (keysize >= 512) { 103 index = PSS_INDEX_512; 104 } else { 105 throw new RuntimeException("Keysize too small: " + keysize); 106 } 107 result = result.subList(index, PSS_INDEX_END); 108 break; 109 default: 110 // XXX maybe just return result instead of error out? 111 throw new RuntimeException("Unsupported signature type: " + type); 112 } 113 return result; 114 } 115 116 public static AlgorithmParameterSpec generateDefaultParameter( 117 SignatureType type, String mdAlg) throws RuntimeException { 118 // only RSASSA-PSS signature uses parameters 119 switch (type) { 120 case RSASSA_PSS: 121 try { 122 MessageDigest md = MessageDigest.getInstance(mdAlg); 123 return new PSSParameterSpec(mdAlg, "MGF1", 124 new MGF1ParameterSpec(mdAlg), md.getDigestLength(), 125 PSSParameterSpec.TRAILER_FIELD_BC); 126 } catch (Exception e) { 127 throw new RuntimeException(e); 128 } 129 default: 130 return null; 131 } 132 } 133 134 public static String generateSigAlg(SignatureType type, 135 String mdAlg) throws RuntimeException { 136 switch (type) { 137 case RSA: 138 int idx = mdAlg.indexOf("-"); 139 if (idx != -1) { 140 mdAlg = mdAlg.substring(0, idx) + mdAlg.substring(idx+1); 141 } 142 return mdAlg + "with" + type.toString(); 143 case RSASSA_PSS: 144 return type.toString(); 145 default: 146 throw new RuntimeException("Unsupported signature type " + type ); 147 } 148 } 149 150 }