ws-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cohei...@apache.org
Subject svn commit: r1805066 - in /webservices/wss4j/trunk/ws-security-common/src: main/java/org/apache/wss4j/common/crypto/ test/java/org/apache/wss4j/common/crypto/ test/resources/keys/nameconstraints/
Date Tue, 15 Aug 2017 11:02:50 GMT
Author: coheigea
Date: Tue Aug 15 11:02:49 2017
New Revision: 1805066

URL: http://svn.apache.org/viewvc?rev=1805066&view=rev
Log:
WSS-611 Fixes logic for extracting NameConstraint information from a cert. This closes #6.

Adds a new property so users can affirm that their cert provider can handle TrustAnchors with
NameConstraints added and updates the Merlin and MerlinAKI crypto implementations to respect
that and either add the NameConstraints or set them to null.

Includes changes made for WSS-612 (available in a separate commit) to fix the CertificateStore's
handling of certificate chains.

Signed-off-by: Colm O hEigeartaigh <coheigea@apache.org>

Added:
    webservices/wss4j/trunk/ws-security-common/src/test/java/org/apache/wss4j/common/crypto/NameConstraintsTest.java
    webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/
    webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/intermediate_signed.p12
    webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/nameconstraints.jks
    webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/root_signed.p12
    webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/self_signed.p12
Modified:
    webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/CryptoBase.java
    webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/Merlin.java
    webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/MerlinAKI.java

Modified: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/CryptoBase.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/CryptoBase.java?rev=1805066&r1=1805065&r2=1805066&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/CryptoBase.java
(original)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/CryptoBase.java
Tue Aug 15 11:02:49 2017
@@ -376,4 +376,41 @@ public abstract class CryptoBase impleme
         return true;
     }
 
+    /**
+     * Extracts the NameConstraints sequence from the certificate.
+     * Handles the case where the data is encoded directly as {@link DERDecoder#TYPE_SEQUENCE}
+     * or where the sequence has been encoded as an {@link DERDecoder#TYPE_OCTET_STRING}.
+     * <p>
+     * By contract, the values retrieved from calls to {@link X509Certificate#getExtensionValue(String)}
+     * should always be DER-encoded OCTET strings; however, because of ambiguity in the RFC
and
+     * the potential for a future breaking change to this contract, testing whether the bytes
+     * returned are tagged as a sequence or an encoded octet string is prudent. Considering
the fact
+     * that it is a single byte comparison, the performance hit is negligible.
+     *
+     * @param cert the certificate to extract NameConstraints from
+     * @return the NameConstraints, or null if not present
+     * @throws WSSecurityException if a processing error occurs decoding the Octet String
+     */
+    protected byte[]
+    getNameConstraints(
+            final X509Certificate cert
+    ) throws WSSecurityException {
+        byte[] bytes = cert.getExtensionValue(NAME_CONSTRAINTS_OID);
+        if (bytes == null || bytes.length <= 0) {
+            return null;
+        }
+
+        switch (bytes[0]) {
+            case DERDecoder.TYPE_OCTET_STRING:
+                DERDecoder extVal = new DERDecoder(bytes);
+                extVal.expect(DERDecoder.TYPE_OCTET_STRING);
+                int seqLen = extVal.getLength();
+                return extVal.getBytes(seqLen);
+            case DERDecoder.TYPE_SEQUENCE:
+                return bytes;
+            default:
+                throw new IllegalArgumentException(
+                        "Invalid type for NameConstraints; must be Sequence or OctetString-encoded
Sequence");
+        }
+    }
 }

