forked from keycloak/keycloak
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
KEYCLOAK-8996: Provide a way to set a responder certificate in OCSP/X…
…509 Authenticator
- Loading branch information
Showing
12 changed files
with
255 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,13 +48,15 @@ | |
import static org.keycloak.authentication.authenticators.x509.AbstractX509ClientCertificateAuthenticator.MAPPING_SOURCE_CERT_SUBJECTDN_CN; | ||
import static org.keycloak.authentication.authenticators.x509.AbstractX509ClientCertificateAuthenticator.MAPPING_SOURCE_CERT_SUBJECTDN_EMAIL; | ||
import static org.keycloak.authentication.authenticators.x509.AbstractX509ClientCertificateAuthenticator.MAPPING_SOURCE_SELECTION; | ||
import static org.keycloak.authentication.authenticators.x509.AbstractX509ClientCertificateAuthenticator.OCSPRESPONDER_CERTIFICATE; | ||
import static org.keycloak.authentication.authenticators.x509.AbstractX509ClientCertificateAuthenticator.OCSPRESPONDER_URI; | ||
import static org.keycloak.authentication.authenticators.x509.AbstractX509ClientCertificateAuthenticator.REGULAR_EXPRESSION; | ||
import static org.keycloak.authentication.authenticators.x509.AbstractX509ClientCertificateAuthenticator.USERNAME_EMAIL_MAPPER; | ||
import static org.keycloak.authentication.authenticators.x509.AbstractX509ClientCertificateAuthenticator.USER_ATTRIBUTE_MAPPER; | ||
import static org.keycloak.authentication.authenticators.x509.AbstractX509ClientCertificateAuthenticator.USER_MAPPER_SELECTION; | ||
import static org.keycloak.provider.ProviderConfigProperty.BOOLEAN_TYPE; | ||
import static org.keycloak.provider.ProviderConfigProperty.STRING_TYPE; | ||
import static org.keycloak.provider.ProviderConfigProperty.TEXT_TYPE; | ||
|
||
/** | ||
* @author <a href="mailto:[email protected]">Peter Nalyvayko</a> | ||
|
@@ -155,6 +157,12 @@ public abstract class AbstractX509ClientCertificateAuthenticatorFactory implemen | |
ocspResponderUri.setLabel("OCSP Responder Uri"); | ||
ocspResponderUri.setHelpText("Clients use OCSP Responder Uri to check certificate revocation status."); | ||
|
||
ProviderConfigProperty ocspResponderCert = new ProviderConfigProperty(); | ||
ocspResponderCert.setType(TEXT_TYPE); | ||
ocspResponderCert.setName(OCSPRESPONDER_CERTIFICATE); | ||
ocspResponderCert.setLabel("OCSP Responder Certificate"); | ||
ocspResponderCert.setHelpText("Optional certificate used by the responder to sign the responses. The certificate should be in PEM format without BEGIN and END tags. It is only used if the OCSP Responder URI is set. By default, the certificate of the OCSP responder is that of the issuer of the certificate being validated or one with the OCSPSigning extension and also issued by the same CA. This option identifies the certificate of the OCSP responder when the defaults do not apply."); | ||
|
||
ProviderConfigProperty keyUsage = new ProviderConfigProperty(); | ||
keyUsage.setType(STRING_TYPE); | ||
keyUsage.setName(CERTIFICATE_KEY_USAGE); | ||
|
@@ -182,6 +190,7 @@ public abstract class AbstractX509ClientCertificateAuthenticatorFactory implemen | |
cRLRelativePath, | ||
oCspCheckingEnabled, | ||
ocspResponderUri, | ||
ocspResponderCert, | ||
keyUsage, | ||
extendedKeyUsage, | ||
identityConfirmationPageDisallowed); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,6 +51,8 @@ | |
import java.util.Set; | ||
import java.util.LinkedList; | ||
import java.util.ArrayList; | ||
import org.keycloak.saml.common.exceptions.ProcessingException; | ||
import org.keycloak.saml.processing.core.util.XMLSignatureUtil; | ||
|
||
/** | ||
* @author <a href="mailto:[email protected]">Peter Nalyvayko</a> | ||
|
@@ -149,8 +151,11 @@ public static abstract class CRLLoaderImpl { | |
public static class BouncyCastleOCSPChecker extends OCSPChecker { | ||
|
||
private final String responderUri; | ||
BouncyCastleOCSPChecker(String responderUri) { | ||
private final X509Certificate responderCert; | ||
|
||
BouncyCastleOCSPChecker(String responderUri, X509Certificate responderCert) { | ||
this.responderUri = responderUri; | ||
this.responderCert = responderCert; | ||
} | ||
|
||
@Override | ||
|
@@ -177,12 +182,13 @@ public OCSPUtils.OCSPRevocationStatus check(X509Certificate cert, X509Certificat | |
String message = String.format("Unable to check certificate revocation status using OCSP.\n%s", e.getMessage()); | ||
throw new CertPathValidatorException(message, e); | ||
} | ||
logger.tracef("Responder URI \"%s\" will be used to verify revocation status of the certificate using OCSP", uri.toString()); | ||
logger.tracef("Responder URI \"%s\" will be used to verify revocation status of the certificate using OCSP with responderCert=%s", | ||
uri.toString(), responderCert); | ||
// Obtains the revocation status of a certificate using OCSP. | ||
// OCSP responder's certificate is assumed to be the issuer's certificate | ||
// certificate. | ||
// responderUri overrides the contents (if any) of the certificate's AIA extension | ||
ocspRevocationStatus = OCSPUtils.check(cert, issuerCertificate, uri, null, null); | ||
ocspRevocationStatus = OCSPUtils.check(cert, issuerCertificate, uri, responderCert, null); | ||
} | ||
return ocspRevocationStatus; | ||
} | ||
|
@@ -529,6 +535,7 @@ public static class CertificateValidatorBuilder { | |
CRLLoaderImpl _crlLoader; | ||
boolean _ocspEnabled; | ||
String _responderUri; | ||
X509Certificate _responderCert; | ||
|
||
public CertificateValidatorBuilder() { | ||
_extendedKeyUsage = new LinkedList<>(); | ||
|
@@ -675,6 +682,21 @@ public GotCRLRelativePath cRLLoader(CRLLoaderImpl cRLLoader) { | |
} | ||
|
||
public class GotOCSP { | ||
public GotOCSP oCSPResponseCertificate(String responderCert) { | ||
if (responderCert != null && !responderCert.isEmpty()) { | ||
try { | ||
_responderCert = XMLSignatureUtil.getX509CertificateFromKeyInfoString(responderCert); | ||
_responderCert.checkValidity(); | ||
} catch(CertificateException e) { | ||
logger.warnf("Ignoring invalid certificate: %s", _responderCert); | ||
_responderCert = null; | ||
} catch (ProcessingException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
return new GotOCSP(); | ||
} | ||
|
||
public CertificateValidatorBuilder oCSPResponderURI(String responderURI) { | ||
_responderUri = responderURI; | ||
return _parent; | ||
|
@@ -699,7 +721,8 @@ public CertificateValidator build(X509Certificate[] certs) { | |
_crlLoader = new CRLFileLoader(""); | ||
} | ||
return new CertificateValidator(certs, _keyUsageBits, _extendedKeyUsage, | ||
_crlCheckingEnabled, _crldpEnabled, _crlLoader, _ocspEnabled, new BouncyCastleOCSPChecker(_responderUri)); | ||
_crlCheckingEnabled, _crldpEnabled, _crlLoader, _ocspEnabled, | ||
new BouncyCastleOCSPChecker(_responderUri, _responderCert)); | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.