1 /* 2 * Copyright (c) 2018, 2020, 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 "SHA3-512", 58 "SHA-512", 59 "SHA3-384", 60 "SHA-384", 61 "SHA3-256", 62 "SHA-256", 63 "SHA-512/256", 64 "SHA3-224", 65 "SHA-224", 66 "SHA-512/224", 67 "SHA-1", 68 "MD2", "MD5" // these aren't supported by RSA PSS 69 }; 70 71 // indice for message digest algorithms lookup 72 // may need to be adjusted if new algorithms are added 73 private static final int PKCS1_5_INDEX_768 = 0; // 512, 384-bit digests 74 private static final int PKCS1_5_INDEX_512 = 4; // 256-bit digests 75 private static final int PKCS1_5_INDEX_END = DIGEST_ALGS.length; 76 private static final int PSS_INDEX_2048 = 0; // 512-bit digests 77 private static final int PSS_INDEX_1024 = 2; // 384-bit digests 78 private static final int PSS_INDEX_768 = 4; // 256-bit digests 79 private static final int PSS_INDEX_512 = 7; // 224-bit digests 80 private static final int PSS_INDEX_END = DIGEST_ALGS.length - 2; 81 82 public static Iterable<String> getDigestAlgorithms(SignatureType type, 83 int keysize) throws RuntimeException { 84 85 // initialize to all, then trim based on key size 86 List<String> result = new ArrayList<>(Arrays.asList(DIGEST_ALGS)); 87 int index = 0; 88 switch (type) { 89 case RSA: 90 if (keysize >= 768) { 91 index = PKCS1_5_INDEX_768; 92 } else if (keysize >= 512) { 93 index = PKCS1_5_INDEX_512; 94 } else { 95 throw new RuntimeException("Keysize too small: " + keysize); 96 } 97 result = result.subList(index, PKCS1_5_INDEX_END); 98 break; 99 case RSASSA_PSS: 100 if (keysize >= 2048) { 101 index = PSS_INDEX_2048; 102 } else if (keysize >= 1024) { 103 index = PSS_INDEX_1024; 104 } else if (keysize >= 768) { 105 index = PSS_INDEX_768; 106 } else if (keysize >= 512) { 107 index = PSS_INDEX_512; 108 } else { 109 throw new RuntimeException("Keysize too small: " + keysize); 110 } 111 result = result.subList(index, PSS_INDEX_END); 112 break; 113 default: 114 // XXX maybe just return result instead of error out? 115 throw new RuntimeException("Unsupported signature type: " + type); 116 } 117 return result; 118 } 119 120 public static AlgorithmParameterSpec generateDefaultParameter( 121 SignatureType type, String mdAlg) throws RuntimeException { 122 // only RSASSA-PSS signature uses parameters 123 switch (type) { 124 case RSASSA_PSS: 125 try { 126 MessageDigest md = MessageDigest.getInstance(mdAlg); 127 return new PSSParameterSpec(mdAlg, "MGF1", 128 new MGF1ParameterSpec(mdAlg), md.getDigestLength(), 129 PSSParameterSpec.TRAILER_FIELD_BC); 130 } catch (Exception e) { 131 throw new RuntimeException(e); 132 } 133 default: 134 return null; 135 } 136 } 137 138 public static String generateSigAlg(SignatureType type, 139 String mdAlg) throws RuntimeException { 140 switch (type) { 141 case RSA: 142 if (mdAlg.startsWith("SHA-")) { 143 mdAlg = mdAlg.substring(0, 3) + mdAlg.substring(4); 144 } 145 return mdAlg + "with" + type.toString(); 146 case RSASSA_PSS: 147 return type.toString(); 148 default: 149 throw new RuntimeException("Unsupported signature type " + type ); 150 } 151 } 152 153 }