/**
 * 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
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 */
/*
 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
 */
package javax.xml.crypto.test.dsig;

import static org.junit.Assert.*;

import java.io.*;
import java.util.*;
import java.security.*;

import javax.xml.crypto.URIDereferencer;
import javax.xml.crypto.dom.DOMStructure;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.crypto.spec.SecretKeySpec;

import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.*;

/**
 * Unit test for javax.xml.crypto.dsig.XMLSignature
 *
 */
public class XMLSignatureTest {
    private XMLSignatureFactory fac;
    private KeyInfoFactory kifac;
    private SignedInfo defSi;
    private KeyInfo defKi;
    private List<XMLObject> objs;
    private String id = "id";
    private String sigValueId = "signatureValueId";
    private Key[] SIGN_KEYS;
    private Key[] VALIDATE_KEYS;
    private SignatureMethod[] SIG_METHODS;
    private URIDereferencer ud;
    private static final String DSA_SHA256 =
        "http://www.w3.org/2009/xmldsig11#dsa-sha256";

    static {
        Security.insertProviderAt
            (new org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI(), 1);
    }

    public XMLSignatureTest() throws Exception {
        fac = XMLSignatureFactory.getInstance
            ("DOM", new org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI());
        kifac = KeyInfoFactory.getInstance
            ("DOM", new org.apache.jcp.xml.dsig.internal.dom.XMLDSigRI());

        // set up the corresponding SignatureMethod
        SIG_METHODS = new SignatureMethod[3];
        SIG_METHODS[0] = fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null);
        SIG_METHODS[1] = fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null);
        SIG_METHODS[2] = fac.newSignatureMethod(SignatureMethod.HMAC_SHA1, null);
        // set up the signingKeys
        SIGN_KEYS = new Key[3];
        SIGN_KEYS[0] = TestUtils.getPrivateKey("DSA", 1024);
        SIGN_KEYS[1] = TestUtils.getPrivateKey("RSA", 512);
        SIGN_KEYS[2] = new SecretKeySpec(new byte[16], "HmacSHA1");
        // set up the validatingKeys
        VALIDATE_KEYS = new Key[3];
        VALIDATE_KEYS[0] = TestUtils.getPublicKey("DSA", 1024);
        VALIDATE_KEYS[1] = TestUtils.getPublicKey("RSA", 512);
        VALIDATE_KEYS[2] = new SecretKeySpec(new byte[16], "HmacSHA1");
        defSi = createSignedInfo(SIG_METHODS[0]);
        defKi = kifac.newKeyInfo
            (Collections.singletonList(kifac.newKeyName("Alice")));
        objs = Collections.singletonList
            (fac.newXMLObject(null, null, null, null));
        ud = new LocalHttpCacheURIDereferencer();
    }

    @SuppressWarnings("rawtypes")
    @org.junit.Test
    public void testConstructor() throws Exception {
        XMLSignature sig = null;
        // test XMLSignatureFactory.newXMLSignature(SignedInfo, KeyInfo)
        // and XMLSignatureFactory.newXMLSignature(SignedInfo,
        //          KeyInfo, List, String, String)
        // for generating XMLSignature objects
        for (int i = 0; i < 2; i++) {
            try {
                switch (i) {
                case 0:
                    sig = fac.newXMLSignature(null, defKi);
                    break;
                case 1:
                    sig = fac.newXMLSignature(null, defKi, objs, id, sigValueId);
                    break;
                }
                fail("Should throw a NPE for null references");
            } catch (NullPointerException npe) {
            } catch (Exception ex) {
                fail("Should throw a NPE instead of " + ex +
                     " for null references");
            }
        }
        try {
            // use raw List type to test for invalid entries
            List invalidObjects = new ArrayList();
            addEntryToRawList(invalidObjects, "wrongType");
            fac.newXMLSignature(defSi, defKi, invalidObjects, id, sigValueId);
            fail("Should throw a CCE for invalid objects");
        } catch (ClassCastException cce) {
        } catch (Exception ex) {
            fail("Should throw a CCE instead of " + ex +
                 " for invalid objects");
        }
        sig = fac.newXMLSignature(defSi, defKi, objs, id, sigValueId);
        assertEquals(sig.getId(), id);
        assertEquals(sig.getKeyInfo(), defKi);
        assertTrue(Arrays.equals(sig.getObjects().toArray(), objs.toArray()));
        assertNull(sig.getSignatureValue().getValue());
        assertEquals(sig.getSignatureValue().getId(), sigValueId);
        assertEquals(sig.getSignedInfo(), defSi);

        sig = fac.newXMLSignature(defSi, defKi);
        assertNull(sig.getId());
        assertEquals(sig.getKeyInfo(), defKi);
        assertTrue(sig.getObjects().size()==0);
        assertNull(sig.getSignatureValue().getValue());
        assertNull(sig.getSignatureValue().getId());
        assertEquals(sig.getSignedInfo(), defSi);
    }

    @org.junit.Test
    public void testisFeatureSupported() throws Exception {

        XMLSignature sig = fac.newXMLSignature(defSi, null);

        try {
            sig.isFeatureSupported(null);
            fail("Should raise a NPE for null feature");
        } catch (NullPointerException npe) {}

        assertTrue(!sig.isFeatureSupported("not supported"));
    }

    @org.junit.Test
    public void testsignANDvalidate() throws Exception {
        XMLSignature sig;
        SignedInfo si;
        KeyInfo ki = null;
        XMLSignContext signContext;
        XMLValidateContext validateContext;
        boolean status = true;
        for (int i = SIGN_KEYS.length-1; i>=0 ; i--) {
            si = createSignedInfo(SIG_METHODS[i]);
            if (VALIDATE_KEYS[i] instanceof PublicKey) {
                ki = kifac.newKeyInfo(Collections.singletonList
                    (kifac.newKeyValue((PublicKey) VALIDATE_KEYS[i])));
            } else {
                ki = kifac.newKeyInfo(Collections.singletonList
                    (kifac.newKeyName("testuser")));
            }
            sig = fac.newXMLSignature(si, ki, objs, id, sigValueId);
            Document doc = TestUtils.newDocument();
            signContext = new DOMSignContext(SIGN_KEYS[i], doc);
            signContext.setURIDereferencer(ud);
            sig.sign(signContext);
            validateContext = new DOMValidateContext
                (VALIDATE_KEYS[i], doc.getDocumentElement());
            validateContext.setURIDereferencer(ud);
            if (sig.validate(validateContext) == false) {
                status = false;
                TestUtils.dumpDocument(doc, "signatureTest_out"+i+".xml");
            }
        }
        assertTrue(status);
    }

    @org.junit.Test
    public void testSignWithProvider() throws Exception {
        XMLSignature sig;
        SignedInfo si;
        KeyInfo ki = null;
        XMLSignContext signContext;
        Provider p = new TestProvider();
        for (int i = SIGN_KEYS.length-2; i>=0 ; i--) {
            si = createSignedInfo(SIG_METHODS[i]);
            if (VALIDATE_KEYS[i] instanceof PublicKey) {
                ki = kifac.newKeyInfo(Collections.singletonList
                    (kifac.newKeyValue((PublicKey) VALIDATE_KEYS[i])));
            } else {
                ki = kifac.newKeyInfo(Collections.singletonList
                    (kifac.newKeyName("testuser")));
            }
            sig = fac.newXMLSignature(si, ki, objs, id, sigValueId);
            Document doc = TestUtils.newDocument();
            signContext = new DOMSignContext(SIGN_KEYS[i], doc);
            signContext.setProperty
                ("org.jcp.xml.dsig.internal.dom.SignatureProvider", p);
            signContext.setURIDereferencer(ud);
            try {
                sig.sign(signContext);
                fail("Should have failed because TestProvider does not " +
                     "support " + SIGN_KEYS[i].getAlgorithm());
            } catch (Exception e) {
                assertTrue(e.getMessage(),
                    e.getCause() instanceof NoSuchAlgorithmException);
            }
        }
    }

    @org.junit.Test
    public void testSignWithEmptyNSPrefix() throws Exception {
        SignedInfo si = createSignedInfo(SIG_METHODS[1]);
        KeyInfo ki = kifac.newKeyInfo(Collections.singletonList
                    (kifac.newKeyValue((PublicKey) VALIDATE_KEYS[1])));
        XMLSignature sig = fac.newXMLSignature(si, ki, objs, id, sigValueId);
        Document doc = TestUtils.newDocument();
        XMLSignContext signContext = new DOMSignContext(SIGN_KEYS[1], doc);
        signContext.putNamespacePrefix(XMLSignature.XMLNS, "");
        signContext.setURIDereferencer(ud);
        sig.sign(signContext);
/*
        StringWriter sw = new StringWriter();
        dumpDocument(doc, sw);
        System.out.println(sw);
*/
    }

    @org.junit.Test
    public void testSignWithReferenceManifestDependencies() throws Exception {
        // create references
        DigestMethod dm = fac.newDigestMethod(DigestMethod.SHA1, null);
        List<Reference> refs = Collections.singletonList(fac.newReference("#object-1", dm));

        // create SignedInfo
        CanonicalizationMethod cm = fac.newCanonicalizationMethod
            (CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null);
        SignedInfo si = fac.newSignedInfo(cm, SIG_METHODS[1], refs);

        // create objects
        List<XMLObject> objs = new ArrayList<>();

        // Object 1
        List<Reference> manRefs = Collections.singletonList
            (fac.newReference("#object-2", dm));
        objs.add(fac.newXMLObject(Collections.singletonList
            (fac.newManifest(manRefs, "manifest-1")), "object-1", null, null));

        // Object 2
        Document doc = TestUtils.newDocument();
        Element nc = doc.createElementNS(null, "NonCommentandus");
        nc.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "");
        nc.appendChild(doc.createComment(" Commentandum "));
        objs.add(fac.newXMLObject(Collections.singletonList
            (new DOMStructure(nc)), "object-2", null, null));

        KeyInfo ki = kifac.newKeyInfo(Collections.singletonList
                    (kifac.newKeyValue((PublicKey) VALIDATE_KEYS[1])));

        // create XMLSignature
        XMLSignature sig = fac.newXMLSignature(si, ki, objs, "signature", null);
        DOMSignContext dsc = new DOMSignContext(SIGN_KEYS[1], doc);

        sig.sign(dsc);

