/**
 * 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
 *
 * checkSig := (Very ugly) tool to check a signature embedded in an XML file
 *
 * $Id$
 *
 */

#include "AnonymousResolver.hpp"
#include "InteropResolver.hpp"

// XSEC

#include <xsec/utils/XSECPlatformUtils.hpp>
#include <xsec/framework/XSECProvider.hpp>
#include <xsec/canon/XSECC14n20010315.hpp>
#include <xsec/dsig/DSIGSignature.hpp>
#include <xsec/framework/XSECException.hpp>
#include <xsec/enc/XSECCryptoException.hpp>
#include <xsec/enc/XSECKeyInfoResolverDefault.hpp>

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

// General

#include <memory.h>
#include <string.h>
#include <iostream>
#include <stdlib.h>

#if defined(HAVE_UNISTD_H)
# include <unistd.h>
#else
# if defined(HAVE_DIRECT_H)
#  include <direct.h>
# endif
#endif

#if defined (_DEBUG) && defined (_MSC_VER)
#include <crtdbg.h>
#endif


#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/XMLString.hpp>

#include <xercesc/dom/DOM.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/util/XMLException.hpp>
#include <xercesc/util/XMLUri.hpp>
#include <xercesc/util/Janitor.hpp>

XERCES_CPP_NAMESPACE_USE

using std::cerr;
using std::cout;
using std::endl;

#ifdef XSEC_HAVE_XALAN

// XALAN

#include <xalanc/XPath/XPathEvaluator.hpp>
#include <xalanc/XalanTransformer/XalanTransformer.hpp>

XALAN_USING_XALAN(XPathEvaluator)
XALAN_USING_XALAN(XalanTransformer)

#endif

#if defined (XSEC_HAVE_OPENSSL)
// OpenSSL

#	include <xsec/enc/OpenSSL/OpenSSLCryptoKeyHMAC.hpp>
#	include <openssl/err.h>

#endif

#if defined (XSEC_HAVE_WINCAPI)

#	include <xsec/enc/WinCAPI/WinCAPICryptoProvider.hpp>
#	include <xsec/enc/WinCAPI/WinCAPICryptoKeyHMAC.hpp>

#endif

#if defined (XSEC_HAVE_NSS)

#	include <xsec/enc/NSS/NSSCryptoProvider.hpp>
#	include <xsec/enc/NSS/NSSCryptoKeyHMAC.hpp>

#endif

#include <time.h>

#ifndef XSEC_HAVE_XALAN

std::ostream& operator<< (std::ostream& target, const XMLCh * s)
{
    char *p = XMLString::transcode(s);
    target << p;
    XSEC_RELEASE_XMLCH(p);
    return target;
}

#endif

// ----------------------------------------------------------------------------
//           Checksig
// ----------------------------------------------------------------------------


void printUsage(void) {

	cerr << "\nUsage: checksig [options] <input file name>\n\n";
	cerr << "     Where options are :\n\n";
	cerr << "     --skiprefs/-s\n";
	cerr << "         Skip checking references - check signature only\n\n";
	cerr << "     --hmackey/-h <string>\n";
	cerr << "         Set an hmac key using the <string>\n\n";
	cerr << "     --xsecresolver/-x\n";
	cerr << "         Use the xml-security test XMLDSig URI resolver\n\n";
	cerr << "     --id <name>\n";
	cerr << "         Define an attribute Id by name\n\n";
	cerr << "     --idns/-d <ns uri> <name>\n";
	cerr << "         Define an attribute Id by namespace URI and name\n\n";
#if defined (XSEC_HAVE_OPENSSL)
	cerr << "     --interop/-i\n";
	cerr << "         Use the interop resolver for Baltimore interop examples\n\n";
#endif
#if defined(XSEC_HAVE_WINCAPI)
#	if defined (XSEC_HAVE_OPENSSL)
	cerr << "     --wincapi/-w\n";
	cerr << "         Use the Windows CAPI crypto Provider\n\n";
#	endif
	cerr << "     --winhmackey/-wh <string>\n";
	cerr << "         Use the Windows CAPI crypto provider and hash the <string>\n";
	cerr << "         into a Windows key using SHA-1\n\n";
#endif
	cerr << "     Exits with codes :\n";
	cerr << "         0 = Signature OK\n";
	cerr << "         1 = Signature Bad\n";
	cerr << "         2 = Processing error\n";

}

