/*
 * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/**
 * @test
 * @bug 4635230 6365103 6366054 6824440
 * @summary Basic unit tests for validating XML Signatures with JSR 105
 * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java
 *     X509KeySelector.java ValidationTests.java
 * @run main ValidationTests
 * @author Sean Mullan
 */
import java.io.File;
import java.io.FileInputStream;
import java.security.*;
import javax.xml.crypto.Data;
import javax.xml.crypto.KeySelector;
import javax.xml.crypto.OctetStreamData;
import javax.xml.crypto.URIDereferencer;
import javax.xml.crypto.URIReference;
import javax.xml.crypto.URIReferenceException;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.dsig.XMLSignatureException;
import javax.xml.crypto.dsig.XMLSignatureFactory;

/**
 * This is a testcase to validate all "merlin-xmldsig-twenty-three"
 * testcases from Baltimore
 */
public class ValidationTests {

    private static SignatureValidator validator;
    private final static String DIR = System.getProperty("test.src", ".");
    private final static String DATA_DIR =
        DIR + System.getProperty("file.separator") + "data";
    private final static String KEYSTORE =
        DATA_DIR + System.getProperty("file.separator") + "certs" +
        System.getProperty("file.separator") + "xmldsig.jks";
    private final static String STYLESHEET =
        "http://www.w3.org/TR/xml-stylesheet";
    private final static String STYLESHEET_B64 =
        "http://www.w3.org/Signature/2002/04/xml-stylesheet.b64";

    private final static String[] FILES = {
        "signature-enveloped-dsa.xml",
        "signature-enveloping-b64-dsa.xml",
        "signature-enveloping-dsa.xml",
        "signature-enveloping-rsa.xml",
        "signature-enveloping-hmac-sha1.xml",
        "signature-external-dsa.xml",
        "signature-external-b64-dsa.xml",
        "signature-retrievalmethod-rawx509crt.xml",
        "signature-keyname.xml",
        "signature-x509-crt-crl.xml",
        "signature-x509-crt.xml",
        "signature-x509-is.xml",
        "signature-x509-ski.xml",
        "signature-x509-sn.xml",
//      "signature.xml",
        "exc-signature.xml",
        "sign-spec.xml"
    };

    static KeySelector skks;
    static {
        try {
            skks =
                new KeySelectors.SecretKeySelector("secret".getBytes("ASCII"));
        } catch (Exception e) {
            //should not occur
        }
    }
    private final static KeySelector SKKS = skks;
    private final static KeySelector KVKS =
        new KeySelectors.KeyValueKeySelector();
    private final static KeySelector CKS =
        new KeySelectors.CollectionKeySelector(new File(DATA_DIR));
    private final static KeySelector RXKS =
        new KeySelectors.RawX509KeySelector();
    private final static KeySelector XKS = null;
    private final static KeySelector[] KEY_SELECTORS = {
        KVKS,
        KVKS,
        KVKS,
        KVKS,
        SKKS,
        KVKS,
        KVKS,
        CKS,
        CKS,
        RXKS,
        RXKS,
        CKS,
        CKS,
        CKS,
//        XKS,
        KVKS,
        RXKS
    };
    private static URIDereferencer httpUd = null;

    public static void main(String args[]) throws Exception {
        httpUd = new HttpURIDereferencer();

        validator = new SignatureValidator(new File(DATA_DIR));

        boolean atLeastOneFailed = false;
        for (int i=0; i < FILES.length; i++) {
            System.out.println("Validating " + FILES[i]);
            if (test_signature(FILES[i], KEY_SELECTORS[i])) {
                System.out.println("PASSED");
            } else {
                System.out.println("FAILED");
                atLeastOneFailed = true;
            }
        }
        // test with reference caching enabled
        System.out.println("Validating sign-spec.xml with caching enabled");
        if (test_signature("sign-spec.xml", RXKS, true)) {
            System.out.println("PASSED");
        } else {
            System.out.println("FAILED");
            atLeastOneFailed = true;
        }

        System.out.println("Validating signature-enveloping-hmac-sha1-40.xml");
        try {
            test_signature("signature-enveloping-hmac-sha1-40.xml", SKKS, false);
            System.out.println("FAILED");
            atLeastOneFailed = true;
        } catch (XMLSignatureException xse) {
            System.out.println(xse.getMessage());
            System.out.println("PASSED");
        }

        System.out.println("Validating signature-enveloping-hmac-sha1-trunclen-0-attack.xml");
        try {
            test_signature("signature-enveloping-hmac-sha1-trunclen-0-attack.xml", SKKS, false);
            System.out.println("FAILED");
            atLeastOneFailed = true;
        } catch (XMLSignatureException xse) {
            System.out.println(xse.getMessage());
            System.out.println("PASSED");
        }

        System.out.println("Validating signature-enveloping-hmac-sha1-trunclen-8-attack.xml");
        try {
            test_signature("signature-enveloping-hmac-sha1-trunclen-8-attack.xml", SKKS, false);
            System.out.println("FAILED");
            atLeastOneFailed = true;
        } catch (XMLSignatureException xse) {
            System.out.println(xse.getMessage());
            System.out.println("PASSED");
        }

        if (atLeastOneFailed) {
            throw new Exception
                ("At least one signature did not validate as expected");
        }
    }

    public static boolean test_signature(String file, KeySelector ks)
        throws Exception {
        return test_signature(file, ks, false);
    }

    public static boolean test_signature(String file, KeySelector ks,
        boolean cache) throws Exception {
        if (ks == null) {
            KeyStore keystore = KeyStore.getInstance("JKS");
            keystore.load
                (new FileInputStream(KEYSTORE), "changeit".toCharArray());
            ks = new X509KeySelector(keystore, false);
        }
        return validator.validate(file, ks, httpUd, cache);
    }

    /**
     * This URIDereferencer returns locally cached copies of http content to
     * avoid test failures due to network glitches, etc.
     */
    private static class HttpURIDereferencer implements URIDereferencer {
        private URIDereferencer defaultUd;

        HttpURIDereferencer() {
            defaultUd = XMLSignatureFactory.getInstance().getURIDereferencer();
        }

        public Data dereference(final URIReference ref, XMLCryptoContext ctx)
        throws URIReferenceException {
            String uri = ref.getURI();
            if (uri.equals(STYLESHEET) || uri.equals(STYLESHEET_B64)) {
                try {
                    FileInputStream fis = new FileInputStream(new File
                        (DATA_DIR, uri.substring(uri.lastIndexOf('/'))));
                    return new OctetStreamData(fis,ref.getURI(),ref.getType());
                } catch (Exception e) { throw new URIReferenceException(e); }
            }

            // fallback on builtin deref
            return defaultUd.dereference(ref, ctx);
        }
    }
}
