/**
 * 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
 *
 * OpenSSLCryptoKeyEC := EC Keys
 *
 * Author(s): Scott Cantor
 *
 * $Id:$
 *
 */
#include <xsec/framework/XSECDefs.hpp>
#if defined (XSEC_HAVE_OPENSSL) && defined (XSEC_OPENSSL_HAVE_EC)

#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyEC.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoBase64.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoProvider.hpp>
#include <xsec/enc/OpenSSL/OpenSSLSupport.hpp>

#include <xsec/enc/XSECCryptoException.hpp>
#include <xsec/enc/XSECCryptoUtils.hpp>
#include <xsec/enc/XSCrypt/XSCryptCryptoBase64.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/utils/XSECPlatformUtils.hpp>

#include <xercesc/util/Janitor.hpp>

XSEC_USING_XERCES(Janitor);
XSEC_USING_XERCES(ArrayJanitor);


#include <openssl/ecdsa.h>

OpenSSLCryptoKeyEC::OpenSSLCryptoKeyEC() : mp_ecKey(NULL) {
};

OpenSSLCryptoKeyEC::~OpenSSLCryptoKeyEC() {


    // If we have a EC_KEY, delete it
    // OpenSSL will ensure the memory holding any private key is freed.

    if (mp_ecKey)
        EC_KEY_free(mp_ecKey);

};

const XMLCh* OpenSSLCryptoKeyEC::getProviderName() const {
	return DSIGConstants::s_unicodeStrPROVOpenSSL;
}

// Generic key functions

XSECCryptoKey::KeyType OpenSSLCryptoKeyEC::getKeyType() const {

    // Find out what we have
    if (mp_ecKey == NULL)
        return KEY_NONE;

    if (EC_KEY_get0_private_key(mp_ecKey) && EC_KEY_get0_public_key(mp_ecKey))
        return KEY_EC_PAIR;

    if (EC_KEY_get0_private_key(mp_ecKey))
        return KEY_EC_PRIVATE;

    if (EC_KEY_get0_public_key(mp_ecKey))
        return KEY_EC_PUBLIC;

    return KEY_NONE;

}

void OpenSSLCryptoKeyEC::loadPublicKeyBase64(const char* curveName, const char * buf, unsigned int len) {

    if (mp_ecKey) {
        EC_KEY_free(mp_ecKey);
        mp_ecKey = NULL;
    }

    EC_KEY* key = EC_KEY_new_by_curve_name(static_cast<OpenSSLCryptoProvider*>(XSECPlatformUtils::g_cryptoProvider)->curveNameToNID(curveName));

    int bufLen = len;
    unsigned char * outBuf;
    XSECnew(outBuf, unsigned char[len + 1]);
    ArrayJanitor<unsigned char> j_outBuf(outBuf);

    XSCryptCryptoBase64 *b64;
    XSECnew(b64, XSCryptCryptoBase64);
    Janitor<XSCryptCryptoBase64> j_b64(b64);

    b64->decodeInit();
    bufLen = b64->decode((unsigned char *) buf, len, outBuf, len);
    bufLen += b64->decodeFinish(&outBuf[bufLen], len-bufLen);

    if (bufLen > 0) {
        if (o2i_ECPublicKey(&key, (const unsigned char **) &outBuf, bufLen) == NULL) {
            EC_KEY_free(key);
            key = NULL;
        }
    }

    if (key == NULL) {

        throw XSECCryptoException(XSECCryptoException::ECError,
        "OpenSSL:EC - Error translating Base64 octets into OpenSSL EC_KEY structure");

    }

    mp_ecKey = key;
}


// "Hidden" OpenSSL functions

OpenSSLCryptoKeyEC::OpenSSLCryptoKeyEC(EVP_PKEY *k) {

    // Create a new key to be loaded as we go

    if (k == NULL || EVP_PKEY_id(k) != EVP_PKEY_EC)
        return; // Nothing to do with us

    mp_ecKey = EC_KEY_dup(EVP_PKEY_get0_EC_KEY(k));
}

// --------------------------------------------------------------------------------
//           Verify a signature encoded as a Base64 string
// --------------------------------------------------------------------------------

