# HG changeset patch # User xuelei # Date 1529939651 25200 # Node ID 32a737f51e37382d072cca9a077bbd47571dd5e6 # Parent 985a8862b6bf4aa3b4a9b14a5d7af0f74ee5a2ae Support RSASSS-PSS for TLS 1.2 diff -r 985a8862b6bf -r 32a737f51e37 src/java.base/share/classes/sun/security/ssl/CertificateMessage.java --- a/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java Sun Jun 24 13:34:42 2018 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java Mon Jun 25 08:14:11 2018 -0700 @@ -651,15 +651,16 @@ PublicKey key = certs[0].getPublicKey(); String keyAlgorithm = key.getAlgorithm(); String authType; - if (keyAlgorithm.equals("RSA")) { - authType = "RSA"; - } else if (keyAlgorithm.equals("DSA")) { - authType = "DSA"; - } else if (keyAlgorithm.equals("EC")) { - authType = "EC"; - } else { - // unknown public key type - authType = "UNKNOWN"; + switch (keyAlgorithm) { + case "RSA": + case "DSA": + case "EC": + case "RSASSA-PSS": + authType = keyAlgorithm; + break; + default: + // unknown public key type + authType = "UNKNOWN"; } try { @@ -1035,14 +1036,14 @@ if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.warning( - "Unable to produce CertificateVerify for scheme: " + ss.name); + "Unable to produce CertificateVerify for " + + "signature scheme: " + ss.name); } checkedKeyTypes.add(ss.keyAlgorithm); continue; } - SSLAuthentication ka = - X509Authentication.nameOf(ss.keyAlgorithm); + SSLAuthentication ka = X509Authentication.valueOf(ss); if (ka == null) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.warning( @@ -1232,18 +1233,14 @@ String authType; switch (keyAlgorithm) { case "RSA": - authType = "RSA"; - break; case "DSA": - authType = "DSA"; - break; case "EC": - authType = "EC"; + case "RSASSA-PSS": + authType = keyAlgorithm; break; default: // unknown public key type authType = "UNKNOWN"; - break; } try { @@ -1296,26 +1293,10 @@ "Failed to parse server certificates", ce); } - // find out the types of client authentication used - /* - String keyAlgorithm = certs[0].getPublicKey().getAlgorithm(); - String authType; - switch (keyAlgorithm) { - case "RSA": - authType = "RSA"; - break; - case "DSA": - authType = "DSA"; - break; - case "EC": - authType = "EC"; - break; - default: - // unknown public key type - authType = "UNKNOWN"; - break; - } - */ + // find out the types of server authentication used + // + // Note that the "UNKNOWN" authentication type is sufficient to + // check the required digitalSignature KeyUsage for TLS 1.3. String authType = "UNKNOWN"; try { diff -r 985a8862b6bf -r 32a737f51e37 src/java.base/share/classes/sun/security/ssl/CertificateRequest.java --- a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java Sun Jun 24 13:34:42 2018 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java Mon Jun 25 08:14:11 2018 -0700 @@ -67,7 +67,7 @@ // RFC 2246 RSA_SIGN ((byte)0x01, "rsa_sign", "RSA", true), DSS_SIGN ((byte)0x02, "dss_sign", "DSA", true), - RSA_FIXED_DH ((byte)0x03, "rsa__fixed_dh"), + RSA_FIXED_DH ((byte)0x03, "rsa_fixed_dh"), DSS_FIXED_DH ((byte)0x04, "dss_fixed_dh"), // RFC 4346 diff -r 985a8862b6bf -r 32a737f51e37 src/java.base/share/classes/sun/security/ssl/ClientKeyExchange.java --- a/src/java.base/share/classes/sun/security/ssl/ClientKeyExchange.java Sun Jun 24 13:34:42 2018 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/ClientKeyExchange.java Mon Jun 25 08:14:11 2018 -0700 @@ -55,8 +55,9 @@ HandshakeMessage message) throws IOException { // The producing happens in client side only. ClientHandshakeContext chc = (ClientHandshakeContext)context; - SSLKeyExchange ke = - SSLKeyExchange.valueOf(chc.negotiatedCipherSuite.keyExchange); + SSLKeyExchange ke = SSLKeyExchange.valueOf( + chc.negotiatedCipherSuite.keyExchange, + chc.negotiatedProtocol); if (ke != null) { for (Map.Entry hp : ke.getHandshakeProducers(chc)) { @@ -90,8 +91,9 @@ ServerHandshakeContext shc = (ServerHandshakeContext)context; // clean up this consumer shc.handshakeConsumers.remove(SSLHandshake.CLIENT_KEY_EXCHANGE.id); - SSLKeyExchange ke = - SSLKeyExchange.valueOf(shc.negotiatedCipherSuite.keyExchange); + SSLKeyExchange ke = SSLKeyExchange.valueOf( + shc.negotiatedCipherSuite.keyExchange, + shc.negotiatedProtocol); if (ke != null) { for (Map.Entry hc : ke.getHandshakeConsumers(shc)) { diff -r 985a8862b6bf -r 32a737f51e37 src/java.base/share/classes/sun/security/ssl/DHClientKeyExchange.java --- a/src/java.base/share/classes/sun/security/ssl/DHClientKeyExchange.java Sun Jun 24 13:34:42 2018 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/DHClientKeyExchange.java Mon Jun 25 08:14:11 2018 -0700 @@ -197,8 +197,9 @@ chc.handshakeOutput.flush(); // update the states - SSLKeyExchange ke = - SSLKeyExchange.valueOf(chc.negotiatedCipherSuite.keyExchange); + SSLKeyExchange ke = SSLKeyExchange.valueOf( + chc.negotiatedCipherSuite.keyExchange, + chc.negotiatedProtocol); if (ke == null) { // unlikely chc.conContext.fatal(Alert.INTERNAL_ERROR, @@ -258,7 +259,8 @@ } SSLKeyExchange ke = SSLKeyExchange.valueOf( - shc.negotiatedCipherSuite.keyExchange); + shc.negotiatedCipherSuite.keyExchange, + shc.negotiatedProtocol); if (ke == null) { // unlikely shc.conContext.fatal(Alert.INTERNAL_ERROR, diff -r 985a8862b6bf -r 32a737f51e37 src/java.base/share/classes/sun/security/ssl/ECDHClientKeyExchange.java --- a/src/java.base/share/classes/sun/security/ssl/ECDHClientKeyExchange.java Sun Jun 24 13:34:42 2018 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/ECDHClientKeyExchange.java Mon Jun 25 08:14:11 2018 -0700 @@ -223,8 +223,9 @@ chc.handshakeOutput.flush(); // update the states - SSLKeyExchange ke = - SSLKeyExchange.valueOf(chc.negotiatedCipherSuite.keyExchange); + SSLKeyExchange ke = SSLKeyExchange.valueOf( + chc.negotiatedCipherSuite.keyExchange, + chc.negotiatedProtocol); if (ke == null) { // unlikely chc.conContext.fatal(Alert.INTERNAL_ERROR, @@ -300,7 +301,8 @@ } SSLKeyExchange ke = SSLKeyExchange.valueOf( - shc.negotiatedCipherSuite.keyExchange); + shc.negotiatedCipherSuite.keyExchange, + shc.negotiatedProtocol); if (ke == null) { // unlikely shc.conContext.fatal(Alert.INTERNAL_ERROR, @@ -405,8 +407,9 @@ chc.handshakeOutput.flush(); // update the states - SSLKeyExchange ke = - SSLKeyExchange.valueOf(chc.negotiatedCipherSuite.keyExchange); + SSLKeyExchange ke = SSLKeyExchange.valueOf( + chc.negotiatedCipherSuite.keyExchange, + chc.negotiatedProtocol); if (ke == null) { // unlikely chc.conContext.fatal(Alert.INTERNAL_ERROR, @@ -474,7 +477,8 @@ } SSLKeyExchange ke = SSLKeyExchange.valueOf( - shc.negotiatedCipherSuite.keyExchange); + shc.negotiatedCipherSuite.keyExchange, + shc.negotiatedProtocol); if (ke == null) { // unlikely shc.conContext.fatal(Alert.INTERNAL_ERROR, diff -r 985a8862b6bf -r 32a737f51e37 src/java.base/share/classes/sun/security/ssl/JsseJce.java --- a/src/java.base/share/classes/sun/security/ssl/JsseJce.java Sun Jun 24 13:34:42 2018 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/JsseJce.java Mon Jun 25 08:14:11 2018 -0700 @@ -100,37 +100,45 @@ * Can be used for encryption, decryption, signing, verifying. */ static final String CIPHER_RSA_PKCS1 = "RSA/ECB/PKCS1Padding"; + /** * JCE transformation string for the stream cipher RC4. */ static final String CIPHER_RC4 = "RC4"; + /** * JCE transformation string for DES in CBC mode without padding. */ static final String CIPHER_DES = "DES/CBC/NoPadding"; + /** * JCE transformation string for (3-key) Triple DES in CBC mode * without padding. */ static final String CIPHER_3DES = "DESede/CBC/NoPadding"; + /** * JCE transformation string for AES in CBC mode * without padding. */ static final String CIPHER_AES = "AES/CBC/NoPadding"; + /** * JCE transformation string for AES in GCM mode * without padding. */ static final String CIPHER_AES_GCM = "AES/GCM/NoPadding"; + /** * JCA identifier string for DSA, i.e. a DSA with SHA-1. */ static final String SIGNATURE_DSA = "DSA"; + /** * JCA identifier string for ECDSA, i.e. a ECDSA with SHA-1. */ static final String SIGNATURE_ECDSA = "SHA1withECDSA"; + /** * JCA identifier string for Raw DSA, i.e. a DSA signature without * hashing where the application provides the SHA-1 hash of the data. @@ -138,17 +146,20 @@ * for compatibility. */ static final String SIGNATURE_RAWDSA = "RawDSA"; + /** * JCA identifier string for Raw ECDSA, i.e. a DSA signature without * hashing where the application provides the SHA-1 hash of the data. */ static final String SIGNATURE_RAWECDSA = "NONEwithECDSA"; + /** * JCA identifier string for Raw RSA, i.e. a RSA PKCS#1 v1.5 signature * without hashing where the application provides the hash of the data. * Used for RSA client authentication with a 36 byte hash. */ static final String SIGNATURE_RAWRSA = "NONEwithRSA"; + /** * JCA identifier string for the SSL/TLS style RSA Signature. I.e. * an signature using RSA with PKCS#1 v1.5 padding signing a diff -r 985a8862b6bf -r 32a737f51e37 src/java.base/share/classes/sun/security/ssl/RSAClientKeyExchange.java --- a/src/java.base/share/classes/sun/security/ssl/RSAClientKeyExchange.java Sun Jun 24 13:34:42 2018 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/RSAClientKeyExchange.java Mon Jun 25 08:14:11 2018 -0700 @@ -201,8 +201,9 @@ chc.handshakeOutput.flush(); // update the states - SSLKeyExchange ke = - SSLKeyExchange.valueOf(chc.negotiatedCipherSuite.keyExchange); + SSLKeyExchange ke = SSLKeyExchange.valueOf( + chc.negotiatedCipherSuite.keyExchange, + chc.negotiatedProtocol); if (ke == null) { // unlikely chc.conContext.fatal(Alert.INTERNAL_ERROR, "Not supported key exchange type"); @@ -291,8 +292,9 @@ } // update the states - SSLKeyExchange ke = - SSLKeyExchange.valueOf(shc.negotiatedCipherSuite.keyExchange); + SSLKeyExchange ke = SSLKeyExchange.valueOf( + shc.negotiatedCipherSuite.keyExchange, + shc.negotiatedProtocol); if (ke == null) { // unlikely shc.conContext.fatal(Alert.INTERNAL_ERROR, "Not supported key exchange type"); diff -r 985a8862b6bf -r 32a737f51e37 src/java.base/share/classes/sun/security/ssl/SSLKeyExchange.java --- a/src/java.base/share/classes/sun/security/ssl/SSLKeyExchange.java Sun Jun 24 13:34:42 2018 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/SSLKeyExchange.java Mon Jun 25 08:14:11 2018 -0700 @@ -193,8 +193,9 @@ // SSL 3.0 - (D)TLS 1.2 static SSLKeyExchange valueOf( - CipherSuite.KeyExchange keyExchange) { - if (keyExchange == null) { + CipherSuite.KeyExchange keyExchange, + ProtocolVersion protocolVersion) { + if (keyExchange == null || protocolVersion == null) { return null; } @@ -208,7 +209,11 @@ case K_DHE_DSS_EXPORT: return SSLKeyExDHEDSSExport.KE; case K_DHE_RSA: - return SSLKeyExDHERSA.KE; + if (protocolVersion.useTLS12PlusSpec()) { // (D)TLS 1.2 + return SSLKeyExDHERSAOrPSS.KE; + } else { // SSL 3.0, TLS 1.0/1.1 + return SSLKeyExDHERSA.KE; + } case K_DHE_RSA_EXPORT: return SSLKeyExDHERSAExport.KE; case K_DH_ANON: @@ -222,7 +227,11 @@ case K_ECDHE_ECDSA: return SSLKeyExECDHEECDSA.KE; case K_ECDHE_RSA: - return SSLKeyExECDHERSA.KE; + if (protocolVersion.useTLS12PlusSpec()) { // (D)TLS 1.2 + return SSLKeyExECDHERSAOrPSS.KE; + } else { // SSL 3.0, TLS 1.0/1.1 + return SSLKeyExECDHERSA.KE; + } case K_ECDH_ANON: return SSLKeyExECDHANON.KE; } @@ -266,6 +275,11 @@ X509Authentication.RSA, T12KeyAgreement.DHE); } + private static class SSLKeyExDHERSAOrPSS { + private static SSLKeyExchange KE = new SSLKeyExchange( + X509Authentication.RSA_OR_PSS, T12KeyAgreement.DHE); + } + private static class SSLKeyExDHERSAExport { private static SSLKeyExchange KE = new SSLKeyExchange( X509Authentication.RSA, T12KeyAgreement.DHE_EXPORT); @@ -301,6 +315,11 @@ X509Authentication.RSA, T12KeyAgreement.ECDHE); } + private static class SSLKeyExECDHERSAOrPSS { + private static SSLKeyExchange KE = new SSLKeyExchange( + X509Authentication.RSA_OR_PSS, T12KeyAgreement.ECDHE); + } + private static class SSLKeyExECDHANON { private static SSLKeyExchange KE = new SSLKeyExchange( null, T12KeyAgreement.ECDHE); diff -r 985a8862b6bf -r 32a737f51e37 src/java.base/share/classes/sun/security/ssl/ServerHello.java --- a/src/java.base/share/classes/sun/security/ssl/ServerHello.java Sun Jun 24 13:34:42 2018 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/ServerHello.java Mon Jun 25 08:14:11 2018 -0700 @@ -415,7 +415,8 @@ } } - SSLKeyExchange ke = SSLKeyExchange.valueOf(cs.keyExchange); + SSLKeyExchange ke = SSLKeyExchange.valueOf( + cs.keyExchange, shc.negotiatedProtocol); if (ke == null) { continue; } @@ -439,7 +440,8 @@ } for (CipherSuite cs : legacySuites) { - SSLKeyExchange ke = SSLKeyExchange.valueOf(cs.keyExchange); + SSLKeyExchange ke = SSLKeyExchange.valueOf( + cs.keyExchange, shc.negotiatedProtocol); if (ke != null) { SSLPossession[] hcds = ke.createPossessions(shc); if ((hcds != null) && (hcds.length != 0)) { @@ -1122,7 +1124,8 @@ SSLHandshake.FINISHED); } else { SSLKeyExchange ke = SSLKeyExchange.valueOf( - chc.negotiatedCipherSuite.keyExchange); + chc.negotiatedCipherSuite.keyExchange, + chc.negotiatedProtocol); chc.handshakeKeyExchange = ke; if (ke != null) { for (SSLHandshake handshake : @@ -1154,7 +1157,8 @@ HKDF hkdf = new HKDF(hashAlg.name); byte[] zeros = new byte[hashAlg.hashLength]; SecretKey earlySecret = hkdf.extract(zeros, psk, "TlsEarlySecret"); - hc.handshakeKeyDerivation = new SSLSecretDerivation(hc, earlySecret); + hc.handshakeKeyDerivation = + new SSLSecretDerivation(hc, earlySecret); } catch (GeneralSecurityException gse) { throw (SSLHandshakeException) new SSLHandshakeException( "Could not generate secret").initCause(gse); diff -r 985a8862b6bf -r 32a737f51e37 src/java.base/share/classes/sun/security/ssl/ServerKeyExchange.java --- a/src/java.base/share/classes/sun/security/ssl/ServerKeyExchange.java Sun Jun 24 13:34:42 2018 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/ServerKeyExchange.java Mon Jun 25 08:14:11 2018 -0700 @@ -55,8 +55,9 @@ // The producing happens in server side only. ServerHandshakeContext shc = (ServerHandshakeContext)context; - SSLKeyExchange ke = - SSLKeyExchange.valueOf(shc.negotiatedCipherSuite.keyExchange); + SSLKeyExchange ke = SSLKeyExchange.valueOf( + shc.negotiatedCipherSuite.keyExchange, + shc.negotiatedProtocol); if (ke != null) { for (Map.Entry hc : ke.getHandshakeProducers(shc)) { @@ -92,8 +93,9 @@ // clean up this consumer chc.handshakeConsumers.remove(SSLHandshake.SERVER_KEY_EXCHANGE.id); - SSLKeyExchange ke = - SSLKeyExchange.valueOf(chc.negotiatedCipherSuite.keyExchange); + SSLKeyExchange ke = SSLKeyExchange.valueOf( + chc.negotiatedCipherSuite.keyExchange, + chc.negotiatedProtocol); if (ke != null) { for (Map.Entry hc : ke.getHandshakeConsumers(chc)) { diff -r 985a8862b6bf -r 32a737f51e37 src/java.base/share/classes/sun/security/ssl/SignatureScheme.java --- a/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java Sun Jun 24 13:34:42 2018 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java Mon Jun 25 08:14:11 2018 -0700 @@ -76,15 +76,15 @@ RSA_PSS_RSAE_SHA256 (0x0804, "rsa_pss_rsae_sha256", "RSASSA-PSS", "RSA", SigAlgParamSpec.RSA_PSS_SHA256, 528, - ProtocolVersion.PROTOCOLS_TO_13), + ProtocolVersion.PROTOCOLS_12_13), RSA_PSS_RSAE_SHA384 (0x0805, "rsa_pss_rsae_sha384", "RSASSA-PSS", "RSA", SigAlgParamSpec.RSA_PSS_SHA384, 784, - ProtocolVersion.PROTOCOLS_TO_13), + ProtocolVersion.PROTOCOLS_12_13), RSA_PSS_RSAE_SHA512 (0x0806, "rsa_pss_rsae_sha512", "RSASSA-PSS", "RSA", SigAlgParamSpec.RSA_PSS_SHA512, 1040, - ProtocolVersion.PROTOCOLS_TO_13), + ProtocolVersion.PROTOCOLS_12_13), // RSASSA-PSS algorithms with public key OID RSASSA-PSS // @@ -93,15 +93,15 @@ RSA_PSS_PSS_SHA256 (0x0809, "rsa_pss_pss_sha256", "RSASSA-PSS", "RSASSA-PSS", SigAlgParamSpec.RSA_PSS_SHA256, 528, - ProtocolVersion.PROTOCOLS_TO_13), + ProtocolVersion.PROTOCOLS_12_13), RSA_PSS_PSS_SHA384 (0x080A, "rsa_pss_pss_sha384", "RSASSA-PSS", "RSASSA-PSS", SigAlgParamSpec.RSA_PSS_SHA384, 784, - ProtocolVersion.PROTOCOLS_TO_13), + ProtocolVersion.PROTOCOLS_12_13), RSA_PSS_PSS_SHA512 (0x080B, "rsa_pss_pss_sha512", "RSASSA-PSS", "RSASSA-PSS", SigAlgParamSpec.RSA_PSS_SHA512, 1040, - ProtocolVersion.PROTOCOLS_TO_13), + ProtocolVersion.PROTOCOLS_12_13), // RSASSA-PKCS1-v1_5 algorithms RSA_PKCS1_SHA256 (0x0401, "rsa_pkcs1_sha256", "SHA256withRSA", diff -r 985a8862b6bf -r 32a737f51e37 src/java.base/share/classes/sun/security/ssl/X509Authentication.java --- a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java Sun Jun 24 13:34:42 2018 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java Mon Jun 25 08:14:11 2018 -0700 @@ -39,10 +39,29 @@ import sun.security.ssl.SupportedGroupsExtension.SupportedGroups; enum X509Authentication implements SSLAuthentication { - RSA ("RSA", new X509PossessionGenerator("RSA")), - RSA_PSS ("RSASSA-PSS", new X509PossessionGenerator("RSASSA-PSS")), - DSA ("DSA", new X509PossessionGenerator("DSA")), - EC ("EC", new X509PossessionGenerator("EC")); + // Require rsaEncryption public key + RSA ("RSA", new X509PossessionGenerator( + new String[]{"RSA"})), + + // Require RSASSA-PSS public key + RSASSA_PSS ("RSASSA-PSS", new X509PossessionGenerator( + new String[] {"RSASSA-PSS"})), + + // Require rsaEncryption or RSASSA-PSS public key + // + // Note that this is a specifical scheme for TLS 1.2. (EC)DHE_RSA cipher + // suites of TLS 1.2 can use either rsaEncryption or RSASSA-PSS public + // key for authentication and handshake. + RSA_OR_PSS ("RSA_OR_PSS", new X509PossessionGenerator( + new String[] {"RSA", "RSASSA-PSS"})), + + // Require DSA public key + DSA ("DSA", new X509PossessionGenerator( + new String[] {"DSA"})), + + // Require EC public key + EC ("EC", new X509PossessionGenerator( + new String[] {"EC"})); final String keyType; final SSLPossessionGenerator possessionGenerator; @@ -53,9 +72,9 @@ this.possessionGenerator = possessionGenerator; } - static X509Authentication nameOf(String keyType) { + static X509Authentication valueOf(SignatureScheme signatureScheme) { for (X509Authentication au: X509Authentication.values()) { - if (au.keyType.equals(keyType)) { + if (au.keyType.equals(signatureScheme.keyAlgorithm)) { return au; } } @@ -122,24 +141,38 @@ private static final class X509PossessionGenerator implements SSLPossessionGenerator { - final String keyType; + private final String[] keyTypes; - private X509PossessionGenerator(String keyType) { - this.keyType = keyType; + private X509PossessionGenerator(String[] keyTypes) { + this.keyTypes = keyTypes; } @Override public SSLPossession createPossession(HandshakeContext context) { if (context.sslConfig.isClientMode) { - return createClientPossession((ClientHandshakeContext)context); + for (String keyType : keyTypes) { + SSLPossession poss = createClientPossession( + (ClientHandshakeContext)context, keyType); + if (poss != null) { + return poss; + } + } } else { - return createServerPossession((ServerHandshakeContext)context); + for (String keyType : keyTypes) { + SSLPossession poss = createServerPossession( + (ServerHandshakeContext)context, keyType); + if (poss != null) { + return poss; + } + } } + + return null; } // Used by TLS 1.3 only. private SSLPossession createClientPossession( - ClientHandshakeContext chc) { + ClientHandshakeContext chc, String keyType) { X509ExtendedKeyManager km = chc.sslContext.getX509KeyManager(); String clientAlias = null; if (chc.conContext.transport instanceof SSLSocketImpl) { @@ -192,7 +225,7 @@ } private SSLPossession createServerPossession( - ServerHandshakeContext shc) { + ServerHandshakeContext shc, String keyType) { X509ExtendedKeyManager km = shc.sslContext.getX509KeyManager(); String serverAlias = null; if (shc.conContext.transport instanceof SSLSocketImpl) { diff -r 985a8862b6bf -r 32a737f51e37 src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java --- a/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java Sun Jun 24 13:34:42 2018 -0700 +++ b/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java Mon Jun 25 08:14:11 2018 -0700 @@ -39,7 +39,6 @@ import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.*; -import static java.util.Locale.ENGLISH; import java.util.concurrent.atomic.AtomicLong; import javax.net.ssl.*; import sun.security.provider.certpath.AlgorithmChecker; @@ -292,6 +291,7 @@ // In TLS 1.2, the signature algorithm has been obsoleted by the // supported_signature_algorithms, and the certificate type no longer // restricts the algorithm used to sign the certificate. + // // However, because we don't support certificate type checking other // than rsa_sign, dss_sign and ecdsa_sign, we don't have to check the // protocol version here. @@ -323,8 +323,10 @@ // Check the signature algorithm of the certificate itself. // Look for the "withRSA" in "SHA1withRSA", etc. X509Certificate issuer = (X509Certificate)chain[0]; - String sigAlgName = issuer.getSigAlgName().toUpperCase(ENGLISH); - String pattern = "WITH" + sigKeyAlgorithm.toUpperCase(ENGLISH); + String sigAlgName = + issuer.getSigAlgName().toUpperCase(Locale.ENGLISH); + String pattern = + "WITH" + sigKeyAlgorithm.toUpperCase(Locale.ENGLISH); return sigAlgName.contains(pattern); } } @@ -434,7 +436,7 @@ null, null); if (results != null) { if (allResults == null) { - allResults = new ArrayList(); + allResults = new ArrayList<>(); } allResults.addAll(results); } @@ -539,9 +541,10 @@ return (bit < keyUsage.length) && keyUsage[bit]; } - // check if this certificate is appropriate for this type of use - // first check extensions, if they match, check expiration - // note: we may want to move this code into the sun.security.validator + // Check if this certificate is appropriate for this type of use + // first check extensions, if they match, check expiration. + // + // Note: we may want to move this code into the sun.security.validator // package CheckResult check(X509Certificate cert, Date date, List serverNames, String idAlgorithm) { @@ -565,20 +568,25 @@ boolean[] ku = cert.getKeyUsage(); if (ku != null) { String algorithm = cert.getPublicKey().getAlgorithm(); - boolean kuSignature = getBit(ku, 0); + boolean supportsDigitalSignature = getBit(ku, 0); switch (algorithm) { case "RSA": // require either signature bit // or if server also allow key encipherment bit - if (kuSignature == false) { + if (!supportsDigitalSignature) { if (this == CLIENT || getBit(ku, 2) == false) { return CheckResult.EXTENSION_MISMATCH; } } break; + case "RSASSA-PSS": + if (!supportsDigitalSignature && (this == SERVER)) { + return CheckResult.EXTENSION_MISMATCH; + } + break; case "DSA": // require signature bit - if (kuSignature == false) { + if (!supportsDigitalSignature) { return CheckResult.EXTENSION_MISMATCH; } break; @@ -590,7 +598,7 @@ break; case "EC": // require signature bit - if (kuSignature == false) { + if (!supportsDigitalSignature) { return CheckResult.EXTENSION_MISMATCH; } // For servers, also require key agreement. @@ -811,7 +819,7 @@ return Collections.singletonList(status); } else { if (results == null) { - results = new ArrayList(); + results = new ArrayList<>(); } results.add(status); } diff -r 985a8862b6bf -r 32a737f51e37 test/jdk/sun/security/ssl/ClientHandshaker/LengthCheckTest.java --- a/test/jdk/sun/security/ssl/ClientHandshaker/LengthCheckTest.java Sun Jun 24 13:34:42 2018 -0700 +++ b/test/jdk/sun/security/ssl/ClientHandshaker/LengthCheckTest.java Mon Jun 25 08:14:11 2018 -0700 @@ -268,7 +268,7 @@ runDelegatedTasks(serverResult, serverEngine); sTOc.flip(); dumpByteBuffer("SERVER-TO-CLIENT", sTOc); - + // We expect to see the server generate an alert here serverResult = serverEngine.wrap(serverOut, sTOc); log("server wrap: ", serverResult); diff -r 985a8862b6bf -r 32a737f51e37 test/jdk/sun/security/ssl/SSLEngineImpl/CloseEngineException.java --- a/test/jdk/sun/security/ssl/SSLEngineImpl/CloseEngineException.java Sun Jun 24 13:34:42 2018 -0700 +++ b/test/jdk/sun/security/ssl/SSLEngineImpl/CloseEngineException.java Mon Jun 25 08:14:11 2018 -0700 @@ -129,7 +129,7 @@ log("unwrap1: " + result1); log("twoToOne = " + twoToOne); log(""); - + twoToOne.compact(); } if (!isEngineClosed(ssle2)) { diff -r 985a8862b6bf -r 32a737f51e37 test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java --- a/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java Sun Jun 24 13:34:42 2018 -0700 +++ b/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineKeyLimit.java Mon Jun 25 08:14:11 2018 -0700 @@ -181,13 +181,15 @@ private static void doTask(SSLEngineResult result, SSLEngine engine) throws Exception { - if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) { + if (result.getHandshakeStatus() == + SSLEngineResult.HandshakeStatus.NEED_TASK) { Runnable runnable; while ((runnable = engine.getDelegatedTask()) != null) { print("\trunning delegated task..."); runnable.run(); } - SSLEngineResult.HandshakeStatus hsStatus = engine.getHandshakeStatus(); + SSLEngineResult.HandshakeStatus hsStatus = + engine.getHandshakeStatus(); if (hsStatus == SSLEngineResult.HandshakeStatus.NEED_TASK) { throw new Exception( "handshake shouldn't need additional tasks"); @@ -247,7 +249,8 @@ " cap: " + getWriteBuf().capacity()); } if (again && r.getStatus() == SSLEngineResult.Status.OK && - r.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_WRAP) { + r.getHandshakeStatus() == + SSLEngineResult.HandshakeStatus.NEED_WRAP) { print("again"); again = false; continue; @@ -317,7 +320,8 @@ buf2.flip(); r = eng.wrap(buf2, getWriteBuf()); log("read wrap", r); - if (debug) { //&& r.getStatus() != SSLEngineResult.Status.OK) { + if (debug) { + // && r.getStatus() != SSLEngineResult.Status.OK) { print("buf2 pos: " + buf2.position() + " rem: " + buf2.remaining() + " cap: " + buf2.capacity()); @@ -326,7 +330,8 @@ " cap: " + getWriteBuf().capacity()); } if (again && r.getStatus() == SSLEngineResult.Status.OK && - r.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_WRAP) { + r.getHandshakeStatus() == + SSLEngineResult.HandshakeStatus.NEED_WRAP) { buf2.compact(); again = false; continue; @@ -347,7 +352,8 @@ buf.clear(); r = eng.unwrap(getReadBuf(), buf); log("read unwrap", r); - if (debug && r.getStatus() != SSLEngineResult.Status.OK) { + if (debug && + r.getStatus() != SSLEngineResult.Status.OK) { print("buf pos " + buf.position() + " rem: " + buf.remaining() + " lim: " + buf.limit() + @@ -360,7 +366,8 @@ } if (again && r.getStatus() == SSLEngineResult.Status.OK && - r.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) { + r.getHandshakeStatus() == + SSLEngineResult.HandshakeStatus.NEED_UNWRAP) { buf.clear(); print("again"); again = false; @@ -398,12 +405,14 @@ KeyStore ks = KeyStore.getInstance( new File(System.getProperty("javax.net.ssl.keyStore")), passwd.toCharArray()); - KeyManagerFactory kmf = - KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + KeyManagerFactory kmf = KeyManagerFactory.getInstance( + KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, passwd.toCharArray()); - TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + TrustManagerFactory tmf = TrustManagerFactory.getInstance( + TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); - sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom()); + sc.init(kmf.getKeyManagers(), + tmf.getTrustManagers(), new SecureRandom()); return sc; } @@ -414,7 +423,7 @@ eng.setUseClientMode(false); eng.setNeedClientAuth(true); } - + public void run() { try { if (serverwrite) {