31
31
import org .bouncycastle .crypto .encodings .OAEPEncoding ;
32
32
import org .bouncycastle .crypto .engines .RSABlindedEngine ;
33
33
import org .bouncycastle .crypto .params .ParametersWithRandom ;
34
+ import org .bouncycastle .crypto .params .RSAKeyParameters ;
35
+ import org .bouncycastle .crypto .params .RSAPrivateCrtKeyParameters ;
36
+ import org .bouncycastle .crypto .tls .TlsRsaKeyExchange ;
34
37
import org .bouncycastle .jcajce .provider .asymmetric .util .BaseCipherSpi ;
35
38
import org .bouncycastle .jcajce .provider .util .BadBlockException ;
36
39
import org .bouncycastle .jcajce .provider .util .DigestFactory ;
40
+ import org .bouncycastle .jcajce .spec .TLSRSAPremasterSecretParameterSpec ;
37
41
import org .bouncycastle .jcajce .util .BCJcaJceHelper ;
38
42
import org .bouncycastle .jcajce .util .JcaJceHelper ;
39
43
import org .bouncycastle .util .Strings ;
@@ -49,6 +53,8 @@ public class CipherSpi
49
53
private boolean publicKeyOnly = false ;
50
54
private boolean privateKeyOnly = false ;
51
55
private ErasableOutputStream bOut = new ErasableOutputStream ();
56
+ private TLSRSAPremasterSecretParameterSpec tlsRsaSpec = null ;
57
+ private CipherParameters param = null ;
52
58
53
59
public CipherSpi (
54
60
AsymmetricBlockCipher engine )
@@ -262,9 +268,12 @@ protected void engineInit(
262
268
SecureRandom random )
263
269
throws InvalidKeyException , InvalidAlgorithmParameterException
264
270
{
265
- CipherParameters param ;
266
271
267
- if (params == null || params instanceof OAEPParameterSpec )
272
+ this .tlsRsaSpec = null ;
273
+
274
+ if (params == null
275
+ || params instanceof OAEPParameterSpec
276
+ || params instanceof TLSRSAPremasterSecretParameterSpec )
268
277
{
269
278
if (key instanceof RSAPublicKey )
270
279
{
@@ -291,7 +300,7 @@ else if (key instanceof RSAPrivateKey)
291
300
throw new InvalidKeyException ("unknown key type passed to RSA" );
292
301
}
293
302
294
- if (params != null )
303
+ if (params instanceof OAEPParameterSpec )
295
304
{
296
305
OAEPParameterSpec spec = (OAEPParameterSpec )params ;
297
306
@@ -324,6 +333,14 @@ else if (key instanceof RSAPrivateKey)
324
333
325
334
cipher = new OAEPEncoding (new RSABlindedEngine (), digest , mgfDigest , ((PSource .PSpecified )spec .getPSource ()).getValue ());
326
335
}
336
+ else if (params instanceof TLSRSAPremasterSecretParameterSpec )
337
+ {
338
+ if (!(param instanceof RSAPrivateCrtKeyParameters ))
339
+ {
340
+ throw new InvalidKeyException ("RSA private key required for TLS decryption" );
341
+ }
342
+ this .tlsRsaSpec = (TLSRSAPremasterSecretParameterSpec )params ;
343
+ }
327
344
}
328
345
else
329
346
{
@@ -403,6 +420,11 @@ protected byte[] engineUpdate(
403
420
int inputOffset ,
404
421
int inputLen )
405
422
{
423
+ if (tlsRsaSpec != null )
424
+ {
425
+ throw new IllegalStateException ("RSA cipher initialized for TLS only" );
426
+ }
427
+
406
428
bOut .write (input , inputOffset , inputLen );
407
429
408
430
if (cipher instanceof RSABlindedEngine )
@@ -430,6 +452,11 @@ protected int engineUpdate(
430
452
byte [] output ,
431
453
int outputOffset )
432
454
{
455
+ if (tlsRsaSpec != null )
456
+ {
457
+ throw new IllegalStateException ("RSA cipher initialized for TLS only" );
458
+ }
459
+
433
460
bOut .write (input , inputOffset , inputLen );
434
461
435
462
if (cipher instanceof RSABlindedEngine )
@@ -456,6 +483,12 @@ protected byte[] engineDoFinal(
456
483
int inputLen )
457
484
throws IllegalBlockSizeException , BadPaddingException
458
485
{
486
+ if (tlsRsaSpec != null )
487
+ {
488
+ ParametersWithRandom pWithR = (ParametersWithRandom )param ;
489
+ return TlsRsaKeyExchange .decryptPreMasterSecret (input , (RSAKeyParameters )pWithR .getParameters (), tlsRsaSpec .getProtocolVersion (), pWithR .getRandom ());
490
+ }
491
+
459
492
if (input != null )
460
493
{
461
494
bOut .write (input , inputOffset , inputLen );
@@ -487,6 +520,11 @@ protected int engineDoFinal(
487
520
int outputOffset )
488
521
throws IllegalBlockSizeException , BadPaddingException , ShortBufferException
489
522
{
523
+ if (tlsRsaSpec != null )
524
+ {
525
+ throw new IllegalStateException ("RSA cipher initialized for TLS only" );
526
+ }
527
+
490
528
if (outputOffset + engineGetOutputSize (inputLen ) > output .length )
491
529
{
492
530
throw new ShortBufferException ("output buffer too short for input." );
0 commit comments