/**
 * 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
 *
 * XSECAlgorithmHandlerDefault := Interface class to define handling of
 *                                  default encryption algorithms
 *
 * $Id$
 *
 */

// XSEC Includes


#include <xsec/dsig/DSIGAlgorithmHandlerDefault.hpp>
#include <xsec/enc/XSECCryptoKey.hpp>
#include <xsec/framework/XSECDefs.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/transformers/TXFMChain.hpp>
#include <xsec/transformers/TXFMBase64.hpp>
#include <xsec/transformers/TXFMHash.hpp>

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

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

XERCES_CPP_NAMESPACE_USE

#define MAXB64BUFSIZE 2048

// --------------------------------------------------------------------------------
//           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 maxCompare > 0)
    // Note - whilst the other parameters are bytes, maxCompare is bits

    // The div function below takes signed int, so make sure the value
    // is safe to cast.
    if ((int) maxCompare < 0) {

        throw XSECException(XSECException::CryptoProviderError,
                "Comparison length was unsafe");

    }

    unsigned char outputStr[MAXB64BUFSIZE];
    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, MAXB64BUFSIZE);
    outputLen += b64->decodeFinish(&outputStr[outputLen], MAXB64BUFSIZE - outputLen);

    // Compare

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

    unsigned int maxCompareBytes;

    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; ++j) {

            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[MAXB64BUFSIZE];
    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, MAXB64BUFSIZE - 1);
    outputLen += b64->encodeFinish(&b64Str[outputLen], MAXB64BUFSIZE - outputLen - 1);
    b64Str[outputLen] = '\0';

    // Copy out

    b64SB.sbStrcpyIn((char *) b64Str);
}

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

XSECAlgorithmHandler* DSIGAlgorithmHandlerDefault::clone() const {

    DSIGAlgorithmHandlerDefault* ret;
    XSECnew(ret, DSIGAlgorithmHandlerDefault);

    return ret;
}

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