int evaluate(int argc, char ** argv) {
	
	char					* filename = NULL;
	char					* hmacKeyStr = NULL;
	char					* useIdAttributeNS = NULL;
	char					* useIdAttributeName = NULL;
	XSECCryptoKey			* key = NULL;
	bool					useXSECURIResolver = false;
	bool                    useAnonymousResolver = false;
	bool					useInteropResolver = false;
#if defined (XSEC_HAVE_WINCAPI)
	HCRYPTPROV				win32CSP = 0;
#endif

	bool skipRefs = false;

	if (argc < 2) {

		printUsage();
		return 2;
	}

	// Run through parameters
	int paramCount = 1;

	while (paramCount < argc - 1) {

		if (_stricmp(argv[paramCount], "--hmackey") == 0 || _stricmp(argv[paramCount], "-h") == 0) {
			paramCount++;
			hmacKeyStr = argv[paramCount++];
		}
		else if (_stricmp(argv[paramCount], "--skiprefs") == 0 || _stricmp(argv[paramCount], "-s") == 0) {
			skipRefs = true;
			paramCount++;
		}
		else if (_stricmp(argv[paramCount], "--xsecresolver") == 0 || _stricmp(argv[paramCount], "-x") == 0) {
			useXSECURIResolver = true;
			paramCount++;
		}
		else if (_stricmp(argv[paramCount], "--id") == 0) {
			if (paramCount +1 >= argc) {
				printUsage();
				return 2;
			}
			paramCount++;
			useIdAttributeName = argv[paramCount++];
		}
		else if (_stricmp(argv[paramCount], "--idns") == 0 || _stricmp(argv[paramCount], "-d") == 0) {
			if (paramCount +2 >= argc) {
				printUsage();
				return 2;
			}
			paramCount++;
			useIdAttributeNS = argv[paramCount++];
			useIdAttributeName = argv[paramCount++];
		}
#if defined (XSEC_HAVE_OPENSSL)
		else if (_stricmp(argv[paramCount], "--interop") == 0 || _stricmp(argv[paramCount], "-i") == 0) {
			// Use the interop key resolver
			useInteropResolver = true;
			paramCount++;
		}
#endif
		else if (_stricmp(argv[paramCount], "--anonymousresolver") == 0 || _stricmp(argv[paramCount], "-a") ==0) {
			useAnonymousResolver = true;
			paramCount++;
		}
#if defined (XSEC_HAVE_WINCAPI)
		else if (_stricmp(argv[paramCount], "--wincapi") == 0 || _stricmp(argv[paramCount], "-w") == 0 ||
			_stricmp(argv[paramCount], "--winhmackey") == 0 || _stricmp(argv[paramCount], "-wh") == 0) {

			WinCAPICryptoProvider * cp = new WinCAPICryptoProvider();
			XSECPlatformUtils::SetCryptoProvider(cp);

			if (_stricmp(argv[paramCount], "--winhmackey") == 0 || _stricmp(argv[paramCount], "-wh") == 0) {

				// Create a SHA-1 based key based on the <string> parameter

				paramCount++;

				if (!CryptAcquireContext(&win32CSP,
					NULL,
					NULL,
					PROV_RSA_FULL,
					CRYPT_VERIFYCONTEXT)) 
				{
					cerr << "Error obtaining default RSA_PROV" << endl;
					return 2;
				}

				HCRYPTKEY k;
				HCRYPTHASH h;
				BOOL fResult = CryptCreateHash(
					win32CSP,
					CALG_SHA,
					0,
					0,
					&h);

				if (fResult == 0) {
					cerr << "Error creating hash to create windows hmac key from password" << endl;
					return 2;
				}
				fResult = CryptHashData(
					h,
					(unsigned char *) argv[paramCount],
					(DWORD) strlen(argv[paramCount]),
					0);
				
				if (fResult == 0) {
					cerr << "Error hashing password to create windows hmac key" << endl;
					return 2;
				}

				// Now create a key
				fResult = CryptDeriveKey(
					win32CSP,
					CALG_RC2,
					h,
					CRYPT_EXPORTABLE,
					&k);

				if (fResult == 0) {
					cerr << "Error deriving key from hash value" << endl;
					return 2;
				}

				// Wrap in a WinCAPI object
				WinCAPICryptoKeyHMAC * hk;
				hk = new WinCAPICryptoKeyHMAC(win32CSP);
				hk->setWinKey(k); 

				key = hk;

				CryptDestroyHash(h);

			}

			paramCount++;

		}
#endif
		else {
			cerr << "Unknown option: " << argv[paramCount] << endl << endl;
			printUsage();
			return 2;
		}
	}

#if defined (XSEC_HAVE_WINCAPI) && !defined(XSEC_HAVE_OPENSSL)

	// Use default DSS provider
	WinCAPICryptoProvider * cp = new WinCAPICryptoProvider();
	XSECPlatformUtils::SetCryptoProvider(cp);

#endif

	if (paramCount >= argc) {
		printUsage();
		return 2;
	}

	filename = argv[paramCount];

	// Create and set up the parser

	XercesDOMParser * parser = new XercesDOMParser;
	Janitor<XercesDOMParser> j_parser(parser);

	parser->setDoNamespaces(true);
	parser->setCreateEntityReferenceNodes(true);

	// Now parse out file

	bool errorsOccured = false;
	XMLSize_t errorCount = 0;
    try
    {
    	parser->parse(filename);
        errorCount = parser->getErrorCount();
        if (errorCount > 0)
            errorsOccured = true;
    }

    catch (const XMLException& e)
    {
        cerr << "An error occurred during parsing\n   Message: "
             << e.getMessage() << endl;
        errorsOccured = true;
    }


    catch (const DOMException& e)
    {
       cerr << "A DOM error occurred during parsing\n   DOMException code: "
             << e.code << endl;
        errorsOccured = true;
    }

	if (errorsOccured) {

		cout << "Errors during parse" << endl;
		return (2);

	}

	/*

		Now that we have the parsed file, get the DOM document and start looking at it

	*/
	
	DOMNode *doc;		// The document that we parsed

	doc = parser->getDocument();
	DOMDocument *theDOM = parser->getDocument();

	// Find the signature node
	
	DOMNode *sigNode = findDSIGNode(doc, "Signature");

	// Create the signature checker

	if (sigNode == 0) {

		cerr << "Could not find <Signature> node in " << argv[argc-1] << endl;
		return 2;
	}

	XSECProvider prov;
	XSECKeyInfoResolverDefault theKeyInfoResolver;

	DSIGSignature * sig = prov.newSignatureFromDOM(theDOM, sigNode);

	// The only way we can verify is using keys read directly from the KeyInfo list,
	// so we add a KeyInfoResolverDefault to the Signature.

	sig->setKeyInfoResolver(&theKeyInfoResolver);

	// Register defined attribute name
	if (useIdAttributeName != NULL) {
        sig->setIdByAttributeName(true);
        if (useIdAttributeNS != NULL) {
		    sig->registerIdAttributeNameNS(MAKE_UNICODE_STRING(useIdAttributeNS), 
									       MAKE_UNICODE_STRING(useIdAttributeName));
        } else {
            sig->registerIdAttributeName(MAKE_UNICODE_STRING(useIdAttributeName));
        }
    }

	// Check whether we should use the internal resolver

	
	if (useXSECURIResolver == true || 
		useAnonymousResolver == true ||
		useInteropResolver == true) {

		AnonymousResolver theAnonymousResolver;
		     
		// Map out base path of the file
#if XSEC_HAVE_GETCWD_DYN
		char *path = getcwd(NULL, 0);
		char *baseURI = (char*)malloc(strlen(path) + 8 + 1 + strlen(filename) + 1);
#else
		char path[PATH_MAX];
		char baseURI[(PATH_MAX * 2) + 10];
		getcwd(path, PATH_MAX);
#endif
		strcpy(baseURI, "file:///");		

		// Ugly and nasty but quick
		if (filename[0] != '\\' && filename[0] != '/' && filename[1] != ':') {
			strcat(baseURI, path);
			strcat(baseURI, "/");
		} else if (path[1] == ':') {
			path[2] = '\0';
			strcat(baseURI, path);
		}

		strcat(baseURI, filename);

		// Find any ':' and "\" characters
		int lastSlash = 0;
		for (unsigned int i = 8; i < strlen(baseURI); ++i) {
			if (baseURI[i] == '\\') {
				lastSlash = i;
				baseURI[i] = '/';
			}
			else if (baseURI[i] == '/')
				lastSlash = i;
		}

		// The last "\\" must prefix the filename
		baseURI[lastSlash + 1] = '\0';
		XMLCh * baseURIXMLCh = XMLString::transcode(baseURI);

		XMLUri uri(MAKE_UNICODE_STRING(baseURI));
#if XSEC_HAVE_GETCWD_DYN
		free(path);
		free(baseURI);
#endif

		if (useAnonymousResolver == true) {
			sig->setURIResolver(&theAnonymousResolver);
		}
        sig->getURIResolver()->setBaseURI(baseURIXMLCh);

#if defined (XSEC_HAVE_OPENSSL)
		if (useInteropResolver == true) {
			InteropResolver ires(&(baseURIXMLCh[8]));
			sig->setKeyInfoResolver(&ires);
		}
#endif
		XSEC_RELEASE_XMLCH(baseURIXMLCh);
	}

	bool result;

	try {

		// Load a key if necessary
		if (hmacKeyStr != NULL) {

			XSECCryptoKeyHMAC * hmacKey = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
			hmacKey->setKey((unsigned char *) hmacKeyStr, (unsigned int) strlen(hmacKeyStr));
			sig->setSigningKey(hmacKey);

		}
		else if (key != NULL) {

			sig->setSigningKey(key);

		}

		sig->load();
		if (skipRefs)
			result = sig->verifySignatureOnly();
		else
			result = sig->verify();
	}

	catch (const XSECException &e) {
		char * msg = XMLString::transcode(e.getMsg());
		cerr << "An error occurred during signature verification\n   Message: "
		<< msg << endl;
		XSEC_RELEASE_XMLCH(msg);
		errorsOccured = true;
		return 2;
	}
	catch (const XSECCryptoException &e) {
		cerr << "An error occurred during signature verification\n   Message: "
		<< e.getMsg() << endl;
		errorsOccured = true;

#if defined (XSEC_HAVE_OPENSSL)
		ERR_load_crypto_strings();
		BIO * bio_err;
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

		ERR_print_errors(bio_err);
#endif
		return 2;
	}

#if 0
	catch (...) {

		cerr << "Unknown Exception type occurred.  Cleaning up and exiting\n" << endl;

		return 2;

	}
#endif
	int retResult;


	if (result) {
		cout << "Signature verified OK!" << endl;
		retResult = 0;
	}
	else {
		cout << "Signature failed verification" << endl;
		char * e = XMLString::transcode(sig->getErrMsgs());
		cout << e << endl;
		XSEC_RELEASE_XMLCH(e);
		retResult = 1;
	}

#if defined (XSEC_HAVE_WINCAPI)
	// Clean up the handle to the CSP
	if (win32CSP != 0)
		CryptReleaseContext(win32CSP, 0);
#endif

	// Janitor will clean up the parser
	return retResult;

}


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

	int retResult;

