33 |
33 |
34 import javax.crypto.*; |
34 import javax.crypto.*; |
35 import javax.crypto.spec.*; |
35 import javax.crypto.spec.*; |
36 |
36 |
37 import sun.security.rsa.RSAKeyFactory; |
37 import sun.security.rsa.RSAKeyFactory; |
|
38 import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; |
|
39 import sun.security.util.KeyUtil; |
38 |
40 |
39 /** |
41 /** |
40 * RSA cipher implementation using the Microsoft Crypto API. |
42 * RSA cipher implementation using the Microsoft Crypto API. |
41 * Supports RSA en/decryption and signing/verifying using PKCS#1 v1.5 padding. |
43 * Supports RSA en/decryption and signing/verifying using PKCS#1 v1.5 padding. |
42 * |
44 * |
90 // size of the output (the length of the key). |
92 // size of the output (the length of the key). |
91 private int outputSize; |
93 private int outputSize; |
92 |
94 |
93 // the public key, if we were initialized using a public key |
95 // the public key, if we were initialized using a public key |
94 private sun.security.mscapi.Key publicKey; |
96 private sun.security.mscapi.Key publicKey; |
|
97 |
95 // the private key, if we were initialized using a private key |
98 // the private key, if we were initialized using a private key |
96 private sun.security.mscapi.Key privateKey; |
99 private sun.security.mscapi.Key privateKey; |
|
100 |
|
101 // cipher parameter for TLS RSA premaster secret |
|
102 private AlgorithmParameterSpec spec = null; |
|
103 |
|
104 // the source of randomness |
|
105 private SecureRandom random; |
97 |
106 |
98 public RSACipher() { |
107 public RSACipher() { |
99 paddingType = PAD_PKCS1; |
108 paddingType = PAD_PKCS1; |
100 } |
109 } |
101 |
110 |
153 protected void engineInit(int opmode, Key key, |
162 protected void engineInit(int opmode, Key key, |
154 AlgorithmParameterSpec params, SecureRandom random) |
163 AlgorithmParameterSpec params, SecureRandom random) |
155 throws InvalidKeyException, InvalidAlgorithmParameterException { |
164 throws InvalidKeyException, InvalidAlgorithmParameterException { |
156 |
165 |
157 if (params != null) { |
166 if (params != null) { |
158 throw new InvalidAlgorithmParameterException |
167 if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) { |
159 ("Parameters not supported"); |
168 throw new InvalidAlgorithmParameterException( |
|
169 "Parameters not supported"); |
|
170 } |
|
171 spec = params; |
|
172 this.random = random; // for TLS RSA premaster secret |
160 } |
173 } |
161 init(opmode, key); |
174 init(opmode, key); |
162 } |
175 } |
163 |
176 |
164 // see JCE spec |
177 // see JCE spec |
354 throw new InvalidKeyException("Wrapping failed", e); |
367 throw new InvalidKeyException("Wrapping failed", e); |
355 } |
368 } |
356 } |
369 } |
357 |
370 |
358 // see JCE spec |
371 // see JCE spec |
359 protected java.security.Key engineUnwrap(byte[] wrappedKey, String algorithm, |
372 protected java.security.Key engineUnwrap(byte[] wrappedKey, |
|
373 String algorithm, |
360 int type) throws InvalidKeyException, NoSuchAlgorithmException { |
374 int type) throws InvalidKeyException, NoSuchAlgorithmException { |
361 |
375 |
362 if (wrappedKey.length > buffer.length) { |
376 if (wrappedKey.length > buffer.length) { |
363 throw new InvalidKeyException("Key is too long for unwrapping"); |
377 throw new InvalidKeyException("Key is too long for unwrapping"); |
364 } |
378 } |
|
379 |
|
380 boolean isTlsRsaPremasterSecret = |
|
381 algorithm.equals("TlsRsaPremasterSecret"); |
|
382 Exception failover = null; |
|
383 byte[] encoded = null; |
|
384 |
365 update(wrappedKey, 0, wrappedKey.length); |
385 update(wrappedKey, 0, wrappedKey.length); |
366 |
|
367 try { |
386 try { |
368 byte[] encoding = doFinal(); |
387 encoded = doFinal(); |
369 |
388 } catch (BadPaddingException e) { |
370 switch (type) { |
389 if (isTlsRsaPremasterSecret) { |
371 case Cipher.PUBLIC_KEY: |
390 failover = e; |
372 return constructPublicKey(encoding, algorithm); |
391 } else { |
373 |
392 throw new InvalidKeyException("Unwrapping failed", e); |
374 case Cipher.PRIVATE_KEY: |
|
375 return constructPrivateKey(encoding, algorithm); |
|
376 |
|
377 case Cipher.SECRET_KEY: |
|
378 return constructSecretKey(encoding, algorithm); |
|
379 |
|
380 default: |
|
381 throw new InvalidKeyException("Unknown key type " + type); |
|
382 } |
393 } |
383 |
|
384 } catch (BadPaddingException e) { |
|
385 // should not occur |
|
386 throw new InvalidKeyException("Unwrapping failed", e); |
|
387 |
|
388 } catch (IllegalBlockSizeException e) { |
394 } catch (IllegalBlockSizeException e) { |
389 // should not occur, handled with length check above |
395 // should not occur, handled with length check above |
390 throw new InvalidKeyException("Unwrapping failed", e); |
396 throw new InvalidKeyException("Unwrapping failed", e); |
391 } |
397 } |
|
398 |
|
399 if (isTlsRsaPremasterSecret) { |
|
400 if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) { |
|
401 throw new IllegalStateException( |
|
402 "No TlsRsaPremasterSecretParameterSpec specified"); |
|
403 } |
|
404 |
|
405 // polish the TLS premaster secret |
|
406 encoded = KeyUtil.checkTlsPreMasterSecretKey( |
|
407 ((TlsRsaPremasterSecretParameterSpec)spec).getClientVersion(), |
|
408 ((TlsRsaPremasterSecretParameterSpec)spec).getServerVersion(), |
|
409 random, encoded, (failover != null)); |
|
410 } |
|
411 |
|
412 return constructKey(encoded, algorithm, type); |
392 } |
413 } |
393 |
414 |
394 // see JCE spec |
415 // see JCE spec |
395 protected int engineGetKeySize(Key key) throws InvalidKeyException { |
416 protected int engineGetKeySize(Key key) throws InvalidKeyException { |
396 |
417 |
448 // Construct an encoded secret key. |
469 // Construct an encoded secret key. |
449 private static SecretKey constructSecretKey(byte[] encodedKey, |
470 private static SecretKey constructSecretKey(byte[] encodedKey, |
450 String encodedKeyAlgorithm) { |
471 String encodedKeyAlgorithm) { |
451 |
472 |
452 return new SecretKeySpec(encodedKey, encodedKeyAlgorithm); |
473 return new SecretKeySpec(encodedKey, encodedKeyAlgorithm); |
|
474 } |
|
475 |
|
476 private static Key constructKey(byte[] encodedKey, |
|
477 String encodedKeyAlgorithm, |
|
478 int keyType) throws InvalidKeyException, NoSuchAlgorithmException { |
|
479 |
|
480 switch (keyType) { |
|
481 case Cipher.PUBLIC_KEY: |
|
482 return constructPublicKey(encodedKey, encodedKeyAlgorithm); |
|
483 case Cipher.PRIVATE_KEY: |
|
484 return constructPrivateKey(encodedKey, encodedKeyAlgorithm); |
|
485 case Cipher.SECRET_KEY: |
|
486 return constructSecretKey(encodedKey, encodedKeyAlgorithm); |
|
487 default: |
|
488 throw new InvalidKeyException("Unknown key type " + keyType); |
|
489 } |
453 } |
490 } |
454 |
491 |
455 /* |
492 /* |
456 * Encrypt/decrypt a data buffer using Microsoft Crypto API with HCRYPTKEY. |
493 * Encrypt/decrypt a data buffer using Microsoft Crypto API with HCRYPTKEY. |
457 * It expects and returns ciphertext data in big-endian form. |
494 * It expects and returns ciphertext data in big-endian form. |