Modified: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/Merlin.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/Merlin.java?rev=1805066&r1=1805065&r2=1805066&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/Merlin.java
(original)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/Merlin.java
Tue Aug 15 11:02:49 2017
@@ -91,6 +91,8 @@ public class Merlin extends CryptoBase {
      */
     public static final String CRYPTO_KEYSTORE_PROVIDER = "keystore.provider";
     public static final String CRYPTO_CERT_PROVIDER = "cert.provider";
+    public static final String CRYPTO_CERT_PROVIDER_HANDLES_NAME_CONSTRAINTS =
+            "cert.provider.nameconstraints";
 
     /*
      * KeyStore configuration types
@@ -127,6 +129,8 @@ public class Merlin extends CryptoBase {
     protected boolean privatePasswordSet;
     protected PasswordEncryptor passwordEncryptor;
 
+    private boolean certProviderHandlesNameConstraints = false;
+
     public Merlin() {
         // default constructor
     }
@@ -192,6 +196,11 @@ public class Merlin extends CryptoBase {
         if (certProvider != null) {
             setCryptoProvider(certProvider);
         }
+        String cpNameConstraintsProp =
+                properties.getProperty(prefix + CRYPTO_CERT_PROVIDER_HANDLES_NAME_CONSTRAINTS);
+        if (cpNameConstraintsProp != null) {
+            certProviderHandlesNameConstraints = Boolean.parseBoolean(cpNameConstraintsProp);
+        }
         //
         // Load the KeyStore
         //
@@ -834,17 +843,7 @@ public class Merlin extends CryptoBase {
         try {
             Set<TrustAnchor> set = new HashSet<>();
             if (truststore != null) {
-                Enumeration<String> truststoreAliases = truststore.aliases();
-                while (truststoreAliases.hasMoreElements()) {
-                    String alias = truststoreAliases.nextElement();
-                    X509Certificate cert =
-                        (X509Certificate) truststore.getCertificate(alias);
-                    if (cert != null) {
-                        TrustAnchor anchor =
-                            new TrustAnchor(cert, cert.getExtensionValue(NAME_CONSTRAINTS_OID));
-                        set.add(anchor);
-                    }
-                }
+                addTrustAnchors(set, truststore);
             }
 
             //
@@ -853,17 +852,7 @@ public class Merlin extends CryptoBase {
             // for backwards compatibility reasons
             //
             if (keystore != null && (truststore == null || loadCACerts)) {
-                Enumeration<String> aliases = keystore.aliases();
-                while (aliases.hasMoreElements()) {
-                    String alias = aliases.nextElement();
-                    X509Certificate cert =
-                        (X509Certificate) keystore.getCertificate(alias);
-                    if (cert != null) {
-                        TrustAnchor anchor =
-                            new TrustAnchor(cert, cert.getExtensionValue(NAME_CONSTRAINTS_OID));
-                        set.add(anchor);
-                    }
-                }
+                addTrustAnchors(set, keystore);
             }
 
             // Verify the trust path using the above settings
@@ -886,7 +875,7 @@ public class Merlin extends CryptoBase {
                     x509certs[0] = certs[0];
                     System.arraycopy(foundCertChain, 0, x509certs, 1, foundCertChain.length);
 
-                    List<X509Certificate> certList = Arrays.asList(certs);
+                    List<X509Certificate> certList = Arrays.asList(x509certs);
                     CertPath path = getCertificateFactory().generateCertPath(certList);
 
                     try {
@@ -1408,6 +1397,42 @@ public class Merlin extends CryptoBase {
     }
 
     /**
+     * Adds {@code TrustAnchor}s found in the provided key store to the set.
+     * <p>
+     * When the Trust Anchors are constructed, the value of the
+     * {@link #CRYPTO_CERT_PROVIDER_HANDLES_NAME_CONSTRAINTS} property will be checked.
+     * If it has been set to {@code true}, then {@code NameConstraint}s will be added
+     * to their Trust Anchors; if unset or set to false, the Name Constraints
+     * will be nulled out on their Trust Anchors.
+     *
+     * The default Sun PKIX Path Validator does not support Name Constraints on
+     * Trust Anchors and will throw an InvalidAlgorithmParameterException if they
+     * are provided. Other implementations may also be unsafe.
+     *
+     * @param set       the set to which to add the {@code TrustAnchor}s
+     * @param keyStore  the store to search for {@code X509Certificate}s
+     * @throws KeyStoreException if a problem occurs accessing the keyStore
+     */
+    protected void addTrustAnchors(Set<TrustAnchor> set, KeyStore keyStore)
+            throws KeyStoreException, WSSecurityException {
+        Enumeration<String> aliases = keyStore.aliases();
+        while (aliases.hasMoreElements()) {
+            String alias = aliases.nextElement();
+            X509Certificate cert =
+                    (X509Certificate) keyStore.getCertificate(alias);
+            if (cert != null) {
+                if (certProviderHandlesNameConstraints) {
+                    TrustAnchor anchor = new TrustAnchor(cert, getNameConstraints(cert));
+                    set.add(anchor);
+                } else {
+                    TrustAnchor anchor = new TrustAnchor(cert, null);
+                    set.add(anchor);
+                }
+            }
+        }
+    }
+
+    /**
      * Get an implementation-specific identifier that corresponds to the X509Certificate.
In
      * this case, the identifier is the KeyStore alias.
      * @param cert The X509Certificate corresponding to the returned identifier

Modified: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/MerlinAKI.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/MerlinAKI.java?rev=1805066&r1=1805065&r2=1805066&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/MerlinAKI.java
(original)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/MerlinAKI.java
Tue Aug 15 11:02:49 2017
@@ -168,17 +168,7 @@ public class MerlinAKI extends Merlin {
 
             Set<TrustAnchor> set = new HashSet<>();
             if (truststore != null) {
-                Enumeration<String> truststoreAliases = truststore.aliases();
-                while (truststoreAliases.hasMoreElements()) {
-                    String alias = truststoreAliases.nextElement();
-                    X509Certificate cert =
-                        (X509Certificate) truststore.getCertificate(alias);
-                    if (cert != null) {
-                        TrustAnchor anchor =
-                            new TrustAnchor(cert, cert.getExtensionValue(NAME_CONSTRAINTS_OID));
-                        set.add(anchor);
-                    }
-                }
+                addTrustAnchors(set, truststore);
             }
 
             //
@@ -187,17 +177,7 @@ public class MerlinAKI extends Merlin {
             // for backwards compatibility reasons
             //
             if (keystore != null && (truststore == null || loadCACerts)) {
-                Enumeration<String> aliases = keystore.aliases();
-                while (aliases.hasMoreElements()) {
-                    String alias = aliases.nextElement();
-                    X509Certificate cert =
-                        (X509Certificate) keystore.getCertificate(alias);
-                    if (cert != null) {
-                        TrustAnchor anchor =
-                            new TrustAnchor(cert, cert.getExtensionValue(NAME_CONSTRAINTS_OID));
-                        set.add(anchor);
-                    }
-                }
+                addTrustAnchors(set, keystore);
             }
 
             // Verify the trust path using the above settings

Added: webservices/wss4j/trunk/ws-security-common/src/test/java/org/apache/wss4j/common/crypto/NameConstraintsTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/test/java/org/apache/wss4j/common/crypto/NameConstraintsTest.java?rev=1805066&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/test/java/org/apache/wss4j/common/crypto/NameConstraintsTest.java
(added)
+++ webservices/wss4j/trunk/ws-security-common/src/test/java/org/apache/wss4j/common/crypto/NameConstraintsTest.java
Tue Aug 15 11:02:49 2017
@@ -0,0 +1,351 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.wss4j.common.crypto;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsEqual.equalTo;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.util.Loader;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests the handling of {@code NameConstraint}s with {@code TrustAnchor}s in the
+ * {@link Merlin}, {@link MerlinAKI}, and {@link CertificateStore} crypto implementations.
+ * Specifically tests the following:
+ * <ul>
+ * <li>That when Name Constraints are extracted from a certificate they are correctly
+ * decoded into a SEQUENCE</li>
+ * <li>That when the new property {@code org.apache.wss4j.crypto.merlin.cert.provider.nameconstraints}
+ * is set to true on the Merlin and MerlinAKI implementations the Trust Anchors constructed
+ * for path validation have the Name Constraints added</li>
+ * <li>That when the above property is <em>not</em> set, the Trust Anchors
have
+ * null Name Constraints added</li>
+ * </ul>
+ */
+public class NameConstraintsTest extends org.junit.Assert {
+    private static final String KEY_ROOT = "keys/nameconstraints/";
+
+    private static final String SELF_SIGNED = KEY_ROOT + "self_signed.p12";
+
+    private static final String ROOT_SIGNED = KEY_ROOT + "root_signed.p12";
+
+    private static final String INTERMEDIATE_SIGNED = KEY_ROOT + "intermediate_signed.p12";
+
+    private static final String KEYSTORE = KEY_ROOT + "nameconstraints.jks";
+
+    private static final char[] PASSWORD = "changeit".toCharArray();
+
+    private static final Pattern SUBJ_PATTERN = Pattern.compile(".*OU=wss4j,O=apache");
+
+    @Before
+    public void setup() throws Exception {
+        WSProviderConfig.init();
+    }
+
+    private KeyStore getRootKeyStore() throws Exception {
+        ClassLoader loader = Loader.getClassLoader(NameConstraintsTest.class);
+        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+
+        try (InputStream inputStream = Merlin.loadInputStream(loader, KEYSTORE)) {
+            keyStore.load(inputStream, PASSWORD);
+            return keyStore;
+        }
+    }
+
+    private KeyStore getSelfKeyStore() throws Exception {
+        ClassLoader loader = Loader.getClassLoader(NameConstraintsTest.class);
+        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+
+        try (InputStream inputStream = loader.getResourceAsStream(SELF_SIGNED)) {
+            keyStore.load(inputStream, PASSWORD);
+            return keyStore;
+        }
+    }
+
+    private X509Certificate[] getTestCertificateChain(String keychainPath) throws Exception
{
+        ClassLoader loader = Loader.getClassLoader(NameConstraintsTest.class);
+        KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
+
+        try (InputStream inputStream = loader.getResourceAsStream(keychainPath)) {
+            keystore.load(inputStream, PASSWORD);
+
+            // We're loading a single cert chain; there will be one alias
+            Enumeration<String> aliases = keystore.aliases();
+            Certificate[] certificates = keystore.getCertificateChain(aliases.nextElement());
+            assertTrue(certificates != null);
+
+            X509Certificate[] x509Certificates = new X509Certificate[certificates.length];
+            System.arraycopy(certificates, 0, x509Certificates, 0, certificates.length);
+
+            return x509Certificates;
+        }
+    }
+
+    @Test
+    public void testNameConstraints() throws Exception {
+        Merlin merlin = new Merlin();
+        X509Certificate[] certificates = getTestCertificateChain(INTERMEDIATE_SIGNED);
+
+        assertNull(merlin.getNameConstraints(certificates[0]));
+        assertNull(merlin.getNameConstraints(certificates[1]));
+
+        byte[] nameConstraints = merlin.getNameConstraints(certificates[2]);
+        assertNotNull(nameConstraints);
+        assertThat("Tag byte is wrong", nameConstraints[0], is(DERDecoder.TYPE_SEQUENCE));
+
+        TrustAnchor trustAnchor = new TrustAnchor(certificates[2], nameConstraints);
+        assertThat("TrustAnchor constraints wrong",
+                trustAnchor.getNameConstraints(),
+                equalTo(nameConstraints));
+    }
+
+    @Test
+    public void testNameConstraintsWithKeyStoreUsingMerlin() throws Exception {
+        withKeyStoreUsingMerlin(getSelfKeyStore(),
+                getTestCertificateChain(SELF_SIGNED),
+                new Merlin());
+        withKeyStoreUsingMerlin(getRootKeyStore(),
+                getTestCertificateChain(ROOT_SIGNED),
+                new Merlin());
+        withKeyStoreUsingMerlin(getRootKeyStore(),
+                getTestCertificateChain(INTERMEDIATE_SIGNED),
+                new Merlin());
+    }
+
+    @Test
+    public void testNameConstraintsWithTrustStoreUsingMerlin() throws Exception {
+        withTrustStoreUsingMerlin(getSelfKeyStore(),
+                getTestCertificateChain(SELF_SIGNED),
+                new Merlin());
+        withTrustStoreUsingMerlin(getRootKeyStore(),
+                getTestCertificateChain(ROOT_SIGNED),
+                new Merlin());
+        withTrustStoreUsingMerlin(getRootKeyStore(),
+                getTestCertificateChain(INTERMEDIATE_SIGNED),
+                new Merlin());
+    }
+
+    @Test
+    public void testNameConstraintsWithKeyStoreUsingMerlinAki() throws Exception {
+        withKeyStoreUsingMerlinAKI(getSelfKeyStore(),
+                getTestCertificateChain(SELF_SIGNED),
+                new MerlinAKI());
+        withKeyStoreUsingMerlinAKI(getRootKeyStore(),
+                getTestCertificateChain(ROOT_SIGNED),
+                new MerlinAKI());
+        withKeyStoreUsingMerlinAKI(getRootKeyStore(),
+                getTestCertificateChain(INTERMEDIATE_SIGNED),
+                new MerlinAKI());
+    }
+
+    @Test
+    public void testNameConstraintsWithTrustStoreUsingMerlinAki() throws Exception {
+        withTrustStoreUsingMerlinAKI(getSelfKeyStore(),
+                getTestCertificateChain(SELF_SIGNED),
+                new MerlinAKI());
+        withTrustStoreUsingMerlinAKI(getRootKeyStore(),
+                getTestCertificateChain(ROOT_SIGNED),
+                new MerlinAKI());
+        withTrustStoreUsingMerlinAKI(getRootKeyStore(),
+                getTestCertificateChain(INTERMEDIATE_SIGNED),
+                new MerlinAKI());
+    }
+
+    @Test
+    public void testNameConstraintsWithKeyStoreUsingMerlinBc() throws Exception {
+        withKeyStoreUsingMerlin(getSelfKeyStore(),
+                getTestCertificateChain(SELF_SIGNED),
+                getMerlinBc());
+        withKeyStoreUsingMerlin(getRootKeyStore(),
+                getTestCertificateChain(ROOT_SIGNED),
+                getMerlinBc());
+        withKeyStoreUsingMerlin(getRootKeyStore(),
+                getTestCertificateChain(INTERMEDIATE_SIGNED),
+                getMerlinBc());
+    }
+
+    @Test
+    public void testNameConstraintsWithTrustStoreUsingMerlinBc() throws Exception {
+        withTrustStoreUsingMerlin(getSelfKeyStore(),
+                getTestCertificateChain(SELF_SIGNED),
+                getMerlinBc());
+        withTrustStoreUsingMerlin(getRootKeyStore(),
+                getTestCertificateChain(ROOT_SIGNED),
+                getMerlinBc());
+        withTrustStoreUsingMerlin(getRootKeyStore(),
+                getTestCertificateChain(INTERMEDIATE_SIGNED),
+                getMerlinBc());
+    }
+
+    @Test
+    public void testNameConstraintsWithKeyStoreUsingMerlinAkiBc() throws Exception {
+        withKeyStoreUsingMerlinAKI(getSelfKeyStore(),
+                getTestCertificateChain(SELF_SIGNED),
+                getMerlinAkiBc());
+        withKeyStoreUsingMerlinAKI(getRootKeyStore(),
+                getTestCertificateChain(ROOT_SIGNED),
+                getMerlinAkiBc());
+        withKeyStoreUsingMerlinAKI(getRootKeyStore(),
+                getTestCertificateChain(INTERMEDIATE_SIGNED),
+                getMerlinAkiBc());
+    }
+
+    @Test
+    public void testNameConstraintsWithTrustStoreUsingMerlinAkiBc() throws Exception {
+        withTrustStoreUsingMerlinAKI(getSelfKeyStore(),
+                getTestCertificateChain(SELF_SIGNED),
+                getMerlinAkiBc());
+        withTrustStoreUsingMerlinAKI(getRootKeyStore(),
+                getTestCertificateChain(ROOT_SIGNED),
+                getMerlinAkiBc());
+        withTrustStoreUsingMerlinAKI(getRootKeyStore(),
+                getTestCertificateChain(INTERMEDIATE_SIGNED),
+                getMerlinAkiBc());
+    }
+
+    @Test(expected = Exception.class)
+    public void testNameConstraintsWithKeyStoreUsingMerlinBreaking() throws Exception {
+        Properties properties = new Properties();
+        properties.setProperty("org.apache.wss4j.crypto.merlin.cert.provider.nameconstraints",
+                "true");
+
+        Merlin merlin = new Merlin(properties,
+                this.getClass()
+                        .getClassLoader(),
+                null);
+
+        withKeyStoreUsingMerlin(getRootKeyStore(), getTestCertificateChain(ROOT_SIGNED),
merlin);
+    }
+
+    @Test(expected = Exception.class)
+    public void testNameConstraintsWithKeyStoreUsingMerlinAkiBreaking() throws Exception
{
+        Properties properties = new Properties();
+        properties.setProperty("org.apache.wss4j.crypto.merlin.cert.provider.nameconstraints",
+                "true");
+
+        MerlinAKI merlin = new MerlinAKI(properties,
+                this.getClass()
+                        .getClassLoader(),
+                null);
+
+        withKeyStoreUsingMerlin(getRootKeyStore(), getTestCertificateChain(ROOT_SIGNED),
merlin);
+    }
+
+    @Test
+    public void testNameConstraintsUsingCertificateStore() throws Exception {
+        usingCertificateStore(getSelfKeyStore(), getTestCertificateChain(SELF_SIGNED));
+        usingCertificateStore(getRootKeyStore(), getTestCertificateChain(ROOT_SIGNED));
+        usingCertificateStore(getRootKeyStore(), getTestCertificateChain(INTERMEDIATE_SIGNED));
+    }
+
+    private void withKeyStoreUsingMerlin(KeyStore keyStore, X509Certificate[] certificates,
+            Merlin crypto) throws Exception {
+        // Load the keystore
+        crypto.setKeyStore(keyStore);
+
+        crypto.verifyTrust(certificates, false, Collections.singletonList(SUBJ_PATTERN));
+        // No WSSecurityException thrown
+    }
+
+    private void withTrustStoreUsingMerlin(KeyStore keyStore, X509Certificate[] certificates,
+            Merlin crypto) throws Exception {
+        // Load the keystore
+        crypto.setTrustStore(keyStore);
+
+        crypto.verifyTrust(certificates, false, Collections.singletonList(SUBJ_PATTERN));
+        // No WSSecurityException thrown
+    }
+
+    private void withKeyStoreUsingMerlinAKI(KeyStore keyStore, X509Certificate[] certificates,
+            MerlinAKI crypto) throws Exception {
+        // Load the keystore
+        crypto.setKeyStore(keyStore);
+
+        crypto.verifyTrust(certificates, false, Collections.singletonList(SUBJ_PATTERN));
+        // No WSSecurityException thrown
+    }
+
+    private void withTrustStoreUsingMerlinAKI(KeyStore keyStore, X509Certificate[] certificates,
+            MerlinAKI crypto) throws Exception {
+        // Load the keystore
+        crypto.setTrustStore(keyStore);
+
+        crypto.verifyTrust(certificates, false, Collections.singletonList(SUBJ_PATTERN));
+        // No WSSecurityException thrown
+    }
+
+    private void usingCertificateStore(KeyStore keyStore, X509Certificate[] certificates)
+            throws Exception {
+        // Load the keystore
+        Enumeration<String> aliases = keyStore.aliases();
+        List<X509Certificate> certList = new ArrayList<>();
+        while (aliases.hasMoreElements()) {
+            String alias = aliases.nextElement();
+            certList.add((X509Certificate) keyStore.getCertificate(alias));
+        }
+
+        CertificateStore crypto = new CertificateStore(certList.toArray(new X509Certificate[]
{}));
+
+        crypto.verifyTrust(certificates, false, Collections.singletonList(SUBJ_PATTERN));
+        // No WSSecurityException thrown
+    }
+
+    private Merlin getMerlinBc() throws WSSecurityException, IOException {
+        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
+        Properties properties = new Properties();
+        properties.setProperty("org.apache.wss4j.crypto.merlin.cert.provider", "BC");
+        properties.setProperty("org.apache.wss4j.crypto.merlin.cert.provider.nameconstraints",
+                "true");
+
+        return new Merlin(properties,
+                this.getClass()
+                        .getClassLoader(),
+                null);
+    }
+
+    private MerlinAKI getMerlinAkiBc() throws WSSecurityException, IOException {
+        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
+        Properties properties = new Properties();
+        properties.setProperty("org.apache.wss4j.crypto.merlin.cert.provider", "BC");
+        properties.setProperty("org.apache.wss4j.crypto.merlin.cert.provider.nameconstraints",
+                "true");
+
+        return new MerlinAKI(properties,
+                this.getClass()
+                        .getClassLoader(),
+                null);
+    }
+}

Added: webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/intermediate_signed.p12
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/intermediate_signed.p12?rev=1805066&view=auto
==============================================================================
Binary files webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/intermediate_signed.p12
(added) and webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/intermediate_signed.p12
Tue Aug 15 11:02:49 2017 differ

Added: webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/nameconstraints.jks
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/nameconstraints.jks?rev=1805066&view=auto
==============================================================================
Binary files webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/nameconstraints.jks
(added) and webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/nameconstraints.jks
Tue Aug 15 11:02:49 2017 differ

Added: webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/root_signed.p12
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/root_signed.p12?rev=1805066&view=auto
==============================================================================
Binary files webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/root_signed.p12
(added) and webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/root_signed.p12
Tue Aug 15 11:02:49 2017 differ

Added: webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/self_signed.p12
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/self_signed.p12?rev=1805066&view=auto
==============================================================================
Binary files webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/self_signed.p12
(added) and webservices/wss4j/trunk/ws-security-common/src/test/resources/keys/nameconstraints/self_signed.p12
Tue Aug 15 11:02:49 2017 differ



Mime
View raw message