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 */
29
30import java.math.BigInteger;
31
32import java.security.*;
33import javax.crypto.*;
34import javax.crypto.interfaces.*;
35import javax.crypto.spec.*;
36
37public class SupportedDHKeys {
38
39    /*
40     * Sizes and values for various lengths.
41     */
42    private enum SupportedKeySize {
43        dhp512(512),   dhp768(768),    dhp832(832),
44        dhp1024(1024), dhp1536(1536),  dhp2048(2048),
45        dhp3072(3072), dhp4096(4096),  dhp6144(6144),
46        dhp8192(8192);
47
48        final int primeSize;
49
50        SupportedKeySize(int primeSize) {
51            this.primeSize = primeSize;
52        }
53    }
54
55    public static void main(String[] args) throws Exception {
56        for (SupportedKeySize keySize : SupportedKeySize.values()) {
57            System.out.println("Checking " + keySize.primeSize + " ...");
58            KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", "SunJCE");
59            kpg.initialize(keySize.primeSize);
60            KeyPair kp = kpg.generateKeyPair();
61            checkKeyPair(kp, keySize.primeSize);
62
63            DHPublicKey publicKey = (DHPublicKey)kp.getPublic();
64            BigInteger p = publicKey.getParams().getP();
65            BigInteger g = publicKey.getParams().getG();
66            kpg.initialize(new DHParameterSpec(p, g));
67            kp = kpg.generateKeyPair();
68            checkKeyPair(kp, keySize.primeSize);
69        }
70    }
71
72    private static void checkKeyPair(KeyPair kp, int pSize) throws Exception {
73
74        DHPrivateKey privateKey = (DHPrivateKey)kp.getPrivate();
75        BigInteger p = privateKey.getParams().getP();
76        if (p.bitLength() != pSize) {
77            throw new Exception(
78                "Invalid modulus size: " + p.bitLength() + "/" + pSize);
79        }
80
81        // System.out.println("P(" + pSize + "): " + p.toString());
82        if (!p.isProbablePrime(128)) {
83            throw new Exception("Good luck, the modulus is composite!");
84        }
85
86        DHPublicKey publicKey = (DHPublicKey)kp.getPublic();
87        p = publicKey.getParams().getP();
88        if (p.bitLength() != pSize) {
89            throw new Exception(
90                "Invalid modulus size: " + p.bitLength() + "/" + pSize);
91        }
92
93        BigInteger leftOpen = BigInteger.ONE;
94        BigInteger rightOpen = p.subtract(BigInteger.ONE);
95
96        BigInteger x = privateKey.getX();
97        if ((x.compareTo(leftOpen) <= 0) ||
98                (x.compareTo(rightOpen) >= 0)) {
99            throw new Exception(
100                "X outside range [2, p - 2]:  x: " + x + " p: " + p);
101        }
102
103        BigInteger y = publicKey.getY();
104        if ((y.compareTo(leftOpen) <= 0) ||
105                (y.compareTo(rightOpen) >= 0)) {
106            throw new Exception(
107                "Y outside range [2, p - 2]:  x: " + x + " p: " + p);
108        }
109    }
110}
111