changeset 11514:39a4f2f49ff0

8149017: Delayed provider selection broken in RSA client key exchange Reviewed-by: coffeys
author igerasim
date Sat, 02 Apr 2016 22:32:48 +0300
parents cb701a5bd82c
children ce81447f4df6
files src/share/classes/sun/security/ssl/RSAClientKeyExchange.java
diffstat 1 files changed, 25 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java	Wed Jan 21 21:42:22 2015 +0100
+++ b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java	Sat Apr 02 22:32:48 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -113,10 +113,31 @@
 
         byte[] encoded = null;
         try {
+            boolean needFailover = false;
             Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
-            boolean needFailover = !KeyUtil.isOracleJCEProvider(
-                    cipher.getProvider().getName());
+            try {
+                // Try UNWRAP_MODE mode firstly.
+                cipher.init(Cipher.UNWRAP_MODE, privateKey,
+                        new TlsRsaPremasterSecretParameterSpec(
+                                maxVersion.v, currentVersion.v),
+                        generator);
+
+                // The provider selection can be delayed, please don't call
+                // any Cipher method before the call to Cipher.init().
+                needFailover = !KeyUtil.isOracleJCEProvider(
+                        cipher.getProvider().getName());
+            } catch (InvalidKeyException | UnsupportedOperationException iue) {
+                if (debug != null && Debug.isOn("handshake")) {
+                    System.out.println("The Cipher provider " +
+                        cipher.getProvider().getName() +
+                        " caused exception: " + iue.getMessage());
+                }
+
+                needFailover = true;
+            }
+
             if (needFailover) {
+                // Use DECRYPT_MODE and dispose the previous initialization.
                 cipher.init(Cipher.DECRYPT_MODE, privateKey);
                 boolean failed = false;
                 try {
@@ -132,10 +153,7 @@
                                 maxVersion.v, currentVersion.v,
                                 encoded, generator);
             } else {
-                cipher.init(Cipher.UNWRAP_MODE, privateKey,
-                        new TlsRsaPremasterSecretParameterSpec(
-                                maxVersion.v, currentVersion.v),
-                        generator);
+                // the cipher should have been initialized
                 preMaster = (SecretKey)cipher.unwrap(encrypted,
                         "TlsRsaPremasterSecret", Cipher.SECRET_KEY);
             }