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 * @library .. 29 * @run main/othervm SupportedDHKeys 30 * @run main/othervm SupportedDHKeys sm 31 */ 32 33 import java.math.BigInteger; 34 35 import java.security.*; 36 import javax.crypto.*; 37 import javax.crypto.interfaces.*; 38 import javax.crypto.spec.*; 39 40 public 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("KeyAgreement", "DH") == null) { 64 System.out.println("DH not supported, skipping"); 65 return; 66 } 67 68 for (SupportedKeySize keySize : SupportedKeySize.values()) { 69 System.out.println("Checking " + keySize.primeSize + " ..."); 70 KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH", provider); 71 kpg.initialize(keySize.primeSize); 72 KeyPair kp = kpg.generateKeyPair(); 73 checkKeyPair(kp, keySize.primeSize); 74 75 DHPublicKey publicKey = (DHPublicKey)kp.getPublic(); 76 BigInteger p = publicKey.getParams().getP(); 77 BigInteger g = publicKey.getParams().getG(); 78 kpg.initialize(new DHParameterSpec(p, g)); 79 kp = kpg.generateKeyPair(); 80 checkKeyPair(kp, keySize.primeSize); 81 } 82 } 83 84 private static void checkKeyPair(KeyPair kp, int pSize) throws Exception { 85 86 DHPrivateKey privateKey = (DHPrivateKey)kp.getPrivate(); 87 BigInteger p = privateKey.getParams().getP(); 88 if (p.bitLength() != pSize) { 89 throw new Exception( 90 "Invalid modulus size: " + p.bitLength() + "/" + pSize); 91 } 92 93 // System.out.println("P(" + pSize + "): " + p.toString()); 94 if (!p.isProbablePrime(128)) { 95 throw new Exception("Good luck, the modulus is composite!"); 96 } 97 98 DHPublicKey publicKey = (DHPublicKey)kp.getPublic(); 99 p = publicKey.getParams().getP(); 100 if (p.bitLength() != pSize) { 101 throw new Exception( 102 "Invalid modulus size: " + p.bitLength() + "/" + pSize); 103 } 104 105 BigInteger leftOpen = BigInteger.ONE; 106 BigInteger rightOpen = p.subtract(BigInteger.ONE); 107 108 BigInteger x = privateKey.getX(); 109 if ((x.compareTo(leftOpen) <= 0) || 110 (x.compareTo(rightOpen) >= 0)) { 111 throw new Exception( 112 "X outside range [2, p - 2]: x: " + x + " p: " + p); 113 } 114 115 BigInteger y = publicKey.getY(); 116 if ((y.compareTo(leftOpen) <= 0) || 117 (y.compareTo(rightOpen) >= 0)) { 118 throw new Exception( 119 "Y outside range [2, p - 2]: x: " + x + " p: " + p); 120 } 121 } 122 123 public static void main(String[] args) throws Exception { 124 main(new SupportedDHKeys(), args); 125 } 126 }