/**
 * 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.
 */
package org.apache.xml.security.test.dom.encryption;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.xml.security.algorithms.JCEMapper;
import org.apache.xml.security.encryption.EncryptedData;
import org.apache.xml.security.encryption.EncryptedKey;
import org.apache.xml.security.encryption.XMLCipher;
import org.apache.xml.security.keys.KeyInfo;
import org.apache.xml.security.keys.content.KeyName;
import org.apache.xml.security.keys.content.X509Data;
import org.apache.xml.security.keys.content.x509.XMLX509Certificate;
import org.apache.xml.security.keys.keyresolver.KeyResolver;
import org.apache.xml.security.test.dom.DSNamespaceContext;
import org.apache.xml.security.utils.EncryptionConstants;
import org.apache.xml.security.utils.JavaUtils;
import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;


/**
 * Interop test for XML Encryption
 *
 */
public class BaltimoreEncTest {

    private static String cardNumber;
    private static String rsaCertSerialNumber;
    private static String testDecryptString;
    private static int nodeCount = 0;
    private static byte[] jebBytes;
    private static byte[] jobBytes;
    private static byte[] jedBytes;
    private static PrivateKey rsaKey;
    private boolean haveISOPadding;
    private boolean haveKeyWraps;

    static org.slf4j.Logger LOG =
        org.slf4j.LoggerFactory.getLogger(BaltimoreEncTest.class);

    /**
     *  Constructor BaltimoreEncTest
     */
    public BaltimoreEncTest() throws Exception {
        // Create the comparison strings
        String filename =
            "src/test/resources/ie/baltimore/merlin-examples/merlin-xmlenc-five/plaintext.xml";
        String basedir = System.getProperty("basedir");
        if (basedir != null && !"".equals(basedir)) {
            filename = basedir + "/" + filename;
        }
        File f = new File(filename);

        Document doc = XMLUtils.read(new java.io.FileInputStream(f), false);

        cardNumber = retrieveCCNumber(doc);

        // Test decrypt
        testDecryptString = "top secret message\n";

        // Count the nodes in the document as a secondary test
        nodeCount = countNodes(doc);

        // Create the keys
        jebBytes = "abcdefghijklmnopqrstuvwx".getBytes(StandardCharsets.US_ASCII);
        jobBytes = "abcdefghijklmnop".getBytes(StandardCharsets.US_ASCII);
        jedBytes = "abcdefghijklmnopqrstuvwxyz012345".getBytes(StandardCharsets.US_ASCII);

        // Certificate information
        rsaCertSerialNumber = "1014918766910";

        // rsaKey
        filename = "src/test/resources/ie/baltimore/merlin-examples/merlin-xmlenc-five/rsa.p8";
        if (basedir != null && !"".equals(basedir)) {
            filename = basedir + "/" + filename;
        }

        byte[] pkcs8Bytes = JavaUtils.getBytesFromFile(filename);
        PKCS8EncodedKeySpec pkcs8Spec = new PKCS8EncodedKeySpec(pkcs8Bytes);

        // Create a key factory
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        rsaKey = keyFactory.generatePrivate(pkcs8Spec);

        // Initialise the library
        org.apache.xml.security.Init.init();

        // Register our key resolver
        KeyResolver.register("org.apache.xml.security.test.dom.encryption.BobKeyResolver", false);

        // Check what algorithms are available

        haveISOPadding = false;
        String algorithmId =
            JCEMapper.translateURItoJCEID(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128);

        if (algorithmId != null) {
            try {
                if (Cipher.getInstance(algorithmId) != null) {
                    haveISOPadding = true;
                }
            } catch (NoSuchAlgorithmException nsae) {
                //
            } catch (NoSuchPaddingException nspe) {
                //
            }
        }

        haveKeyWraps =
            JCEMapper.translateURItoJCEID(EncryptionConstants.ALGO_ID_KEYWRAP_AES128) != null;
    }

    /**
     * Method test_five_content_3des_cbc
     *
     * Check the merlin-enc-five element content test for 3DES
     */
    @org.junit.Test
    public void test_five_content_3des_cbc() throws Exception {
        if (haveISOPadding) {
            String filename =
                "src/test/resources/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-content-tripledes-cbc.xml";

            Document dd = decryptElement(filename);
            checkDecryptedDoc(dd, true);
        } else {
            LOG.warn(
                "Skipping test test_five_content_3des_cbs as necessary "
                + "crypto algorithms are not available"
            );
        }
    }

