/**
 * 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
 *
 * XSECCryptoUtils:= Helper crypo utilities that make life easier
 *
 * Author(s): Berin Lautenbach
 *
 * $Id$
 *
 */

#include <xsec/framework/XSECDefs.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/enc/XSECCryptoUtils.hpp>
#include <xsec/enc/XSECCryptoKeyHMAC.hpp>
#include <xsec/utils/XSECPlatformUtils.hpp>

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

#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUniDefs.hpp>

XERCES_CPP_NAMESPACE_USE

#ifdef XSEC_XKMS_ENABLED

// --------------------------------------------------------------------------------
//           XKMS Limited-Use Shared Secret handling
// --------------------------------------------------------------------------------

int CleanXKMSPassPhrase(unsigned char * input, int inputLen, safeBuffer &output) {

    // Now obsolete - use SASLCleanXKMSPassPhrase instead
    int j = 0;
    unsigned char c;
    for (int i = 0; i < inputLen; ++i) {

        c = input[i];

        if (c >= 'A' && c <= 'Z') {
            output[j++] = c - 'A' + 'a';
        }
        else if (c != '\n' && c != '\r' && c != '\t' && c != ' ') {
            output[j++] = c;
        }

    }

    return j;

}

int SASLCleanXKMSPassPhrase(unsigned char * input, int inputLen, safeBuffer &output) {

    // For now - this does *not* implement the full SASLPrep algorithm.
    // THe NFKC form is not trivial to implement - so this is kept very simple.
    // TODO - Fix this - it can be an interoperability issue as pass phrases from
    // different implementations could be treated differently.
    // Currently we only check for prohibited unput for chars < 0xFFFF and drop any
    // chars over 0xFFFF

    unsigned char * inp = new unsigned char[inputLen + 1];
    ArrayJanitor<unsigned char> j_inp(inp);
    memcpy(inp, input, inputLen);
    inp[inputLen] = '\0';

    XSECAutoPtrXMLCh uinput((char *) inp);
    XMLSize_t l = XMLString::stringLen(uinput.get());
    XMLCh* uoutput = new XMLCh[l + 1];
    ArrayJanitor<XMLCh> j_uoutput(uoutput);

    XMLSize_t i, j;
    j = 0;

    XMLCh ch1;

    for (i = 0; i < l; ++i) {

        ch1 = uinput.get()[i];
        // Case one - char is < 0x10000
        if (ch1 < 0xD800 || ch1 > 0xDFFF) {

            // OK - ch1 is "real" value - let's see if it is legal
            // The following switch tables are derived from
            // RFC 3454 - see http://www.ietf.org/rfc/rfc3454.txt

            // Non-ASCII Spaces - C.1.2
            switch (ch1) {

            case 0x00A0:        // NO-BREAK SPACE
            case 0x1680:        // OGHAM SPACE MARK
            case 0x2000:        // EN QUAD
            case 0x2001:        // EM QUAD
            case 0x2002:        // EN SPACE
            case 0x2003:        // EM SPACE
            case 0x2004:        // THREE-PER-EM SPACE
            case 0x2005:        // FOUR-PER-EM SPACE
            case 0x2006:        // SIX-PER-EM SPACE
            case 0x2007:        // FIGURE SPACE
            case 0x2008:        // PUNCTUATION SPACE
            case 0x2009:        // THIN SPACE
            case 0x200A:        // HAIR SPACE
            case 0x200B:        // ZERO WIDTH SPACE
            case 0x202F:        // NARROW NO-BREAK SPACE
            case 0x205F:        // MEDIUM MATHEMATICAL SPACE
            case 0x3000:        // IDEOGRAPHIC SPACE

                throw XSECException(XSECException::XKMSError,
                    "SASLCleanXKMSPassPhrase - Non ASCII space character in XKMS pass phrase");
            default:

                break;

            }

            // ASCII Control characters
            // Note - us unsigned, so always >= 0)
            if ((ch1 <= 0x1F) || (ch1 == 0x7F)) {
                throw XSECException(XSECException::XKMSError,
                    "SASLCleanXKMSPassPhrase - ASCII control character in XKMS pass phrase");
            }

            // Non-ASCII Control Characters
            if ((ch1 >= 0x80 && ch1 <= 0x9F) ||
                (ch1 >= 0x206A && ch1 <= 0x206F) ||
                (ch1 >= 0xFFF9 && ch1 <= 0xFFFC)) {

                throw XSECException(XSECException::XKMSError,
                    "SASLCleanXKMSPassPhrase - NON ASCII control character in XKMS pass phrase");
            }

            switch (ch1) {


            case 0x06DD:        // ARABIC END OF AYAH
            case 0x070F:        // SYRIAC ABBREVIATION MARK
            case 0x180E:        // MONGOLIAN VOWEL SEPARATOR
            case 0x200C:        // ZERO WIDTH NON-JOINER
            case 0x200D:        // ZERO WIDTH JOINER
            case 0x2028:        // LINE SEPARATOR
            case 0x2029:        // PARAGRAPH SEPARATOR
            case 0x2060:        // WORD JOINER
            case 0x2061:        // FUNCTION APPLICATION
            case 0x2062:        // INVISIBLE TIMES
            case 0x2063:        // INVISIBLE SEPARATOR
            case 0xFEFF:        // ZERO WIDTH NO-BREAK SPACE
                throw XSECException(XSECException::XKMSError,
                    "SASLCleanXKMSPassPhrase - NON ASCII control character in XKMS pass phrase");
            default:
                break;            }
            // 1D173-1D17A; [MUSICAL CONTROL CHARACTERS] is not relevant as we are looking at
            // ch1 at the moment

            // Private Use characters
            if ((ch1 >= 0xE000 && ch1 <= 0xF8FF)) {

                throw XSECException(XSECException::XKMSError,
                    "SASLCleanXKMSPassPhrase - Private Use character in XKMS pass phrase");
            }

            // Non-character code points
            if ((ch1 >= 0xFDD0 && ch1 <= 0xFDEF) ||
                (ch1 >= 0xFFFE)) {

                throw XSECException(XSECException::XKMSError,
                    "SASLCleanXKMSPassPhrase - Non-character code points in XKMS pass phrase");
            }

            // Inappropriate for plain text characters
   
            switch (ch1) {
            case 0xFFF9:        // INTERLINEAR ANNOTATION ANCHOR
            case 0xFFFA:        // INTERLINEAR ANNOTATION SEPARATOR
            case 0xFFFB:        // INTERLINEAR ANNOTATION TERMINATOR
            case 0xFFFC:        // OBJECT REPLACEMENT CHARACTER
            case 0xFFFD:        // REPLACEMENT CHARACTER
                throw XSECException(XSECException::XKMSError,
                    "SASLCleanXKMSPassPhrase - Innappropriate for plain text chararcters in XKMS pass phrase");
            default:
                break;
            }

            // Inappripriate for canonical representation characters
            if (ch1 >= 0x2FF0 && ch1 <= 0x2FFB) {
                throw XSECException(XSECException::XKMSError,
                    "SASLCleanXKMSPassPhrase - Innappropriate for canonicalisation chararcters in XKMS pass phrase");
            }

            // Change display properties or are deprecated
            switch (ch1) {
            case 0x0340:        // COMBINING GRAVE TONE MARK
            case 0x0341:        // COMBINING ACUTE TONE MARK
            case 0x200E:        // LEFT-TO-RIGHT MARK
            case 0x200F:        // RIGHT-TO-LEFT MARK
            case 0x202A:        // LEFT-TO-RIGHT EMBEDDING
            case 0x202B:        // RIGHT-TO-LEFT EMBEDDING
            case 0x202C:        // POP DIRECTIONAL FORMATTING
            case 0x202D:        // LEFT-TO-RIGHT OVERRIDE
            case 0x202E:        // RIGHT-TO-LEFT OVERRIDE
            case 0x206A:        // INHIBIT SYMMETRIC SWAPPING
            case 0x206B:        // ACTIVATE SYMMETRIC SWAPPING
            case 0x206C:        // INHIBIT ARABIC FORM SHAPING
            case 0x206D:        // ACTIVATE ARABIC FORM SHAPING
            case 0x206E:        // NATIONAL DIGIT SHAPES
            case 0x206F:        // NOMINAL DIGIT SHAPES
                throw XSECException(XSECException::XKMSError,
                    "SASLCleanXKMSPassPhrase - change display or deprecated chararcters in XKMS pass phrase");
            default:
                break;
            }

            // We got this far = just run with it for now
            uoutput[j++] = ch1;
        }
        else {
            throw XSECException(XSECException::XKMSError,
                "SASLCleanXKMSPassPhrase - don't support XKMS pass phrase chars > 0xFFFF");
        }
    } /* for */
    uoutput[j++] = chNull;

    // Now transcode
    char * utf8output= transcodeToUTF8(uoutput);
    output.sbStrcpyIn(utf8output);

    int ret = (int)strlen(utf8output);
    XSEC_RELEASE_XMLCH(utf8output);
    return ret;
}

