/*
 * Copyright 2003-2005 The Apache Software Foundation.
 *
 * Licensed 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
 *
 * XSECAlgorithmHandlerDefault := Interface class to define handling of
 *								  default encryption algorithms
 *
 * $Id$
 *
 */

// XSEC Includes

#include <xsec/framework/XSECDefs.hpp>
#include <xsec/transformers/TXFMChain.hpp>
#include <xsec/transformers/TXFMBase64.hpp>
#include <xsec/transformers/TXFMSHA1.hpp>
#include <xsec/transformers/TXFMMD5.hpp>
#include <xsec/enc/XSECCryptoKey.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/utils/XSECDOMUtils.hpp>

#include "DSIGAlgorithmHandlerDefault.hpp"

#include <xercesc/dom/DOM.hpp>
#include <xercesc/util/Janitor.hpp>

XERCES_CPP_NAMESPACE_USE


// --------------------------------------------------------------------------------
//           Some useful utility functions
// --------------------------------------------------------------------------------


bool compareBase64StringToRaw(const char * b64Str, 
							  unsigned char * raw, 
							  unsigned int rawLen, 
							  unsigned int maxCompare = 0) {
	// Decode a base64 buffer and then compare the result to a raw buffer
	// Compare at most maxCompare bits (if maxComare > 0)
	// Note - whilst the other parameters are bytes, maxCompare is bits

	unsigned char outputStr[1024];
	unsigned int outputLen = 0;
	
	XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64();
	
	if (!b64) {

		throw XSECException(XSECException::CryptoProviderError, 
				"Error requesting Base64 object from Crypto Provider");

	}

	Janitor<XSECCryptoBase64> j_b64(b64);

	b64->decodeInit();
	outputLen = b64->decode((unsigned char *) b64Str, (unsigned int) strlen((char *) b64Str), outputStr, 1024);
	outputLen += b64->decodeFinish(&outputStr[outputLen], 1024 - outputLen);

	// Compare

	div_t d;
    d.rem = 0;
    d.quot = 0;

	unsigned int maxCompareBytes, maxCompareBits;
	maxCompareBits = 0;

	unsigned int size;

	if (maxCompare > 0) {
		d = div(maxCompare, 8);
		maxCompareBytes = d.quot;
		if (d.rem != 0)
			maxCompareBytes++;

		if (rawLen < maxCompareBytes && outputLen < maxCompareBytes) {
			if (rawLen != outputLen)
				return false;
			size = rawLen;
		}
		else if (rawLen < maxCompareBytes || outputLen < maxCompareBytes) {
			return false;
		}
		else
			size = maxCompareBytes;
	}
	else {

		if (rawLen != outputLen)
			return false;

		size = rawLen;

	}

	// Compare bytes
	unsigned int i, j;
	for (i = 0; i < size; ++ i) {
		if (raw[i] != outputStr[i])
			return false;
	}

	// Compare bits

	char mask = 0x01;
	if (maxCompare != 0) {
	    for (j = 0 ; j < (unsigned int) d.rem; ++i) {

		    if ((raw[i] & mask) != (outputStr[i] & mask))
			    return false;

			mask = mask << 1;
		}
	}

	return true;

}


void convertRawToBase64String(safeBuffer &b64SB, 
							  unsigned char * raw, 
							  unsigned int rawLen, 
							  unsigned int maxBits = 0) {

	// Translate the rawbuffer (at most maxBits or rawLen - whichever is smaller)
	// to a base64 string

	unsigned char b64Str[1024];
	unsigned int outputLen = 0;
	
	XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64();
	
	if (!b64) {

		throw XSECException(XSECException::CryptoProviderError, 
				"Error requesting Base64 object from Crypto Provider");

	}

	Janitor<XSECCryptoBase64> j_b64(b64);

	// Determine length to translate
	unsigned int size;

	if (maxBits > 0) {
		div_t d = div(maxBits, 8);
		size = d.quot;
		if (d.rem != 0)
			++size;
		
		if (size > rawLen)
			size = rawLen;
	}

	else
		size = rawLen;

	b64->encodeInit();
	outputLen = b64->encode((unsigned char *) raw, rawLen, b64Str, 1024);
	outputLen += b64->encodeFinish(&b64Str[outputLen], 1024 - outputLen);
	b64Str[outputLen] = '\0';

	// Copy out

	b64SB.sbStrcpyIn((char *) b64Str);

}

