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