I implemented spring-ws
application with validation of incoming request by signature
action. It works correctly but I would like to enable revocation status verification of certificate by CRL file. But the incoming request always ends with an error java.security.cert.CertPathValidatorException: Could not determine revocation status
caused by sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
.
What I noticed that the CRL could not be verified by sun.security.provider.certpath.DistributionPointFetcher#verifyCRL
method because DistributionPoint
of CRL has not value true
for indirect_crl
attribute and then it tried to find another key that might be able to sign CRLs vouching for given cert.
What does it mean?
Implementation of the web-service
@Bean
public KeyStoreCallbackHandler securityCallbackHandler() {
KeyStoreCallbackHandler callbackHandler = new KeyStoreCallbackHandler();
callbackHandler.setPrivateKeyPassword(wsSecurityProperties.privateKeyPassword());
return callbackHandler;
}
@Bean
public Wss4jSecurityInterceptor securityInterceptor() throws Exception {
Wss4jSecurityInterceptor securityInterceptor = new Wss4jSecurityInterceptor();
securityInterceptor.setValidationActions("Signature");
Merlin crypto = (Merlin) getCryptoFactoryBean().getObject();
securityInterceptor.setValidationSignatureCrypto(crypto);
securityInterceptor.setValidationCallbackHandler(securityCallbackHandler());
securityInterceptor.setEnableRevocation(true);
return securityInterceptor;
}
@Bean
public Properties cryptoProperties() {
var prop = new Properties();
// CRL file
prop.setProperty("org.apache.ws.security.crypto.merlin.x509crl.file", crlLocation);
// keystore contains public certificate
prop.setProperty("org.apache.ws.security.crypto.merlin.file", keyStoreLocation);
prop.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", "changeit");
// trustStore contains rootCA and intermediate
prop.setProperty("org.apache.ws.security.crypto.merlin.truststore.file", trustStoreLocation);
prop.setProperty("org.apache.ws.security.crypto.merlin.truststore.password", "changeit");
prop.setProperty("org.apache.wss4j.crypto.provider", Merlin.class.getName());
return prop;
}
@Bean
public CryptoFactoryBean getCryptoFactoryBean() {
CryptoFactoryBean cryptoFactoryBean = new CryptoFactoryBean();
cryptoFactoryBean.setConfiguration(cryptoProperties());
return cryptoFactoryBean;
}
What I tried so far is to check the revocation status manually but the result is the same.
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
// load RootCA
X509Certificate cerRootCa;
try (InputStream in = new FileInputStream(locationRootCa)) {
cerRootCa = (X509Certificate) certificateFactory.generateCertificate(in);
}
// load Intermediate
X509Certificate cerCaCCS1;
try (InputStream in = new FileInputStream(locationIntermediate)) {
cerCaCCS1 = (X509Certificate) certificateFactory.generateCertificate(in);
}
// load user certificate
X509Certificate cerUser;
try (InputStream in = new FileInputStream(locationUserCertificte)) {
cerUser = (X509Certificate) certificateFactory.generateCertificate(in);
}
// load CRL file
CertStore store = null;
try (InputStream in = new FileInputStream(locationCRL)) {
Set<CRL> certSet = new HashSet<>();
X509CRL crl = (X509CRL) certificateFactory.generateCRL(in);
certSet.add(crl);
store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certSet));
assertTrue(crl.isRevoked(cerUser)); // it is revoked, which is correct
}
Set<TrustAnchor> hashSet = new HashSet<>();
hashSet.add(new TrustAnchor(cerCaCCS1, null));
hashSet.add(new TrustAnchor(cerRootCa, null));
var pkixParams = new PKIXBuilderParameters(hashSet, new X509CertSelector());
CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
PKIXRevocationChecker rc = (PKIXRevocationChecker) cpb.getRevocationChecker();
rc.setOptions(EnumSet.of(PKIXRevocationChecker.Option.PREFER_CRLS, PKIXRevocationChecker.Option.NO_FALLBACK));
pkixParams.addCertPathChecker(rc);
pkixParams.addCertStore(store);
pkixParams.setRevocationEnabled(false);
var certPath = certificateFactory.generateCertPath(Arrays.asList(cerUser, cerCaCCS1));
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
validator.validate(certPath, pkixParams); // ERROR: could not determine revocation status
DEBUG -Djava.security.debug=certpath
certpath: PKIXCertPathValidator.engineValidate()...
certpath: X509CertSelector.match(SN: 731c01746a4b6813
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
Subject: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA)
certpath: X509CertSelector.match returning: true
certpath: YES - try this trustedCert
certpath: anchor.getTrustedCert().getSubjectX500Principal() = C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
certpath: Constraints: DSA keySize < 1024
certpath: Constraints set to keySize: keySize < 1024
certpath: Constraints: EC keySize < 224
certpath: Constraints set to keySize: keySize < 224
certpath: Constraints: MD2
certpath: Constraints: MD5
certpath: Constraints: RSA keySize < 1024
certpath: Constraints set to keySize: keySize < 1024
certpath: Constraints: SHA1 jdkCA & usage TLSServer
certpath: Constraints set to jdkCA.
certpath: Constraints usage length is 1
certpath: Constraints: SHA1 usage SignedJAR & denyAfter 2019-01-01
certpath: Constraints usage length is 1
certpath: Constraints set to denyAfter
certpath: DenyAfterConstraint read in as: year 2019, month = 1, day = 1
certpath: DenyAfterConstraint date set to: Tue Jan 01 01:00:00 CET 2019
certpath: --------------------------------------------------------------
certpath: Executing PKIX certification path validation algorithm.
certpath: Checking cert1 - Subject: C=SK, ST=Poprad, L=Poprad, O=XXX, OU=Common Components System, CN=CA CCS 1
certpath: Set of critical extensions: {2.5.29.15, 2.5.29.19}
certpath: -Using checker1 ... [sun.security.provider.certpath.UntrustedChecker]
certpath: -checker1 validation succeeded
certpath: -Using checker2 ... [sun.security.provider.certpath.AlgorithmChecker]
certpath: Constraints.permits(): SHA256withRSA, [
Variant: generic
Anchor: [
Trusted CA cert: [
[
Version: V3
Subject: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
Signature Algorithm: SHA512withRSA, OID = 1.2.840.113549.1.1.13
Key: Sun RSA public key, 4096 bits
params: null
modulus: ???
public exponent: 65537
Validity: [From: Mon Nov 27 17:34:03 CET 2017,
To: Thu Nov 25 17:34:03 CET 2027]
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
SerialNumber: [ 731c0174 6a4b6813]
Certificate Extensions: 5
[1]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 4F 6E AE 18 71 95 DE 3F A0 1D F5 AA 24 E7 99 11 On..q..?....$...
0010: CE BC DA B6 ....
]
]
[2]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen: no limit
]
[3]: ObjectId: 2.5.29.32 Criticality=false
CertificatePolicies [
[CertificatePolicyId: [1.3.6.1.4.1.50887.1.2]
[] ]
]
[4]: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_CertSign
Crl_Sign
]
[5]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 4F 6E AE 18 71 95 DE 3F A0 1D F5 AA 24 E7 99 11 On..q..?....$...
0010: CE BC DA B6 ....
]
]
]
Algorithm: [SHA512withRSA]
Signature:
???
]
Cert Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
Cert Subject: C=SK, ST=Poprad, L=Poprad, O=XXX, OU=Common Components System, CN=CA CCS 1
Key: RSA
Date: Fri Nov 04 17:16:56 CET 2022
]
certpath: KeySizeConstraints.permits(): RSA
certpath: -checker2 validation succeeded
certpath: -Using checker3 ... [sun.security.provider.certpath.KeyChecker]
certpath: KeyChecker.verifyCAKeyUsage() ---checking CA key usage...
certpath: KeyChecker.verifyCAKeyUsage() CA key usage verified.
certpath: -checker3 validation succeeded
certpath: -Using checker4 ... [sun.security.provider.certpath.ConstraintsChecker]
certpath: ---checking basic constraints...
certpath: i = 1, maxPathLength = 2
certpath: after processing, maxPathLength = 1
certpath: basic constraints verified.
certpath: ---checking name constraints...
certpath: prevNC = null, newNC = null
certpath: mergedNC = null
certpath: name constraints verified.
certpath: -checker4 validation succeeded
certpath: -Using checker5 ... [sun.security.provider.certpath.PolicyChecker]
certpath: PolicyChecker.checkPolicy() ---checking certificate policies...
certpath: PolicyChecker.checkPolicy() certIndex = 1
certpath: PolicyChecker.checkPolicy() BEFORE PROCESSING: explicitPolicy = 3
certpath: PolicyChecker.checkPolicy() BEFORE PROCESSING: policyMapping = 3
certpath: PolicyChecker.checkPolicy() BEFORE PROCESSING: inhibitAnyPolicy = 3
certpath: PolicyChecker.checkPolicy() BEFORE PROCESSING: policyTree = anyPolicy ROOT
certpath: PolicyChecker.processPolicies() policiesCritical = false
certpath: PolicyChecker.processPolicies() rejectPolicyQualifiers = true
certpath: PolicyChecker.processPolicies() processing policy: 1.3.6.1.4.1.50887.1.2
certpath: PolicyChecker.processParents(): matchAny = false
certpath: PolicyChecker.processParents(): matchAny = true
certpath: PolicyChecker.processParents() found parent:
anyPolicy ROOT
certpath: PolicyChecker.checkPolicy() AFTER PROCESSING: explicitPolicy = 2
certpath: PolicyChecker.checkPolicy() AFTER PROCESSING: policyMapping = 2
certpath: PolicyChecker.checkPolicy() AFTER PROCESSING: inhibitAnyPolicy = 2
certpath: PolicyChecker.checkPolicy() AFTER PROCESSING: policyTree = anyPolicy ROOT
1.3.6.1.4.1.50887.1.2 CRIT: false EP: 1.3.6.1.4.1.50887.1.2 (1)
certpath: PolicyChecker.checkPolicy() certificate policies verified
certpath: -checker5 validation succeeded
certpath: -Using checker6 ... [sun.security.provider.certpath.BasicChecker]
certpath: ---checking validity:Fri Nov 04 17:16:56 CET 2022...
certpath: validity verified.
certpath: ---checking subject/issuer name chaining...
certpath: subject/issuer name chaining verified.
certpath: ---checking signature...
certpath: signature verified.
certpath: BasicChecker.updateState issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA; subject: C=SK, ST=Poprad, L=Poprad, O=XXX, OU=Common Components System, CN=CA CCS 1; serial#: 4850766695757291669
certpath: -checker6 validation succeeded
certpath: -Using checker7 ... [sun.security.provider.certpath.RevocationChecker]
certpath: RevocationChecker.check: checking cert
SN: 4351629b fce8a095
Subject: C=SK, ST=Poprad, L=Poprad, O=XXX, OU=Common Components System, CN=CA CCS 1
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
certpath: RevocationChecker.checkCRLs() ---checking revocation status ...
certpath: RevocationChecker.checkCRLs() possible crls.size() = 1
certpath: RevocationChecker.verifyPossibleCRLs: Checking CRLDPs for C=SK, ST=Poprad, L=Poprad, O=XXX, OU=Common Components System, CN=CA CCS 1
certpath: DistributionPointFetcher.verifyCRL: checking revocation status for
SN: 4351629b fce8a095
Subject: C=SK, ST=Poprad, L=Poprad, O=XXX, OU=Common Components System, CN=CA CCS 1
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
certpath: RevocationChecker.checkCRLs() approved crls.size() = 0
certpath: RevocationChecker.verifyWithSeparateSigningKey() ---checking revocation status...
certpath: RevocationChecker.buildToNewKey() starting work
certpath: RevocationChecker.buildToNewKey() about to try build ...
certpath: SunCertPathBuilder.engineBuild([
[
Trust Anchors: [[
Trusted CA cert: [
[
Version: V3
Subject: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
Signature Algorithm: SHA512withRSA, OID = 1.2.840.113549.1.1.13
Key: Sun RSA public key, 4096 bits
params: null
modulus: ???
public exponent: 65537
Validity: [From: Mon Nov 27 17:34:03 CET 2017,
To: Thu Nov 25 17:34:03 CET 2027]
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
SerialNumber: [ 731c0174 6a4b6813]
Certificate Extensions: 5
[1]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
???
]
]
[2]: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
CA:true
PathLen: no limit
]
[3]: ObjectId: 2.5.29.32 Criticality=false
CertificatePolicies [
[CertificatePolicyId: [1.3.6.1.4.1.50887.1.2]
[] ]
]
[4]: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_CertSign
Crl_Sign
]
[5]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
???
]
]
]
Algorithm: [SHA512withRSA]
Signature:
???
]
]
Initial Policy OIDs: any
Validity Date: Fri Nov 04 17:16:56 CET 2022
Signature Provider: null
Default Revocation Enabled: false
Explicit Policy Required: false
Policy Mapping Inhibited: false
Any Policy Inhibited: false
Policy Qualifiers Rejected: true
Target Cert Constraints: RejectKeySelector: [
X509CertSelector: [
Subject: C=SK,ST=Poprad,L=Poprad,O=XXX,CN=Root CA
matchAllSubjectAltNames flag: true
Key Usage: KeyUsage [
Crl_Sign
]
][Sun RSA public key, 4096 bits
params: null
modulus: ???
public exponent: 65537]]
Certification Path Checkers: [[]]
CertStores: [[java.security.cert.CertStore@5bdc6be6, java.security.cert.CertStore@5595b4b3]]
] Maximum Path Length: 5
]
)
certpath: SunCertPathBuilder.buildForward()...
certpath: SunCertPathBuilder.depthFirstSearchForward(C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA, State [
issuerDN of last cert: null
traversedCACerts: 0
init: true
keyParamsNeeded: false
subjectNamesTraversed:
[]]
)
certpath: ForwardBuilder.getMatchingCerts()...
certpath: ForwardBuilder.getMatchingEECerts()...
certpath: X509CertSelector.match(SN: 4351629bfce8a095
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
Subject: C=SK, ST=Poprad, L=Poprad, O=XXX, OU=Common Components System, CN=CA CCS 1)
certpath: X509CertSelector.match: subject DNs don't match
certpath: X509CertSelector.match(SN: 1553cecfabe305c9
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, OU=Common Components System, CN=CA CCS 1
Subject: C=SK, ST=Slovakia, L=Poprad, O=OTest, OU=Test, CN=CNTest, CN=UIDTest)
certpath: X509CertSelector.match: subject DNs don't match
certpath: ForwardBuilder.getMatchingCACerts()...
certpath: ForwardBuilder.getMatchingCACerts(): the target is a CA
certpath: X509CertSelector.match(SN: 731c01746a4b6813
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
Subject: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA)
certpath: X509CertSelector.match returning: true
certpath: RejectKeySelector.match: bad key
certpath: X509CertSelector.match(SN: 4351629bfce8a095
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
Subject: C=SK, ST=Poprad, L=Poprad, O=XXX, OU=Common Components System, CN=CA CCS 1)
certpath: X509CertSelector.match: subject DNs don't match
certpath: X509CertSelector.match(SN: 1553cecfabe305c9
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, OU=Common Components System, CN=CA CCS 1
Subject: C=SK, ST=Slovakia, L=Poprad, O=OTest, OU=Test, CN=CNTest, CN=UIDTest)
certpath: X509CertSelector.match: subject DNs don't match
certpath: ForwardBuilder.getMatchingCACerts: found 0 CA certs
certpath: SunCertPathBuilder.depthFirstSearchForward(): certs.size=0
certpath: SunCertPathBuilder.engineBuild: 2nd pass; try building again searching all certstores
certpath: SunCertPathBuilder.buildForward()...
certpath: SunCertPathBuilder.depthFirstSearchForward(C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA, State [
issuerDN of last cert: null
traversedCACerts: 0
init: true
keyParamsNeeded: false
subjectNamesTraversed:
[]]
)
certpath: ForwardBuilder.getMatchingCerts()...
certpath: ForwardBuilder.getMatchingEECerts()...
certpath: X509CertSelector.match(SN: 4351629bfce8a095
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
Subject: C=SK, ST=Poprad, L=Poprad, O=XXX, OU=Common Components System, CN=CA CCS 1)
certpath: X509CertSelector.match: subject DNs don't match
certpath: X509CertSelector.match(SN: 1553cecfabe305c9
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, OU=Common Components System, CN=CA CCS 1
Subject: C=SK, ST=Slovakia, L=Poprad, O=OTest, OU=Test, CN=CNTest, CN=UIDTest)
certpath: X509CertSelector.match: subject DNs don't match
certpath: ForwardBuilder.getMatchingCACerts()...
certpath: ForwardBuilder.getMatchingCACerts(): the target is a CA
certpath: X509CertSelector.match(SN: 731c01746a4b6813
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
Subject: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA)
certpath: X509CertSelector.match returning: true
certpath: RejectKeySelector.match: bad key
certpath: X509CertSelector.match(SN: 4351629bfce8a095
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, CN=Root CA
Subject: C=SK, ST=Poprad, L=Poprad, O=XXX, OU=Common Components System, CN=CA CCS 1)
certpath: X509CertSelector.match: subject DNs don't match
certpath: X509CertSelector.match(SN: 1553cecfabe305c9
Issuer: C=SK, ST=Poprad, L=Poprad, O=XXX, OU=Common Components System, CN=CA CCS 1
Subject: C=SK, ST=Slovakia, L=Poprad, O=OTest, OU=Test, CN=CNTest, CN=UIDTest)
certpath: X509CertSelector.match: subject DNs don't match
certpath: ForwardBuilder.getMatchingCACerts: found 0 CA certs
certpath: SunCertPathBuilder.depthFirstSearchForward(): certs.size=0