// --------------------------------------------------------------------------------
//			Clone
// --------------------------------------------------------------------------------

XSECAlgorithmHandler * DSIGAlgorithmHandlerDefault::clone(void) const {

	DSIGAlgorithmHandlerDefault * ret;
	XSECnew(ret, DSIGAlgorithmHandlerDefault);

	return ret;

}
// --------------------------------------------------------------------------------
//			Add a hash txfm
// --------------------------------------------------------------------------------

TXFMBase * addHashTxfm(signatureMethod sm, hashMethod hm, XSECCryptoKey * key, 
					   DOMDocument * doc) {

	// Given a hash method and signature method, create an appropriate TXFM

	TXFMBase * txfm;
	
	switch (hm) {

	case HASH_MD5 :

		if (sm == SIGNATURE_HMAC){
			if (key->getKeyType() != XSECCryptoKey::KEY_HMAC) {
				throw XSECException(XSECException::AlgorithmMapperError,
					"DSIGAlgorithmHandlerDefault::addHashTxfm - non HMAC key passed in to HMAC signature");
			}
			XSECnew(txfm, TXFMMD5(doc, key));
		}
		else  {
			XSECnew(txfm, TXFMMD5(doc));
		}

		break;

	case HASH_SHA1 :

		if (sm == SIGNATURE_HMAC){
			if (key->getKeyType() != XSECCryptoKey::KEY_HMAC) {
				throw XSECException(XSECException::AlgorithmMapperError,
					"DSIGAlgorithmHandlerDefault::addHashTxfm - non HMAC key passed in to HMAC signature");
			}
			XSECnew(txfm, TXFMSHA1(doc, HASH_SHA1, key));
		}
		else  {
			XSECnew(txfm, TXFMSHA1(doc));
		}

		break;

	case HASH_SHA224 :

		if (sm == SIGNATURE_HMAC){
			if (key->getKeyType() != XSECCryptoKey::KEY_HMAC) {
				throw XSECException(XSECException::AlgorithmMapperError,
					"DSIGAlgorithmHandlerDefault::addHashTxfm - non HMAC key passed in to HMAC signature");
			}
			XSECnew(txfm, TXFMSHA1(doc, HASH_SHA224, key));
		}
		else  {
			XSECnew(txfm, TXFMSHA1(doc, HASH_SHA224));
		}

		break;

	case HASH_SHA256 :

		if (sm == SIGNATURE_HMAC){
			if (key->getKeyType() != XSECCryptoKey::KEY_HMAC) {
				throw XSECException(XSECException::AlgorithmMapperError,
					"DSIGAlgorithmHandlerDefault::addHashTxfm - non HMAC key passed in to HMAC signature");
			}
			XSECnew(txfm, TXFMSHA1(doc, HASH_SHA256, key));
		}
		else  {
			XSECnew(txfm, TXFMSHA1(doc, HASH_SHA256));
		}

		break;

	case HASH_SHA384 :

		if (sm == SIGNATURE_HMAC){
			if (key->getKeyType() != XSECCryptoKey::KEY_HMAC) {
				throw XSECException(XSECException::AlgorithmMapperError,
					"DSIGAlgorithmHandlerDefault::addHashTxfm - non HMAC key passed in to HMAC signature");
			}
			XSECnew(txfm, TXFMSHA1(doc, HASH_SHA384, key));
		}
		else  {
			XSECnew(txfm, TXFMSHA1(doc, HASH_SHA384));
		}

		break;

	case HASH_SHA512 :

		if (sm == SIGNATURE_HMAC){
			if (key->getKeyType() != XSECCryptoKey::KEY_HMAC) {
				throw XSECException(XSECException::AlgorithmMapperError,
					"DSIGAlgorithmHandlerDefault::addHashTxfm - non HMAC key passed in to HMAC signature");
			}
			XSECnew(txfm, TXFMSHA1(doc, HASH_SHA512, key));
		}
		else  {
			XSECnew(txfm, TXFMSHA1(doc, HASH_SHA512));
		}

		break;

	default :

			throw XSECException(XSECException::AlgorithmMapperError,
				"Hash method unknown in DSIGAlgorithmHandlerDefault::addHashTxfm");

	}

	return txfm;
}

