1 /*
2 * Copyright (c) 2016, 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 8072452
27 * @summary Support DHE sizes up to 8192-bits and DSA sizes up to 3072-bits
28 * @library ..
29 * @modules jdk.crypto.token
30 * @run main/othervm SupportedDHKeys
31 * @run main/othervm SupportedDHKeys sm
32 */
33
34 import java.math.BigInteger;
35 import java.security.KeyPair;
36 import java.security.KeyPairGenerator;
37 import java.security.Provider;
38 import javax.crypto.interfaces.DHPrivateKey;
39 import javax.crypto.interfaces.DHPublicKey;
40 import javax.crypto.spec.DHParameterSpec;
41
42 public class SupportedDHKeys extends PKCS11Test {
43
44 /*
45 * Sizes and values for various lengths.
46 */
47 private enum SupportedKeySize {
48 dhp512(512), dhp768(768), dhp832(832),
49 dhp1024(1024), dhp1536(1536), dhp2048(2048);
50
51 // the underlying pkcs11 may not support the following sizes yet
52 //
53 // dhp3072(3072), dhp4096(4096), dhp6144(6144),
54 // dhp8192(8192);
55
56 final int primeSize;
57
58 SupportedKeySize(int primeSize) {
59 this.primeSize = primeSize;
60 }
61 }
62
63 @Override
64 public void main(Provider provider) throws Exception {
65 if (provider.getService("KeyPairGenerator", "DiffieHellman") == null) {
66 System.out.println("No support of DH KeyPairGenerator, skipping");
67 return;
68 }
69
70 for (SupportedKeySize keySize : SupportedKeySize.values()) {
71 System.out.println("Checking " + keySize.primeSize + " ...");
72 KeyPairGenerator kpg =
73 KeyPairGenerator.getInstance("DiffieHellman", provider);
74 kpg.initialize(keySize.primeSize);
75 KeyPair kp = kpg.generateKeyPair();
76 checkKeyPair(kp, keySize.primeSize, provider);
77
78 DHPublicKey publicKey = (DHPublicKey)kp.getPublic();
79 BigInteger p = publicKey.getParams().getP();
80 BigInteger g = publicKey.getParams().getG();
81 kpg.initialize(new DHParameterSpec(p, g));
82 kp = kpg.generateKeyPair();
83 checkKeyPair(kp, keySize.primeSize, provider);
84 }
85 }
86
87 private static void checkKeyPair(KeyPair kp, int pSize,
88 Provider provider) throws Exception {
89
90 DHPrivateKey privateKey = (DHPrivateKey)kp.getPrivate();
91 BigInteger p = privateKey.getParams().getP();
92 if (p.bitLength() != pSize) {
93 throw new Exception(
94 "Invalid modulus size: " + p.bitLength() + "/" + pSize);
95 }
96
97 // System.out.println("P(" + pSize + "): " + p.toString());
98 if (!p.isProbablePrime(128)) {
99 throw new Exception("Good luck, the modulus is composite!");
100 }
101
102 DHPublicKey publicKey = (DHPublicKey)kp.getPublic();
103 p = publicKey.getParams().getP();
104 if (p.bitLength() != pSize) {
105 throw new Exception(
106 "Invalid modulus size: " + p.bitLength() + "/" + pSize);
107 }
108
109 BigInteger leftOpen = BigInteger.ONE;
110 BigInteger rightOpen = p.subtract(BigInteger.ONE);
111
112 // ignore the private key range checking on Solaris at present
113 if (!provider.getName().equals("SunPKCS11-Solaris")) {
114 BigInteger x = privateKey.getX();
115 if ((x.compareTo(leftOpen) <= 0) ||
116 (x.compareTo(rightOpen) >= 0)) {
117 throw new Exception(
118 "X outside range [2, p - 2]: x: " + x + " p: " + p);
119 }
120 }
121
122 BigInteger y = publicKey.getY();
123 if ((y.compareTo(leftOpen) <= 0) ||
124 (y.compareTo(rightOpen) >= 0)) {
125 throw new Exception(
126 "Y outside range [2, p - 2]: y: " + y + " p: " + p);
127 }
128 }
129
130 public static void main(String[] args) throws Exception {
131 main(new SupportedDHKeys(), args);
132 }
133 }