    /**
     * Method test_five_content_aes256_cbc
     *
     * Check the merlin-enc-five element content test for AES256
     */
    @org.junit.Test
    public void test_five_content_aes256_cbc() throws Exception {

        if (haveISOPadding) {
            String filename =
                "src/test/resources/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-content-aes256-cbc-prop.xml";

            Document dd = decryptElement(filename);
            checkDecryptedDoc(dd, true);
        } else {
            LOG.warn(
                "Skipping test test_five_content_aes256_cbc as necessary "
                + "crypto algorithms are not available"
            );
        }
    }

    /**
     * Method test_five_content_aes128_cbc_kw_aes192
     *
     * Check the merlin-enc-five element content test for AES128 with
     * AES 192 key wrap
     */
    @org.junit.Test
    public void test_five_content_aes128_cbc_kw_aes192() throws Exception {
        if (haveISOPadding && haveKeyWraps) {
            String filename =
                "src/test/resources/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-content-aes128-cbc-kw-aes192.xml";

            Document dd = decryptElement(filename);
            checkDecryptedDoc(dd, true);
        } else {
            LOG.warn(
                "Skipping test test_five_content_aes128_cbc_kw_aes192 as necessary "
                + "crypto algorithms are not available"
            );
        }
    }

    /**
     * Method test_five_content_3des_cbc_kw_aes128
     *
     * Check the merlin-enc-five element content test for 3DES with
     * AES 128 key wrap
     */
    @org.junit.Test
    public void test_five_content_3des_cbc_kw_aes128() throws Exception {

        if (haveISOPadding && haveKeyWraps) {
            String filename =
                "src/test/resources/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-element-tripledes-cbc-kw-aes128.xml";

            Document dd = decryptElement(filename);
            checkDecryptedDoc(dd, true);
        } else {
            LOG.warn(
                "Skipping test test_five_content_3des_cbc_kw_aes128 as necessary "
                + "crypto algorithms are not available"
            );
        }
    }

    /**
     * Method test_five_content_aes128_cbc_kw_rsa_15
     *
     * Check the merlin-enc-five element content test for AES128 with
     * RSA key wrap (PKCS 1.5 padding)
     */
    @org.junit.Test
    public void test_five_content_aes128_cbc_rsa_15() throws Exception {
        if (haveISOPadding) {
            String filename =
                "src/test/resources/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-element-aes128-cbc-rsa-1_5.xml";

            Document dd = decryptElement(filename);
            checkDecryptedDoc(dd, true);
        } else {
            LOG.warn(
                "Skipping test test_five_content_aes128_cbc_rsa_15 as necessary "
                + "crypto algorithms are not available"
            );
        }
    }

    /**
     * Method test_five_element_aes192_cbc_ref
     *
     * Check the merlin-enc-five element data test for AES192 with
     * a CipherReference element
     */
    @org.junit.Test
    public void test_five_element_aes192_cbc_ref() throws Exception {
        if (haveISOPadding) {
            String filename =
                "src/test/resources/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-element-aes192-cbc-ref.xml";

            Document dd = decryptElement(filename);
            // Note - we don't check the node count, as it will be different
            // due to the encrypted text remainin in the reference nodes
            checkDecryptedDoc(dd, false);
        } else {
            LOG.warn(
                "Skipping test test_five_element_aes192_cbc_ref as necessary "
                + "crypto algorithms are not available"
            );
        }
    }

    /**
     * Method test_five_data_aes128_cbc
     *
     * Check the merlin-enc-five element data test for AES128 with no
     * key wrap
     */
    @org.junit.Test
    public void test_five_data_aes128_cbc() throws Exception {
        if (haveISOPadding) {
            String filename =
                "src/test/resources/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-data-aes128-cbc.xml";

            byte[] decrypt = decryptData(filename);
            checkDecryptedData(decrypt);
        } else {
            LOG.warn(
                "Skipping test test_five_data_aes128_cbc as necessary "
                + "crypto algorithms are not available"
            );
        }
    }

