1/* 2 * Copyright (c) 1997, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.crypto.provider; 27 28import java.math.BigInteger; 29import java.security.*; 30import java.security.spec.*; 31import javax.crypto.spec.DHParameterSpec; 32import javax.crypto.spec.DHGenParameterSpec; 33 34/* 35 * This class generates parameters for the Diffie-Hellman algorithm. 36 * The parameters are a prime, a base, and optionally the length in bits of 37 * the private value. 38 * 39 * <p>The Diffie-Hellman parameter generation accepts the size in bits of the 40 * prime modulus and the size in bits of the random exponent as input. 41 * The size of the prime modulus defaults to 2048 bits. 42 * 43 * @author Jan Luehe 44 * 45 * 46 * @see java.security.AlgorithmParameters 47 * @see java.security.spec.AlgorithmParameterSpec 48 * @see DHParameters 49 */ 50public final class DHParameterGenerator extends AlgorithmParameterGeneratorSpi { 51 52 // The size in bits of the prime modulus 53 private int primeSize = 2048; 54 55 // The size in bits of the random exponent (private value) 56 private int exponentSize = 0; 57 58 // The source of randomness 59 private SecureRandom random = null; 60 61 private static void checkKeySize(int keysize) 62 throws InvalidParameterException { 63 64 boolean supported = ((keysize == 2048) || (keysize == 3072) || 65 ((keysize >= 512) && (keysize <= 1024) && ((keysize & 0x3F) == 0))); 66 67 if (!supported) { 68 throw new InvalidParameterException( 69 "DH key size must be multiple of 64 and range " + 70 "from 512 to 1024 (inclusive), or 2048, 3072. " + 71 "The specific key size " + keysize + " is not supported"); 72 } 73 } 74 75 /** 76 * Initializes this parameter generator for a certain keysize 77 * and source of randomness. 78 * The keysize is specified as the size in bits of the prime modulus. 79 * 80 * @param keysize the keysize (size of prime modulus) in bits 81 * @param random the source of randomness 82 */ 83 @Override 84 protected void engineInit(int keysize, SecureRandom random) { 85 checkKeySize(keysize); 86 this.primeSize = keysize; 87 this.random = random; 88 } 89 90 /** 91 * Initializes this parameter generator with a set of parameter 92 * generation values, which specify the size of the prime modulus and 93 * the size of the random exponent, both in bits. 94 * 95 * @param genParamSpec the set of parameter generation values 96 * @param random the source of randomness 97 * 98 * @exception InvalidAlgorithmParameterException if the given parameter 99 * generation values are inappropriate for this parameter generator 100 */ 101 @Override 102 protected void engineInit(AlgorithmParameterSpec genParamSpec, 103 SecureRandom random) throws InvalidAlgorithmParameterException { 104 105 if (!(genParamSpec instanceof DHGenParameterSpec)) { 106 throw new InvalidAlgorithmParameterException 107 ("Inappropriate parameter type"); 108 } 109 110 DHGenParameterSpec dhParamSpec = (DHGenParameterSpec)genParamSpec; 111 primeSize = dhParamSpec.getPrimeSize(); 112 exponentSize = dhParamSpec.getExponentSize(); 113 if ((exponentSize <= 0) || (exponentSize >= primeSize)) { 114 throw new InvalidAlgorithmParameterException( 115 "Exponent size (" + exponentSize + 116 ") must be positive and less than modulus size (" + 117 primeSize + ")"); 118 } 119 try { 120 checkKeySize(primeSize); 121 } catch (InvalidParameterException ipe) { 122 throw new InvalidAlgorithmParameterException(ipe.getMessage()); 123 } 124 125 this.random = random; 126 } 127 128 /** 129 * Generates the parameters. 130 * 131 * @return the new AlgorithmParameters object 132 */ 133 @Override 134 protected AlgorithmParameters engineGenerateParameters() { 135 136 if (random == null) { 137 random = SunJCE.getRandom(); 138 } 139 140 BigInteger paramP = null; 141 BigInteger paramG = null; 142 try { 143 AlgorithmParameterGenerator dsaParamGen = 144 AlgorithmParameterGenerator.getInstance("DSA"); 145 dsaParamGen.init(primeSize, random); 146 AlgorithmParameters dsaParams = dsaParamGen.generateParameters(); 147 DSAParameterSpec dsaParamSpec = 148 dsaParams.getParameterSpec(DSAParameterSpec.class); 149 150 DHParameterSpec dhParamSpec; 151 if (this.exponentSize > 0) { 152 dhParamSpec = new DHParameterSpec(dsaParamSpec.getP(), 153 dsaParamSpec.getG(), 154 this.exponentSize); 155 } else { 156 dhParamSpec = new DHParameterSpec(dsaParamSpec.getP(), 157 dsaParamSpec.getG()); 158 } 159 AlgorithmParameters algParams = 160 AlgorithmParameters.getInstance("DH", SunJCE.getInstance()); 161 algParams.init(dhParamSpec); 162 163 return algParams; 164 } catch (Exception ex) { 165 throw new ProviderException("Unexpected exception", ex); 166 } 167 } 168} 169