8149017: Delayed provider selection broken in RSA client key exchange
authorxuelei
Wed, 23 Mar 2016 12:25:08 +0000
changeset 36661 044bf6a5474a
parent 36660 b386281c6f08
child 36662 616fd89e60ac
8149017: Delayed provider selection broken in RSA client key exchange Reviewed-by: coffeys
jdk/src/java.base/share/classes/sun/security/ssl/RSAClientKeyExchange.java
--- a/jdk/src/java.base/share/classes/sun/security/ssl/RSAClientKeyExchange.java	Wed Mar 23 14:54:30 2016 +0530
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/RSAClientKeyExchange.java	Wed Mar 23 12:25:08 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2015, 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
@@ -115,10 +115,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 {
@@ -134,10 +155,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);
             }