    /**
     * Method test_five_data_aes256_cbc_3des
     *
     * Check the merlin-enc-five element data test for AES256 with 3DES
     * key wrap
     */
    @org.junit.Test
    public void test_five_data_aes256_cbc_3des() throws Exception {
        if (haveISOPadding && haveKeyWraps) {
            String filename =
                "src/test/resources/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-data-aes256-cbc-kw-tripledes.xml";

            byte[] decrypt = decryptData(filename);
            checkDecryptedData(decrypt);
        } else {
            LOG.warn(
                "Skipping test test_five_data_aes256_cbc_3des as necessary "
                + "crypto algorithms are not available"
            );
        }
    }

    /**
     * Method test_five_data_aes192_cbc_aes256
     *
     * Check the merlin-enc-five element data test for AES192 with AES256
     * key wrap
     */
    @org.junit.Test
    public void test_five_data_aes192_cbc_aes256() throws Exception {
        if (haveISOPadding && haveKeyWraps) {
            String filename =
                "src/test/resources/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-data-aes192-cbc-kw-aes256.xml";

            byte[] decrypt = decryptData(filename);
            checkDecryptedData(decrypt);
        } else {
            LOG.warn(
                "Skipping test test_five_data_aes192_cbc_aes256 as necessary "
                + "crypto algorithms are not available"
            );
        }
    }

    /**
     * Method test_five_data_3des_cbc_rsa_oaep
     *
     * Check the merlin-enc-five element data test for 3DES with
     * RSA key wrap (OAEP and no parameters)
     */
    @org.junit.Test
    public void test_five_data_3des_cbc_rsa_oaep() throws Exception {
        if (haveISOPadding) {
            String filename =
                "src/test/resources/ie/baltimore/merlin-examples/merlin-xmlenc-five/encrypt-data-tripledes-cbc-rsa-oaep-mgf1p.xml";

            byte[] decrypt = decryptData(filename);
            checkDecryptedData(decrypt);
        } else {
            LOG.warn(
                "Skipping test test_five_data_3des_cbc_rsa_oaep as necessary "
                + "crypto algorithms are not available"
            );
        }
    }

    /**
     * Method decryptElement
     *
     * Take a key, encryption type and a file, find an encrypted element
     * decrypt it and return the resulting document
     *
     * @param filename File to decrypt from
     */
    private Document decryptElement(String filename) throws Exception {
        XMLCipher cipher;

        // Parse the document in question

        String basedir = System.getProperty("basedir");
        if (basedir != null && !"".equals(basedir)) {
            filename = basedir + "/" + filename;
        }
        File f = new File(filename);

        Document doc = XMLUtils.read(new java.io.FileInputStream(f), false);

        // Now we have the document, lets build the XMLCipher element
        Element ee = null;

        // Create the XMLCipher element
        cipher = XMLCipher.getInstance();

        // Need to pre-load the Encrypted Data so we can get the key info
        ee = (Element) doc.getElementsByTagName("EncryptedData").item(0);
        cipher.init(XMLCipher.DECRYPT_MODE, null);
        EncryptedData encryptedData = cipher.loadEncryptedData(doc, ee);

        Key key = findKey(encryptedData);
        cipher.init(XMLCipher.DECRYPT_MODE, key);
        Document dd = cipher.doFinal(doc, ee);

        return dd;
    }

    /**
     * Method decryptData
     *
     * Take a file, find an encrypted element decrypt it and return the
     * resulting byte array
     *
     * @param filename File to decrypt from
     */
    private byte[] decryptData(String filename) throws Exception {

        XMLCipher cipher;

        // Parse the document in question
        String basedir = System.getProperty("basedir");
        if (basedir != null && !"".equals(basedir)) {
            filename = basedir + "/" + filename;
        }
        File f = new File(filename);

        Document doc = XMLUtils.read(new java.io.FileInputStream(f), false);

        // Now we have the document, lets build the XMLCipher element
        Element ee = null;

        // Create the XMLCipher element
        cipher = XMLCipher.getInstance();

        // Need to pre-load the Encrypted Data so we can get the key info
        ee = (Element) doc.getElementsByTagName("EncryptedData").item(0);
        cipher.init(XMLCipher.DECRYPT_MODE, null);
        EncryptedData encryptedData = cipher.loadEncryptedData(doc, ee);

        Key key = findKey(encryptedData);
        cipher.init(XMLCipher.DECRYPT_MODE, key);

        return cipher.decryptToByteArray(ee);
    }

