Andreas Martens created RAMPART-461:
---------------------------------------
Summary: Can't validate cert used for encryption that's not
present in keystore/truststore
Key: RAMPART-461
URL: https://issues.apache.org/jira/browse/RAMPART-461
Project: Rampart
Issue Type: Bug
Components: rampart-core
Affects Versions: 2.0.0
Reporter: Andreas Martens
When the client performs encryption and places its cert in the message, WSS4J
accepts it because the cert is signed by a CA in the truststore, but Rampart
isn't.
AI writeup:
{{org.apache.rampart.PolicyBasedResultsValidator.isCertificateInKeyStore(Crypto,
X509Certificate)}} assumes {{Crypto.getX509Certificates(CryptoType)}} returns
{{null}} when no certificate matches:
{{X509Certificate[] foundCerts = new X509Certificate[0];try { foundCerts =
crypto.getX509Certificates(cryptoType); // ISSUER_SERIAL lookup} catch
(WSSecurityException e) \{ ... }if (foundCerts != null && foundCerts[0] != null
&& foundCerts[0].equals(cert)) { ... return true;}return false;}}
WSS4J 2.x and later return an empty array, never {{{}null{}}}, when nothing
matches. For example, {{Merlin.getX509Certificates(String issuer, BigInteger
serial)}} ends with {{{}return new X509Certificate[0]{}}}. The check
{{foundCerts != null}} passes, then {{foundCerts[0]}} throws
{{{}ArrayIndexOutOfBoundsException{}}}.
The method is documented as "directly copied from WSS4J
(SignatureTrustValidator)". WSS4J's own versions of this check include the
length guard: {{{}foundCerts != null && foundCerts.length > 0 && foundCerts[0]
!= null && foundCerts[0].equals(...){}}}, for example in {{Merlin}} and
{{{}CertificateStore{}}}.
*Impact:* The failure only happens when the message signer's certificate is
trusted through its issuing CA and is not itself in the keystore or truststore.
That is the normal PKI deployment. Any inbound message signed by such a
certificate fails with an AIOOBE, whereas the expected behaviour is to fall
through to the issuer-chain check in {{isCertificateTrusted}} (steps 2 and 3).
This hides the bug from deployments that pin the client certificate.
*Steps to reproduce:*
# Truststore contains only the CA certificates (root and intermediate). The
signer's end-entity certificate is in neither the keystore nor the truststore.
# Client signs the request with {{AsymmetricBinding}} and an {{X509Token}}
whose {{IncludeToken}} includes the cert as a {{{}BinarySecurityToken{}}}. The
client's certificate is issued by the intermediate CA.
# The server runs {{RampartReceiver}} with the default
{{{}PolicyBasedResultsValidator{}}}.
# WSS4J's {{SignatureTrustValidator}} accepts the signature, because the
certificate path verifies to the intermediate CA.
# Rampart's {{PolicyBasedResultsValidator.validate}} then calls
{{{}verifyTrust{}}}, which calls {{{}isCertificateTrusted{}}}, which calls
{{{}isCertificateInKeyStore{}}}.
*Actual:*
{{java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 0 at
org.apache.rampart.PolicyBasedResultsValidator.isCertificateInKeyStore(PolicyBasedResultsValidator.java:934)
at
org.apache.rampart.PolicyBasedResultsValidator.isCertificateTrusted(PolicyBasedResultsValidator.java:833)
at
org.apache.rampart.PolicyBasedResultsValidator.verifyTrust(PolicyBasedResultsValidator.java:791)
at
org.apache.rampart.PolicyBasedResultsValidator.validate(PolicyBasedResultsValidator.java:196)
at org.apache.rampart.RampartEngine.process(RampartEngine.java:408)}}
*Expected:* {{isCertificateInKeyStore}} returns {{false}} when no certificate
matches, and {{isCertificateTrusted}} continues to the issuer lookup and path
validation.
*Proposed fix:* add {{foundCerts.length > 0 &&}} to the condition.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]