/**
 * 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.
 */

/*
 * XSEC
 *
 * SimpleEncrypt := An application to generate an XML document (via Xerces) and encrypt
 *					a portion of it
 *
 * $Id$
 *
 */

#include "IOStreamOutputter.hpp"

// Xerces

#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>

// XML-Security-C (XSEC)

#include <xsec/framework/XSECProvider.hpp>
#include <xsec/framework/XSECException.hpp>
#include <xsec/xenc/XENCCipher.hpp>

#ifdef XSEC_HAVE_OPENSSL
# include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>
# include <openssl/bio.h>
# include <openssl/evp.h>
# include <openssl/pem.h>
#endif

#include "../utils/XSECDOMUtils.hpp"

// Xalan

#ifdef XSEC_HAVE_XALAN
#include <xalanc/XalanTransformer/XalanTransformer.hpp>

// If this isn't defined, we're on Xalan 1.12+ and require modern C++
#ifndef XALAN_USING_XALAN
# define XALAN_USING_XALAN(NAME) using xalanc :: NAME;
#endif

XALAN_USING_XALAN(XalanTransformer)
#endif

// OpenSSL

XERCES_CPP_NAMESPACE_USE

char letter[] = "\n\
<Letter>\n\
<ToAddress>The address of the Recipient</ToAddress>\n\
<FromAddress>The address of the Sender</FromAddress>\n\
<xenc:EncryptedData Type=\"http://www.w3.org/2001/04/xmlenc#Element\" xmlns:xenc=\"http://www.w3.org/2001/04/xmlenc#\">\n\
<xenc:EncryptionMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#tripledes-cbc\"/>\n\
<ds:KeyInfo xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\">\n\
<xenc:EncryptedKey xmlns:xenc=\"http://www.w3.org/2001/04/xmlenc#\">\n\
<xenc:EncryptionMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#rsa-1_5\"/>\n\
<xenc:CipherData>\n\
<xenc:CipherValue>UDH9I9k6dRvlIS7fHLMONtlP24mqEDPzsjSYUg4X5SSzUFskiVaOIzhYPeF21ZeG\n\
MCmdo6wsu6TQB0XebmvJR2wgvYqDd2L2IbXZ1zj2/G7FbVsB/GSGxuQTFw22aMFd\n\
l47P8bKjxX8cUwwYFzbGAUfkgeQp5DglmnJYJPO1cTw=\n\
</xenc:CipherValue>\n\
</xenc:CipherData>\n\
</xenc:EncryptedKey>\n\
</ds:KeyInfo>\n\
<xenc:CipherData>\n\
<xenc:CipherValue>Q7M6QhZOqjyYXdUDOw809dGEJWkyAygRv7r3EJ8FlcY7dYpn78ON79N/ZB5wJxQt\n\
koyHvWimPWkNRlKGP10DJ42PIGDvuTnTBFHCKbvaMrEjkll8PUd8zHQ0OJIaWIYi\n\
AKydplJy2rCzppwn0bI0YQ==\n\
</xenc:CipherValue>\n\
</xenc:CipherData>\n\
</xenc:EncryptedData></Letter>";


// PKCS8 PEM encoded PrivateKey structure (not Encrypted)