#if defined (_DEBUG) && defined (_MSC_VER)

	// Do some memory debugging under Visual C++

	_CrtMemState s1, s2, s3;

	// At this point we are about to start really using XSEC, so
	// Take a "before" checkpoing

	_CrtMemCheckpoint( &s1 );

#endif

	// Initialise the XML system

	try {

		XMLPlatformUtils::Initialize();
#ifdef XSEC_HAVE_XALAN
		XPathEvaluator::initialize();
		XalanTransformer::initialize();
#endif
		XSECPlatformUtils::Initialise();

	}
	catch (const XMLException &e) {

		cerr << "Error during initialisation of Xerces" << endl;
		cerr << "Error Message = : "
		     << e.getMessage() << endl;

	}

	retResult = evaluate(argc, argv);

	XSECPlatformUtils::Terminate();
#ifdef XSEC_HAVE_XALAN
	XalanTransformer::terminate();
	XPathEvaluator::terminate();
#endif
	XMLPlatformUtils::Terminate();

#if defined (_DEBUG) && defined (_MSC_VER)

	_CrtMemCheckpoint( &s2 );

	if ( _CrtMemDifference( &s3, &s1, &s2 ) && (
		s3.lCounts[0] > 0 ||
		s3.lCounts[1] > 1 ||
		// s3.lCounts[2] > 2 ||  We don't worry about C Runtime
		s3.lCounts[3] > 0 ||
		s3.lCounts[4] > 0)) {

		// Note that there is generally 1 Normal and 1 CRT block
		// still taken.  1 is from Xalan and 1 from stdio

		// Send all reports to STDOUT
		_CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
		_CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
		_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
		_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
		_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
		_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );

		// Dumpy memory stats

 		_CrtMemDumpAllObjectsSince( &s3 );
	    _CrtMemDumpStatistics( &s3 );
	}

	// Now turn off memory leak checking and end as there are some 
	// Globals that are allocated that get seen as leaks (Xalan?)

	int dbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
	dbgFlag &= ~(_CRTDBG_LEAK_CHECK_DF);
	_CrtSetDbgFlag( dbgFlag );

#endif

	return retResult;
}
