# HG changeset patch # User jnimeh # Date 1578287079 28800 # Sun Jan 05 21:04:39 2020 -0800 # Node ID b9d1ce20dd4b2ce34e74c8fa2d784335231abcd1 # Parent 3782f295811625b65d57f1aef15daa10d82a58a7 8236039: JSSE Client does not accept status_request extension in CertificateRequest messages for TLS 1.3 Reviewed-by: xuelei diff --git a/src/java.base/share/classes/sun/security/ssl/CertStatusExtension.java b/src/java.base/share/classes/sun/security/ssl/CertStatusExtension.java --- a/src/java.base/share/classes/sun/security/ssl/CertStatusExtension.java +++ b/src/java.base/share/classes/sun/security/ssl/CertStatusExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2020, 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 @@ -39,11 +39,7 @@ import javax.net.ssl.SSLProtocolException; import sun.security.provider.certpath.OCSPResponse; import sun.security.provider.certpath.ResponderId; -import static sun.security.ssl.SSLExtension.CH_STATUS_REQUEST; -import static sun.security.ssl.SSLExtension.CH_STATUS_REQUEST_V2; import sun.security.ssl.SSLExtension.ExtensionConsumer; -import static sun.security.ssl.SSLExtension.SH_STATUS_REQUEST; -import static sun.security.ssl.SSLExtension.SH_STATUS_REQUEST_V2; import sun.security.ssl.SSLExtension.SSLExtensionSpec; import sun.security.ssl.SSLHandshake.HandshakeMessage; import sun.security.util.DerInputStream; @@ -434,8 +430,9 @@ } else { extBuilder.append(",\n"); } - extBuilder.append( - "{\n" + Utilities.indent(ext.toString()) + "}"); + extBuilder.append("{\n"). + append(Utilities.indent(ext.toString())). + append("}"); } extsStr = extBuilder.toString(); @@ -552,11 +549,11 @@ return null; } - if (!chc.sslConfig.isAvailable(CH_STATUS_REQUEST)) { + if (!chc.sslConfig.isAvailable(SSLExtension.CH_STATUS_REQUEST)) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.fine( "Ignore unavailable extension: " + - CH_STATUS_REQUEST.name); + SSLExtension.CH_STATUS_REQUEST.name); } return null; } @@ -568,8 +565,8 @@ byte[] extData = new byte[] {0x01, 0x00, 0x00, 0x00, 0x00}; // Update the context. - chc.handshakeExtensions.put( - CH_STATUS_REQUEST, CertStatusRequestSpec.DEFAULT); + chc.handshakeExtensions.put(SSLExtension.CH_STATUS_REQUEST, + CertStatusRequestSpec.DEFAULT); return extData; } @@ -593,10 +590,10 @@ // The consuming happens in server side only. ServerHandshakeContext shc = (ServerHandshakeContext)context; - if (!shc.sslConfig.isAvailable(CH_STATUS_REQUEST)) { + if (!shc.sslConfig.isAvailable(SSLExtension.CH_STATUS_REQUEST)) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.fine("Ignore unavailable extension: " + - CH_STATUS_REQUEST.name); + SSLExtension.CH_STATUS_REQUEST.name); } return; // ignore the extension } @@ -610,7 +607,7 @@ } // Update the context. - shc.handshakeExtensions.put(CH_STATUS_REQUEST, spec); + shc.handshakeExtensions.put(SSLExtension.CH_STATUS_REQUEST, spec); if (!shc.isResumption && !shc.negotiatedProtocol.useTLS13PlusSpec()) { shc.handshakeProducers.put(SSLHandshake.CERTIFICATE_STATUS.id, @@ -654,13 +651,12 @@ // In response to "status_request" extension request only. CertStatusRequestSpec spec = (CertStatusRequestSpec) - shc.handshakeExtensions.get(CH_STATUS_REQUEST); + shc.handshakeExtensions.get(SSLExtension.CH_STATUS_REQUEST); if (spec == null) { // Ignore, no status_request extension requested. if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { - SSLLogger.finest( - "Ignore unavailable extension: " + - CH_STATUS_REQUEST.name); + SSLLogger.finest("Ignore unavailable extension: " + + SSLExtension.CH_STATUS_REQUEST.name); } return null; // ignore the extension @@ -681,8 +677,8 @@ byte[] extData = new byte[0]; // Update the context. - shc.handshakeExtensions.put( - SH_STATUS_REQUEST, CertStatusRequestSpec.DEFAULT); + shc.handshakeExtensions.put(SSLExtension.SH_STATUS_REQUEST, + CertStatusRequestSpec.DEFAULT); return extData; } @@ -708,7 +704,7 @@ // In response to "status_request" extension request only. CertStatusRequestSpec requestedCsr = (CertStatusRequestSpec) - chc.handshakeExtensions.get(CH_STATUS_REQUEST); + chc.handshakeExtensions.get(SSLExtension.CH_STATUS_REQUEST); if (requestedCsr == null) { throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, "Unexpected status_request extension in ServerHello"); @@ -722,8 +718,8 @@ } // Update the context. - chc.handshakeExtensions.put( - SH_STATUS_REQUEST, CertStatusRequestSpec.DEFAULT); + chc.handshakeExtensions.put(SSLExtension.SH_STATUS_REQUEST, + CertStatusRequestSpec.DEFAULT); // Since we've received a legitimate status_request in the // ServerHello, stapling is active if it's been enabled. @@ -909,7 +905,7 @@ return null; } - if (!chc.sslConfig.isAvailable(CH_STATUS_REQUEST_V2)) { + if (!chc.sslConfig.isAvailable(SSLExtension.CH_STATUS_REQUEST_V2)) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.finest( "Ignore unavailable status_request_v2 extension"); @@ -926,8 +922,8 @@ 0x00, 0x07, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}; // Update the context. - chc.handshakeExtensions.put( - CH_STATUS_REQUEST_V2, CertStatusRequestV2Spec.DEFAULT); + chc.handshakeExtensions.put(SSLExtension.CH_STATUS_REQUEST_V2, + CertStatusRequestV2Spec.DEFAULT); return extData; } @@ -951,7 +947,7 @@ // The consuming happens in server side only. ServerHandshakeContext shc = (ServerHandshakeContext)context; - if (!shc.sslConfig.isAvailable(CH_STATUS_REQUEST_V2)) { + if (!shc.sslConfig.isAvailable(SSLExtension.CH_STATUS_REQUEST_V2)) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.finest( "Ignore unavailable status_request_v2 extension"); @@ -969,7 +965,8 @@ } // Update the context. - shc.handshakeExtensions.put(CH_STATUS_REQUEST_V2, spec); + shc.handshakeExtensions.put(SSLExtension.CH_STATUS_REQUEST_V2, + spec); if (!shc.isResumption) { shc.handshakeProducers.putIfAbsent( SSLHandshake.CERTIFICATE_STATUS.id, @@ -1013,7 +1010,7 @@ // In response to "status_request_v2" extension request only CertStatusRequestV2Spec spec = (CertStatusRequestV2Spec) - shc.handshakeExtensions.get(CH_STATUS_REQUEST_V2); + shc.handshakeExtensions.get(SSLExtension.CH_STATUS_REQUEST_V2); if (spec == null) { // Ignore, no status_request_v2 extension requested. if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { @@ -1038,8 +1035,8 @@ byte[] extData = new byte[0]; // Update the context. - shc.handshakeExtensions.put( - SH_STATUS_REQUEST_V2, CertStatusRequestV2Spec.DEFAULT); + shc.handshakeExtensions.put(SSLExtension.SH_STATUS_REQUEST_V2, + CertStatusRequestV2Spec.DEFAULT); return extData; } @@ -1065,7 +1062,7 @@ // In response to "status_request" extension request only CertStatusRequestV2Spec requestedCsr = (CertStatusRequestV2Spec) - chc.handshakeExtensions.get(CH_STATUS_REQUEST_V2); + chc.handshakeExtensions.get(SSLExtension.CH_STATUS_REQUEST_V2); if (requestedCsr == null) { throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, "Unexpected status_request_v2 extension in ServerHello"); @@ -1079,8 +1076,8 @@ } // Update the context. - chc.handshakeExtensions.put( - SH_STATUS_REQUEST_V2, CertStatusRequestV2Spec.DEFAULT); + chc.handshakeExtensions.put(SSLExtension.SH_STATUS_REQUEST_V2, + CertStatusRequestV2Spec.DEFAULT); // Since we've received a legitimate status_request in the // ServerHello, stapling is active if it's been enabled. If it diff --git a/src/java.base/share/classes/sun/security/ssl/SSLExtension.java b/src/java.base/share/classes/sun/security/ssl/SSLExtension.java --- a/src/java.base/share/classes/sun/security/ssl/SSLExtension.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, 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,7 +113,6 @@ null, null, CertStatusExtension.certStatusReqStringizer), - CR_STATUS_REQUEST (0x0005, "status_request"), CT_STATUS_REQUEST (0x0005, "status_request", SSLHandshake.CERTIFICATE, @@ -124,6 +123,7 @@ null, null, CertStatusExtension.certStatusRespStringizer), + // extensions defined in RFC 4681 USER_MAPPING (0x0006, "user_mapping"), @@ -515,6 +515,16 @@ return null; } + static String nameOf(int extensionType) { + for (SSLExtension ext : SSLExtension.values()) { + if (ext.id == extensionType) { + return ext.name; + } + } + + return "unknown extension"; + } + static boolean isConsumable(int extensionType) { for (SSLExtension ext : SSLExtension.values()) { if (ext.id == extensionType && diff --git a/src/java.base/share/classes/sun/security/ssl/SSLExtensions.java b/src/java.base/share/classes/sun/security/ssl/SSLExtensions.java --- a/src/java.base/share/classes/sun/security/ssl/SSLExtensions.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLExtensions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020 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 @@ -86,11 +86,14 @@ "Received buggy supported_groups extension " + "in the ServerHello handshake message"); } - } else { + } else if (handshakeType == SSLHandshake.SERVER_HELLO) { throw hm.handshakeContext.conContext.fatal( - Alert.UNSUPPORTED_EXTENSION, - "extension (" + extId + - ") should not be presented in " + handshakeType.name); + Alert.UNSUPPORTED_EXTENSION, "extension (" + + extId + ") should not be presented in " + + handshakeType.name); + } else { + isSupported = false; + // debug log to ignore unknown extension for handshakeType } } @@ -365,9 +368,10 @@ } private static String toString(int extId, byte[] extData) { + String extName = SSLExtension.nameOf(extId); MessageFormat messageFormat = new MessageFormat( - "\"unknown extension ({0})\": '{'\n" + - "{1}\n" + + "\"{0} ({1})\": '{'\n" + + "{2}\n" + "'}'", Locale.ENGLISH); @@ -375,6 +379,7 @@ String encoded = hexEncoder.encodeBuffer(extData); Object[] messageFields = { + extName, extId, Utilities.indent(encoded) };