bool OpenSSLCryptoKeyEC::verifyBase64SignatureDSA(unsigned char * hashBuf,
                                 unsigned int hashLen,
                                 char * base64Signature,
                                 unsigned int sigLen) const {

    // Use the currently loaded key to validate the Base64 encoded signature

    if (mp_ecKey == NULL) {

        throw XSECCryptoException(XSECCryptoException::ECError,
            "OpenSSL:EC - Attempt to validate signature with empty key");
    }

    char * cleanedBase64Signature;
    unsigned int cleanedBase64SignatureLen = 0;

    cleanedBase64Signature =
        XSECCryptoBase64::cleanBuffer(base64Signature, sigLen, cleanedBase64SignatureLen);
    ArrayJanitor<char> j_cleanedBase64Signature(cleanedBase64Signature);

    int sigValLen;
    unsigned char* sigVal = new unsigned char[sigLen + 1];
    ArrayJanitor<unsigned char> j_sigVal(sigVal);

    EvpEncodeCtxRAII dctx;

    if (!dctx.of()) {
        throw XSECCryptoException(XSECCryptoException::ECError,
            "OpenSSL:EC - allocation fail during Context Creation");
    }

    EVP_DecodeInit(dctx.of());
    int rc = EVP_DecodeUpdate(dctx.of(),
                          sigVal,
                          &sigValLen,
                          (unsigned char *) cleanedBase64Signature,
                          cleanedBase64SignatureLen);

    if (rc < 0) {

        throw XSECCryptoException(XSECCryptoException::ECError,
            "OpenSSL:EC - Error during Base64 Decode");
    }
    int t = 0;

    EVP_DecodeFinal(dctx.of(), &sigVal[sigValLen], &t);

    sigValLen += t;

    if (sigValLen <= 0 || sigValLen % 2 != 0) {
        throw XSECCryptoException(XSECCryptoException::ECError,
            "OpenSSL:EC - Signature length was odd");
    }

    // Translate to BNs by splitting in half, and thence to ECDSA_SIG

    ECDSA_SIG * ecdsa_sig = ECDSA_SIG_new();
    BIGNUM *newR = BN_bin2bn(sigVal, sigValLen / 2, NULL);
    BIGNUM *newS =  BN_bin2bn(&sigVal[sigValLen / 2], sigValLen / 2, NULL);

    ECDSA_SIG_set0(ecdsa_sig, newR, newS);

    // Now we have a signature and a key - lets check

    int err = ECDSA_do_verify(hashBuf, hashLen, ecdsa_sig, mp_ecKey);

    ECDSA_SIG_free(ecdsa_sig);

    if (err < 0) {

        throw XSECCryptoException(XSECCryptoException::ECError,
            "OpenSSL:EC - Error validating signature");
    }

    return (err == 1);

}

// --------------------------------------------------------------------------------
//           Sign and encode result as a Base64 string
// --------------------------------------------------------------------------------


unsigned int OpenSSLCryptoKeyEC::signBase64SignatureDSA(unsigned char * hashBuf,
        unsigned int hashLen,
        char * base64SignatureBuf,
        unsigned int base64SignatureBufLen) const {

    // Sign a pre-calculated hash using this key

    if (mp_ecKey == NULL) {
        throw XSECCryptoException(XSECCryptoException::ECError,
            "OpenSSL:EC - Attempt to sign data with empty key");
    }

    ECDSA_SIG * ecdsa_sig;

    ecdsa_sig = ECDSA_do_sign(hashBuf, hashLen, mp_ecKey);

    if (ecdsa_sig == NULL) {
        throw XSECCryptoException(XSECCryptoException::ECError,
            "OpenSSL:EC - Error signing data");
    }

    // To encode the signature properly, we need to know the "size of the
    // base point order of the curve in bytes", which seems to correspond to the
    // number of bits in the EC Group "order", using the OpenSSL API.
    // This is the size of the r and s values in the signature when converting them
    // to octet strings. The code below is cribbed from ECDSA_size.

    unsigned int keyLen = 0;
    const EC_GROUP* group = EC_KEY_get0_group(mp_ecKey);
    if (group) {
        BIGNUM* order = BN_new();
        if (order) {
            if (EC_GROUP_get_order(group, order, NULL)) {
                keyLen = (BN_num_bits(order) + 7) / 8; // round up to byte size
            }
            BN_clear_free(order);
        }
    }

    if (keyLen == 0) {
        throw XSECCryptoException(XSECCryptoException::ECError,
            "OpenSSL:EC - Error caclulating signature size");
    }

    // Now turn the signature into a raw octet string, half r and half s.

    unsigned char* rawSigBuf = new unsigned char[keyLen * 2];
    memset(rawSigBuf, 0, keyLen * 2);
    ArrayJanitor<unsigned char> j_sigbuf(rawSigBuf);

    const BIGNUM *sigR;
    const BIGNUM *sigS;
    ECDSA_SIG_get0(ecdsa_sig, &sigR, &sigS);

    unsigned int rawLen = (BN_num_bits(sigR) + 7) / 8;
    if (BN_bn2bin(sigR, rawSigBuf + keyLen - rawLen) <= 0) {
        throw XSECCryptoException(XSECCryptoException::ECError,
            "OpenSSL:EC - Error copying signature 'r' value to buffer");
    }

    rawLen = (BN_num_bits(sigS) + 7) / 8;
    if (BN_bn2bin(sigS, rawSigBuf + keyLen + keyLen - rawLen) <= 0) {
        throw XSECCryptoException(XSECCryptoException::ECError,
            "OpenSSL:EC - Error copying signature 's' value to buffer");
    }

    // Now convert to Base 64

    BIO * b64 = BIO_new(BIO_f_base64());
    BIO * bmem = BIO_new(BIO_s_mem());

    BIO_set_mem_eof_return(bmem, 0);
    b64 = BIO_push(b64, bmem);

    BIO_write(b64, rawSigBuf, keyLen * 2);
    BIO_flush(b64);

    unsigned int sigValLen = BIO_read(bmem, base64SignatureBuf, base64SignatureBufLen);

    BIO_free_all(b64);

    if (sigValLen <= 0) {
        throw XSECCryptoException(XSECCryptoException::ECError,
            "OpenSSL:EC - Error base64 encoding signature");
    }

    return sigValLen;
}



XSECCryptoKey * OpenSSLCryptoKeyEC::clone() const {

    OpenSSLCryptoKeyEC * ret;

    XSECnew(ret, OpenSSLCryptoKeyEC);

    if (mp_ecKey)
        ret->mp_ecKey = EC_KEY_dup(mp_ecKey);

    return ret;

}

#endif /* XSEC_HAVE_OPENSSL */
