1 /* 2 * Copyright (c) 2003, 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.pkcs11; 27 28 import java.math.BigInteger; 29 30 import java.security.*; 31 import java.security.interfaces.*; 32 import java.security.spec.*; 33 34 import sun.security.rsa.RSAPublicKeyImpl; 35 import static sun.security.pkcs11.TemplateManager.*; 36 import sun.security.pkcs11.wrapper.*; 37 import static sun.security.pkcs11.wrapper.PKCS11Constants.*; 38 39 import sun.security.rsa.RSAKeyFactory; 40 41 /** 42 * RSA KeyFactory implementation. 43 * 44 * @author Andreas Sterbenz 45 * @since 1.5 46 */ 47 final class P11RSAKeyFactory extends P11KeyFactory { 48 49 P11RSAKeyFactory(Token token, String algorithm) { 50 super(token, algorithm); 51 } 52 53 PublicKey implTranslatePublicKey(PublicKey key) throws InvalidKeyException { 54 try { 55 if (key instanceof RSAPublicKey) { 56 RSAPublicKey rsaKey = (RSAPublicKey)key; 57 return generatePublic( 58 rsaKey.getModulus(), 59 rsaKey.getPublicExponent() 60 ); 61 } else if ("X.509".equals(key.getFormat())) { 62 // let SunRsaSign provider parse for us, then recurse 63 byte[] encoded = key.getEncoded(); 64 key = RSAPublicKeyImpl.newKey(encoded); 65 return implTranslatePublicKey(key); 66 } else { 67 throw new InvalidKeyException("PublicKey must be instance " 68 + "of RSAPublicKey or have X.509 encoding"); 69 } 70 } catch (PKCS11Exception e) { 71 throw new InvalidKeyException("Could not create RSA public key", e); 72 } 73 } 74 75 PrivateKey implTranslatePrivateKey(PrivateKey key) 76 throws InvalidKeyException { 77 try { 78 if (key instanceof RSAPrivateCrtKey) { 79 RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key; 80 return generatePrivate( 81 rsaKey.getModulus(), 82 rsaKey.getPublicExponent(), 83 rsaKey.getPrivateExponent(), 84 rsaKey.getPrimeP(), 85 rsaKey.getPrimeQ(), 86 rsaKey.getPrimeExponentP(), 87 rsaKey.getPrimeExponentQ(), 88 rsaKey.getCrtCoefficient() 89 ); 90 } else if (key instanceof RSAPrivateKey) { 91 RSAPrivateKey rsaKey = (RSAPrivateKey)key; 92 return generatePrivate( 93 rsaKey.getModulus(), 94 rsaKey.getPrivateExponent() 95 ); 96 } else if ("PKCS#8".equals(key.getFormat())) { 97 // let SunRsaSign provider parse for us, then recurse 98 byte[] encoded = key.getEncoded(); 99 key = sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded); 100 return implTranslatePrivateKey(key); 101 } else { 102 throw new InvalidKeyException("Private key must be instance " 103 + "of RSAPrivate(Crt)Key or have PKCS#8 encoding"); 104 } 105 } catch (PKCS11Exception e) { 106 throw new InvalidKeyException("Could not create RSA private key", e); 107 } 108 } 109 110 // see JCA spec 111 protected PublicKey engineGeneratePublic(KeySpec keySpec) 112 throws InvalidKeySpecException { 113 token.ensureValid(); 114 if (keySpec instanceof X509EncodedKeySpec) { 115 try { 116 byte[] encoded = ((X509EncodedKeySpec)keySpec).getEncoded(); 117 PublicKey key = RSAPublicKeyImpl.newKey(encoded); 118 return implTranslatePublicKey(key); 119 } catch (InvalidKeyException e) { 120 throw new InvalidKeySpecException 121 ("Could not create RSA public key", e); 122 } 123 } 124 if (keySpec instanceof RSAPublicKeySpec == false) { 125 throw new InvalidKeySpecException("Only RSAPublicKeySpec and " 126 + "X509EncodedKeySpec supported for RSA public keys"); 127 } 128 try { 129 RSAPublicKeySpec rs = (RSAPublicKeySpec)keySpec; 130 return generatePublic( 131 rs.getModulus(), 132 rs.getPublicExponent() 133 ); 134 } catch (PKCS11Exception | InvalidKeyException e) { 135 throw new InvalidKeySpecException 136 ("Could not create RSA public key", e); 137 } 138 } 139 140 // see JCA spec 141 protected PrivateKey engineGeneratePrivate(KeySpec keySpec) 142 throws InvalidKeySpecException { 143 token.ensureValid(); 144 if (keySpec instanceof PKCS8EncodedKeySpec) { 145 try { 146 byte[] encoded = ((PKCS8EncodedKeySpec)keySpec).getEncoded(); 147 PrivateKey key = 148 sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(encoded); 149 return implTranslatePrivateKey(key); 150 } catch (GeneralSecurityException e) { 151 throw new InvalidKeySpecException 152 ("Could not create RSA private key", e); 153 } 154 } 155 try { 156 if (keySpec instanceof RSAPrivateCrtKeySpec) { 157 RSAPrivateCrtKeySpec rs = (RSAPrivateCrtKeySpec)keySpec; 158 return generatePrivate( 159 rs.getModulus(), 160 rs.getPublicExponent(), 161 rs.getPrivateExponent(), 162 rs.getPrimeP(), 163 rs.getPrimeQ(), 164 rs.getPrimeExponentP(), 165 rs.getPrimeExponentQ(), 166 rs.getCrtCoefficient() 167 ); 168 } else if (keySpec instanceof RSAPrivateKeySpec) { 169 RSAPrivateKeySpec rs = (RSAPrivateKeySpec)keySpec; 170 return generatePrivate( 171 rs.getModulus(), 172 rs.getPrivateExponent() 173 ); 174 } else { 175 throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec " 176 + "and PKCS8EncodedKeySpec supported for RSA private keys"); 177 } 178 } catch (PKCS11Exception | InvalidKeyException e) { 179 throw new InvalidKeySpecException 180 ("Could not create RSA private key", e); 181 } 182 } 183 184 private PublicKey generatePublic(BigInteger n, BigInteger e) 185 throws PKCS11Exception, InvalidKeyException { 186 RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024); 187 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { 188 new CK_ATTRIBUTE(CKA_CLASS, CKO_PUBLIC_KEY), 189 new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA), 190 new CK_ATTRIBUTE(CKA_MODULUS, n), 191 new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, e), 192 }; 193 attributes = token.getAttributes 194 (O_IMPORT, CKO_PUBLIC_KEY, CKK_RSA, attributes); 195 Session session = null; 196 try { 197 session = token.getObjSession(); 198 long keyID = token.p11.C_CreateObject(session.id(), attributes); 199 return P11Key.publicKey 200 (session, keyID, "RSA", n.bitLength(), attributes); 201 } finally { 202 token.releaseSession(session); 203 } 204 } 205 206 private PrivateKey generatePrivate(BigInteger n, BigInteger d) 207 throws PKCS11Exception, InvalidKeyException { 208 RSAKeyFactory.checkKeyLengths(n.bitLength(), null, -1, 64 * 1024); 209 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { 210 new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY), 211 new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA), 212 new CK_ATTRIBUTE(CKA_MODULUS, n), 213 new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT, d), 214 }; 215 attributes = token.getAttributes 216 (O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attributes); 217 Session session = null; 218 try { 219 session = token.getObjSession(); 220 long keyID = token.p11.C_CreateObject(session.id(), attributes); 221 return P11Key.privateKey 222 (session, keyID, "RSA", n.bitLength(), attributes); 223 } finally { 224 token.releaseSession(session); 225 } 226 } 227 228 private PrivateKey generatePrivate(BigInteger n, BigInteger e, 229 BigInteger d, BigInteger p, BigInteger q, BigInteger pe, 230 BigInteger qe, BigInteger coeff) throws PKCS11Exception, 231 InvalidKeyException { 232 RSAKeyFactory.checkKeyLengths(n.bitLength(), e, -1, 64 * 1024); 233 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { 234 new CK_ATTRIBUTE(CKA_CLASS, CKO_PRIVATE_KEY), 235 new CK_ATTRIBUTE(CKA_KEY_TYPE, CKK_RSA), 236 new CK_ATTRIBUTE(CKA_MODULUS, n), 237 new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT, e), 238 new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT, d), 239 new CK_ATTRIBUTE(CKA_PRIME_1, p), 240 new CK_ATTRIBUTE(CKA_PRIME_2, q), 241 new CK_ATTRIBUTE(CKA_EXPONENT_1, pe), 242 new CK_ATTRIBUTE(CKA_EXPONENT_2, qe), 243 new CK_ATTRIBUTE(CKA_COEFFICIENT, coeff), 244 }; 245 attributes = token.getAttributes 246 (O_IMPORT, CKO_PRIVATE_KEY, CKK_RSA, attributes); 247 Session session = null; 248 try { 249 session = token.getObjSession(); 250 long keyID = token.p11.C_CreateObject(session.id(), attributes); 251 return P11Key.privateKey 252 (session, keyID, "RSA", n.bitLength(), attributes); 253 } finally { 254 token.releaseSession(session); 255 } 256 } 257 258 <T extends KeySpec> T implGetPublicKeySpec(P11Key key, Class<T> keySpec, 259 Session[] session) throws PKCS11Exception, InvalidKeySpecException { 260 if (RSAPublicKeySpec.class.isAssignableFrom(keySpec)) { 261 session[0] = token.getObjSession(); 262 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { 263 new CK_ATTRIBUTE(CKA_MODULUS), 264 new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT), 265 }; 266 token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes); 267 KeySpec spec = new RSAPublicKeySpec( 268 attributes[0].getBigInteger(), 269 attributes[1].getBigInteger() 270 ); 271 return keySpec.cast(spec); 272 } else { // X.509 handled in superclass 273 throw new InvalidKeySpecException("Only RSAPublicKeySpec and " 274 + "X509EncodedKeySpec supported for RSA public keys"); 275 } 276 } 277 278 <T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec, 279 Session[] session) throws PKCS11Exception, InvalidKeySpecException { 280 if (RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) { 281 session[0] = token.getObjSession(); 282 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { 283 new CK_ATTRIBUTE(CKA_MODULUS), 284 new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT), 285 new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT), 286 new CK_ATTRIBUTE(CKA_PRIME_1), 287 new CK_ATTRIBUTE(CKA_PRIME_2), 288 new CK_ATTRIBUTE(CKA_EXPONENT_1), 289 new CK_ATTRIBUTE(CKA_EXPONENT_2), 290 new CK_ATTRIBUTE(CKA_COEFFICIENT), 291 }; 292 token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes); 293 KeySpec spec = new RSAPrivateCrtKeySpec( 294 attributes[0].getBigInteger(), 295 attributes[1].getBigInteger(), 296 attributes[2].getBigInteger(), 297 attributes[3].getBigInteger(), 298 attributes[4].getBigInteger(), 299 attributes[5].getBigInteger(), 300 attributes[6].getBigInteger(), 301 attributes[7].getBigInteger() 302 ); 303 return keySpec.cast(spec); 304 } else if (RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) { 305 session[0] = token.getObjSession(); 306 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { 307 new CK_ATTRIBUTE(CKA_MODULUS), 308 new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT), 309 }; 310 token.p11.C_GetAttributeValue(session[0].id(), key.keyID, attributes); 311 KeySpec spec = new RSAPrivateKeySpec( 312 attributes[0].getBigInteger(), 313 attributes[1].getBigInteger() 314 ); 315 return keySpec.cast(spec); 316 } else { // PKCS#8 handled in superclass 317 throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec " 318 + "and PKCS8EncodedKeySpec supported for RSA private keys"); 319 } 320 } 321 322 KeyFactory implGetSoftwareFactory() throws GeneralSecurityException { 323 return KeyFactory.getInstance("RSA", P11Util.getSunRsaSignProvider()); 324 } 325 326 }