1 /* |
1 /* |
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
37 import javax.crypto.spec.PSource; |
37 import javax.crypto.spec.PSource; |
38 import javax.crypto.spec.OAEPParameterSpec; |
38 import javax.crypto.spec.OAEPParameterSpec; |
39 |
39 |
40 import sun.security.rsa.*; |
40 import sun.security.rsa.*; |
41 import sun.security.jca.Providers; |
41 import sun.security.jca.Providers; |
|
42 import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; |
|
43 import sun.security.util.KeyUtil; |
42 |
44 |
43 /** |
45 /** |
44 * RSA cipher implementation. Supports RSA en/decryption and signing/verifying |
46 * RSA cipher implementation. Supports RSA en/decryption and signing/verifying |
45 * using PKCS#1 v1.5 padding and without padding (raw RSA). Note that raw RSA |
47 * using PKCS#1 v1.5 padding and without padding (raw RSA). Note that raw RSA |
46 * is supported mostly for completeness and should only be used in rare cases. |
48 * is supported mostly for completeness and should only be used in rare cases. |
89 private String paddingType; |
91 private String paddingType; |
90 |
92 |
91 // padding object |
93 // padding object |
92 private RSAPadding padding; |
94 private RSAPadding padding; |
93 |
95 |
94 // cipher parameter for OAEP padding |
96 // cipher parameter for OAEP padding and TLS RSA premaster secret |
95 private OAEPParameterSpec spec = null; |
97 private AlgorithmParameterSpec spec = null; |
96 |
98 |
97 // buffer for the data |
99 // buffer for the data |
98 private byte[] buffer; |
100 private byte[] buffer; |
99 // offset into the buffer (number of bytes buffered) |
101 // offset into the buffer (number of bytes buffered) |
100 private int bufOfs; |
102 private int bufOfs; |
107 // the private key, if we were initialized using a private key |
109 // the private key, if we were initialized using a private key |
108 private RSAPrivateKey privateKey; |
110 private RSAPrivateKey privateKey; |
109 |
111 |
110 // hash algorithm for OAEP |
112 // hash algorithm for OAEP |
111 private String oaepHashAlgorithm = "SHA-1"; |
113 private String oaepHashAlgorithm = "SHA-1"; |
|
114 |
|
115 // the source of randomness |
|
116 private SecureRandom random; |
112 |
117 |
113 public RSACipher() { |
118 public RSACipher() { |
114 paddingType = PAD_PKCS1; |
119 paddingType = PAD_PKCS1; |
115 } |
120 } |
116 |
121 |
274 } |
279 } |
275 padding = RSAPadding.getInstance(RSAPadding.PAD_NONE, n, random); |
280 padding = RSAPadding.getInstance(RSAPadding.PAD_NONE, n, random); |
276 buffer = new byte[n]; |
281 buffer = new byte[n]; |
277 } else if (paddingType == PAD_PKCS1) { |
282 } else if (paddingType == PAD_PKCS1) { |
278 if (params != null) { |
283 if (params != null) { |
279 throw new InvalidAlgorithmParameterException |
284 if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) { |
280 ("Parameters not supported"); |
285 throw new InvalidAlgorithmParameterException( |
|
286 "Parameters not supported"); |
|
287 } |
|
288 |
|
289 spec = params; |
|
290 this.random = random; // for TLS RSA premaster secret |
281 } |
291 } |
282 int blockType = (mode <= MODE_DECRYPT) ? RSAPadding.PAD_BLOCKTYPE_2 |
292 int blockType = (mode <= MODE_DECRYPT) ? RSAPadding.PAD_BLOCKTYPE_2 |
283 : RSAPadding.PAD_BLOCKTYPE_1; |
293 : RSAPadding.PAD_BLOCKTYPE_1; |
284 padding = RSAPadding.getInstance(blockType, n, random); |
294 padding = RSAPadding.getInstance(blockType, n, random); |
285 if (encrypt) { |
295 if (encrypt) { |
291 } else { // PAD_OAEP_MGF1 |
301 } else { // PAD_OAEP_MGF1 |
292 if ((mode == MODE_SIGN) || (mode == MODE_VERIFY)) { |
302 if ((mode == MODE_SIGN) || (mode == MODE_VERIFY)) { |
293 throw new InvalidKeyException |
303 throw new InvalidKeyException |
294 ("OAEP cannot be used to sign or verify signatures"); |
304 ("OAEP cannot be used to sign or verify signatures"); |
295 } |
305 } |
296 OAEPParameterSpec myParams; |
|
297 if (params != null) { |
306 if (params != null) { |
298 if (!(params instanceof OAEPParameterSpec)) { |
307 if (!(params instanceof OAEPParameterSpec)) { |
299 throw new InvalidAlgorithmParameterException |
308 throw new InvalidAlgorithmParameterException |
300 ("Wrong Parameters for OAEP Padding"); |
309 ("Wrong Parameters for OAEP Padding"); |
301 } |
310 } |
302 myParams = (OAEPParameterSpec) params; |
311 spec = params; |
303 } else { |
312 } else { |
304 myParams = new OAEPParameterSpec(oaepHashAlgorithm, "MGF1", |
313 spec = new OAEPParameterSpec(oaepHashAlgorithm, "MGF1", |
305 MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT); |
314 MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT); |
306 } |
315 } |
307 padding = RSAPadding.getInstance(RSAPadding.PAD_OAEP_MGF1, n, |
316 padding = RSAPadding.getInstance(RSAPadding.PAD_OAEP_MGF1, n, |
308 random, myParams); |
317 random, (OAEPParameterSpec)spec); |
309 if (encrypt) { |
318 if (encrypt) { |
310 int k = padding.getMaxDataSize(); |
319 int k = padding.getMaxDataSize(); |
311 buffer = new byte[k]; |
320 buffer = new byte[k]; |
312 } else { |
321 } else { |
313 buffer = new byte[n]; |
322 buffer = new byte[n]; |
418 protected Key engineUnwrap(byte[] wrappedKey, String algorithm, |
427 protected Key engineUnwrap(byte[] wrappedKey, String algorithm, |
419 int type) throws InvalidKeyException, NoSuchAlgorithmException { |
428 int type) throws InvalidKeyException, NoSuchAlgorithmException { |
420 if (wrappedKey.length > buffer.length) { |
429 if (wrappedKey.length > buffer.length) { |
421 throw new InvalidKeyException("Key is too long for unwrapping"); |
430 throw new InvalidKeyException("Key is too long for unwrapping"); |
422 } |
431 } |
|
432 |
|
433 boolean isTlsRsaPremasterSecret = |
|
434 algorithm.equals("TlsRsaPremasterSecret"); |
|
435 Exception failover = null; |
|
436 byte[] encoded = null; |
|
437 |
423 update(wrappedKey, 0, wrappedKey.length); |
438 update(wrappedKey, 0, wrappedKey.length); |
424 try { |
439 try { |
425 byte[] encoded = doFinal(); |
440 encoded = doFinal(); |
426 return ConstructKeys.constructKey(encoded, algorithm, type); |
|
427 } catch (BadPaddingException e) { |
441 } catch (BadPaddingException e) { |
428 // should not occur |
442 if (isTlsRsaPremasterSecret) { |
429 throw new InvalidKeyException("Unwrapping failed", e); |
443 failover = e; |
|
444 } else { |
|
445 throw new InvalidKeyException("Unwrapping failed", e); |
|
446 } |
430 } catch (IllegalBlockSizeException e) { |
447 } catch (IllegalBlockSizeException e) { |
431 // should not occur, handled with length check above |
448 // should not occur, handled with length check above |
432 throw new InvalidKeyException("Unwrapping failed", e); |
449 throw new InvalidKeyException("Unwrapping failed", e); |
433 } |
450 } |
|
451 |
|
452 if (isTlsRsaPremasterSecret) { |
|
453 if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) { |
|
454 throw new IllegalStateException( |
|
455 "No TlsRsaPremasterSecretParameterSpec specified"); |
|
456 } |
|
457 |
|
458 // polish the TLS premaster secret |
|
459 encoded = KeyUtil.checkTlsPreMasterSecretKey( |
|
460 ((TlsRsaPremasterSecretParameterSpec)spec).getClientVersion(), |
|
461 ((TlsRsaPremasterSecretParameterSpec)spec).getServerVersion(), |
|
462 random, encoded, (failover != null)); |
|
463 } |
|
464 |
|
465 return ConstructKeys.constructKey(encoded, algorithm, type); |
434 } |
466 } |
435 |
467 |
436 // see JCE spec |
468 // see JCE spec |
437 protected int engineGetKeySize(Key key) throws InvalidKeyException { |
469 protected int engineGetKeySize(Key key) throws InvalidKeyException { |
438 RSAKey rsaKey = RSAKeyFactory.toRSAKey(key); |
470 RSAKey rsaKey = RSAKeyFactory.toRSAKey(key); |
439 return rsaKey.getModulus().bitLength(); |
471 return rsaKey.getModulus().bitLength(); |
440 } |
472 } |
441 |
|
442 } |
473 } |