/**
 * 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.security.MessageDigest;
import java.security.Security;
import java.util.*;
import javax.xml.crypto.URIDereferencer;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import org.w3c.dom.Document;

/**
 * Unit test for javax.xml.crypto.dsig.Reference
 *
 */
public class ReferenceTest {
    private XMLSignatureFactory fac;
    private KeyInfoFactory kifac;
    private DigestMethod dmSHA1;
    private String uri = "http://www.ietf.org/rfc/rfc3275.txt";

    private static final String[] CRYPTO_ALGS = { "RSA", "DSA" };
    private static final String[] SIG_ALGS = {
        SignatureMethod.RSA_SHA1,
        SignatureMethod.DSA_SHA1
    };

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

    public ReferenceTest() 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());
        dmSHA1 = fac.newDigestMethod(DigestMethod.SHA1, null);
    }

    @SuppressWarnings("rawtypes")
    @org.junit.Test
    public void testConstructor() throws Exception {
        Reference ref;
        // test XMLSignatureFactory.newReference(String uri,
        //     DigestMethod dm) for generating Reference objects
        ref = fac.newReference(null, dmSHA1);
        assertNotNull(ref);
        ref = fac.newReference(uri, dmSHA1);
        assertNotNull(ref);

        try {
            ref = fac.newReference("illegal!@#$%" + uri, dmSHA1);
            fail("Should throw a IAE for non-RFC2396-compliant uri");
        } catch (IllegalArgumentException iae) {
        } catch (Exception ex) {
            fail("Should throw a IAE instead of " + ex +
                 " for non-RFC2396-compliant uri");
        }

        try {
            ref = fac.newReference(uri, null);
            fail("Should throw a NPE for null dm");
        } catch (NullPointerException npe) {
        } catch (Exception ex) {
            fail("Should throw a NPE instead of " + ex + " for null dm");
        }

        // test XMLSignatureFactory.newReference(String uri,
        //    DigestMethod dm, List transforms, String type, String id)
        // for generating Reference objects
        try {
            ref = fac.newReference(null, dmSHA1, null, null, null);
            assertEquals(ref.getDigestMethod(), dmSHA1);
        } catch(Exception ex) {
            fail("Unexpected Exception: " + ex);
        }

        try {
            ref = fac.newReference(null, null, null, null, null);
            fail("Should throw a NPE for null dm");
        } catch (NullPointerException npe) {
        } catch(Exception ex) {
            fail("Should throw a NPE instead of " + ex + " for null dm");
        }

        String id = "id";
        String type = "type";
        try {
            ref = fac.newReference(uri, dmSHA1, null, type, id);
            assertNotNull(ref.getDigestMethod());
            assertEquals(uri, ref.getURI());
            assertEquals(id, ref.getId());
            assertEquals(type, ref.getType());
            assertEquals(ref.getTransforms(), Collections.EMPTY_LIST);

        } catch(Exception ex) {
            fail("Unexpected Exception: " + ex);
        }

        List<Transform> transforms = new ArrayList<>();
        try {
            // try empty transforms list
            ref = fac.newReference(uri, dmSHA1, transforms,
                                   type, id);
            assertTrue(Arrays.equals(transforms.toArray(),
                                     ref.getTransforms().toArray()));
        } catch(Exception ex) {
            fail("Unexpected Exception: " + ex);
        }
        List invalidTransforms = new ArrayList();
        addEntryToRawList(invalidTransforms, new Object());
        try {
            // try a transforms list with an invalid object
            fac.newReference(uri, dmSHA1, invalidTransforms,
                                   type, id);
        } catch (ClassCastException cce) {
        } catch (Exception ex) {
            fail("Should throw a ClassCastException instead of " + ex);
        }

        // Test with various composition of Transform list
        // 1. String only
        invalidTransforms.clear();
        addEntryToRawList(invalidTransforms, Transform.BASE64);
        try {
            // try a transforms list with a String object
            fac.newReference(uri, dmSHA1, invalidTransforms,
                                   type, id);
            fail("Should throw a CCE for illegal transforms");
        } catch (ClassCastException cce) {
        } catch(Exception ex) {
            fail("Should throw a CCE instead of " + ex +
                 " for illegal transforms");
        }

        // 2. Transform only
        transforms.clear();
        Transform c14nWithComments = fac.newTransform
            (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
             (TransformParameterSpec) null);
        transforms.add(c14nWithComments);
        try {
            // try a transforms list with a Transform object
            ref = fac.newReference(uri, dmSHA1, transforms, type, id);
            assertTrue(Arrays.equals(transforms.toArray(),
                                     ref.getTransforms().toArray()));
        } catch (Exception ex) {
            fail("Unexpected Exception: " + ex);
        }
    }

    @org.junit.Test
    public void testisFeatureSupported() throws Exception {
        Reference ref = fac.newReference(null, dmSHA1, null, null, null);
        try {
            ref.isFeatureSupported(null);
            fail("Should raise a NPE for null feature");
        } catch (NullPointerException npe) {}

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

    @org.junit.Test
    public void testvalidate() throws Exception {
        testvalidate(false);
    }

    @org.junit.Test
    public void testvalidateWithCaching() throws Exception {
        testvalidate(true);
    }

    private void testvalidate(boolean cache) throws Exception {
        Reference ref = null;
        String type = "http://www.w3.org/2000/09/xmldsig#Object";
        byte[] in = new byte[200];
        Random rand = new Random();

        // Test XMLSignContext
        XMLSignContext signContext;
        XMLValidateContext validateContext;
        for (int i = 0; i < CRYPTO_ALGS.length; i++) {
            rand.nextBytes(in);
            URIDereferencer dereferrer =
                new TestUtils.OctetStreamURIDereferencer(in);
            Document doc = TestUtils.newDocument();
            signContext = new
                DOMSignContext(TestUtils.getPrivateKey(CRYPTO_ALGS[i]), doc);
            signContext.setURIDereferencer(dereferrer);
            if (cache) {
                signContext.setProperty
                    ("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
            }
            ref = fac.newReference(null, dmSHA1, null, type, null);
            XMLSignature sig = fac.newXMLSignature(fac.newSignedInfo
                (fac.newCanonicalizationMethod
                 (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
                  (C14NMethodParameterSpec) null),
                fac.newSignatureMethod(SIG_ALGS[i], null),
                Collections.singletonList(ref)),
                kifac.newKeyInfo(Collections.singletonList
                (kifac.newKeyValue(TestUtils.getPublicKey(CRYPTO_ALGS[i])))));
            try {
                sig.sign(signContext);
                if (!cache) {
                    assertNull(ref.getDereferencedData());
                    assertNull(ref.getDigestInputStream());
                } else {
                    assertNotNull(ref.getDereferencedData());
                    assertNotNull(ref.getDigestInputStream());
                    assertTrue(digestInputEqual(ref));
                }
                validateContext = new DOMValidateContext
                    (TestUtils.getPublicKey(CRYPTO_ALGS[i]),
                    doc.getDocumentElement());
                validateContext.setURIDereferencer(dereferrer);

                if (cache) {
                    validateContext.setProperty
                        ("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
                }
                boolean result = sig.validate(validateContext);
                assertTrue(result);

                @SuppressWarnings("unchecked")
                Iterator<Reference> iter = sig.getSignedInfo().getReferences().iterator();
                while (iter.hasNext()) {
                    Reference validated_ref = iter.next();
                    if (!cache) {
                        assertNull(validated_ref.getDereferencedData());
                        assertNull(validated_ref.getDigestInputStream());
                    } else {
                        assertNotNull(validated_ref.getDereferencedData());
                        assertNotNull(validated_ref.getDigestInputStream());
                        assertTrue(digestInputEqual(validated_ref));
                    }
                    byte[] dv = validated_ref.getDigestValue();
                    byte[] cdv = validated_ref.getCalculatedDigestValue();
                    assertTrue(Arrays.equals(dv, cdv));
                    boolean valid = validated_ref.validate(validateContext);
                    assertTrue(valid);
                }
            } catch (XMLSignatureException xse) {
                fail("Unexpected Exception: " + xse);
            }
        }
    }

    private boolean digestInputEqual(Reference ref) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA1");
        InputStream is = ref.getDigestInputStream();
        int nbytes;
        byte[] buf = new byte[256];
        while ((nbytes = is.read(buf, 0, buf.length)) != -1) {
            md.update(buf, 0, nbytes);
        }
        return Arrays.equals(md.digest(), ref.getDigestValue());
    }

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