/*
        StringWriter sw = new StringWriter();
        dumpDocument(doc, sw);
        System.out.println(sw);
*/

        DOMValidateContext dvc = new DOMValidateContext
            (VALIDATE_KEYS[1], doc.getDocumentElement());
        XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);

        if (sig.equals(sig2) == false) {
            throw new Exception
                ("Unmarshalled signature is not equal to generated signature");
        }
        if (sig2.validate(dvc) == false) {
            throw new Exception("Validation of generated signature failed");
        }
    }

    @org.junit.Test
    public void testSignTemplateWithObjectNSDefs() throws Exception {
        String base = System.getProperty("basedir") == null ? "./"
                      : System.getProperty("basedir");

        File f = new File(base + "/src/test/resources/javax/xml/crypto/dsig/" +
            "signature-enveloping-rsa-template.xml");

        Document doc = XMLUtils.createDocumentBuilder(false).parse(new FileInputStream(f));

        // Find Signature element
        NodeList nl =
            doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
        if (nl.getLength() == 0) {
            throw new Exception("Cannot find Signature element");
        }
        DOMStructure domSignature = new DOMStructure(nl.item(0));
        // unmarshal the XMLSignature
        XMLSignature signature = fac.unmarshalXMLSignature(domSignature);

        // create copy of Signature
        XMLSignature newSignature = fac.newXMLSignature
            (signature.getSignedInfo(), null, signature.getObjects(),
             signature.getId(), signature.getSignatureValue().getId());

        // Sign the template
        Node parent = domSignature.getNode().getParentNode();
        DOMSignContext signContext = new DOMSignContext(SIGN_KEYS[0], parent);
        // remove the signature node (since it will get recreated)
        parent.removeChild(domSignature.getNode());
        newSignature.sign(signContext);

        // check that Object element retained namespace definitions
        Element objElem = (Element)parent.getFirstChild().getLastChild();
        Attr a = objElem.getAttributeNode("xmlns:test");
        if (!a.getValue().equals("http://www.example.org/ns")) {
            throw new Exception("Object namespace definition not retained");
        }
    }

    @org.junit.Test
    public void testCreateSignatureWithEmptyId() throws Exception {
        // create references
        DigestMethod dm = fac.newDigestMethod(DigestMethod.SHA1, null);
        List<Reference> refs = Collections.singletonList
            (fac.newReference("#", dm));

        // create SignedInfo
        CanonicalizationMethod cm = fac.newCanonicalizationMethod
            (CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null);
        SignedInfo si = fac.newSignedInfo(cm, SIG_METHODS[1], refs);

        // create object with empty id
        Document doc = TestUtils.newDocument();
        XMLObject obj = fac.newXMLObject(Collections.singletonList
            (new DOMStructure(doc.createTextNode("I am the text."))),
            "", "text/plain", null);

        KeyInfo ki = kifac.newKeyInfo(Collections.singletonList
                    (kifac.newKeyValue((PublicKey) VALIDATE_KEYS[1])));

        // create XMLSignature
        XMLSignature sig = fac.newXMLSignature(si, ki,
                                               Collections.singletonList(obj),
                                               "signature", null);
        DOMSignContext dsc = new DOMSignContext(SIGN_KEYS[1], doc);
        sig.sign(dsc);
    }

    @org.junit.Test
    public void testCreateDSA2048Signature() throws Exception {

        // check if SHA256withDSA is supported
        boolean gotSHA256withDSA = false;
        try {
            Signature.getInstance("SHA256withDSA");
            gotSHA256withDSA = true;
        } catch (NoSuchAlgorithmException e) {}
        org.junit.Assume.assumeTrue(gotSHA256withDSA);

        SignatureMethod sm = fac.newSignatureMethod(DSA_SHA256, null);
        SignedInfo si = createSignedInfo(sm);
        KeyInfo ki = kifac.newKeyInfo(Collections.singletonList
            (kifac.newKeyValue((PublicKey)TestUtils.getPublicKey("DSA", 2048))));
        XMLSignature sig = fac.newXMLSignature(si, ki, objs, id, sigValueId);
        Document doc = TestUtils.newDocument();
        XMLSignContext signContext =
            new DOMSignContext(TestUtils.getPrivateKey("DSA", 2048), doc);
        signContext.setURIDereferencer(ud);
        sig.sign(signContext);
        XMLValidateContext validateContext = new DOMValidateContext
            (TestUtils.getPublicKey("DSA", 2048), doc.getDocumentElement());
        validateContext.setURIDereferencer(ud);
        assertTrue(sig.validate(validateContext));
    }

    private SignedInfo createSignedInfo(SignatureMethod sm) throws Exception {
        // set up the building blocks
        CanonicalizationMethod cm = fac.newCanonicalizationMethod
            (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
             (C14NMethodParameterSpec) null);
        DigestMethod dm = fac.newDigestMethod(DigestMethod.SHA1, null);
        List<Reference> refs = Collections.singletonList(fac.newReference
            ("http://www.w3.org/Signature/2002/04/xml-stylesheet.b64", dm));
        return fac.newSignedInfo(cm, sm, refs);
    }

    @SuppressWarnings({
     "unchecked", "rawtypes"
    })
    private static void addEntryToRawList(List list, Object entry) {
        list.add(entry);
    }

    static class TestProvider extends Provider {
        private static final long serialVersionUID = 1L;

        TestProvider() {
            super("TestProvider", 0, "TestProvider");
        }
    }
}
