You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ws.apache.org by "Jo Van Hoof (JIRA)" <ji...@apache.org> on 2016/07/16 17:21:20 UTC

[jira] [Created] (WSS-583) crypto.verifyTrust can fail when the DN of the issuer is more than once in the truststore

Jo Van Hoof created WSS-583:
-------------------------------

             Summary: crypto.verifyTrust can fail when the DN of the issuer is more than once in the truststore
                 Key: WSS-583
                 URL: https://issues.apache.org/jira/browse/WSS-583
             Project: WSS4J
          Issue Type: Bug
          Components: WSS4J Core
    Affects Versions: 2.1.6
            Reporter: Jo Van Hoof
            Assignee: Colm O hEigeartaigh
            Priority: Minor


crypto.verifyTrust can fail when the DN of the issuer is more than once in the truststore

lets assume the following situation of 2 totally separated PKI, 

* PKI 1 
ROOT CA A <- INTERMEDIATE CA A <- END CERT A

* PKI 2
ROOT CA B <- INTERMEDIATE CA B <- END CERT B

* Subject Distinguished Name of INTERMEDIATE CA A happens to be equal to Subject Distinguished Name of INTERMEDIATE CA B

* truststore contains CA's of the 2 PKI: it contains ROOT CA A, ROOT CA B, INTERMEDIATE CA A & INTERMEDIATE CA B 

-> the CertPath object constructed in verifyTrust method in the org.apache.wss4j.common.crypto.Merlin class can contain the intermediate of PKI2 even 
   if the end certificate is cryptograhically signed by intermediate of PKI 1, hence the PKIX CertPathValidator fails 

this is because there is only a string comparison when determining the issuer of a certificate before putting it to the CertPath object, i think there should be a signature verification too before putting the issuer on the CertPath object

reproducer (java 8 / wss4j-ws-security-common-2.1.6 )
{code:title=Validate.java|borderStyle=solid}
import java.security.cert.X509Certificate;
import java.security.cert.CertificateFactory;
import java.io.ByteArrayInputStream;
import java.util.Properties;
import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.crypto.CryptoFactory;
import java.util.Base64;

