1 /* 2 * Copyright (c) 1997, 2013, 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 1024 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 = 1024; 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 if ((keysize != 2048) && 64 ((keysize < 512) || (keysize > 1024) || (keysize % 64 != 0))) { 65 throw new InvalidParameterException( 66 "DH key size must be multiple of 64 and range " + 67 "from 512 to 1024 (inclusive), or 2048. " + 68 "The specific key size " + keysize + " is not supported"); 69 } 70 } 71 72 /** 73 * Initializes this parameter generator for a certain keysize 74 * and source of randomness. 75 * The keysize is specified as the size in bits of the prime modulus. 76 * 77 * @param keysize the keysize (size of prime modulus) in bits 78 * @param random the source of randomness 79 */ 80 protected void engineInit(int keysize, SecureRandom random) { 81 // Re-uses DSA parameters and thus have the same range 82 checkKeySize(keysize); 83 this.primeSize = keysize; 84 this.random = random; 85 } 86 87 /** 88 * Initializes this parameter generator with a set of parameter 89 * generation values, which specify the size of the prime modulus and 90 * the size of the random exponent, both in bits. 91 * 92 * @param params the set of parameter generation values 93 * @param random the source of randomness 94 * 95 * @exception InvalidAlgorithmParameterException if the given parameter 96 * generation values are inappropriate for this parameter generator 97 */ 98 protected void engineInit(AlgorithmParameterSpec genParamSpec, 99 SecureRandom random) 100 throws InvalidAlgorithmParameterException { 101 if (!(genParamSpec instanceof DHGenParameterSpec)) { 102 throw new InvalidAlgorithmParameterException 103 ("Inappropriate parameter type"); 104 } 105 106 DHGenParameterSpec dhParamSpec = (DHGenParameterSpec)genParamSpec; 107 108 primeSize = dhParamSpec.getPrimeSize(); 109 110 // Re-uses DSA parameters and thus have the same range 111 try { 112 checkKeySize(primeSize); 113 } catch (InvalidParameterException ipe) { 114 throw new InvalidAlgorithmParameterException(ipe.getMessage()); 115 } 116 117 exponentSize = dhParamSpec.getExponentSize(); 118 if (exponentSize <= 0) { 119 throw new InvalidAlgorithmParameterException 120 ("Exponent size must be greater than zero"); 121 } 122 123 // Require exponentSize < primeSize 124 if (exponentSize >= primeSize) { 125 throw new InvalidAlgorithmParameterException 126 ("Exponent size must be less than modulus size"); 127 } 128 } 129 130 /** 131 * Generates the parameters. 132 * 133 * @return the new AlgorithmParameters object 134 */ 135 protected AlgorithmParameters engineGenerateParameters() { 136 AlgorithmParameters algParams = null; 137 138 if (this.exponentSize == 0) { 139 this.exponentSize = this.primeSize - 1; 140 } 141 142 if (this.random == null) 143 this.random = SunJCE.getRandom(); 144 145 try { 146 AlgorithmParameterGenerator paramGen; 147 DSAParameterSpec dsaParamSpec; 148 149 paramGen = AlgorithmParameterGenerator.getInstance("DSA"); 150 paramGen.init(this.primeSize, random); 151 algParams = paramGen.generateParameters(); 152 dsaParamSpec = algParams.getParameterSpec(DSAParameterSpec.class); 153 154 DHParameterSpec dhParamSpec; 155 if (this.exponentSize > 0) { 156 dhParamSpec = new DHParameterSpec(dsaParamSpec.getP(), 157 dsaParamSpec.getG(), 158 this.exponentSize); 159 } else { 160 dhParamSpec = new DHParameterSpec(dsaParamSpec.getP(), 161 dsaParamSpec.getG()); 162 } 163 algParams = AlgorithmParameters.getInstance("DH", 164 SunJCE.getInstance()); 165 algParams.init(dhParamSpec); 166 } catch (InvalidParameterSpecException e) { 167 // this should never happen 168 throw new RuntimeException(e.getMessage()); 169 } catch (NoSuchAlgorithmException e) { 170 // this should never happen, because we provide it 171 throw new RuntimeException(e.getMessage()); 172 } 173 return algParams; 174 } 175 }