# HG changeset patch # User xuelei # Date 1458735908 0 # Node ID 044bf6a5474aabcf0c11fa24ae734fbb21ab35a3 # Parent b386281c6f083866753803f13060203e7baf4992 8149017: Delayed provider selection broken in RSA client key exchange Reviewed-by: coffeys diff -r b386281c6f08 -r 044bf6a5474a 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); }