1 /*
2  * Copyright (c) 2003, 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 /*
25  * @test
26  * @bug 4921804 6324825
27  * @summary Verify that DH works properly
28  * @author Andreas Sterbenz
29  * @library /test/lib ..
30  * @modules jdk.crypto.cryptoki
31  * @run main/othervm -Djdk.crypto.KeyAgreement.legacyKDF=true TestDH
32  * @run main/othervm -Djdk.crypto.KeyAgreement.legacyKDF=true TestDH sm
33  */
34 
35 import java.security.KeyPair;
36 import java.security.KeyPairGenerator;
37 import java.security.Provider;
38 import java.util.Arrays;
39 import javax.crypto.KeyAgreement;
40 import javax.crypto.SecretKey;
41 
42 public class TestDH extends PKCS11Test {
43 
44     @Override
main(Provider p)45     public void main(Provider p) throws Exception {
46         if (p.getService("KeyAgreement", "DH") == null) {
47             System.out.println("DH not supported, skipping");
48             return;
49         }
50         KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", p);
51         kpg.initialize(512);
52         KeyPair kp1 = kpg.generateKeyPair();
53         KeyPair kp2 = kpg.generateKeyPair();
54 
55         KeyAgreement ka1, ka2;
56         ka1 = KeyAgreement.getInstance("DH", p);
57         ka1.init(kp1.getPrivate());
58         ka1.doPhase(kp2.getPublic(), true);
59         System.out.println("Derive 1...");
60         byte[] secret1 = ka1.generateSecret();
61 
62         ka1.init(kp2.getPrivate());
63         ka1.doPhase(kp1.getPublic(), true);
64         System.out.println("Derive 2...");
65         byte[] secret2 = ka1.generateSecret();
66 
67         if (Arrays.equals(secret1, secret2) == false) {
68             throw new Exception("Secrets (1,2) do not match");
69         }
70 
71         ka2 = KeyAgreement.getInstance("DH", "SunJCE");
72         ka2.init(kp1.getPrivate());
73         ka2.doPhase(kp2.getPublic(), true);
74         System.out.println("Derive 3...");
75         byte[] secret3 = ka2.generateSecret();
76 
77         if (Arrays.equals(secret1, secret3) == false) {
78             throw new Exception("Secrets (1,3) do not match");
79         }
80 
81         ka2.init(kp2.getPrivate());
82         ka2.doPhase(kp1.getPublic(), true);
83         System.out.println("Derive 4...");
84         byte[] secret4 = ka2.generateSecret();
85 
86         if (Arrays.equals(secret1, secret4) == false) {
87             throw new Exception("Secrets (1,4) do not match");
88         }
89 
90         testAlgorithm(ka2, kp2, ka1, kp1, "DES");
91         testAlgorithm(ka2, kp2, ka1, kp1, "DESede");
92 //      testAlgorithm(ka2, kp2, ka1, kp1, "AES");
93 //      testAlgorithm(ka2, kp2, ka1, kp1, "RC4");
94         testAlgorithm(ka2, kp2, ka1, kp1, "Blowfish");
95         testAlgorithm(ka2, kp2, ka1, kp1, "TlsPremasterSecret");
96     }
97 
testAlgorithm(KeyAgreement ka1, KeyPair kp1, KeyAgreement ka2, KeyPair kp2, String algorithm)98     private static void testAlgorithm(KeyAgreement ka1, KeyPair kp1,
99             KeyAgreement ka2, KeyPair kp2, String algorithm) throws Exception {
100         SecretKey key1;
101 
102         ka1.init(kp1.getPrivate());
103         ka1.doPhase(kp2.getPublic(), true);
104         System.out.println("Derive " + algorithm + " using SunJCE...");
105         key1 = ka1.generateSecret(algorithm);
106 
107         ka2.init(kp1.getPrivate());
108         ka2.doPhase(kp2.getPublic(), true);
109         System.out.println("Derive " + algorithm + " using PKCS#11...");
110         SecretKey key2 = ka2.generateSecret(algorithm);
111 
112         byte[] b1 = key1.getEncoded();
113         byte[] b2 = key2.getEncoded();
114 
115         if (Arrays.equals(b1, b2) == false) {
116             System.out.println(b1.length + " bytes: " + toString(b1));
117             System.out.println(b2.length + " bytes: " + toString(b2));
118             throw new Exception(algorithm + " secret mismatch");
119         }
120     }
121 
main(String[] args)122     public static void main(String[] args) throws Exception {
123         main(new TestDH(), args);
124     }
125 
126 }
127