Improper Client Certificate Validation for OAuth/OpenID clients (#20)

Co-authored-by: Stian Thorgersen <stianst@gmail.com>
This commit is contained in:
Marek Posolda
2023-06-01 14:18:13 +02:00
committed by Bruno Oliveira da Silva
parent 1973d0f0d4
commit 51a9712e59
5 changed files with 45 additions and 23 deletions
@@ -130,42 +130,38 @@ public class X509ClientAuthenticator extends AbstractClientAuthenticator {
return;
}
Optional<String> matchedCertificate;
// Testing only 1st certificate in the chain to match with configured subject
X509Certificate certificate = certs[0];
boolean matchedCertificate = false;
if (clientCfg.getAllowRegexPatternComparison()) {
Pattern subjectDNPattern = Pattern.compile(subjectDNRegexp);
matchedCertificate = Arrays.stream(certs)
.map(certificate -> certificate.getSubjectDN().getName())
.filter(subjectdn -> subjectDNPattern.matcher(subjectdn).matches())
.findFirst();
String subjectdn = certificate.getSubjectDN().getName();
matchedCertificate = subjectDNPattern.matcher(subjectdn).matches();
} else {
// OIDC/OAuth2 does not use regex comparison as it expects exact DN given in the format according to RFC4514. See RFC8705 for the details.
// We allow custom OIDs attributes to be "expanded" or not expanded in the given Subject DN
X500Principal expectedDNPrincipal = new X500Principal(subjectDNRegexp, CUSTOM_OIDS_REVERSED);
matchedCertificate = Arrays.stream(certs)
.filter(certificate -> expectedDNPrincipal.getName(X500Principal.RFC2253, CUSTOM_OIDS).equals(certificate.getSubjectX500Principal().getName(X500Principal.RFC2253, CUSTOM_OIDS)))
.map(certificate -> certificate.getSubjectDN().getName())
.findFirst();
matchedCertificate = (expectedDNPrincipal.getName(X500Principal.RFC2253, CUSTOM_OIDS).equals(certificate.getSubjectX500Principal().getName(X500Principal.RFC2253, CUSTOM_OIDS)));
}
if (!matchedCertificate.isPresent()) {
if (!matchedCertificate) {
// We do quite expensive operation here, so better check the logging level beforehand.
if (logger.isDebugEnabled()) {
logger.debug("[X509ClientCertificateAuthenticator:authenticate] Couldn't match any certificate for expected Subject DN '" + subjectDNRegexp + "' with allow regex pattern '" + clientCfg.getAllowRegexPatternComparison() + "'.");
logger.debug("[X509ClientCertificateAuthenticator:authenticate] Available SubjectDNs: " +
logger.debug("[X509ClientCertificateAuthenticator:authenticate] Checked Subject DN: " + certificate.getSubjectDN().getName());
logger.debug("[X509ClientCertificateAuthenticator:authenticate] All SubjectDNs from the certificate chain: " +
Arrays.stream(certs)
.map(cert -> cert.getSubjectDN().getName())
.collect(Collectors.toList()));
}
context.attempted();
return;
} else {
logger.debug("[X509ClientCertificateAuthenticator:authenticate] Matched " + matchedCertificate.get() + " certificate.");
logger.debug("[X509ClientCertificateAuthenticator:authenticate] Matched " + certificate.getSubjectDN().getName() + " certificate.");
context.success();
}
context.success();
}
public String getDisplayType() {