// --------------------------------------------------------------------------------
//			Map a Signature hash
// --------------------------------------------------------------------------------

bool DSIGAlgorithmHandlerDefault::appendSignatureHashTxfm(TXFMChain * inputBytes,
														  const XMLCh * URI,
														  XSECCryptoKey * key) {

	signatureMethod sm;
	hashMethod hm;

	// Map to internal constants

	if (!XSECmapURIToSignatureMethods(URI, sm, hm)) {
		safeBuffer sb;
		sb.sbTranscodeIn("DSIGAlgorithmHandlerDefault - Unknown URI : ");
		sb.sbXMLChCat(URI);

		throw XSECException(XSECException::AlgorithmMapperError, 
			sb.rawXMLChBuffer());
	}

	// Now append the appropriate hash transform onto the end of the chain
	// If this is an HMAC of some kind - this function will add the appropriate key

	TXFMBase * htxfm = addHashTxfm(sm, hm, key, inputBytes->getLastTxfm()->getDocument());
	inputBytes->appendTxfm(htxfm);

	return true;

}


// --------------------------------------------------------------------------------
//			Sign
// --------------------------------------------------------------------------------

unsigned int DSIGAlgorithmHandlerDefault::signToSafeBuffer(
		TXFMChain * inputBytes,
		const XMLCh * URI,
		XSECCryptoKey * key,
		unsigned int outputLength,
		safeBuffer & result) {

	signatureMethod sm;
	hashMethod hm;

	// Map to internal constants

	if (!XSECmapURIToSignatureMethods(URI, sm, hm)) {
		safeBuffer sb;
		sb.sbTranscodeIn("DSIGAlgorithmHandlerDefault - Unknown URI : ");
		sb.sbXMLChCat(URI);

		throw XSECException(XSECException::AlgorithmMapperError, 
			sb.rawXMLChBuffer());
	}

	// Now append the appropriate hash transform onto the end of the chain
	// If this is an HMAC of some kind - this function will add the appropriate key

	TXFMBase * htxfm = addHashTxfm(sm, hm, key, inputBytes->getLastTxfm()->getDocument());
	inputBytes->appendTxfm(htxfm);

	unsigned char hash[4096];

	int hashLen = inputBytes->getLastTxfm()->readBytes((XMLByte *) hash, 4096);
	
	// Now check the calculated hash

	char b64Buf[1024];
	unsigned int b64Len;
	safeBuffer b64SB;
	
	switch (key->getKeyType()) {

	case (XSECCryptoKey::KEY_DSA_PRIVATE) :
	case (XSECCryptoKey::KEY_DSA_PAIR) :

		if (sm != SIGNATURE_DSA) {

			throw XSECException(XSECException::AlgorithmMapperError,
				"Key type does not match <SignedInfo> signature type");

		}

		b64Len = ((XSECCryptoKeyDSA *) key)->signBase64Signature(
			hash, 
			hashLen,
			(char *) b64Buf, 
			1024);

		if (b64Len <= 0) {

			throw XSECException(XSECException::AlgorithmMapperError,
				"Unknown error occured during a DSA Signing operation");

		}

		if (b64Buf[b64Len-1] == '\n')
			b64Buf[b64Len-1] = '\0';
		else
			b64Buf[b64Len] = '\0';

		break;

	case (XSECCryptoKey::KEY_RSA_PRIVATE) :
	case (XSECCryptoKey::KEY_RSA_PAIR) :

		if (sm != SIGNATURE_RSA) {

			throw XSECException(XSECException::AlgorithmMapperError,
				"Key type does not match <SignedInfo> signature type");

		}

		b64Len = ((XSECCryptoKeyRSA *) key)->signSHA1PKCS1Base64Signature(
			hash, 
			hashLen,
			(char *) b64Buf, 
			1024,
			hm);

		if (b64Len <= 0) {

			throw XSECException(XSECException::AlgorithmMapperError,
				"Unknown error occured during a RSA Signing operation");

		}

		// Clean up some "funnies" and make sure the string is NULL terminated

		if (b64Buf[b64Len-1] == '\n')
			b64Buf[b64Len-1] = '\0';
		else
			b64Buf[b64Len] = '\0';

		break;

	case (XSECCryptoKey::KEY_HMAC) :

		if (sm != SIGNATURE_HMAC) {

			throw XSECException(XSECException::AlgorithmMapperError,
				"Key type does not match <SignedInfo> signature type");

		}

		// Signature already created, so just translate to base 64 and enter string
		
		convertRawToBase64String(b64SB, 
								hash, 
								hashLen, 
								outputLength);
		
		strncpy(b64Buf, (char *) b64SB.rawBuffer(), 1024);
		break;

	default :

		throw XSECException(XSECException::AlgorithmMapperError,
			"Key found, but don't know how to sign the document using it");

	}

	result = b64Buf;

	return (unsigned int) strlen(b64Buf);

}