public class Validate {


public static void main(String[] args) {
  try {
     //end cert A
     byte [] decoded = Base64.getDecoder().decode("MIIC+DCCAeCgAwIBAgIBBDANBgkqhkiG9w0BAQUFADAaMRgwFgYDVQQDEw9JTlRFUk1FRElBVEUgQ0EwHhcNMTYwNzE2MTYwMjAwWhcNMjYwNzE2MTUwNDAwWjBGMUQwQgYDVQQDEztFTkQgQ0VSVCBTSUdORUQgQlkgSU5URVJNRURJQVRFIFRIQVQgSVMgU0lHTkVEIEJZIFJPT1QgQ0EgQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANokxXPsi4KargS5z/IqtYTvNqpcWwEUjwAMuCwgymQsZDqBU8N9oUS4aLqZErZ9T8vUrNFuHEdqKDo9iH5gY3JOirlhFD05wxBxsHF9lUcCI/hXT3VBfEIW6xGnkhCJxV/ye5Yq7uM1UWFhVAxWgNlZnOsP/uMU1EUmhwqFEYum/JfWbLQZCb3G7Oraxatq2NNIk+Huvca9cEgqNXYdiBaaPyU390iML1PN9rKTGlLaWoCLj9VyuaIsOrsD+MF6MJx16p6O4G7P7lx8fZkxbk0y5keF0WNEyBnZ9+YiVOY8EPLQVB/GySBLK0n9Z4RV2RNIL+rAuw61gn05+gpXrLsCAwEAAaMdMBswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQEFBQADggEBAFJyt2LMeO7QEjZI82N5VcMTVSlKDee0E2pzHeMPOip80wD+/Xx+PKkTyRiuSHwwK6yz/URf6P1ucHbUMIwcXTKiCY5/2imJlzC8CXoLNnwfduBP3MzyBz1L6ecV6fXJkwWzBjhaPZmZ2cISmkiNIK0vobT6PZ/ikmtCk2zyU6XFNTHssSGmZrBS6Muk+O0iT+v1DU6A7T2122cIEu5GEaR3cidcRi0c4Y4yZ8+vP8JqrQZmHe35FyHKvu/+z9/GYCQsbOT5x5ybhB3jtE60qIzYDNaOfmoxKW3b4JUpGpE5fzAz+9jwbtixjZGh2KPU/KsXBv0bIeM8qo7/aV23XbM=");
     //end cert B
     //byte [] decoded = Base64.getDecoder().decode("MIIC+DCCAeCgAwIBAgIBAzANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9JTlRFUk1FRElBVEUgQ0EwHhcNMTYwNzE2MTUyMDAwWhcNMjYwNzE2MTUwNzAwWjBGMUQwQgYDVQQDEztFTkQgQ0VSVCBTSUdORUQgQlkgSU5URVJNRURJQVRFIFRIQVQgSVMgU0lHTkVEIEJZIFJPT1QgQ0EgQjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN4Z8W4mmFoKWpCK4u427dE/mogExnerWufa1gvUfeQqUiZfln8VzUZmJMFsQy3y2Ze6T3Hj2ao1AuKUT2ouZS5MLSeKrN+UOEoqkYeb/vSNZQETJGEPhqvuEeHPbrpUqK90ioqhVRq+YDeesYO5f9LGcjSOin16aMx7voeJh+DQ1/3EpcydQs13aaC9mwpFJfqRKQzMnVAYkowO9gT8EoM57FVz8LWimXjnHZuZaRIriUA8jxSsA2AUa2M/4Nuza1idbrAwhWZO7J4IVkp0PzSucx71ebiSwE8kDPOy86SEURDnSEtOcvpiOVbGCaAc+4vNH/OVjcSluDBUDIwBmScCAwEAAaMdMBswDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQELBQADggEBAEyjZ55G4YbZR6P7QhbsQN4OrNLEJZYC822FmXVQjM540izo5sLtx2D8sR6JweGDnEtOFKgWrdwkILRrNWaZ+qws4mHYOhCcOgy/XQ1OLOHgetNu6TWvbLr6sjBGEkGABGJ6NPhpv+Z9N8qtHL9u/9e/HVkVK3e4sMtejic1t9LVlJ8mkHGBJ5qu/3jIzcuHncyXX9G/Pqsw/jkIWXSRgZQEyORpxE7J4VvFwr+D5A72bozLxgpIqSOE+xsUFXvTL89p4jlCrGeqQj/TLAKapltLcwNWljVGp4Qlk1aOM5FDIQV+eUd9y/zWcHusx1NqxI6qx9V6NjQRpvTDezZyyVg=");
     X509Certificate[] certs = new X509Certificate[1];
     certs[0]= (X509Certificate)CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(decoded));
     Properties p = new Properties();
     p.setProperty("org.apache.ws.security.crypto.merlin.truststore.file", "truststore.jks");
     p.setProperty("org.apache.ws.security.crypto.merlin.truststore.type", "jks");
     p.setProperty("org.apache.ws.security.crypto.merlin.truststore.password", "wss4j");
     Crypto crypto = CryptoFactory.getInstance(p);
     crypto.verifyTrust(certs, false,null);
    } 
    catch (Exception e) {
       e.printStackTrace();
    }

}
}
{code}

output of java -Dorg.slf4j.simpleLogger.defaultLogLevel=trace -Djava.security.debug=certpath Validate 

{noformat}
[main] DEBUG org.apache.wss4j.common.crypto.Merlin - The TrustStore truststore.jks of type jks has been loaded
[main] DEBUG org.apache.wss4j.common.crypto.Merlin - Searching keystore for cert with issuer CN=INTERMEDIATE CA and serial 4
[main] DEBUG org.apache.wss4j.common.crypto.Merlin - Keystore alias root ca b has issuer CN=ROOT CA B and serial 1
[main] DEBUG org.apache.wss4j.common.crypto.Merlin - Keystore alias root ca a has issuer CN=ROOT CA A and serial 1
[main] DEBUG org.apache.wss4j.common.crypto.Merlin - Keystore alias intermediate ca signed by root ca b has issuer CN=ROOT CA B and serial 2
[main] DEBUG org.apache.wss4j.common.crypto.Merlin - Keystore alias intermediate ca signed by root ca a has issuer CN=ROOT CA A and serial 2
[main] DEBUG org.apache.wss4j.common.crypto.Merlin - No issuer serial match found in keystore
[main] DEBUG org.apache.wss4j.common.crypto.Merlin - Searching keystore for cert with Subject CN=INTERMEDIATE CA
[main] DEBUG org.apache.wss4j.common.crypto.Merlin - Subject certificate match found using keystore alias intermediate ca signed by root ca b
[main] DEBUG org.apache.wss4j.common.crypto.Merlin - Preparing to validate certificate path for issuer CN=INTERMEDIATE CA
certpath: PKIXCertPathValidator.engineValidate()...
certpath: X509CertSelector.match(SN: 2
  Issuer: CN=ROOT CA A
  Subject: CN=INTERMEDIATE CA)
