From 6d3ad7af35ac2f7276c1d70218d0cbb963bd7c40 Mon Sep 17 00:00:00 2001 From: John Jiang Date: Sun, 4 Feb 2024 11:21:38 +0800 Subject: [PATCH] TKSS-658: Simplify TLCPCertificateRequest --- .../security/ssl/TLCPCertificateRequest.java | 165 +----------------- .../tencent/kona/ssl/tlcp/SSLSocketTest.java | 1 + 2 files changed, 10 insertions(+), 156 deletions(-) diff --git a/kona-ssl/src/main/java/com/tencent/kona/sun/security/ssl/TLCPCertificateRequest.java b/kona-ssl/src/main/java/com/tencent/kona/sun/security/ssl/TLCPCertificateRequest.java index 6d07f3a9..baeaab49 100644 --- a/kona-ssl/src/main/java/com/tencent/kona/sun/security/ssl/TLCPCertificateRequest.java +++ b/kona-ssl/src/main/java/com/tencent/kona/sun/security/ssl/TLCPCertificateRequest.java @@ -30,14 +30,12 @@ import java.security.cert.X509Certificate; import java.text.MessageFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Locale; import javax.security.auth.x500.X500Principal; import com.tencent.kona.sun.security.ssl.CertificateRequest.ClientCertificateType; -import com.tencent.kona.sun.security.ssl.CipherSuite.KeyExchange; import com.tencent.kona.sun.security.ssl.SSLHandshake.HandshakeMessage; final class TLCPCertificateRequest { @@ -51,33 +49,16 @@ private static final class TLCPCertificateRequestMessage extends HandshakeMessage { final byte[] types; // certificate types - final int[] algorithmIds; // supported signature algorithms final List authorities; // certificate authorities TLCPCertificateRequestMessage(HandshakeContext handshakeContext, - X509Certificate[] trustedCerts, KeyExchange keyExchange, - List signatureSchemes) throws IOException { + X509Certificate[] trustedCerts) throws IOException { super(handshakeContext); this.types = new byte[] { ClientCertificateType.ECDSA_SIGN.id, ClientCertificateType.RSA_SIGN.id}; - if (handshakeContext.negotiatedProtocol.isTLS12()) { - if (signatureSchemes == null || signatureSchemes.isEmpty()) { - throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, - "No signature algorithms specified for " + - "CertificateRequest hanshake message"); - } - this.algorithmIds = new int[signatureSchemes.size()]; - int i = 0; - for (SignatureScheme scheme : signatureSchemes) { - algorithmIds[i++] = scheme.id; - } - } else { - algorithmIds = new int[0]; - } - this.authorities = new ArrayList<>(trustedCerts.length); for (X509Certificate cert : trustedCerts) { X500Principal x500Principal = cert.getSubjectX500Principal(); @@ -97,39 +78,13 @@ private static final class TLCPCertificateRequestMessage // } CertificateRequest; // certificate_authorities - int minLen = handshakeContext.negotiatedProtocol.isTLCP11() ? 4 : 8; - if (m.remaining() < minLen) { + if (m.remaining() < 4) { throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, "Invalid CertificateRequest handshake message: " + "no sufficient data"); } this.types = Record.getBytes8(m); - if (handshakeContext.negotiatedProtocol.isTLS12()) { - // supported_signature_algorithms - if (m.remaining() < 6) { - throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, - "Invalid CertificateRequest handshake message: " + - "no sufficient data"); - } - - byte[] algs = Record.getBytes16(m); - if (algs.length == 0 || (algs.length & 0x01) != 0) { - throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, - "Invalid CertificateRequest handshake message: " + - "incomplete signature algorithms"); - } - - this.algorithmIds = new int[(algs.length >> 1)]; - for (int i = 0, j = 0; i < algs.length; ) { - byte hash = algs[i++]; - byte sign = algs[i++]; - algorithmIds[j++] = ((hash & 0xFF) << 8) | (sign & 0xFF); - } - } else { - this.algorithmIds = new int[0]; - } - // certificate_authorities if (m.remaining() < 2) { throw handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, @@ -181,9 +136,6 @@ public SSLHandshake handshakeType() { @Override public int messageLength() { int len = 1 + types.length + 2; - if (algorithmIds.length > 0) { - len += (algorithmIds.length << 1) + 2; - } for (byte[] encoded : authorities) { len += encoded.length + 2; } @@ -210,8 +162,8 @@ public String toString() { MessageFormat messageFormat = new MessageFormat( "\"CertificateRequest\": '{'\n" + " \"certificate types\": {0}\n" + - " \"supported signature algorithms\": {1}\n" + - " \"certificate authorities\": {2}\n" + + " \"supported signature algorithms\": [sm2sig_sm3]\n" + + " \"certificate authorities\": {1}\n" + "'}'", Locale.ENGLISH); @@ -220,11 +172,6 @@ public String toString() { typeNames.add(ClientCertificateType.nameOf(type)); } - List algorithmNames = new ArrayList<>(algorithmIds.length); - for (int algorithmId : algorithmIds) { - algorithmNames.add(SignatureScheme.nameOf(algorithmId)); - } - List authorityNames = new ArrayList<>(authorities.size()); for (byte[] encoded : authorities) { try { @@ -236,7 +183,6 @@ public String toString() { } Object[] messageFields = { typeNames, - algorithmNames, authorityNames }; @@ -258,28 +204,10 @@ public byte[] produce(ConnectionContext context, // The producing happens in server side only. ServerHandshakeContext shc = (ServerHandshakeContext)context; - List localSupportedSignAlgs = null; - if (shc.negotiatedProtocol.isTLS12()) { - if (shc.localSupportedSignAlgs == null) { - shc.localSupportedSignAlgs = - SignatureScheme.getSupportedAlgorithms( - shc.sslConfig, - shc.algorithmConstraints, shc.activeProtocols); - } - - if (shc.localSupportedSignAlgs.isEmpty()) { - throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE, - "No supported signature algorithm"); - } - - localSupportedSignAlgs = shc.localSupportedSignAlgs; - } - X509Certificate[] caCerts = shc.sslContext.getX509TrustManager().getAcceptedIssuers(); - TLCPCertificateRequestMessage crm = new TLCPCertificateRequestMessage( - shc, caCerts, shc.negotiatedCipherSuite.keyExchange, - localSupportedSignAlgs); + TLCPCertificateRequestMessage crm + = new TLCPCertificateRequestMessage(shc, caCerts); if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.fine( "Produced CertificateRequest handshake message", crm); @@ -358,22 +286,6 @@ public void consume(ConnectionContext context, chc.handshakeProducers.put(SSLHandshake.CERTIFICATE.id, SSLHandshake.CERTIFICATE); - if (chc.negotiatedProtocol.isTLS12()) { - List sss = - SignatureScheme.getSupportedAlgorithms( - chc.sslConfig, - chc.algorithmConstraints, chc.negotiatedProtocol, - crm.algorithmIds); - if (sss.isEmpty()) { - throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE, - "No supported signature algorithm"); - } - - chc.peerRequestedSignatureSchemes = sss; - chc.peerRequestedCertSignSchemes = sss; // use the same schemes - chc.handshakeSession.setPeerSupportedSignatureAlgorithms(sss); - } - try { chc.peerSupportedAuthorities = crm.getAuthorities(); } catch (IllegalArgumentException iae) { @@ -381,14 +293,9 @@ public void consume(ConnectionContext context, + "distinguished names of the peer's certificate " + "authorities could not be parsed", iae); } - // For TLS 1.2, we no longer use the certificate_types field - // from the CertificateRequest message to directly determine - // the SSLPossession. Instead, the choosePossession method - // will use the accepted signature schemes in the message to - // determine the set of acceptable certificate types to select from. - SSLPossession pos = chc.negotiatedProtocol.isTLCP11() - ? choosePossession4TLCP(chc) - : choosePossession(chc, crm); + + SSLPossession pos = TLCPAuthentication.createPossession( + chc, new String[] {"EC"}); if (pos == null) { return; } @@ -397,59 +304,5 @@ public void consume(ConnectionContext context, chc.handshakeProducers.put(SSLHandshake.CERTIFICATE_VERIFY.id, SSLHandshake.CERTIFICATE_VERIFY); } - - private static SSLPossession choosePossession4TLCP(HandshakeContext hc) { - return TLCPAuthentication.createPossession(hc, new String[] {"EC"}); - } - - private static SSLPossession choosePossession(HandshakeContext hc, - TLCPCertificateRequestMessage crm) throws IOException { - if (hc.peerRequestedCertSignSchemes == null || - hc.peerRequestedCertSignSchemes.isEmpty()) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { - SSLLogger.warning("No signature and hash algorithms " + - "in CertificateRequest"); - } - return null; - } - - // Put the CR key type into a more friendly format for searching - List crKeyTypes = new ArrayList<>( - Arrays.asList(crm.getKeyTypes())); - // For TLS 1.2 only if RSA is a requested key type then we - // should also allow RSASSA-PSS. - if (crKeyTypes.contains("RSA")) { - crKeyTypes.add("RSASSA-PSS"); - } - - String[] supportedKeyTypes = hc.peerRequestedCertSignSchemes - .stream() - .map(ss -> ss.keyAlgorithm) - .distinct() - .filter(ka -> SignatureScheme.getPreferableAlgorithm( // Don't select a signature scheme unless - hc.algorithmConstraints, // we will be able to produce - hc.peerRequestedSignatureSchemes, // a CertificateVerify message later - ka, hc.negotiatedProtocol) != null - || SSLLogger.logWarning("ssl,handshake", - "Unable to produce CertificateVerify for key algorithm: " + ka)) - .filter(ka -> { - X509Authentication xa = X509Authentication.valueOfKeyAlgorithm(ka); - // Any auth object will have a set of allowed key types. - // This set should share at least one common algorithm with - // the CR's allowed key types. - return xa != null && !Collections.disjoint(crKeyTypes, Arrays.asList(xa.keyTypes)) - || SSLLogger.logWarning("ssl,handshake", "Unsupported key algorithm: " + ka); - }) - .toArray(String[]::new); - - SSLPossession pos = X509Authentication - .createPossession(hc, supportedKeyTypes); - if (pos == null) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { - SSLLogger.warning("No available authentication scheme"); - } - } - return pos; - } } } diff --git a/kona-ssl/src/test/java/com/tencent/kona/ssl/tlcp/SSLSocketTest.java b/kona-ssl/src/test/java/com/tencent/kona/ssl/tlcp/SSLSocketTest.java index b84c762f..88bf8c0a 100644 --- a/kona-ssl/src/test/java/com/tencent/kona/ssl/tlcp/SSLSocketTest.java +++ b/kona-ssl/src/test/java/com/tencent/kona/ssl/tlcp/SSLSocketTest.java @@ -75,6 +75,7 @@ public class SSLSocketTest { @BeforeAll public static void setup() { +// System.setProperty("com.tencent.kona.ssl.debug", "all"); TestUtils.addProviders(); }