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:22:20 UTC

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

     [ https://issues.apache.org/jira/browse/WSS-583?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Jo Van Hoof updated WSS-583:
----------------------------
    Attachment: truststore.jks
                certificates.zip

certificates used for the reproducer

> 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
>         Attachments: certificates.zip, truststore.jks
>
>
> 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