certpath: X509CertSelector.match: subject DNs don't match
certpath: NO - don't try this trustedCert
certpath: X509CertSelector.match(SN: 1
  Issuer: CN=ROOT CA B
  Subject: CN=ROOT CA B)
certpath: X509CertSelector.match returning: true
certpath: YES - try this trustedCert
certpath: anchor.getTrustedCert().getSubjectX500Principal() = CN=ROOT CA B
certpath: --------------------------------------------------------------
certpath: Executing PKIX certification path validation algorithm.
certpath: Checking cert1 - Subject: CN=INTERMEDIATE CA
certpath: Set of critical extensions: {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: -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() no policies present in cert
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 = null
certpath: PolicyChecker.checkPolicy() certificate policies verified
certpath: -checker5 validation succeeded
certpath: -Using checker6 ... [sun.security.provider.certpath.BasicChecker]
certpath: ---checking timestamp:Sat Jul 16 19:02:50 CEST 2016...
certpath: timestamp verified.
certpath: ---checking subject/issuer name chaining...
certpath: subject/issuer name chaining verified.
certpath: ---checking signature...
certpath: signature verified.
certpath: BasicChecker.updateState issuer: CN=ROOT CA B; subject: CN=INTERMEDIATE CA; serial#: 2
certpath: -checker6 validation succeeded
certpath: 
cert1 validation succeeded.

certpath: Checking cert2 - Subject: CN=END CERT SIGNED BY INTERMEDIATE THAT IS SIGNED BY ROOT CA A
certpath: Set of critical extensions: {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: -checker2 validation succeeded
certpath: -Using checker3 ... [sun.security.provider.certpath.KeyChecker]
certpath: -checker3 validation succeeded
certpath: -Using checker4 ... [sun.security.provider.certpath.ConstraintsChecker]
certpath: ---checking basic constraints...
certpath: i = 2, maxPathLength = 1
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 = 2
certpath: PolicyChecker.checkPolicy() BEFORE PROCESSING: explicitPolicy = 2
certpath: PolicyChecker.checkPolicy() BEFORE PROCESSING: policyMapping = 2
certpath: PolicyChecker.checkPolicy() BEFORE PROCESSING: inhibitAnyPolicy = 2
certpath: PolicyChecker.checkPolicy() BEFORE PROCESSING: policyTree = null
certpath: PolicyChecker.processPolicies() no policies present in cert
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 = null
certpath: PolicyChecker.checkPolicy() certificate policies verified
certpath: -checker5 validation succeeded
certpath: -Using checker6 ... [sun.security.provider.certpath.BasicChecker]
certpath: ---checking timestamp:Sat Jul 16 19:02:50 CEST 2016...
certpath: timestamp verified.
certpath: ---checking subject/issuer name chaining...
certpath: subject/issuer name chaining verified.
certpath: ---checking signature...
certpath: X509CertSelector.match(SN: 1
  Issuer: CN=ROOT CA A
  Subject: CN=ROOT CA A)
certpath: X509CertSelector.match: subject DNs don't match
certpath: NO - don't try this trustedCert
certpath: X509CertSelector.match(SN: 2
  Issuer: CN=ROOT CA B
  Subject: CN=INTERMEDIATE CA)
certpath: X509CertSelector.match: subject DNs don't match
certpath: NO - don't try this trustedCert
org.apache.wss4j.common.ext.WSSecurityException: Error during certificate path validation: signature check failed
Original Exception was java.security.cert.CertPathValidatorException: signature check failed
	at org.apache.wss4j.common.crypto.Merlin.verifyTrust(Merlin.java:895)
	at Validate.main(Validate.java:25)
Caused by: java.security.cert.CertPathValidatorException: signature check failed
	at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:135)
	at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:212)
	at sun.security.provider.certpath.PKIXCertPathValidator.validate(PKIXCertPathValidator.java:140)
	at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:79)
	at java.security.cert.CertPathValidator.validate(CertPathValidator.java:292)
	at org.apache.wss4j.common.crypto.Merlin.verifyTrust(Merlin.java:890)
	... 1 more
Caused by: java.security.SignatureException: Signature does not match.
	at sun.security.x509.X509CertImpl.verify(X509CertImpl.java:449)
	at sun.security.provider.certpath.BasicChecker.verifySignature(BasicChecker.java:166)
	at sun.security.provider.certpath.BasicChecker.check(BasicChecker.java:147)
	at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:125)
	... 6 more
{noformat}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ws.apache.org
For additional commands, e-mail: dev-help@ws.apache.org