// --------------------------------------------------------------------------------
//			Verify
// --------------------------------------------------------------------------------
bool DSIGAlgorithmHandlerDefault::verifyBase64Signature(
		TXFMChain * inputBytes,
		const XMLCh * URI,
		const char * sig,
		unsigned int outputLength,
		XSECCryptoKey * key) {

	signatureMethod sm;
	hashMethod hm;

	// Map to internal constants

	if (!XSECmapURIToSignatureMethods(URI, sm, hm)) {
		safeBuffer sb;
		sb.sbTranscodeIn("DSIGAlgorithmHandlerDefault - Unknown URI : ");
		sb.sbXMLChCat(URI);

		throw XSECException(XSECException::AlgorithmMapperError, 
			sb.rawXMLChBuffer());
	}

	// Now append the appropriate hash transform onto the end of the chain
	// If this is an HMAC of some kind - this function will add the appropriate key

	TXFMBase * htxfm = addHashTxfm(sm, hm, key, inputBytes->getLastTxfm()->getDocument());
	inputBytes->appendTxfm(htxfm);

	unsigned char hash[4096];

	int hashLen = inputBytes->getLastTxfm()->readBytes((XMLByte *) hash, 4096);
	
	// Now check the calculated hash
	bool sigVfyRet = false;

	switch (key->getKeyType()) {

	case (XSECCryptoKey::KEY_DSA_PUBLIC) :
	case (XSECCryptoKey::KEY_DSA_PAIR) :

		if (sm != SIGNATURE_DSA) {

			throw XSECException(XSECException::AlgorithmMapperError,
				"Key type does not match <SignedInfo> signature type");

		}

		sigVfyRet = ((XSECCryptoKeyDSA *) key)->verifyBase64Signature(
			hash, 
			hashLen,
			(char *) sig, 
			(unsigned int) strlen(sig));

		break;

	case (XSECCryptoKey::KEY_RSA_PUBLIC) :
	case (XSECCryptoKey::KEY_RSA_PAIR) :

		if (sm != SIGNATURE_RSA) {
		
			throw XSECException(XSECException::AlgorithmMapperError,
				"Key type does not match <SignedInfo> signature type");

		}

		sigVfyRet = ((XSECCryptoKeyRSA *) key)->verifySHA1PKCS1Base64Signature(
			hash,
			hashLen,
			sig,
			(unsigned int) strlen(sig),
			hm);

		break;

	case (XSECCryptoKey::KEY_HMAC) :

		// Already done - just compare calculated value with read value
		sigVfyRet = compareBase64StringToRaw(sig, 
			hash, 
			hashLen,
			outputLength);

		break;

	default :

		throw XSECException(XSECException::AlgorithmMapperError,
			"Key found, but don't know how to check the signature using it");

	}

	return sigVfyRet;

}

