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