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.security.*; 29 import java.security.spec.*; 30 import javax.crypto.spec.DHParameterSpec; 31 import javax.crypto.spec.DHGenParameterSpec; 32 33 /* 34 * This class generates parameters for the Diffie-Hellman algorithm. 35 * The parameters are a prime, a base, and optionally the length in bits of 36 * the private value. 37 * 38 * <p>The Diffie-Hellman parameter generation accepts the size in bits of the 39 * prime modulus and the size in bits of the random exponent as input. 40 * The size of the prime modulus defaults to 2048 bits. 41 * 42 * @author Jan Luehe 43 * 44 * 45 * @see java.security.AlgorithmParameters 46 * @see java.security.spec.AlgorithmParameterSpec 47 * @see DHParameters 48 */ 49 public final class DHParameterGenerator 50 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 InvalidAlgorithmParameterException { 63 if ((keysize != 2048) && 64 ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0))) { 65 throw new InvalidAlgorithmParameterException( 66 "Keysize must be multiple of 64 ranging from " 67 + "512 to 1024 (inclusive), or 2048"); 68 } 69 } 70 71 /** 72 * Initializes this parameter generator for a certain keysize 73 * and source of randomness. 74 * The keysize is specified as the size in bits of the prime modulus. 75 * 76 * @param keysize the keysize (size of prime modulus) in bits 77 * @param random the source of randomness 78 */ 79 protected void engineInit(int keysize, SecureRandom random) { 80 // Re-uses DSA parameters and thus have the same range 81 try { 82 checkKeySize(keysize); 83 } catch (InvalidAlgorithmParameterException ex) { 84 throw new InvalidParameterException(ex.getMessage()); 85 } 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 protected void engineInit(AlgorithmParameterSpec genParamSpec, 102 SecureRandom random) 103 throws InvalidAlgorithmParameterException { 104 if (!(genParamSpec instanceof DHGenParameterSpec)) { 105 throw new InvalidAlgorithmParameterException 106 ("Inappropriate parameter type"); 107 } 108 109 DHGenParameterSpec dhParamSpec = (DHGenParameterSpec)genParamSpec; 110 111 primeSize = dhParamSpec.getPrimeSize(); 112 113 // Re-uses DSA parameters and thus have the same range 114 checkKeySize(primeSize); 115 116 exponentSize = dhParamSpec.getExponentSize(); 117 if (exponentSize <= 0) { 118 throw new InvalidAlgorithmParameterException 119 ("Exponent size must be greater than zero"); 120 } 121 122 // Require exponentSize < primeSize 123 if (exponentSize >= primeSize) { 124 throw new InvalidAlgorithmParameterException 125 ("Exponent size must be less than modulus size"); 126 } 127 } 128 129 /** 130 * Generates the parameters. 131 * 132 * @return the new AlgorithmParameters object 133 */ 134 protected AlgorithmParameters engineGenerateParameters() { 135 AlgorithmParameters algParams = null; 136 137 if (this.exponentSize == 0) { 138 this.exponentSize = this.primeSize - 1; 139 } 140 141 if (this.random == null) 142 this.random = SunJCE.getRandom(); 143 144 try { 145 AlgorithmParameterGenerator paramGen; 146 DSAParameterSpec dsaParamSpec; 147 148 paramGen = AlgorithmParameterGenerator.getInstance("DSA"); 149 paramGen.init(this.primeSize, random); 150 algParams = paramGen.generateParameters(); 151 dsaParamSpec = algParams.getParameterSpec(DSAParameterSpec.class); 152 153 DHParameterSpec dhParamSpec; 154 if (this.exponentSize > 0) { 155 dhParamSpec = new DHParameterSpec(dsaParamSpec.getP(), 156 dsaParamSpec.getG(), 157 this.exponentSize); 158 } else { 159 dhParamSpec = new DHParameterSpec(dsaParamSpec.getP(), 160 dsaParamSpec.getG()); 161 } 162 algParams = AlgorithmParameters.getInstance("DH", 163 SunJCE.getInstance()); 164 algParams.init(dhParamSpec); 165 } catch (InvalidParameterSpecException e) { 166 // this should never happen 167 throw new RuntimeException(e.getMessage()); 168 } catch (NoSuchAlgorithmException e) { 169 // this should never happen, because we provide it 170 throw new RuntimeException(e.getMessage()); 171 } 172 return algParams; 173 } 174 }