diff --git a/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java b/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java index 83cfb43d0c1ac..a6af021b59467 100644 --- a/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java +++ b/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2022, 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 @@ -1042,46 +1042,22 @@ private static SSLPossession choosePossession( return null; } - Collection checkedKeyTypes = new HashSet<>(); - List supportedKeyTypes = new ArrayList<>(); - for (SignatureScheme ss : hc.peerRequestedCertSignSchemes) { - if (checkedKeyTypes.contains(ss.keyAlgorithm)) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { - SSLLogger.warning( - "Unsupported authentication scheme: " + ss.name); - } - continue; - } - checkedKeyTypes.add(ss.keyAlgorithm); - - // Don't select a signature scheme unless we will be able to - // produce a CertificateVerify message later - if (SignatureScheme.getPreferableAlgorithm( - hc.algorithmConstraints, - hc.peerRequestedSignatureSchemes, - ss, hc.negotiatedProtocol) == null) { - - if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { - SSLLogger.warning( - "Unable to produce CertificateVerify for " + - "signature scheme: " + ss.name); - } - continue; - } - - X509Authentication ka = X509Authentication.valueOf(ss); - if (ka == null) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { - SSLLogger.warning( - "Unsupported authentication scheme: " + ss.name); - } - continue; - } - supportedKeyTypes.add(ss.keyAlgorithm); - } + 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.valueOfKeyAlgorithm(ka) != null + || SSLLogger.logWarning("ssl,handshake", "Unsupported key algorithm: " + ka)) + .toArray(String[]::new); SSLPossession pos = X509Authentication - .createPossession(hc, supportedKeyTypes.toArray(String[]::new)); + .createPossession(hc, supportedKeyTypes); if (pos == null) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.warning("No available authentication scheme"); diff --git a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java index 975f899f41396..9f415dc46aa3d 100644 --- a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java +++ b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java @@ -32,9 +32,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Locale; @@ -760,59 +758,28 @@ private static SSLPossession choosePossession(HandshakeContext hc, crKeyTypes.add("RSASSA-PSS"); } - Collection checkedKeyTypes = new HashSet<>(); - List supportedKeyTypes = new ArrayList<>(); - for (SignatureScheme ss : hc.peerRequestedCertSignSchemes) { - if (checkedKeyTypes.contains(ss.keyAlgorithm)) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { - SSLLogger.warning( - "Unsupported authentication scheme: " + ss.name); - } - continue; - } - checkedKeyTypes.add(ss.keyAlgorithm); - - // Don't select a signature scheme unless we will be able to - // produce a CertificateVerify message later - if (SignatureScheme.getPreferableAlgorithm( - hc.algorithmConstraints, - hc.peerRequestedSignatureSchemes, - ss, hc.negotiatedProtocol) == null) { - - if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { - SSLLogger.warning( - "Unable to produce CertificateVerify for " + - "signature scheme: " + ss.name); - } - continue; - } - - X509Authentication ka = X509Authentication.valueOf(ss); - if (ka == null) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { - SSLLogger.warning( - "Unsupported authentication scheme: " + ss.name); - } - continue; - } else { - // 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. - if (Collections.disjoint(crKeyTypes, - Arrays.asList(ka.keyTypes))) { - if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { - SSLLogger.warning( - "Unsupported authentication scheme: " + - ss.name); - } - continue; - } - } - supportedKeyTypes.add(ss.keyAlgorithm); - } + 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 -> { + var 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.toArray(String[]::new)); + .createPossession(hc, supportedKeyTypes); if (pos == null) { if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { SSLLogger.warning("No available authentication scheme"); diff --git a/src/java.base/share/classes/sun/security/ssl/SSLLogger.java b/src/java.base/share/classes/sun/security/ssl/SSLLogger.java index e096463459d0b..acc0ec7e1c6bf 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLLogger.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLLogger.java @@ -207,6 +207,15 @@ static String toString(Object... params) { } } + // Logs a warning message and always returns false. This method + // can be used as an OR Predicate to add a log in a stream filter. + public static boolean logWarning(String option, String s) { + if (SSLLogger.isOn && SSLLogger.isOn(option)) { + SSLLogger.warning(s); + } + return false; + } + private static class SSLConsoleLogger implements Logger { private final String loggerName; private final boolean useCompactFormat; diff --git a/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java b/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java index 87feda0e83bee..4897258a93d31 100644 --- a/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java +++ b/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java @@ -450,13 +450,13 @@ static List getSupportedAlgorithms( static SignatureScheme getPreferableAlgorithm( AlgorithmConstraints constraints, List schemes, - SignatureScheme certScheme, + String keyAlgorithm, ProtocolVersion version) { for (SignatureScheme ss : schemes) { if (ss.isAvailable && ss.handshakeSupportedProtocols.contains(version) && - certScheme.keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm) && + keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm) && ss.isPermitted(constraints)) { return ss; } diff --git a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java index ba1396f017b16..9a051f57ae983 100644 --- a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java +++ b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, 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 @@ -72,9 +72,9 @@ private X509Authentication(String keyAlgorithm, this.keyTypes = keyTypes; } - static X509Authentication valueOf(SignatureScheme signatureScheme) { + static X509Authentication valueOfKeyAlgorithm(String keyAlgorithm) { for (X509Authentication au : X509Authentication.values()) { - if (au.keyAlgorithm.equals(signatureScheme.keyAlgorithm)) { + if (au.keyAlgorithm.equals(keyAlgorithm)) { return au; } }