// --------------------------------------------------------------------------------
//			Hash TXFM appenders
// --------------------------------------------------------------------------------

bool DSIGAlgorithmHandlerDefault::appendHashTxfm(
		TXFMChain * inputBytes,
		const XMLCh * URI) {

	hashMethod hm;

	// Is this a URI we recognise?

	if (!XSECmapURIToHashMethod(URI, hm)) {
		safeBuffer sb;
		sb.sbTranscodeIn("DSIGAlgorithmHandlerDefault - Unknown Hash URI : ");
		sb.sbXMLChCat(URI);

		throw XSECException(XSECException::AlgorithmMapperError, 
			sb.rawXMLChBuffer());
	}

	TXFMBase * txfm;
	DOMDocument *d = inputBytes->getLastTxfm()->getDocument();
	switch (hm) {

	case HASH_SHA1 :
	case HASH_SHA224 :
	case HASH_SHA256 :
	case HASH_SHA384 :
	case HASH_SHA512 :

		XSECnew(txfm, TXFMSHA1(d, hm));
		break;
	
	case HASH_MD5 :

		XSECnew(txfm, TXFMMD5(d));
		break;

	default :

		safeBuffer sb;
		sb.sbTranscodeIn("DSIGAlgorithmHandlerDefault - Internal error unknown Hash, but URI known. URI : ");
		sb.sbXMLChCat(URI);

		throw XSECException(XSECException::AlgorithmMapperError, 
			sb.rawXMLChBuffer());

	}

	inputBytes->appendTxfm(txfm);

	return true;

}

// --------------------------------------------------------------------------------
//			SafeBuffer decryption
// --------------------------------------------------------------------------------

unsigned int DSIGAlgorithmHandlerDefault::decryptToSafeBuffer(
		TXFMChain * cipherText,
		XENCEncryptionMethod * encryptionMethod,
		XSECCryptoKey * key,
		DOMDocument * doc,
		safeBuffer & result
		) {

	throw XSECException(XSECException::AlgorithmMapperError, 
			"DSIGAlgorithmHandlerDefault - Encryption operations not supported");

}

bool DSIGAlgorithmHandlerDefault::appendDecryptCipherTXFM(
		TXFMChain * cipherText,
		XENCEncryptionMethod * encryptionMethod,
		XSECCryptoKey * key,
		XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * doc
		) {

	throw XSECException(XSECException::AlgorithmMapperError, 
			"DSIGAlgorithmHandlerDefault - Encryption operations not supported");
}


// --------------------------------------------------------------------------------
//			SafeBuffer encryption
// --------------------------------------------------------------------------------

bool DSIGAlgorithmHandlerDefault::encryptToSafeBuffer(
		TXFMChain * plainText,
		XENCEncryptionMethod * encryptionMethod,
		XSECCryptoKey * key,
		XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * doc,
		safeBuffer & result
		) {

	throw XSECException(XSECException::AlgorithmMapperError, 
			"DSIGAlgorithmHandlerDefault - Encryption operations not supported");

}

// --------------------------------------------------------------------------------
//			Key Creation
// --------------------------------------------------------------------------------

XSECCryptoKey * DSIGAlgorithmHandlerDefault::createKeyForURI(
		const XMLCh * uri,
		const unsigned char * keyBuffer,
		unsigned int keyLen
		) {

	throw XSECException(XSECException::AlgorithmMapperError, 
			"DSIGAlgorithmHandlerDefault - Key creation operations not supported");

}

