0

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
Bully
  • 139
  • 1
  • 14

0 Answers0