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 P11RSAKeyFactory(Token token, String algorithm)49 P11RSAKeyFactory(Token token, String algorithm) { 50 super(token, algorithm); 51 } 52 implTranslatePublicKey(PublicKey key)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 implTranslatePrivateKey(PrivateKey key)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 engineGeneratePublic(KeySpec keySpec)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 engineGeneratePrivate(KeySpec keySpec)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 generatePublic(BigInteger n, BigInteger e)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 generatePrivate(BigInteger n, BigInteger d)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 generatePrivate(BigInteger n, BigInteger e, BigInteger d, BigInteger p, BigInteger q, BigInteger pe, BigInteger qe, BigInteger coeff)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 implGetPublicKeySpec(P11Key key, Class<T> keySpec, Session[] session)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 long keyID = key.getKeyID(); 267 try { 268 token.p11.C_GetAttributeValue(session[0].id(), keyID, attributes); 269 } finally { 270 key.releaseKeyID(); 271 } 272 KeySpec spec = new RSAPublicKeySpec( 273 attributes[0].getBigInteger(), 274 attributes[1].getBigInteger() 275 ); 276 return keySpec.cast(spec); 277 } else { // X.509 handled in superclass 278 throw new InvalidKeySpecException("Only RSAPublicKeySpec and " 279 + "X509EncodedKeySpec supported for RSA public keys"); 280 } 281 } 282 implGetPrivateKeySpec(P11Key key, Class<T> keySpec, Session[] session)283 <T extends KeySpec> T implGetPrivateKeySpec(P11Key key, Class<T> keySpec, 284 Session[] session) throws PKCS11Exception, InvalidKeySpecException { 285 if (RSAPrivateCrtKeySpec.class.isAssignableFrom(keySpec)) { 286 session[0] = token.getObjSession(); 287 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { 288 new CK_ATTRIBUTE(CKA_MODULUS), 289 new CK_ATTRIBUTE(CKA_PUBLIC_EXPONENT), 290 new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT), 291 new CK_ATTRIBUTE(CKA_PRIME_1), 292 new CK_ATTRIBUTE(CKA_PRIME_2), 293 new CK_ATTRIBUTE(CKA_EXPONENT_1), 294 new CK_ATTRIBUTE(CKA_EXPONENT_2), 295 new CK_ATTRIBUTE(CKA_COEFFICIENT), 296 }; 297 long keyID = key.getKeyID(); 298 try { 299 token.p11.C_GetAttributeValue(session[0].id(), keyID, attributes); 300 } finally { 301 key.releaseKeyID(); 302 } 303 304 KeySpec spec = new RSAPrivateCrtKeySpec( 305 attributes[0].getBigInteger(), 306 attributes[1].getBigInteger(), 307 attributes[2].getBigInteger(), 308 attributes[3].getBigInteger(), 309 attributes[4].getBigInteger(), 310 attributes[5].getBigInteger(), 311 attributes[6].getBigInteger(), 312 attributes[7].getBigInteger() 313 ); 314 return keySpec.cast(spec); 315 } else if (RSAPrivateKeySpec.class.isAssignableFrom(keySpec)) { 316 session[0] = token.getObjSession(); 317 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { 318 new CK_ATTRIBUTE(CKA_MODULUS), 319 new CK_ATTRIBUTE(CKA_PRIVATE_EXPONENT), 320 }; 321 long keyID = key.getKeyID(); 322 try { 323 token.p11.C_GetAttributeValue(session[0].id(), keyID, attributes); 324 } finally { 325 key.releaseKeyID(); 326 } 327 328 KeySpec spec = new RSAPrivateKeySpec( 329 attributes[0].getBigInteger(), 330 attributes[1].getBigInteger() 331 ); 332 return keySpec.cast(spec); 333 } else { // PKCS#8 handled in superclass 334 throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec " 335 + "and PKCS8EncodedKeySpec supported for RSA private keys"); 336 } 337 } 338 implGetSoftwareFactory()339 KeyFactory implGetSoftwareFactory() throws GeneralSecurityException { 340 return KeyFactory.getInstance("RSA", P11Util.getSunRsaSignProvider()); 341 } 342 343 } 344