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 * @run main/timeout=300 SupportedDHParamGens 512
29 * @run main/timeout=300 SupportedDHParamGens 768
30 * @run main/timeout=300 SupportedDHParamGens 832
31 * @run main/timeout=300 SupportedDHParamGens 1024
32 * @run main/timeout=600 SupportedDHParamGens 2048
33 * @run main/timeout=700 SupportedDHParamGens 3072
34 */
35
36import java.math.BigInteger;
37
38import java.security.*;
39import javax.crypto.*;
40import javax.crypto.interfaces.*;
41import javax.crypto.spec.*;
42
43public class SupportedDHParamGens {
44
45    public static void main(String[] args) throws Exception {
46        int primeSize = Integer.valueOf(args[0]).intValue();
47
48        System.out.println("Checking " + primeSize + " ...");
49        AlgorithmParameterGenerator apg =
50                AlgorithmParameterGenerator.getInstance("DH", "SunJCE");
51        apg.init(primeSize);
52        AlgorithmParameters ap = apg.generateParameters();
53        DHParameterSpec spec = ap.getParameterSpec(DHParameterSpec.class);
54
55        KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", "SunJCE");
56        kpg.initialize(spec);
57        KeyPair kp = kpg.generateKeyPair();
58        checkKeyPair(kp, primeSize);
59    }
60
61    private static void checkKeyPair(KeyPair kp, int pSize) throws Exception {
62
63        DHPrivateKey privateKey = (DHPrivateKey)kp.getPrivate();
64        BigInteger p = privateKey.getParams().getP();
65        if (p.bitLength() != pSize) {
66            throw new Exception(
67                "Invalid modulus size: " + p.bitLength() + "/" + pSize);
68        }
69
70        if (!p.isProbablePrime(128)) {
71            throw new Exception("Good luck, the modulus is composite!");
72        }
73
74        DHPublicKey publicKey = (DHPublicKey)kp.getPublic();
75        p = publicKey.getParams().getP();
76        if (p.bitLength() != pSize) {
77            throw new Exception(
78                "Invalid modulus size: " + p.bitLength() + "/" + pSize);
79        }
80
81        BigInteger leftOpen = BigInteger.ONE;
82        BigInteger rightOpen = p.subtract(BigInteger.ONE);
83
84        BigInteger x = privateKey.getX();
85        if ((x.compareTo(leftOpen) <= 0) ||
86                (x.compareTo(rightOpen) >= 0)) {
87            throw new Exception(
88                "X outside range [2, p - 2]:  x: " + x + " p: " + p);
89        }
90
91        BigInteger y = publicKey.getY();
92        if ((y.compareTo(leftOpen) <= 0) ||
93                (y.compareTo(rightOpen) >= 0)) {
94            throw new Exception(
95                "Y outside range [2, p - 2]:  x: " + x + " p: " + p);
96        }
97    }
98}
99