int XSEC_EXPORT CalculateXKMSAuthenticationKey(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {

    unsigned char keyVal[] = {XKMSAuthenticationValue};

    XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
    Janitor<XSECCryptoKeyHMAC> j_k(k);
    k->setKey(keyVal, 1);

    XSECCryptoHash *h = XSECPlatformUtils::g_cryptoProvider->HMAC(XSECCryptoHash::HASH_SHA1);
    Janitor<XSECCryptoHash> j_h(h);
    h->setKey(k);

    // Clean the input
    safeBuffer sb;
    int l = SASLCleanXKMSPassPhrase(input, inputLen, sb);

    h->hash((unsigned char *) sb.rawBuffer(), l);
    return h->finish(output, maxOutputLen);

}


int XSEC_EXPORT CalculateXKMSRevocationCodeIdentifierEncoding1(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {

    unsigned char keyVal[] = {XKMSRevocationCodeIdenfitierEncoding1};

    XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
    Janitor<XSECCryptoKeyHMAC> j_k(k);
    k->setKey(keyVal, 1);

    XSECCryptoHash *h = XSECPlatformUtils::g_cryptoProvider->HMAC(XSECCryptoHash::HASH_SHA1);
    Janitor<XSECCryptoHash> j_h(h);

    h->setKey(k);

    // Clean the input
    safeBuffer sb;
    int l = CleanXKMSPassPhrase(input, inputLen, sb);

    h->hash((unsigned char *) sb.rawBuffer(), l);
    return h->finish(output, maxOutputLen);

}

int XSEC_EXPORT CalculateXKMSRevocationCodeIdentifierEncoding2(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {


    unsigned char tmpBuf[XSEC_MAX_HASH_SIZE];
    int tmpLen = CalculateXKMSRevocationCodeIdentifierEncoding1(input, inputLen, tmpBuf, XSEC_MAX_HASH_SIZE);
    return CalculateXKMSRevocationCodeIdentifierEncoding2From1(tmpBuf, tmpLen, output, maxOutputLen);

}

int XSEC_EXPORT CalculateXKMSRevocationCodeIdentifierEncoding2From1(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {

    unsigned char keyVal[] = {XKMSRevocationCodeIdenfitierEncoding2};

    XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
    Janitor<XSECCryptoKeyHMAC> j_k(k);
    k->setKey(keyVal, 1);

    XSECCryptoHash *h = XSECPlatformUtils::g_cryptoProvider->HMAC(XSECCryptoHash::HASH_SHA1);
    Janitor<XSECCryptoHash> j_h(h);

    h->setKey(k);

    h->hash(input, inputLen);
    return h->finish(output, maxOutputLen);

}

int XSEC_EXPORT CalculateXKMSKEK(unsigned char * input, int inputLen, unsigned char * output, int maxOutputLen) {

    unsigned char keyVal[] = {XKMSKeyEncryption};
    unsigned char shaOutput[22];    // SHA1 has 20 bytes of output

    // Clean the input
    safeBuffer sb;
    int l = SASLCleanXKMSPassPhrase(input, inputLen, sb);

    // Need to iterate through until we have enough data
    int bytesDone = 0, bytesToDo;;
    shaOutput[0] = keyVal[0];
    int keyLen = 1;
    while (bytesDone < maxOutputLen) {
        XSECCryptoKeyHMAC * k = XSECPlatformUtils::g_cryptoProvider->keyHMAC();
        k->setKey(shaOutput, keyLen);

        XSECCryptoHash *h = XSECPlatformUtils::g_cryptoProvider->HMAC(XSECCryptoHash::HASH_SHA1);
        Janitor<XSECCryptoHash> j_h(h);

        h->setKey(k);
        delete(k);

        // Now hash next round of data
        h->hash((unsigned char *) sb.rawBuffer(), l);
        keyLen = h->finish(shaOutput, 22);

        // Copy into the output buffer
        bytesToDo = maxOutputLen - bytesDone;
        bytesToDo = bytesToDo > 20 ? 20 : bytesToDo;
        memcpy(&output[bytesDone], shaOutput, bytesToDo);
        bytesDone += bytesToDo;

        // Set up for next key
        shaOutput[0] ^= keyVal[0];
        keyLen = 20;

        j_h.release();
        delete h;
    }

    return bytesDone;

}

#endif

// --------------------------------------------------------------------------------
//           Some Base64 helpers
// --------------------------------------------------------------------------------

XMLCh XSEC_EXPORT * EncodeToBase64XMLCh(unsigned char * input, int inputLen) {

    XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64();
    Janitor<XSECCryptoBase64> j_b64(b64);
    unsigned char * output;
    int outputLen = ((4 * inputLen) / 3) + 5;
    XSECnew(output, unsigned char[outputLen]);
    ArrayJanitor<unsigned char> j_output(output);

    b64->encodeInit();
    int j = b64->encode(input, inputLen, output, outputLen - 1);
    j += b64->encodeFinish(&output[j], outputLen - j - 1);

    // Strip any trailing \n\r
    while (j > 0 && (output[j-1] == '\n' || output[j-1] == '\r'))
        j--;

    // Now transcode and get out of here
    output[j] = '\0';
    return XMLString::transcode((char *) output);

}

unsigned int XSEC_EXPORT DecodeFromBase64XMLCh(const XMLCh * input, unsigned char * output, int maxOutputLen) {

    XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64();
    Janitor<XSECCryptoBase64> j_b64(b64);

    XSECAutoPtrChar tinput(input);

    b64->decodeInit();
    unsigned int j = b64->decode((unsigned char *) tinput.get(), (unsigned int) strlen(tinput.get()), output, maxOutputLen - 1);
    j += b64->decodeFinish(&output[j], maxOutputLen - j - 1);

    return j;
}

unsigned int XSEC_EXPORT DecodeFromBase64(const char * input, unsigned char * output, int maxOutputLen) {

    XSECCryptoBase64 * b64 = XSECPlatformUtils::g_cryptoProvider->base64();
    Janitor<XSECCryptoBase64> j_b64(b64);

    b64->decodeInit();
    unsigned int j = b64->decode((unsigned char *) input, (unsigned int) strlen(input), output, maxOutputLen - 1);
    j += b64->decodeFinish(&output[j], maxOutputLen - j - 1);

    return j;
}


// --------------------------------------------------------------------------------
//           Some stuff to help with wierd signatures
// --------------------------------------------------------------------------------

const unsigned char ASNDSAProlog[] = {0x30, 0x2c, 0x02, 0x14};
const unsigned char ASNDSAMiddle[] = {0x02, 0x14};

bool ASN2DSASig(const unsigned char * input, unsigned char * r, unsigned char * s) {

    if (memcmp(ASNDSAProlog, input, 4) != 0 ||
        memcmp(ASNDSAMiddle, &input[24], 2) != 0)

        return false;

    memcpy(r, &input[4], 20);
    memcpy(s, &input[26], 20);

    return true;

}


// --------------------------------------------------------------------------------
//           Calculate correct OIDs for an RSA sig
// --------------------------------------------------------------------------------

/* As per RSA's PKCS #1 v 2.1, Section 9.2 Note 1, the DER encodings for
 * the has types are as follows:
 *
 * MD2: (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 02 05 00 04 10 || H.
 * MD5: (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04 10 || H.
 * SHA-1: (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H.
 * SHA-256: (0x)30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 || H.
 * SHA-384: (0x)30 41 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00 04 30 || H.
 * SHA-512: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00 04 40 || H.
 *
 * More recently the following has been provided for SHA-224
 *
 * SHA-224: 30 2d 30 0d 06 09 60 86 48 01 65 03 04 02 04 05 00 04 1c
 *
 */

int MD5OIDLen = 18;
unsigned char MD5OID[] = {
    0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,
    0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00,
    0x04, 0x10
};


int sha1OIDLen = 15;
unsigned char sha1OID[] = {
    0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E,
    0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14
};

int sha224OIDLen = 19;
unsigned char sha224OID[] = {
    0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05,
    0x00, 0x04, 0x1c
};

int sha256OIDLen = 19;
unsigned char sha256OID[] = {
    0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
    0x00, 0x04, 0x20
};

int sha384OIDLen = 19;
unsigned char sha384OID[] = {
    0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
    0x00, 0x04, 0x30
};

int sha512OIDLen = 19;
unsigned char sha512OID[] = {
    0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
    0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
    0x00, 0x04, 0x40
};


unsigned char* getRSASigOID(XSECCryptoHash::HashType type, int& oidLen) {

    switch (type) {

    case (XSECCryptoHash::HASH_MD5):
        oidLen = MD5OIDLen;
        return MD5OID;
    case (XSECCryptoHash::HASH_SHA1):
        oidLen = sha1OIDLen;
        return sha1OID;
    case (XSECCryptoHash::HASH_SHA224):
        oidLen = sha224OIDLen;
        return sha224OID;
    case (XSECCryptoHash::HASH_SHA256):
        oidLen = sha256OIDLen;
        return sha256OID;
    case (XSECCryptoHash::HASH_SHA384):
        oidLen = sha384OIDLen;
        return sha384OID;
    case (XSECCryptoHash::HASH_SHA512):
        oidLen = sha512OIDLen;
        return sha512OID;
    default:
        oidLen = 0;
        return NULL;

    }
}

XSECCryptoHash* XSECCryptoProvider::hash(const XMLCh* uri) const {

    return hash(XSECAlgorithmSupport::getHashType(uri));
}

XSECCryptoHash* XSECCryptoProvider::HMAC(const XMLCh* uri) const {

    return HMAC(XSECAlgorithmSupport::getHashType(uri));
}
