1 /* 2 * Copyright (c) 1999, 2017, 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 /* 25 * @test 26 * @bug 8048819 27 * @summary This test stressful verifies the assertion of "The secret keys generated 28 * by all involved parties should be the same." for javax.crypto.KeyAgreement 29 * @run main/othervm -Djdk.crypto.KeyAgreement.legacyKDF=true SameDHKeyStressTest 30 */ 31 import java.security.AlgorithmParameterGenerator; 32 import java.security.InvalidAlgorithmParameterException; 33 import java.security.InvalidKeyException; 34 import java.security.Key; 35 import java.security.KeyPair; 36 import java.security.KeyPairGenerator; 37 import java.security.NoSuchAlgorithmException; 38 import java.security.NoSuchProviderException; 39 import java.security.spec.AlgorithmParameterSpec; 40 import java.util.Arrays; 41 import javax.crypto.KeyAgreement; 42 import javax.crypto.SecretKey; 43 import javax.crypto.spec.DHGenParameterSpec; 44 import javax.crypto.spec.DHParameterSpec; 45 46 public class SameDHKeyStressTest { 47 48 static final String[] ALGORITHMS = {"DH", "DiffieHellman", "dh", "diffieHELLMAN"}; 49 static final String[] SECRET_ALOGRITHMS = {"DES", "DESede", "blowfish"}; 50 static final int[] NUMBER_OF_PARTIES = {2, 3, 4}; 51 static final String[] PA_NAMES = {"Alice", "Bob", "Carol", "David"}; 52 main(String args[])53 public static void main(String args[]) { 54 int failedCnt = 0; 55 StringBuilder failedList = new StringBuilder("Failed List:"); 56 57 for (String algorithm : ALGORITHMS) { 58 for (int numOfParties : NUMBER_OF_PARTIES) { 59 for (String secretAlgorithm : SECRET_ALOGRITHMS) { 60 if (!runTest(algorithm, numOfParties, secretAlgorithm)) { 61 failedCnt++; 62 failedList.append("\n Altorightm = ").append(algorithm). 63 append(" Number of Parties = ").append(numOfParties). 64 append(" Secret Algorithm = ").append(secretAlgorithm); 65 } 66 } 67 } 68 } //end of for loop 69 70 if (failedCnt > 0) { 71 System.out.println(failedList); 72 throw new RuntimeException("SameDHKeyStressTest Failed"); 73 } 74 } 75 runTest(String algo, int numParties, String secretAlgo)76 public static boolean runTest(String algo, int numParties, String secretAlgo) { 77 KAParticipant[] parties = new KAParticipant[numParties]; 78 Key[] keyArchives = new Key[numParties]; 79 try { 80 // generate AlogirhtmParameterSpec 81 AlgorithmParameterGenerator apg = AlgorithmParameterGenerator.getInstance("DH","SunJCE"); 82 AlgorithmParameterSpec aps = new DHGenParameterSpec(512, 64); 83 apg.init(aps); 84 DHParameterSpec spec = apg.generateParameters(). 85 getParameterSpec(DHParameterSpec.class); 86 87 //initilize all KeyAgreement participants 88 for (int i = 0; i < numParties; i++) { 89 parties[i] = new KAParticipant(PA_NAMES[i], algo); 90 parties[i].initialize(spec); 91 keyArchives[i] = parties[i].getPublicKey(); 92 } 93 94 // Do all phases in the KeyAgreement for all participants 95 Key[] keyBuffer = new Key[numParties]; 96 boolean lastPhase = false; 97 for (int j = 0; j < numParties - 1; j++) { 98 if (j == numParties - 2) { 99 lastPhase = true; 100 } 101 for (int k = 0; k < numParties; k++) { 102 if (k == numParties - 1) { 103 keyBuffer[k] = parties[k].doPhase(keyArchives[0], lastPhase); 104 } else { 105 keyBuffer[k] = parties[k].doPhase(keyArchives[k + 1], lastPhase); 106 } 107 } 108 System.arraycopy(keyBuffer, 0, keyArchives, 0, numParties); 109 } 110 111 //Comparison: The secret keys generated by all involved parties should be the same 112 SecretKey[] sKeys = new SecretKey[numParties]; 113 for (int n = 0; n < numParties; n++) { 114 sKeys[n] = parties[n].generateSecret(secretAlgo); 115 } 116 for (int q = 0; q < numParties - 1; q++) { 117 if (!Arrays.equals(sKeys[q].getEncoded(), sKeys[q + 1].getEncoded())) { 118 return false; 119 } 120 } 121 return true; 122 } catch (Exception ex) { 123 ex.printStackTrace(); 124 return false; 125 } 126 127 } 128 129 } 130 131 class KAParticipant { 132 133 private String name = null; 134 private String algorithm = null; 135 private KeyPairGenerator keyGen = null; 136 private KeyPair keys = null; 137 private KeyAgreement ka = null; 138 KAParticipant(String pName, String algo)139 public KAParticipant(String pName, String algo) throws NoSuchAlgorithmException, NoSuchProviderException { 140 name = pName; 141 algorithm = algo; 142 keyGen = KeyPairGenerator.getInstance(algo,"SunJCE"); 143 ka = KeyAgreement.getInstance(algo,"SunJCE"); 144 } 145 initialize(AlgorithmParameterSpec spec)146 public void initialize(AlgorithmParameterSpec spec) throws InvalidAlgorithmParameterException, InvalidKeyException { 147 keyGen.initialize(spec); 148 keys = keyGen.generateKeyPair(); 149 ka.init(keys.getPrivate()); 150 } 151 doPhase(Key key, boolean lastPhase)152 public Key doPhase(Key key, boolean lastPhase) throws InvalidKeyException { 153 return ka.doPhase(key, lastPhase); 154 } 155 getPublicKey()156 public Key getPublicKey() { 157 return keys.getPublic(); 158 } 159 generateSecret()160 public byte[] generateSecret() { 161 return ka.generateSecret(); 162 } 163 generateSecret(String algo)164 public SecretKey generateSecret(String algo) throws java.lang.IllegalStateException, 165 java.security.NoSuchAlgorithmException, 166 java.security.InvalidKeyException { 167 return ka.generateSecret(algo); 168 } 169 } 170