How to create a custom KeyProvider for Keycloak

Issue

We’re unable to upgrade to Keycloak 13.0.
The certificate validation is rejecting our certificate chain with the following error:
java.security.cert.CertPathValidatorException: non-null policy tree required and policy tree is null

Is there a way to use the old validation, or overwrite the validation with our own if Keycloak can’t handle our custom certificates.
I’ve tried to create an SPI for it, but despite the logs saying it’s deployed, it never shows up as an option in the console.

SPI Files:

CustomJavaKeystoreKeyProviderFactory

public class CustomJavaKeystoreKeyProviderFactory extends JavaKeystoreKeyProviderFactory {
	private static final Logger logger = Logger.getLogger(CustomJavaKeystoreKeyProviderFactory.class);

	@Override
	public KeyProvider create(KeycloakSession session, ComponentModel model) {
		return new CustomJavaKeystoreKeyProvider(session.getContext().getRealm(), model);
	}

	@Override
	public void validateConfiguration(KeycloakSession session, RealmModel realm, ComponentModel model) throws ComponentValidationException {
		ConfigurationValidationHelper.check(model)
				.checkLong(Attributes.PRIORITY_PROPERTY, false)
				.checkBoolean(Attributes.ENABLED_PROPERTY, false)
				.checkBoolean(Attributes.ACTIVE_PROPERTY, false);

		ConfigurationValidationHelper.check(model)
				.checkSingle(KEYSTORE_PROPERTY, true)
				.checkSingle(KEYSTORE_PASSWORD_PROPERTY, true)
				.checkSingle(KEY_ALIAS_PROPERTY, true)
				.checkSingle(KEY_PASSWORD_PROPERTY, true);
		***** rest of logic *****
	}

	@Override
	public String getId() {
		return "my-java-keystore";
	}
}

CustomJavaKeystoreKeyProvider

public class CustomJavaKeystoreKeyProvider extends AbstractRsaKeyProvider {

	public CustomJavaKeystoreKeyProvider(RealmModel realm, ComponentModel model) {
		super(realm, model);
	}

	@Override
	protected KeyWrapper loadKey(RealmModel realm, ComponentModel model) {
		******* logic ****
	}
}

org.keycloak.keys.KeyProviderFactory

my.key.keycloak.spi.key.CustomJavaKeystoreKeyProviderFactory

Error:

Caused by: java.security.cert.CertPathValidatorException: non-null policy tree required and policy tree is null
    at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135)
    at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:233)
    at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:141)
    at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:80)
    at java.security.cert.CertPathValidator.validate(CertPathValidator.java:292)
    at JavaKeystoreKeyProviderTest.validateCertificateChain(JavaKeystoreKeyProviderTest.java:106)
    at JavaKeystoreKeyProviderTest.loadCertificateChain(JavaKeystoreKeyProviderTest.java:75)
    at JavaKeystoreKeyProviderTest.loadKey(JavaKeystoreKeyProviderTest.java:47)
    ... 1 more
Caused by: java.security.cert.CertPathValidatorException: non-null policy tree required and policy tree is null
    at sun.security.provider.certpath.PolicyChecker.processPolicies(PolicyChecker.java:572)
    at sun.security.provider.certpath.PolicyChecker.checkPolicy(PolicyChecker.java:225)
    at sun.security.provider.certpath.PolicyChecker.check(PolicyChecker.java:180)
    at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125)
    ... 8 more
Picked up JAVA_TOOL_OPTIONS: -Djava.vendor="Sun Microsystems Inc."

I figured out my issues:

  1. The META-INF folder was incorrect: META-INF.servicesMETA-INF/services
  2. The classes I was extending are not accessable to the SPI code, so I had to copy the missing code down and add a few more provided jars to the pom.
    • org.jboss.logging:jboss-logging
    • org.keycloak:keycloak-server-spi
    • org.keycloak:keycloak-server-spi-private
    • org.keycloak:keycloak-common
    • org.keycloak:keycloak-core

Hi @SomeDeveloper13

Did you able to show your custom key in /auth/realms//protocol/openid-connect/certs ?