1 /* 2 * Copyright (c) 2003, 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 sun.security.pkcs11; 27 28 import java.security.*; 29 import java.security.spec.AlgorithmParameterSpec; 30 import java.security.spec.*; 31 32 import java.util.Locale; 33 34 import javax.crypto.*; 35 import javax.crypto.spec.*; 36 37 import static sun.security.pkcs11.TemplateManager.*; 38 import sun.security.pkcs11.wrapper.*; 39 import static sun.security.pkcs11.wrapper.PKCS11Constants.*; 40 import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; 41 import sun.security.util.KeyUtil; 42 43 /** 44 * RSA Cipher implementation class. We currently only support 45 * PKCS#1 v1.5 padding on top of CKM_RSA_PKCS. 46 * 47 * @author Andreas Sterbenz 48 * @since 1.5 49 */ 50 final class P11RSACipher extends CipherSpi { 51 52 // minimum length of PKCS#1 v1.5 padding 53 private final static int PKCS1_MIN_PADDING_LENGTH = 11; 54 55 // constant byte[] of length 0 56 private final static byte[] B0 = new byte[0]; 57 58 // mode constant for public key encryption 59 private final static int MODE_ENCRYPT = 1; 60 // mode constant for private key decryption 61 private final static int MODE_DECRYPT = 2; 62 // mode constant for private key encryption (signing) 63 private final static int MODE_SIGN = 3; 64 // mode constant for public key decryption (verifying) 65 private final static int MODE_VERIFY = 4; 66 67 // padding type constant for NoPadding 68 private final static int PAD_NONE = 1; 69 // padding type constant for PKCS1Padding 70 private final static int PAD_PKCS1 = 2; 71 72 // token instance 73 private final Token token; 74 75 // algorithm name (always "RSA") 76 private final String algorithm; 77 78 // mechanism id 79 private final long mechanism; 80 81 // associated session, if any 82 private Session session; 83 84 // mode, one of MODE_* above 85 private int mode; 86 87 // padding, one of PAD_* above 88 private int padType; 89 90 private byte[] buffer; 91 private int bufOfs; 92 93 // key, if init() was called 94 private P11Key p11Key; 95 96 // flag indicating whether an operation is initialized 97 private boolean initialized; 98 99 // maximum input data size allowed 100 // for decryption, this is the length of the key 101 // for encryption, length of the key minus minimum padding length 102 private int maxInputSize; 103 104 // maximum output size. this is the length of the key 105 private int outputSize; 106 107 // cipher parameter for TLS RSA premaster secret 108 private AlgorithmParameterSpec spec = null; 109 110 // the source of randomness 111 private SecureRandom random; 112 113 P11RSACipher(Token token, String algorithm, long mechanism) 114 throws PKCS11Exception { 115 super(); 116 this.token = token; 117 this.algorithm = "RSA"; 118 this.mechanism = mechanism; 119 } 120 121 // modes do not make sense for RSA, but allow ECB 122 // see JCE spec 123 protected void engineSetMode(String mode) throws NoSuchAlgorithmException { 124 if (mode.equalsIgnoreCase("ECB") == false) { 125 throw new NoSuchAlgorithmException("Unsupported mode " + mode); 126 } 127 } 128 129 protected void engineSetPadding(String padding) 130 throws NoSuchPaddingException { 131 String lowerPadding = padding.toLowerCase(Locale.ENGLISH); 132 if (lowerPadding.equals("pkcs1padding")) { 133 padType = PAD_PKCS1; 134 } else if (lowerPadding.equals("nopadding")) { 135 padType = PAD_NONE; 136 } else { 137 throw new NoSuchPaddingException("Unsupported padding " + padding); 138 } 139 } 140 141 // return 0 as block size, we are not a block cipher 142 // see JCE spec 143 protected int engineGetBlockSize() { 144 return 0; 145 } 146 147 // return the output size 148 // see JCE spec 149 protected int engineGetOutputSize(int inputLen) { 150 return outputSize; 151 } 152 153 // no IV, return null 154 // see JCE spec 155 protected byte[] engineGetIV() { 156 return null; 157 } 158 159 // no parameters, return null 160 // see JCE spec 161 protected AlgorithmParameters engineGetParameters() { 162 return null; 163 } 164 165 // see JCE spec 166 protected void engineInit(int opmode, Key key, SecureRandom random) 167 throws InvalidKeyException { 168 implInit(opmode, key); 169 } 170 171 // see JCE spec 172 protected void engineInit(int opmode, Key key, 173 AlgorithmParameterSpec params, SecureRandom random) 174 throws InvalidKeyException, InvalidAlgorithmParameterException { 175 if (params != null) { 176 if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) { 177 throw new InvalidAlgorithmParameterException( 178 "Parameters not supported"); 179 } 180 spec = params; 181 this.random = random; // for TLS RSA premaster secret 182 } 183 implInit(opmode, key); 184 } 185 186 // see JCE spec 187 protected void engineInit(int opmode, Key key, AlgorithmParameters params, 188 SecureRandom random) 189 throws InvalidKeyException, InvalidAlgorithmParameterException { 190 if (params != null) { 191 throw new InvalidAlgorithmParameterException( 192 "Parameters not supported"); 193 } 194 implInit(opmode, key); 195 } 196 197 private void implInit(int opmode, Key key) throws InvalidKeyException { 198 cancelOperation(); 199 p11Key = P11KeyFactory.convertKey(token, key, algorithm); 200 boolean encrypt; 201 if (opmode == Cipher.ENCRYPT_MODE) { 202 encrypt = true; 203 } else if (opmode == Cipher.DECRYPT_MODE) { 204 encrypt = false; 205 } else if (opmode == Cipher.WRAP_MODE) { 206 if (p11Key.isPublic() == false) { 207 throw new InvalidKeyException 208 ("Wrap has to be used with public keys"); 209 } 210 // No further setup needed for C_Wrap(). We'll initialize later if 211 // we can't use C_Wrap(). 212 return; 213 } else if (opmode == Cipher.UNWRAP_MODE) { 214 if (p11Key.isPrivate() == false) { 215 throw new InvalidKeyException 216 ("Unwrap has to be used with private keys"); 217 } 218 // No further setup needed for C_Unwrap(). We'll initialize later 219 // if we can't use C_Unwrap(). 220 return; 221 } else { 222 throw new InvalidKeyException("Unsupported mode: " + opmode); 223 } 224 if (p11Key.isPublic()) { 225 mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY; 226 } else if (p11Key.isPrivate()) { 227 mode = encrypt ? MODE_SIGN : MODE_DECRYPT; 228 } else { 229 throw new InvalidKeyException("Unknown key type: " + p11Key); 230 } 231 int n = (p11Key.length() + 7) >> 3; 232 outputSize = n; 233 buffer = new byte[n]; 234 maxInputSize = ((padType == PAD_PKCS1 && encrypt) ? 235 (n - PKCS1_MIN_PADDING_LENGTH) : n); 236 try { 237 initialize(); 238 } catch (PKCS11Exception e) { 239 throw new InvalidKeyException("init() failed", e); 240 } 241 } 242 243 private void cancelOperation() { 244 token.ensureValid(); 245 if (initialized == false) { 246 return; 247 } 248 initialized = false; 249 if ((session == null) || (token.explicitCancel == false)) { 250 return; 251 } 252 if (session.hasObjects() == false) { 253 session = token.killSession(session); 254 return; 255 } 256 try { 257 PKCS11 p11 = token.p11; 258 int inLen = maxInputSize; 259 int outLen = buffer.length; 260 switch (mode) { 261 case MODE_ENCRYPT: 262 p11.C_Encrypt 263 (session.id(), buffer, 0, inLen, buffer, 0, outLen); 264 break; 265 case MODE_DECRYPT: 266 p11.C_Decrypt 267 (session.id(), buffer, 0, inLen, buffer, 0, outLen); 268 break; 269 case MODE_SIGN: 270 byte[] tmpBuffer = new byte[maxInputSize]; 271 p11.C_Sign 272 (session.id(), tmpBuffer); 273 break; 274 case MODE_VERIFY: 275 p11.C_VerifyRecover 276 (session.id(), buffer, 0, inLen, buffer, 0, outLen); 277 break; 278 default: 279 throw new ProviderException("internal error"); 280 } 281 } catch (PKCS11Exception e) { 282 // XXX ensure this always works, ignore error 283 } 284 } 285 286 private void ensureInitialized() throws PKCS11Exception { 287 token.ensureValid(); 288 if (initialized == false) { 289 initialize(); 290 } 291 } 292 293 private void initialize() throws PKCS11Exception { 294 if (session == null) { 295 session = token.getOpSession(); 296 } 297 PKCS11 p11 = token.p11; 298 CK_MECHANISM ckMechanism = new CK_MECHANISM(mechanism); 299 switch (mode) { 300 case MODE_ENCRYPT: 301 p11.C_EncryptInit(session.id(), ckMechanism, p11Key.keyID); 302 break; 303 case MODE_DECRYPT: 304 p11.C_DecryptInit(session.id(), ckMechanism, p11Key.keyID); 305 break; 306 case MODE_SIGN: 307 p11.C_SignInit(session.id(), ckMechanism, p11Key.keyID); 308 break; 309 case MODE_VERIFY: 310 p11.C_VerifyRecoverInit(session.id(), ckMechanism, p11Key.keyID); 311 break; 312 default: 313 throw new AssertionError("internal error"); 314 } 315 bufOfs = 0; 316 initialized = true; 317 } 318 319 private void implUpdate(byte[] in, int inOfs, int inLen) { 320 try { 321 ensureInitialized(); 322 } catch (PKCS11Exception e) { 323 throw new ProviderException("update() failed", e); 324 } 325 if ((inLen == 0) || (in == null)) { 326 return; 327 } 328 if (bufOfs + inLen > maxInputSize) { 329 bufOfs = maxInputSize + 1; 330 return; 331 } 332 System.arraycopy(in, inOfs, buffer, bufOfs, inLen); 333 bufOfs += inLen; 334 } 335 336 private int implDoFinal(byte[] out, int outOfs, int outLen) 337 throws BadPaddingException, IllegalBlockSizeException { 338 if (bufOfs > maxInputSize) { 339 throw new IllegalBlockSizeException("Data must not be longer " 340 + "than " + maxInputSize + " bytes"); 341 } 342 try { 343 ensureInitialized(); 344 PKCS11 p11 = token.p11; 345 int n; 346 switch (mode) { 347 case MODE_ENCRYPT: 348 n = p11.C_Encrypt 349 (session.id(), buffer, 0, bufOfs, out, outOfs, outLen); 350 break; 351 case MODE_DECRYPT: 352 n = p11.C_Decrypt 353 (session.id(), buffer, 0, bufOfs, out, outOfs, outLen); 354 break; 355 case MODE_SIGN: 356 byte[] tmpBuffer = new byte[bufOfs]; 357 System.arraycopy(buffer, 0, tmpBuffer, 0, bufOfs); 358 tmpBuffer = p11.C_Sign(session.id(), tmpBuffer); 359 if (tmpBuffer.length > outLen) { 360 throw new BadPaddingException("Output buffer too small"); 361 } 362 System.arraycopy(tmpBuffer, 0, out, outOfs, tmpBuffer.length); 363 n = tmpBuffer.length; 364 break; 365 case MODE_VERIFY: 366 n = p11.C_VerifyRecover 367 (session.id(), buffer, 0, bufOfs, out, outOfs, outLen); 368 break; 369 default: 370 throw new ProviderException("internal error"); 371 } 372 return n; 373 } catch (PKCS11Exception e) { 374 throw (BadPaddingException)new BadPaddingException 375 ("doFinal() failed").initCause(e); 376 } finally { 377 initialized = false; 378 session = token.releaseSession(session); 379 } 380 } 381 382 // see JCE spec 383 protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) { 384 implUpdate(in, inOfs, inLen); 385 return B0; 386 } 387 388 // see JCE spec 389 protected int engineUpdate(byte[] in, int inOfs, int inLen, 390 byte[] out, int outOfs) throws ShortBufferException { 391 implUpdate(in, inOfs, inLen); 392 return 0; 393 } 394 395 // see JCE spec 396 protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen) 397 throws IllegalBlockSizeException, BadPaddingException { 398 implUpdate(in, inOfs, inLen); 399 int n = implDoFinal(buffer, 0, buffer.length); 400 byte[] out = new byte[n]; 401 System.arraycopy(buffer, 0, out, 0, n); 402 return out; 403 } 404 405 // see JCE spec 406 protected int engineDoFinal(byte[] in, int inOfs, int inLen, 407 byte[] out, int outOfs) throws ShortBufferException, 408 IllegalBlockSizeException, BadPaddingException { 409 implUpdate(in, inOfs, inLen); 410 return implDoFinal(out, outOfs, out.length - outOfs); 411 } 412 413 private byte[] doFinal() throws BadPaddingException, 414 IllegalBlockSizeException { 415 byte[] t = new byte[2048]; 416 int n = implDoFinal(t, 0, t.length); 417 byte[] out = new byte[n]; 418 System.arraycopy(t, 0, out, 0, n); 419 return out; 420 } 421 422 // see JCE spec 423 protected byte[] engineWrap(Key key) throws InvalidKeyException, 424 IllegalBlockSizeException { 425 String keyAlg = key.getAlgorithm(); 426 P11Key sKey = null; 427 try { 428 // The conversion may fail, e.g. trying to wrap an AES key on 429 // a token that does not support AES, or when the key size is 430 // not within the range supported by the token. 431 sKey = P11SecretKeyFactory.convertKey(token, key, keyAlg); 432 } catch (InvalidKeyException ike) { 433 byte[] toBeWrappedKey = key.getEncoded(); 434 if (toBeWrappedKey == null) { 435 throw new InvalidKeyException 436 ("wrap() failed, no encoding available", ike); 437 } 438 // Directly encrypt the key encoding when key conversion failed 439 implInit(Cipher.ENCRYPT_MODE, p11Key); 440 implUpdate(toBeWrappedKey, 0, toBeWrappedKey.length); 441 try { 442 return doFinal(); 443 } catch (BadPaddingException bpe) { 444 // should not occur 445 throw new InvalidKeyException("wrap() failed", bpe); 446 } finally { 447 // Restore original mode 448 implInit(Cipher.WRAP_MODE, p11Key); 449 } 450 } 451 Session s = null; 452 try { 453 s = token.getOpSession(); 454 return token.p11.C_WrapKey(s.id(), new CK_MECHANISM(mechanism), 455 p11Key.keyID, sKey.keyID); 456 } catch (PKCS11Exception e) { 457 throw new InvalidKeyException("wrap() failed", e); 458 } finally { 459 token.releaseSession(s); 460 } 461 } 462 463 // see JCE spec 464 protected Key engineUnwrap(byte[] wrappedKey, String algorithm, 465 int type) throws InvalidKeyException, NoSuchAlgorithmException { 466 467 boolean isTlsRsaPremasterSecret = 468 algorithm.equals("TlsRsaPremasterSecret"); 469 Exception failover = null; 470 471 SecureRandom secureRandom = random; 472 if (secureRandom == null && isTlsRsaPremasterSecret) { 473 secureRandom = new SecureRandom(); 474 } 475 476 // Should C_Unwrap be preferred for non-TLS RSA premaster secret? 477 if (token.supportsRawSecretKeyImport()) { 478 // XXX implement unwrap using C_Unwrap() for all keys 479 implInit(Cipher.DECRYPT_MODE, p11Key); 480 if (wrappedKey.length > maxInputSize) { 481 throw new InvalidKeyException("Key is too long for unwrapping"); 482 } 483 484 byte[] encoded = null; 485 implUpdate(wrappedKey, 0, wrappedKey.length); 486 try { 487 encoded = doFinal(); 488 } catch (BadPaddingException e) { 489 if (isTlsRsaPremasterSecret) { 490 failover = e; 491 } else { 492 throw new InvalidKeyException("Unwrapping failed", e); 493 } 494 } catch (IllegalBlockSizeException e) { 495 // should not occur, handled with length check above 496 throw new InvalidKeyException("Unwrapping failed", e); 497 } 498 499 if (isTlsRsaPremasterSecret) { 500 if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) { 501 throw new IllegalStateException( 502 "No TlsRsaPremasterSecretParameterSpec specified"); 503 } 504 505 // polish the TLS premaster secret 506 TlsRsaPremasterSecretParameterSpec psps = 507 (TlsRsaPremasterSecretParameterSpec)spec; 508 encoded = KeyUtil.checkTlsPreMasterSecretKey( 509 psps.getClientVersion(), psps.getServerVersion(), 510 secureRandom, encoded, (failover != null)); 511 } 512 513 return ConstructKeys.constructKey(encoded, algorithm, type); 514 } else { 515 Session s = null; 516 SecretKey secretKey = null; 517 try { 518 try { 519 s = token.getObjSession(); 520 long keyType = CKK_GENERIC_SECRET; 521 CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] { 522 new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY), 523 new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType), 524 }; 525 attributes = token.getAttributes( 526 O_IMPORT, CKO_SECRET_KEY, keyType, attributes); 527 long keyID = token.p11.C_UnwrapKey(s.id(), 528 new CK_MECHANISM(mechanism), p11Key.keyID, 529 wrappedKey, attributes); 530 secretKey = P11Key.secretKey(s, keyID, 531 algorithm, 48 << 3, attributes); 532 } catch (PKCS11Exception e) { 533 if (isTlsRsaPremasterSecret) { 534 failover = e; 535 } else { 536 throw new InvalidKeyException("unwrap() failed", e); 537 } 538 } 539 540 if (isTlsRsaPremasterSecret) { 541 byte[] replacer = new byte[48]; 542 if (failover == null) { 543 // Does smart compiler dispose this operation? 544 secureRandom.nextBytes(replacer); 545 } 546 547 TlsRsaPremasterSecretParameterSpec psps = 548 (TlsRsaPremasterSecretParameterSpec)spec; 549 550 // Please use the tricky failover and replacer byte array 551 // as the parameters so that smart compiler won't dispose 552 // the unused variable . 553 secretKey = polishPreMasterSecretKey(token, s, 554 failover, replacer, secretKey, 555 psps.getClientVersion(), psps.getServerVersion()); 556 } 557 558 return secretKey; 559 } finally { 560 token.releaseSession(s); 561 } 562 } 563 } 564 565 // see JCE spec 566 protected int engineGetKeySize(Key key) throws InvalidKeyException { 567 int n = P11KeyFactory.convertKey(token, key, algorithm).length(); 568 return n; 569 } 570 571 private static SecretKey polishPreMasterSecretKey( 572 Token token, Session session, 573 Exception failover, byte[] replacer, SecretKey secretKey, 574 int clientVersion, int serverVersion) { 575 576 if (failover != null) { 577 CK_VERSION version = new CK_VERSION( 578 (clientVersion >>> 8) & 0xFF, clientVersion & 0xFF); 579 try { 580 CK_ATTRIBUTE[] attributes = token.getAttributes( 581 O_GENERATE, CKO_SECRET_KEY, 582 CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]); 583 long keyID = token.p11.C_GenerateKey(session.id(), 584 // new CK_MECHANISM(CKM_TLS_PRE_MASTER_KEY_GEN, version), 585 new CK_MECHANISM(CKM_SSL3_PRE_MASTER_KEY_GEN, version), 586 attributes); 587 return P11Key.secretKey(session, 588 keyID, "TlsRsaPremasterSecret", 48 << 3, attributes); 589 } catch (PKCS11Exception e) { 590 throw new ProviderException( 591 "Could not generate premaster secret", e); 592 } 593 } 594 595 return secretKey; 596 } 597 598 } 599 600 final class ConstructKeys { 601 /** 602 * Construct a public key from its encoding. 603 * 604 * @param encodedKey the encoding of a public key. 605 * 606 * @param encodedKeyAlgorithm the algorithm the encodedKey is for. 607 * 608 * @return a public key constructed from the encodedKey. 609 */ 610 private static final PublicKey constructPublicKey(byte[] encodedKey, 611 String encodedKeyAlgorithm) 612 throws InvalidKeyException, NoSuchAlgorithmException { 613 try { 614 KeyFactory keyFactory = 615 KeyFactory.getInstance(encodedKeyAlgorithm); 616 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey); 617 return keyFactory.generatePublic(keySpec); 618 } catch (NoSuchAlgorithmException nsae) { 619 throw new NoSuchAlgorithmException("No installed providers " + 620 "can create keys for the " + 621 encodedKeyAlgorithm + 622 "algorithm", nsae); 623 } catch (InvalidKeySpecException ike) { 624 throw new InvalidKeyException("Cannot construct public key", ike); 625 } 626 } 627 628 /** 629 * Construct a private key from its encoding. 630 * 631 * @param encodedKey the encoding of a private key. 632 * 633 * @param encodedKeyAlgorithm the algorithm the wrapped key is for. 634 * 635 * @return a private key constructed from the encodedKey. 636 */ 637 private static final PrivateKey constructPrivateKey(byte[] encodedKey, 638 String encodedKeyAlgorithm) throws InvalidKeyException, 639 NoSuchAlgorithmException { 640 try { 641 KeyFactory keyFactory = 642 KeyFactory.getInstance(encodedKeyAlgorithm); 643 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey); 644 return keyFactory.generatePrivate(keySpec); 645 } catch (NoSuchAlgorithmException nsae) { 646 throw new NoSuchAlgorithmException("No installed providers " + 647 "can create keys for the " + 648 encodedKeyAlgorithm + 649 "algorithm", nsae); 650 } catch (InvalidKeySpecException ike) { 651 throw new InvalidKeyException("Cannot construct private key", ike); 652 } 653 } 654 655 /** 656 * Construct a secret key from its encoding. 657 * 658 * @param encodedKey the encoding of a secret key. 659 * 660 * @param encodedKeyAlgorithm the algorithm the secret key is for. 661 * 662 * @return a secret key constructed from the encodedKey. 663 */ 664 private static final SecretKey constructSecretKey(byte[] encodedKey, 665 String encodedKeyAlgorithm) { 666 return new SecretKeySpec(encodedKey, encodedKeyAlgorithm); 667 } 668 669 static final Key constructKey(byte[] encoding, String keyAlgorithm, 670 int keyType) throws InvalidKeyException, NoSuchAlgorithmException { 671 switch (keyType) { 672 case Cipher.SECRET_KEY: 673 return constructSecretKey(encoding, keyAlgorithm); 674 case Cipher.PRIVATE_KEY: 675 return constructPrivateKey(encoding, keyAlgorithm); 676 case Cipher.PUBLIC_KEY: 677 return constructPublicKey(encoding, keyAlgorithm); 678 default: 679 throw new InvalidKeyException("Unknown keytype " + keyType); 680 } 681 } 682 }