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
  28  * @run main/timeout=300 SupportedDHParaGens 512
  29  * @run main/timeout=300 SupportedDHParaGens 768
  30  * @run main/timeout=300 SupportedDHParaGens 832
  31  * @run main/timeout=300 SupportedDHParaGens 1024
  32  * @run main/timeout=300 SupportedDHParaGens 2048
  33  * @run main/timeout=450 SupportedDHParaGens 3072
  34  */
  35 
  36 import java.math.BigInteger;
  37 
  38 import java.security.*;
  39 import javax.crypto.*;
  40 import javax.crypto.interfaces.*;
  41 import javax.crypto.spec.*;
  42 
  43 public class SupportedDHParaGens {
  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 }