char s_privateKey[] = "\n\
-----BEGIN RSA PRIVATE KEY-----\n\
MIICXAIBAAKBgQDQj3pktZckAzwshRnfvLhz3daNU6xpAzoHo3qjCftxDwH1RynP\n\
A5eycJVkV8mwH2C1PFktpjtQTZ2CvPjuKmUV5zEvmYzuIo6SWYaVZN/PJjzsEZMa\n\
VA+U8GhfX1YF/rsuFzXCi8r6FVd3LN//pXHEwoDGdJUdlpdVEuX1iFKlNQIDAQAB\n\
AoGAYQ7Uc7e6Xa0PvNw4XVHzOSC870pISxqQT+u5b9R+anAEhkQW5dsTJpyUOX1N\n\
RCRmGhG6oq7gnY9xRN1yr0uVfJNtc9/HnzJL7L1jeJC8Ub+zbEBvNuPDL2P21ArW\n\
tcXRycUlfRCRBLop7rfOYPXsjtboAGnQY/6hK4rOF4XGrQUCQQD3Euj+0mZqRRZ4\n\
M1yN2wVP0mKOMg2i/HZXaNeVd9X/wyBgK6b7BxHf6onf/mIBWnJnRBlvdCrSdhuT\n\
lPKEoSgvAkEA2BhfWwQihqD4qJcV65nfosjzOZG41rHX69nIqHI7Ejx5ZgeQByH9\n\
Ym96yXoSpZj9ZlFsJYNogTBBnUBjs+jL2wJAFjpVS9eR7y2X/+hfA0QZDj1XMIPA\n\
RlGANAzymDfXwNLFLuG+fAb+zK5FCSnRl12TvUabIzPIRnbptDVKPDRjcQJBALn8\n\
0CVv+59P8HR6BR3QRBDBT8Xey+3NB4Aw42lHV9wsPHg6ThY1hPYx6MZ70IzCjmZ/\n\
8cqfvVRjijWj86wm0z0CQFKfRfBRraOZqfmOiAB4+ILhbJwKBBO6avX9TPgMYkyN\n\
mWKCxS+9fPiy1iI+G+B9xkw2gJ9i8P81t7fsOvdTDFA=\n\
-----END RSA PRIVATE KEY-----";


int main (int argc, char **argv) {

	try {
		XMLPlatformUtils::Initialize();
#ifdef XSEC_HAVE_XALAN
		XalanTransformer::initialize();
#endif
		XSECPlatformUtils::Initialise();
	}
	catch (const XMLException &e) {

		cerr << "Error during initialization of libraries" << endl;
		cerr << "Error Message = : "
		     << e.getMessage() << endl;
		return -1;
	}

	// Use xerces to parse the document
	XercesDOMParser * parser = new XercesDOMParser;
	parser->setDoNamespaces(true);
	parser->setCreateEntityReferenceNodes(true);
	parser->setDoSchema(true);

	// Create an input source

	MemBufInputSource* memIS = new MemBufInputSource ((const XMLByte*) letter, (unsigned int) strlen(letter), "XSECMem");

	parser->parse(*memIS);
    XMLSize_t errorCount = parser->getErrorCount();
    if (errorCount > 0) {
		cerr << "Error parsing input document\n";
		exit (1);
	}

    DOMDocument *doc = parser->getDocument();

	/* Decrypt Operations */

	try {

		/* Create the cipher object that we need */

		XSECProvider prov;
		XENCCipher *cipher;

		cipher = prov.newCipher(doc);

#ifdef XSEC_HAVE_OPENSSL
		/* Load the private key via OpenSSL and then wrap in an OpenSSLCrypto construct */
		BIO * bioMem = BIO_new(BIO_s_mem());
		BIO_puts(bioMem, s_privateKey);
		EVP_PKEY * pk = PEM_read_bio_PrivateKey(bioMem, NULL, NULL, NULL);

		/* NOTE : For simplicity - no error checking here */

		OpenSSLCryptoKeyRSA * k = new OpenSSLCryptoKeyRSA(pk);
		cipher->setKEK(k);
#else
		throw XSECException(XSECException::CryptoProviderError);
#endif

		/* Find the EncryptedData node */
		DOMNode * encryptedNode = findXENCNode(doc, "EncryptedData");

		/* Do the decrypt */
		cipher->decryptElement((DOMElement *) encryptedNode);

	}

	catch (const XSECException &e)
	{
		char * msg = XMLString::transcode(e.getMsg());
		cerr << "An error occurred during an encryption operation\n   Message: "
		<< msg << endl;
		exit(1);
		
	}

	/* Output */
	docSetup(doc);
	cout << doc;

	return 0;

}