TXFMBase* addHashTxfm(XSECCryptoHash::HashType hashType, const XSECCryptoKey* key, DOMDocument* doc) {

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

    TXFMBase* txfm;

    XSECnew(txfm, TXFMHash(doc, hashType, key));

    return txfm;
}

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

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

    XSECCryptoHash::HashType hashType;

    // Map to internal constants

    if (!XSECAlgorithmSupport::evalSignatureMethod(URI, key, hashType)) {
        safeBuffer sb;
        sb.sbTranscodeIn("DSIGAlgorithmHandlerDefault - Unknown or key-incompatible 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(
            hashType,
            (key->getKeyType() == XSECCryptoKey::KEY_HMAC ? key : NULL),
            inputBytes->getLastTxfm()->getDocument());
    inputBytes->appendTxfm(htxfm);

    return true;
}


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

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

    XSECCryptoHash::HashType hashType;

    // Map to internal constants

    if (!XSECAlgorithmSupport::evalSignatureMethod(URI, key, hashType)) {
        safeBuffer sb;
        sb.sbTranscodeIn("DSIGAlgorithmHandlerDefault - Unknown or key-incompatible 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(
            hashType,
            (key->getKeyType() == XSECCryptoKey::KEY_HMAC ? key : NULL),
            inputBytes->getLastTxfm()->getDocument());
    inputBytes->appendTxfm(htxfm);

    unsigned char hash[4096];

    int hashLen = inputBytes->getLastTxfm()->readBytes((XMLByte *) hash, 4096);

    // Now check the calculated hash

    // For now, use a fixed length buffer, but expand it,
    // and detect if the signature size exceeds what we can
    // handle.
    char b64Buf[MAXB64BUFSIZE];
    unsigned int b64Len;
    safeBuffer b64SB;

    switch (key->getKeyType()) {

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

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

        if (b64Len <= 0) {
            throw XSECException(XSECException::AlgorithmMapperError,
                "Unknown error occurred during a DSA Signing operation");
        }
        else if (b64Len >= MAXB64BUFSIZE) {
            throw XSECException(XSECException::AlgorithmMapperError,
                "DSA Signing operation exceeded size of buffer");
        }

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

        break;

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

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

        if (b64Len <= 0) {
            throw XSECException(XSECException::AlgorithmMapperError,
                "Unknown error occurred during a RSA Signing operation");
        }
        else if (b64Len >= MAXB64BUFSIZE) {
            throw XSECException(XSECException::AlgorithmMapperError,
                "RSA Signing operation exceeded size of buffer");
        }

        // 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_EC_PRIVATE) :
    case (XSECCryptoKey::KEY_EC_PAIR) :

        b64Len = ((XSECCryptoKeyEC *) key)->signBase64SignatureDSA(
            hash,
            hashLen,
            (char *) b64Buf,
            MAXB64BUFSIZE);

        if (b64Len <= 0) {
            throw XSECException(XSECException::AlgorithmMapperError,
                "Unknown error occurred during an ECDSA Signing operation");
        }
        else if (b64Len >= MAXB64BUFSIZE) {
            throw XSECException(XSECException::AlgorithmMapperError,
                "ECDSA Signing operation exceeded size of buffer");
        }

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

        break;

    case (XSECCryptoKey::KEY_HMAC) :

        // Signature already created, so just translate to base 64 and enter string

        // FIX: CVE-2009-0217
        if (outputLength > 0 && (outputLength > (unsigned int)hashLen || outputLength < 80 || outputLength < (unsigned int)hashLen / 2)) {
            throw XSECException(XSECException::AlgorithmMapperError,
                "HMACOutputLength set to unsafe value.");
        }

        convertRawToBase64String(b64SB,
                                hash,
                                hashLen,
                                outputLength);

        strncpy(b64Buf, (char *) b64SB.rawBuffer(), MAXB64BUFSIZE);
        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,
        const XSECCryptoKey* key) const {

    XSECCryptoHash::HashType hashType;

    // Map to internal constants

    if (!XSECAlgorithmSupport::evalSignatureMethod(URI, key, hashType)) {
        safeBuffer sb;
        sb.sbTranscodeIn("DSIGAlgorithmHandlerDefault - Unknown or key-incompatible 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(
            hashType,
            (key->getKeyType() == XSECCryptoKey::KEY_HMAC ? key : NULL),
            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) :

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

        break;

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

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

        break;

    case (XSECCryptoKey::KEY_EC_PUBLIC) :
    case (XSECCryptoKey::KEY_EC_PAIR) :

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

        break;

    case (XSECCryptoKey::KEY_HMAC) :

        // Already done - just compare calculated value with read value

        // FIX: CVE-2009-0217
        if (outputLength > 0 && (outputLength > (unsigned int)hashLen || outputLength < 80 || outputLength < (unsigned int)hashLen / 2)) {
            throw XSECException(XSECException::AlgorithmMapperError,
                "HMACOutputLength set to unsafe value.");
        }

        sigVfyRet = compareBase64StringToRaw(sig,
            hash,
            hashLen,
            outputLength);

        break;

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

    }

    return sigVfyRet;
}

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

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

    // Is this a URI we recognize?

    XSECCryptoHash::HashType hashType = XSECAlgorithmSupport::getHashType(URI);

    if (hashType == XSECCryptoHash::HASH_NONE) {
        safeBuffer sb;
        sb.sbTranscodeIn("DSIGAlgorithmHandlerDefault - Unknown Hash URI : ");
        sb.sbXMLChCat(URI);

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

    TXFMBase* txfm;
    DOMDocument* d = inputBytes->getLastTxfm()->getDocument();
    XSECnew(txfm, TXFMHash(d, hashType));

    inputBytes->appendTxfm(txfm);

    return true;
}

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

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

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

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

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


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

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

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

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

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

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