1/* 2 * Copyright (c) 1998, 2015, 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 0000000 27 * @summary DHKeyAgreement3 28 * @author Jan Luehe 29 */ 30 31import java.io.*; 32import java.math.BigInteger; 33import java.security.*; 34import java.security.spec.*; 35import java.security.interfaces.*; 36import javax.crypto.*; 37import javax.crypto.spec.*; 38import javax.crypto.interfaces.*; 39 40/** 41 * This test utility executes the Diffie-Hellman key agreement protocol 42 * between 3 parties: Alice, Bob, and Carol. 43 * 44 * We use the same 1024 bit prime modulus and base generator that are used by 45 * SKIP. 46 */ 47 48public class DHKeyAgreement3 { 49 50 private DHKeyAgreement3() {} 51 52 public static void main(String argv[]) throws Exception { 53 DHKeyAgreement3 keyAgree = new DHKeyAgreement3(); 54 keyAgree.run(); 55 System.out.println("Test Passed"); 56 } 57 58 private void run() throws Exception { 59 60 DHParameterSpec dhSkipParamSpec; 61 62 System.err.println("Using SKIP Diffie-Hellman parameters"); 63 dhSkipParamSpec = new DHParameterSpec(skip1024Modulus, skip1024Base); 64 65 // Alice creates her own DH key pair 66 System.err.println("ALICE: Generate DH keypair ..."); 67 KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH", "SunJCE"); 68 aliceKpairGen.initialize(dhSkipParamSpec); 69 KeyPair aliceKpair = aliceKpairGen.generateKeyPair(); 70 71 // Bob creates his own DH key pair 72 System.err.println("BOB: Generate DH keypair ..."); 73 KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH", "SunJCE"); 74 bobKpairGen.initialize(dhSkipParamSpec); 75 KeyPair bobKpair = bobKpairGen.generateKeyPair(); 76 77 // Carol creates her own DH key pair 78 System.err.println("CAROL: Generate DH keypair ..."); 79 KeyPairGenerator carolKpairGen = KeyPairGenerator.getInstance("DH", "SunJCE"); 80 carolKpairGen.initialize(dhSkipParamSpec); 81 KeyPair carolKpair = carolKpairGen.generateKeyPair(); 82 83 84 // Alice initialize 85 System.err.println("ALICE: Initialize ..."); 86 KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH", "SunJCE"); 87 aliceKeyAgree.init(aliceKpair.getPrivate()); 88 89 // Bob initialize 90 System.err.println("BOB: Initialize ..."); 91 KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH", "SunJCE"); 92 bobKeyAgree.init(bobKpair.getPrivate()); 93 94 // Carol initialize 95 System.err.println("CAROL: Initialize ..."); 96 KeyAgreement carolKeyAgree = KeyAgreement.getInstance("DH", "SunJCE"); 97 carolKeyAgree.init(carolKpair.getPrivate()); 98 99 100 // Alice uses Carol's public key 101 Key ac = aliceKeyAgree.doPhase(carolKpair.getPublic(), false); 102 103 // Bob uses Alice's public key 104 Key ba = bobKeyAgree.doPhase(aliceKpair.getPublic(), false); 105 106 // Carol uses Bob's public key 107 Key cb = carolKeyAgree.doPhase(bobKpair.getPublic(), false); 108 109 110 // Alice uses Carol's result from above 111 aliceKeyAgree.doPhase(cb, true); 112 113 // Bob uses Alice's result from above 114 bobKeyAgree.doPhase(ac, true); 115 116 // Carol uses Bob's result from above 117 carolKeyAgree.doPhase(ba, true); 118 119 120 // Alice, Bob and Carol compute their secrets 121 byte[] aliceSharedSecret = aliceKeyAgree.generateSecret(); 122 int aliceLen = aliceSharedSecret.length; 123 System.out.println("Alice secret: " + toHexString(aliceSharedSecret)); 124 125 byte[] bobSharedSecret = bobKeyAgree.generateSecret(); 126 int bobLen = bobSharedSecret.length; 127 System.out.println("Bob secret: " + toHexString(bobSharedSecret)); 128 129 byte[] carolSharedSecret = carolKeyAgree.generateSecret(); 130 int carolLen = carolSharedSecret.length; 131 System.out.println("Carol secret: " + toHexString(carolSharedSecret)); 132 133 134 // Compare Alice and Bob 135 if (aliceLen != bobLen) { 136 throw new Exception("Alice and Bob have different lengths"); 137 } 138 for (int i=0; i<aliceLen; i++) { 139 if (aliceSharedSecret[i] != bobSharedSecret[i]) { 140 throw new Exception("Alice and Bob differ"); 141 } 142 } 143 System.err.println("Alice and Bob are the same"); 144 145 // Compare Bob and Carol 146 if (bobLen != carolLen) { 147 throw new Exception("Bob and Carol have different lengths"); 148 } 149 for (int i=0; i<bobLen; i++) { 150 if (bobSharedSecret[i] != carolSharedSecret[i]) { 151 throw new Exception("Bob and Carol differ"); 152 } 153 } 154 System.err.println("Bob and Carol are the same"); 155 } 156 157 158 /* 159 * Converts a byte to hex digit and writes to the supplied buffer 160 */ 161 private void byte2hex(byte b, StringBuffer buf) { 162 char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', 163 '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 164 int high = ((b & 0xf0) >> 4); 165 int low = (b & 0x0f); 166 buf.append(hexChars[high]); 167 buf.append(hexChars[low]); 168 } 169 170 /* 171 * Converts a byte array to hex string 172 */ 173 private String toHexString(byte[] block) { 174 StringBuffer buf = new StringBuffer(); 175 176 int len = block.length; 177 178 for (int i = 0; i < len; i++) { 179 byte2hex(block[i], buf); 180 if (i < len-1) { 181 buf.append(":"); 182 } 183 } 184 return buf.toString(); 185 } 186 187 /* 188 * Prints the usage of this test. 189 */ 190 private void usage() { 191 System.err.print("DHKeyAgreement usage: "); 192 System.err.println("[-gen]"); 193 } 194 195 // The 1024 bit Diffie-Hellman modulus values used by SKIP 196 private static final byte skip1024ModulusBytes[] = { 197 (byte)0xF4, (byte)0x88, (byte)0xFD, (byte)0x58, 198 (byte)0x4E, (byte)0x49, (byte)0xDB, (byte)0xCD, 199 (byte)0x20, (byte)0xB4, (byte)0x9D, (byte)0xE4, 200 (byte)0x91, (byte)0x07, (byte)0x36, (byte)0x6B, 201 (byte)0x33, (byte)0x6C, (byte)0x38, (byte)0x0D, 202 (byte)0x45, (byte)0x1D, (byte)0x0F, (byte)0x7C, 203 (byte)0x88, (byte)0xB3, (byte)0x1C, (byte)0x7C, 204 (byte)0x5B, (byte)0x2D, (byte)0x8E, (byte)0xF6, 205 (byte)0xF3, (byte)0xC9, (byte)0x23, (byte)0xC0, 206 (byte)0x43, (byte)0xF0, (byte)0xA5, (byte)0x5B, 207 (byte)0x18, (byte)0x8D, (byte)0x8E, (byte)0xBB, 208 (byte)0x55, (byte)0x8C, (byte)0xB8, (byte)0x5D, 209 (byte)0x38, (byte)0xD3, (byte)0x34, (byte)0xFD, 210 (byte)0x7C, (byte)0x17, (byte)0x57, (byte)0x43, 211 (byte)0xA3, (byte)0x1D, (byte)0x18, (byte)0x6C, 212 (byte)0xDE, (byte)0x33, (byte)0x21, (byte)0x2C, 213 (byte)0xB5, (byte)0x2A, (byte)0xFF, (byte)0x3C, 214 (byte)0xE1, (byte)0xB1, (byte)0x29, (byte)0x40, 215 (byte)0x18, (byte)0x11, (byte)0x8D, (byte)0x7C, 216 (byte)0x84, (byte)0xA7, (byte)0x0A, (byte)0x72, 217 (byte)0xD6, (byte)0x86, (byte)0xC4, (byte)0x03, 218 (byte)0x19, (byte)0xC8, (byte)0x07, (byte)0x29, 219 (byte)0x7A, (byte)0xCA, (byte)0x95, (byte)0x0C, 220 (byte)0xD9, (byte)0x96, (byte)0x9F, (byte)0xAB, 221 (byte)0xD0, (byte)0x0A, (byte)0x50, (byte)0x9B, 222 (byte)0x02, (byte)0x46, (byte)0xD3, (byte)0x08, 223 (byte)0x3D, (byte)0x66, (byte)0xA4, (byte)0x5D, 224 (byte)0x41, (byte)0x9F, (byte)0x9C, (byte)0x7C, 225 (byte)0xBD, (byte)0x89, (byte)0x4B, (byte)0x22, 226 (byte)0x19, (byte)0x26, (byte)0xBA, (byte)0xAB, 227 (byte)0xA2, (byte)0x5E, (byte)0xC3, (byte)0x55, 228 (byte)0xE9, (byte)0x2F, (byte)0x78, (byte)0xC7 229 }; 230 231 // The SKIP 1024 bit modulus 232 private static final BigInteger skip1024Modulus 233 = new BigInteger(1, skip1024ModulusBytes); 234 235 // The base used with the SKIP 1024 bit modulus 236 private static final BigInteger skip1024Base = BigInteger.valueOf(2); 237} 238