/*
 * 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.camel.dataformat.xmlsecurity;

import java.nio.charset.Charset;
import java.security.Key;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.KeyGenerator;
import javax.xml.transform.OutputKeys;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.converter.jaxp.XmlConverter;
import org.apache.camel.support.jsse.KeyStoreParameters;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.apache.commons.codec.Charsets;
import org.apache.xml.security.encryption.XMLCipher;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * Unit test of the encryptXML data format.
 */
public class XMLSecurityDataFormatTest extends CamelTestSupport {

    protected static String testCypherAlgorithm = XMLCipher.AES_128;

    TestHelper xmlsecTestHelper = new TestHelper();

    private Key defaultKey;

    @Override
    public boolean isUseRouteBuilder() {
        return false;
    }

    @Override
    @Before
    public void setUp() throws Exception {
        super.setUp();
        context.getGlobalOptions().put(XmlConverter.OUTPUT_PROPERTIES_PREFIX + OutputKeys.ENCODING, "UTF-8");
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(256);
        defaultKey = keyGenerator.generateKey();
    }


    /*
     * Encryption Tests
     */

    @Test
    public void testFullPayloadXMLEncryption() throws Exception {
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML(defaultKey.getEncoded())
                    .to("mock:encrypted");
            }
        });
        xmlsecTestHelper.testEncryption(context);
    }

    @Test
    public void testPartialPayloadXMLContentEncryption() throws Exception {
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("//cheesesites/italy/cheese", true, defaultKey.getEncoded())
                    .to("mock:encrypted");
            }
        });
        xmlsecTestHelper.testEncryption(context);
    }

    @Test
    public void testPartialPayloadMultiNodeXMLContentEncryption() throws Exception {
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                     .marshal().secureXML("//cheesesites/*/cheese", true, defaultKey.getEncoded())
                     .to("mock:encrypted");
            }
        });
        xmlsecTestHelper.testEncryption(context);
    }

    @Test
    public void testPartialPayloadXMLElementEncryptionWithKeyAndAlgorithm() throws Exception {
        final byte[] bits128 = {
            (byte) 0x08, (byte) 0x09, (byte) 0x0A, (byte) 0x0B,
            (byte) 0x0C, (byte) 0x0D, (byte) 0x0E, (byte) 0x0F,
            (byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13,
            (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17};

        final String passCode = new String(bits128);
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("//cheesesites/netherlands", false, passCode, XMLCipher.AES_128)
                    .to("mock:encrypted");
            }
        });
        xmlsecTestHelper.testEncryption(context);
    }

    @Test
    public void testPartialPayloadXMLElementEncryptionWithByteKeyAndAlgorithm() throws Exception {
        final byte[] bits192 = {
            (byte)0x24, (byte)0xf2, (byte)0xd3, (byte)0x45,
            (byte)0xc0, (byte)0x75, (byte)0xb1, (byte)0x00,
            (byte)0x30, (byte)0xd4, (byte)0x3d, (byte)0xf5,
            (byte)0x6d, (byte)0xaa, (byte)0x7d, (byte)0xc2,
            (byte)0x85, (byte)0x32, (byte)0x2a, (byte)0xb6,
            (byte)0xfe, (byte)0xed, (byte)0xbe, (byte)0xef};

        final Charset passCodeCharset = Charsets.UTF_8;
        final String passCode = new String(bits192, passCodeCharset);
        byte[] bytes = passCode.getBytes(passCodeCharset);
        assertTrue(bits192.length != bytes.length);
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("//cheesesites/netherlands", false, bits192, XMLCipher.AES_192)
                    .to("mock:encrypted");
            }
        });
        xmlsecTestHelper.testEncryption(context);
    }


    @Test
    public void testFullPayloadAsymmetricKeyEncryption() throws Exception {
        KeyStoreParameters tsParameters = new KeyStoreParameters();
        tsParameters.setPassword("password");
        tsParameters.setResource("sender.ts");

        final XMLSecurityDataFormat xmlEncDataFormat = new XMLSecurityDataFormat();
        xmlEncDataFormat.setKeyCipherAlgorithm(XMLCipher.RSA_v1dot5);
        xmlEncDataFormat.setKeyOrTrustStoreParameters(tsParameters);
        xmlEncDataFormat.setXmlCipherAlgorithm(testCypherAlgorithm);
        xmlEncDataFormat.setRecipientKeyAlias("recipient");

        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal(xmlEncDataFormat).to("mock:encrypted");
            }
        });
        xmlsecTestHelper.testEncryption(context);
    }

    @Test
    public void testPartialPayloadAsymmetricKeyEncryptionWithContextTruststoreProperties() throws Exception {
        final KeyStoreParameters tsParameters = new KeyStoreParameters();
        tsParameters.setPassword("password");
        tsParameters.setResource("sender.ts");

        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("//cheesesites/italy/cheese", true, "recipient", testCypherAlgorithm, XMLCipher.RSA_v1dot5, tsParameters)
                    .to("mock:encrypted");
            }
        });
        xmlsecTestHelper.testEncryption(context);
    }

    @Test
    public void testAsymmetricEncryptionAddKeyValue() throws Exception {
        KeyStoreParameters tsParameters = new KeyStoreParameters();
        tsParameters.setPassword("password");
        tsParameters.setResource("sender.ts");

        final XMLSecurityDataFormat xmlEncDataFormat = new XMLSecurityDataFormat();
        xmlEncDataFormat.setKeyOrTrustStoreParameters(tsParameters);
        xmlEncDataFormat.setXmlCipherAlgorithm(testCypherAlgorithm);
        xmlEncDataFormat.setRecipientKeyAlias("recipient");
        xmlEncDataFormat.setAddKeyValueForEncryptedKey(true);

        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal(xmlEncDataFormat).to("mock:encrypted");
            }
        });
        Document doc = xmlsecTestHelper.testEncryption(TestHelper.XML_FRAGMENT, context);
        NodeList nodeList =
            doc.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "RSAKeyValue");
        Assert.assertTrue(nodeList.getLength() > 0);
    }

    @Test
    public void testAsymmetricEncryptionNoKeyValue() throws Exception {
        KeyStoreParameters tsParameters = new KeyStoreParameters();
        tsParameters.setPassword("password");
        tsParameters.setResource("sender.ts");

        final XMLSecurityDataFormat xmlEncDataFormat = new XMLSecurityDataFormat();
        xmlEncDataFormat.setKeyOrTrustStoreParameters(tsParameters);
        xmlEncDataFormat.setXmlCipherAlgorithm(testCypherAlgorithm);
        xmlEncDataFormat.setRecipientKeyAlias("recipient");
        xmlEncDataFormat.setAddKeyValueForEncryptedKey(false);

        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal(xmlEncDataFormat).to("mock:encrypted");
            }
        });
        Document doc = xmlsecTestHelper.testEncryption(TestHelper.XML_FRAGMENT, context);
        NodeList nodeList =
            doc.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "RSAKeyValue");
        Assert.assertTrue(nodeList.getLength() == 0);
    }

    /*
    * Decryption Tests
    */
    @Test
    public void testFullPayloadXMLDecryption() throws Exception {
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML(defaultKey.getEncoded()).to("mock:encrypted")
                    .unmarshal().secureXML(defaultKey.getEncoded()).to("mock:decrypted");
            }
        });
        xmlsecTestHelper.testDecryption(context);
    }

    @Test
    public void testPartialPayloadXMLContentDecryption() throws Exception {
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("//cheesesites/italy/cheese", true, defaultKey.getEncoded()).to("mock:encrypted")
                    .unmarshal().secureXML("//cheesesites/italy/cheese", true, defaultKey.getEncoded()).to("mock:decrypted");
            }
        });
        xmlsecTestHelper.testDecryption(context);
    }

    @Test
    public void testPartialPayloadMultiNodeXMLContentDecryption() throws Exception {
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("//cheesesites/*/cheese", true, defaultKey.getEncoded()).to("mock:encrypted")
                    .unmarshal().secureXML("//cheesesites/*/cheese", true, defaultKey.getEncoded()).to("mock:decrypted");
            }
        });
        xmlsecTestHelper.testDecryption(context);
    }

    @Test
    public void testPartialPayloadXMLElementDecryptionWithKey() throws Exception {
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("//cheesesites/france/cheese", false, defaultKey.getEncoded()).to("mock:encrypted")
                    .unmarshal().secureXML("//cheesesites/france", false, defaultKey.getEncoded()).to("mock:decrypted");
            }
        });
        xmlsecTestHelper.testDecryption(context);
    }

    @Test
    public void testXMLElementDecryptionWithoutEncryptedKey() throws Exception {
        if (!TestHelper.HAS_3DES) {
            return;
        }
        String passPhrase = "this is a test passphrase";

        byte[] bytes = passPhrase.getBytes();
        final byte[] keyBytes = Arrays.copyOf(bytes, 24);
        for (int j = 0, k = 16; j < 8;) {
            keyBytes[k++] = keyBytes[j++];
        }

        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("timer://foo?period=5000&repeatCount=1").
                to("language:constant:resource:classpath:org/apache/camel/component/xmlsecurity/EncryptedMessage.xml")
                .unmarshal()
                        .secureXML("/*[local-name()='Envelope']/*[local-name()='Body']",
                                   true, keyBytes, XMLCipher.TRIPLEDES)
                        .to("mock:decrypted");
            }
        });
        xmlsecTestHelper.testDecryptionNoEncryptedKey(context);
    }

    @Test
    public void testPartialPayloadXMLContentDecryptionWithKeyAndAlgorithm() throws Exception {
        final byte[] bits128 = {
            (byte) 0x08, (byte) 0x09, (byte) 0x0A, (byte) 0x0B,
            (byte) 0x0C, (byte) 0x0D, (byte) 0x0E, (byte) 0x0F,
            (byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13,
            (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17};
        final String passCode = new String(bits128);

        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("//cheesesites/italy", true, passCode, XMLCipher.AES_128).to("mock:encrypted")
                    .unmarshal().secureXML("//cheesesites/italy", true, passCode, XMLCipher.AES_128).to("mock:decrypted");
            }
        });
        xmlsecTestHelper.testDecryption(context);
    }

    @Test
    public void testFullPayloadAsymmetricKeyDecryption() throws Exception {

        final KeyStoreParameters tsParameters = new KeyStoreParameters();
        tsParameters.setPassword("password");
        tsParameters.setResource("sender.ts");

        final KeyStoreParameters ksParameters = new KeyStoreParameters();
        ksParameters.setPassword("password");
        ksParameters.setResource("recipient.ks");

        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("", true, "recipient", testCypherAlgorithm, XMLCipher.RSA_v1dot5, tsParameters).to("mock:encrypted")
                    .unmarshal().secureXML("", true, "recipient", testCypherAlgorithm, XMLCipher.RSA_v1dot5, ksParameters).to("mock:decrypted");
            }
        });
        xmlsecTestHelper.testDecryption(context);
    }

    @Test
    public void testFullPayloadAsymmetricKeyDecryptionWithKeyPassword() throws Exception {

        final KeyStoreParameters tsParameters = new KeyStoreParameters();
        tsParameters.setPassword("password");
        tsParameters.setResource("sender.ts");

        final KeyStoreParameters ksParameters = new KeyStoreParameters();
        ksParameters.setPassword("password");
        ksParameters.setResource("recipient-with-key-pass.ks");

        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("", true, "recipient", testCypherAlgorithm, XMLCipher.RSA_v1dot5, tsParameters).to("mock:encrypted")
                    .unmarshal().secureXML("", true, "recipient", testCypherAlgorithm, XMLCipher.RSA_v1dot5, ksParameters, "keyPassword").to("mock:decrypted");
            }
        });
        xmlsecTestHelper.testDecryption(context);
    }

    @Test
    public void testPartialPayloadAsymmetricKeyDecryption() throws Exception {
        final Map<String, String> namespaces = new HashMap<>();
        namespaces.put("ns1", "http://cheese.xmlsecurity.camel.apache.org/");

        final KeyStoreParameters tsParameters = new KeyStoreParameters();
        tsParameters.setPassword("password");
        tsParameters.setResource("sender.ts");

        final KeyStoreParameters ksParameters = new KeyStoreParameters();
        ksParameters.setPassword("password");
        ksParameters.setResource("recipient.ks");

        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("//ns1:cheesesites/italy", namespaces, true, "recipient", testCypherAlgorithm, XMLCipher.RSA_v1dot5, tsParameters).to("mock:encrypted")
                    .unmarshal().secureXML("//ns1:cheesesites/italy", namespaces, true, "recipient", testCypherAlgorithm, XMLCipher.RSA_v1dot5, ksParameters).to("mock:decrypted");
            }
        });
        xmlsecTestHelper.testDecryption(TestHelper.NS_XML_FRAGMENT, context);
    }

    @Test
    public void testPartialPayloadAsymmetricKeyDecryptionCustomNS() throws Exception {
        final KeyStoreParameters tsParameters = new KeyStoreParameters();
        tsParameters.setPassword("password");
        tsParameters.setResource("sender.ts");

        final KeyStoreParameters ksParameters = new KeyStoreParameters();
        ksParameters.setPassword("password");
        ksParameters.setResource("recipient.ks");


        final Map<String, String> namespaces = new HashMap<>();
        namespaces.put("cust", "http://cheese.xmlsecurity.camel.apache.org/");


        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("//cust:cheesesites/italy", namespaces, true, "recipient", testCypherAlgorithm, XMLCipher.RSA_v1dot5, tsParameters).to("mock:encrypted")
                    .unmarshal().secureXML("//cust:cheesesites/italy", namespaces, true, "recipient", testCypherAlgorithm, XMLCipher.RSA_v1dot5, ksParameters).to("mock:decrypted");
            }
        });
        xmlsecTestHelper.testDecryption(TestHelper.NS_XML_FRAGMENT, context);
    }

    @Test
    public void testAsymmetricEncryptionAlgorithmFullPayload() throws Exception {

        final KeyStoreParameters tsParameters = new KeyStoreParameters();
        tsParameters.setPassword("password");
        tsParameters.setResource("sender.ts");

        final KeyStoreParameters ksParameters = new KeyStoreParameters();
        ksParameters.setPassword("password");
        ksParameters.setResource("recipient.ks");

        // RSA v1.5 is not allowed unless explicitly configured
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("", true, "recipient", testCypherAlgorithm, XMLCipher.RSA_v1dot5, tsParameters).to("mock:encrypted")
                    .unmarshal().secureXML("", true, "recipient", testCypherAlgorithm, XMLCipher.RSA_OAEP, ksParameters).to("mock:decrypted");
            }
        });

        MockEndpoint resultEndpoint = context.getEndpoint("mock:decrypted", MockEndpoint.class);
        resultEndpoint.setExpectedMessageCount(0);
        // verify that the message was encrypted before checking that it is decrypted
        xmlsecTestHelper.testEncryption(TestHelper.XML_FRAGMENT, context);

        resultEndpoint.assertIsSatisfied(100);
    }

    @Test
    public void testAsymmetricEncryptionAlgorithmPartialPayload() throws Exception {

        final KeyStoreParameters tsParameters = new KeyStoreParameters();
        tsParameters.setPassword("password");
        tsParameters.setResource("sender.ts");

        final KeyStoreParameters ksParameters = new KeyStoreParameters();
        ksParameters.setPassword("password");
        ksParameters.setResource("recipient.ks");

        // RSA v1.5 is not allowed unless explicitly configured
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("//cheesesites/italy", true, "recipient", testCypherAlgorithm, XMLCipher.RSA_v1dot5, tsParameters).to("mock:encrypted")
                    .unmarshal().secureXML("//cheesesites/italy", true, "recipient", testCypherAlgorithm, XMLCipher.RSA_OAEP, ksParameters).to("mock:decrypted");
            }
        });

        MockEndpoint resultEndpoint = context.getEndpoint("mock:decrypted", MockEndpoint.class);
        resultEndpoint.setExpectedMessageCount(0);
        // verify that the message was encrypted before checking that it is decrypted
        xmlsecTestHelper.testEncryption(TestHelper.XML_FRAGMENT, context);

        resultEndpoint.assertIsSatisfied(100);
    }

    @Test
    public void testAsymmetricEncryptionAlgorithmPartialPayloadElement() throws Exception {

        final KeyStoreParameters tsParameters = new KeyStoreParameters();
        tsParameters.setPassword("password");
        tsParameters.setResource("sender.ts");

        final KeyStoreParameters ksParameters = new KeyStoreParameters();
        ksParameters.setPassword("password");
        ksParameters.setResource("recipient.ks");

        // RSA v1.5 is not allowed unless explicitly configured
        context.addRoutes(new RouteBuilder() {
            public void configure() {
                from("direct:start")
                    .marshal().secureXML("//cheesesites/france/cheese", false, "recipient", testCypherAlgorithm, XMLCipher.RSA_v1dot5, tsParameters).to("mock:encrypted")
                    .unmarshal().secureXML("//cheesesites/france", false, "recipient", testCypherAlgorithm, XMLCipher.RSA_OAEP, ksParameters).to("mock:decrypted");
            }
        });

        MockEndpoint resultEndpoint = context.getEndpoint("mock:decrypted", MockEndpoint.class);
        resultEndpoint.setExpectedMessageCount(0);
        // verify that the message was encrypted before checking that it is decrypted
        xmlsecTestHelper.testEncryption(TestHelper.XML_FRAGMENT, context);

        resultEndpoint.assertIsSatisfied(100);
    }
}