    /**
     * Method mapKeyName
     *
     * Create a secret key from a key name for merlin-five
     *
     * @param name Name to map a key from
     */
    private SecretKey mapKeyName(String name) throws Exception {
        if ("job".equals(name)) {
            // Job is a AES-128 key
            SecretKey key = new SecretKeySpec(jobBytes, "AES");
            return key;
        }
        if ("jeb".equals(name)) {
            // Jeb is a AES-192 key
            SecretKey key = new SecretKeySpec(jebBytes, "AES");
            return key;
        }
        if ("jed".equals(name)) {
            // Jed is a AES-256 key
            SecretKey key = new SecretKeySpec(jedBytes, "AES");
            return key;
        }

        return null;
    }

    /**
     * Method findKey
     *
     * Given an encryptedData structure, return the key that will decrypt
     * it
     *
     * @param encryptedData EncryptedData to get key for
     */
    private Key findKey(EncryptedData encryptedData) throws Exception {
        KeyInfo ki = encryptedData.getKeyInfo();

        Key key = null;
        Key kek = null;

        if (ki == null) {
            return null;
        }

        // First check for a known key name
        KeyName keyName = ki.itemKeyName(0);
        if (keyName != null) {
            return mapKeyName(keyName.getKeyName());
        }

        // Decrypt any encryptedKey structures
        EncryptedKey encryptedKey = ki.itemEncryptedKey(0);
        if (encryptedKey == null) {
            return null;
        }

        KeyInfo kiek = encryptedKey.getKeyInfo();
        if (kiek == null) {
            return null;
        }

        KeyName kekKeyName = kiek.itemKeyName(0);
        if (kekKeyName != null) {
            kek = mapKeyName(kekKeyName.getKeyName());
        } else {
            X509Data certData = kiek.itemX509Data(0);
            XMLX509Certificate xcert = certData.itemCertificate(0);
            X509Certificate cert = xcert.getX509Certificate();

            if (cert != null && cert.getSerialNumber().toString().equals(rsaCertSerialNumber)) {
                kek = rsaKey;
            }
        }
        if (kek != null) {
            XMLCipher cipher = XMLCipher.getInstance();
            cipher.init(XMLCipher.UNWRAP_MODE, kek);
            key =
                cipher.decryptKey(
                    encryptedKey, encryptedData.getEncryptionMethod().getAlgorithm()
                );
        }

        return key;
    }

    /**
     * Method countNodes
     *
     * Recursively count the number of nodes in the document
     *
     * @param n Node to count beneath
     */
    private static int countNodes(Node n) {

        if (n == null) {
            return 0;  // Paranoia
        }

        int count = 1;  // Always count myself
        Node c = n.getFirstChild();

        while (c != null) {
            count += countNodes(c);
            c = c.getNextSibling();
        }

        return count;
    }

    /**
     * Method retrieveCCNumber
     *
     * Retrieve the credit card number from the payment info document
     *
     * @param doc The document to retrieve the card number from
     * @return The retrieved credit card number
     * @throws XPathExpressionException
     */
    private static String retrieveCCNumber(Document doc)
        throws javax.xml.transform.TransformerException,
        XPathExpressionException {

        XPathFactory xpf = XPathFactory.newInstance();
        XPath xpath = xpf.newXPath();
        Map<String, String> namespace = new HashMap<>();
        namespace.put("x", "urn:example:po");
        DSNamespaceContext context = new DSNamespaceContext(namespace);
        xpath.setNamespaceContext(context);

        String expression = "//x:Number/text()";
        Node ccnumElt =
            (Node) xpath.evaluate(expression, doc, XPathConstants.NODE);

        if (ccnumElt != null) {
            return ccnumElt.getNodeValue();
        }

        return null;
    }

    /*
     * Check we have retrieved a Credit Card number and that it is OK
     * Check that the document has the correct number of nodes
     */
    private void checkDecryptedDoc(Document d, boolean doNodeCheck) throws Exception {

        String cc = retrieveCCNumber(d);
        LOG.debug("Retrieved Credit Card : " + cc);
        assertEquals(cardNumber, cc);

        // Test cc numbers
        if (doNodeCheck) {
            int myNodeCount = countNodes(d);

            assertTrue(
                "Node count mismatches", myNodeCount > 0 && myNodeCount == nodeCount
            );
        }
    }

    /**
     * Check a decrypt of data was OK
     */
    private void checkDecryptedData(byte[] data) throws Exception {
        String input = new String(data, StandardCharsets.US_ASCII);
        assertEquals(testDecryptString, input);
    }
}