1 /*
   2  * Copyright (c) 2016, 2020, 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 /test/lib ..
  29  * @modules jdk.crypto.cryptoki
  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         BigInteger x = privateKey.getX();
 113         if ((x.compareTo(leftOpen) <= 0) ||
 114             (x.compareTo(rightOpen) >= 0)) {
 115             throw new Exception(
 116                 "X outside range [2, p - 2]:  x: " + x + " p: " + p);
 117         }
 118 
 119         BigInteger y = publicKey.getY();
 120         if ((y.compareTo(leftOpen) <= 0) ||
 121                 (y.compareTo(rightOpen) >= 0)) {
 122             throw new Exception(
 123                 "Y outside range [2, p - 2]:  y: " + y + " p: " + p);
 124         }
 125     }
 126 
 127     public static void main(String[] args) throws Exception {
 128         main(new SupportedDHKeys(), args);
 129     }
 130 }