1 /* 2 * Copyright (c) 2005, 2018, 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 sun.security.mscapi; 27 28 import java.util.UUID; 29 import java.security.*; 30 import java.security.spec.AlgorithmParameterSpec; 31 import java.security.spec.RSAKeyGenParameterSpec; 32 33 import sun.security.rsa.RSAKeyFactory; 34 import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE; 35 36 /** 37 * RSA keypair generator. 38 * 39 * Standard algorithm, minimum key length is 512 bit, maximum is 16,384. 40 * Generates a private key that is exportable. 41 * 42 * @since 1.6 43 */ 44 public abstract class CKeyPairGenerator extends KeyPairGeneratorSpi { 45 46 protected String keyAlg; 47 CKeyPairGenerator(String keyAlg)48 public CKeyPairGenerator(String keyAlg) { 49 this.keyAlg = keyAlg; 50 } 51 52 public static class RSA extends CKeyPairGenerator { RSA()53 public RSA() { 54 super("RSA"); 55 // initialize to default in case the app does not call initialize() 56 initialize(DEF_RSA_KEY_SIZE, null); 57 } 58 59 // Supported by Microsoft Base, Strong and Enhanced Cryptographic Providers 60 static final int KEY_SIZE_MIN = 512; // disallow MSCAPI min. of 384 61 static final int KEY_SIZE_MAX = 16384; 62 63 // size of the key to generate, KEY_SIZE_MIN <= keySize <= KEY_SIZE_MAX 64 private int keySize; 65 66 // initialize the generator. See JCA doc 67 // random is always ignored 68 @Override initialize(int keySize, SecureRandom random)69 public void initialize(int keySize, SecureRandom random) { 70 71 try { 72 RSAKeyFactory.checkKeyLengths(keySize, null, 73 KEY_SIZE_MIN, KEY_SIZE_MAX); 74 } catch (InvalidKeyException e) { 75 throw new InvalidParameterException(e.getMessage()); 76 } 77 78 this.keySize = keySize; 79 } 80 81 // second initialize method. See JCA doc 82 // random and exponent are always ignored 83 @Override initialize(AlgorithmParameterSpec params, SecureRandom random)84 public void initialize(AlgorithmParameterSpec params, SecureRandom random) 85 throws InvalidAlgorithmParameterException { 86 87 int tmpSize; 88 if (params == null) { 89 tmpSize = DEF_RSA_KEY_SIZE; 90 } else if (params instanceof RSAKeyGenParameterSpec) { 91 92 if (((RSAKeyGenParameterSpec) params).getPublicExponent() != null) { 93 throw new InvalidAlgorithmParameterException 94 ("Exponent parameter is not supported"); 95 } 96 tmpSize = ((RSAKeyGenParameterSpec) params).getKeysize(); 97 98 } else { 99 throw new InvalidAlgorithmParameterException 100 ("Params must be an instance of RSAKeyGenParameterSpec"); 101 } 102 103 try { 104 RSAKeyFactory.checkKeyLengths(tmpSize, null, 105 KEY_SIZE_MIN, KEY_SIZE_MAX); 106 } catch (InvalidKeyException e) { 107 throw new InvalidAlgorithmParameterException( 108 "Invalid Key sizes", e); 109 } 110 111 this.keySize = tmpSize; 112 } 113 114 // generate the keypair. See JCA doc 115 @Override generateKeyPair()116 public KeyPair generateKeyPair() { 117 118 try { 119 // Generate each keypair in a unique key container 120 CKeyPair keys = 121 generateCKeyPair(keyAlg, keySize, 122 "{" + UUID.randomUUID().toString() + "}"); 123 return new KeyPair(keys.getPublic(), keys.getPrivate()); 124 125 } catch (KeyException e) { 126 throw new ProviderException(e); 127 } 128 } 129 generateCKeyPair(String alg, int keySize, String keyContainerName)130 private static native CKeyPair generateCKeyPair(String alg, int keySize, 131 String keyContainerName) throws KeyException; 132 } 133 } 134