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 26 package com.sun.crypto.provider; 27 28 import java.math.BigInteger; 29 import java.security.*; 30 import java.security.spec.*; 31 import javax.crypto.spec.DHParameterSpec; 32 import 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 */ 50 public 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 % 64 == 0))); 66 67 if (!supported) { 68 throw new InvalidParameterException 69 ("Keysize must be multiple of 64 and range " 70 + "from 512 to 1024 (inclusive), or 2048, 3072"); 71 } 72 } 73 74 /** 75 * Initializes this parameter generator for a certain keysize 76 * and source of randomness. 77 * The keysize is specified as the size in bits of the prime modulus. 78 * 79 * @param keysize the keysize (size of prime modulus) in bits 80 * @param random the source of randomness 81 */ 82 @Override 83 protected void engineInit(int keysize, SecureRandom random) { 84 checkKeySize(keysize); 85 this.primeSize = keysize; 86 this.random = random; 87 } 88 89 /** 90 * Initializes this parameter generator with a set of parameter 91 * generation values, which specify the size of the prime modulus and 92 * the size of the random exponent, both in bits. 93 * 94 * @param genParamSpec the set of parameter generation values 95 * @param random the source of randomness 96 * 97 * @exception InvalidAlgorithmParameterException if the given parameter 98 * generation values are inappropriate for this parameter generator 99 */ 100 @Override 101 protected void engineInit(AlgorithmParameterSpec genParamSpec, 102 SecureRandom random) throws InvalidAlgorithmParameterException { 103 104 if (!(genParamSpec instanceof DHGenParameterSpec)) { 105 throw new InvalidAlgorithmParameterException 106 ("Inappropriate parameter type"); 107 } 108 109 DHGenParameterSpec dhParamSpec = (DHGenParameterSpec)genParamSpec; 110 primeSize = dhParamSpec.getPrimeSize(); 111 exponentSize = dhParamSpec.getExponentSize(); 112 if ((exponentSize <= 0) || (exponentSize >= primeSize)) { 113 throw new InvalidAlgorithmParameterException( 114 "Exponent size must be positive and less than modulus size"); 115 } 116 try { 117 checkKeySize(primeSize); 118 } catch (InvalidParameterException ipe) { 119 throw new InvalidAlgorithmParameterException(ipe.getMessage()); 120 } 121 122 this.random = random; 123 } 124 125 /** 126 * Generates the parameters. 127 * 128 * @return the new AlgorithmParameters object 129 */ 130 @Override 131 protected AlgorithmParameters engineGenerateParameters() { 132 133 if (random == null) { 134 random = SunJCE.getRandom(); 135 } 136 137 BigInteger paramP = null; 138 BigInteger paramG = null; 139 try { 140 AlgorithmParameterGenerator dsaParamGen = 141 AlgorithmParameterGenerator.getInstance("DSA"); 142 dsaParamGen.init(primeSize, random); 143 AlgorithmParameters dsaParams = dsaParamGen.generateParameters(); 144 DSAParameterSpec dsaParamSpec = 145 dsaParams.getParameterSpec(DSAParameterSpec.class); 146 147 DHParameterSpec dhParamSpec; 148 if (this.exponentSize > 0) { 149 dhParamSpec = new DHParameterSpec(dsaParamSpec.getP(), 150 dsaParamSpec.getG(), 151 this.exponentSize); 152 } else { 153 dhParamSpec = new DHParameterSpec(dsaParamSpec.getP(), 154 dsaParamSpec.getG()); 155 } 156 AlgorithmParameters algParams = 157 AlgorithmParameters.getInstance("DH", SunJCE.getInstance()); 158 algParams.init(dhParamSpec); 159 160 return algParams; 161 } catch (Exception ex) { 162 throw new ProviderException("Unexpected exception: " + ex); 163 } 164 } 165 }