/**
 * 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
 *
 * OpenSSLCryptoProvider := Base class to define an OpenSSL module
 *
 * Author(s): Berin Lautenbach
 *
 * $Id$
 *
 */

#include <xsec/framework/XSECDefs.hpp>
#if defined (XSEC_HAVE_OPENSSL)

#include <xsec/framework/XSECError.hpp>

#include <xsec/enc/OpenSSL/OpenSSLCryptoProvider.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoHash.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoHashHMAC.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoBase64.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyDSA.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyEC.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyHMAC.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoSymmetricKey.hpp>
#include <xsec/enc/OpenSSL/OpenSSLSupport.hpp>

#include <xsec/enc/XSCrypt/XSCryptCryptoBase64.hpp>

#include <xsec/enc/XSECCryptoException.hpp>

#include <xercesc/util/Janitor.hpp>

XSEC_USING_XERCES(ArrayJanitor);
XSEC_USING_XERCES(Janitor);

#include <openssl/rand.h>
#include <openssl/err.h>
#include <openssl/obj_mac.h>

OpenSSLCryptoProvider::OpenSSLCryptoProvider() {

    OpenSSL_add_all_algorithms();       // Initialise Openssl
    ERR_load_crypto_strings();

    //SSLeay_add_all_algorithms();
#ifdef XSEC_OPENSSL_HAVE_EC
    // Populate curve names.
    m_namedCurveMap["urn:oid:1.3.132.0.6"] = NID_secp112r1;
    m_namedCurveMap["urn:oid:1.3.132.0.7"] = NID_secp112r2;
    m_namedCurveMap["urn:oid:1.3.132.0.28"] = NID_secp128r1;
    m_namedCurveMap["urn:oid:1.3.132.0.29"] = NID_secp128r2;
    m_namedCurveMap["urn:oid:1.3.132.0.9"] = NID_secp160k1;
    m_namedCurveMap["urn:oid:1.3.132.0.8"] = NID_secp160r1;
    m_namedCurveMap["urn:oid:1.3.132.0.30"] = NID_secp160r2;
    m_namedCurveMap["urn:oid:1.3.132.0.31"] = NID_secp192k1;
    m_namedCurveMap["urn:oid:1.3.132.0.32"] = NID_secp224k1;
    m_namedCurveMap["urn:oid:1.3.132.0.33"] = NID_secp224r1;
    m_namedCurveMap["urn:oid:1.3.132.0.10"] = NID_secp256k1;
    m_namedCurveMap["urn:oid:1.3.132.0.34"] = NID_secp384r1;
    m_namedCurveMap["urn:oid:1.3.132.0.35"] = NID_secp521r1;

    m_namedCurveMap["urn:oid:1.2.840.10045.3.1.1"] = NID_X9_62_prime192v1;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.1.2"] = NID_X9_62_prime192v2;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.1.3"] = NID_X9_62_prime192v3;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.1.4"] = NID_X9_62_prime239v1;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.1.5"] = NID_X9_62_prime239v2;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.1.6"] = NID_X9_62_prime239v3;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.1.7"] = NID_X9_62_prime256v1;

    m_namedCurveMap["urn:oid:1.3.132.0.4"] = NID_sect113r1;
    m_namedCurveMap["urn:oid:1.3.132.0.5"] = NID_sect113r2;
    m_namedCurveMap["urn:oid:1.3.132.0.22"] = NID_sect131r1;
    m_namedCurveMap["urn:oid:1.3.132.0.23"] = NID_sect131r2;
    m_namedCurveMap["urn:oid:1.3.132.0.1"] = NID_sect163k1;
    m_namedCurveMap["urn:oid:1.3.132.0.2"] = NID_sect163r1;
    m_namedCurveMap["urn:oid:1.3.132.0.15"] = NID_sect163r2;
    m_namedCurveMap["urn:oid:1.3.132.0.24"] = NID_sect193r1;
    m_namedCurveMap["urn:oid:1.3.132.0.25"] = NID_sect193r2;
    m_namedCurveMap["urn:oid:1.3.132.0.26"] = NID_sect233k1;
    m_namedCurveMap["urn:oid:1.3.132.0.27"] = NID_sect233r1;
    m_namedCurveMap["urn:oid:1.3.132.0.3"] = NID_sect239k1;
    m_namedCurveMap["urn:oid:1.3.132.0.16"] = NID_sect283k1;
    m_namedCurveMap["urn:oid:1.3.132.0.17"] = NID_sect283r1;
    m_namedCurveMap["urn:oid:1.3.132.0.36"] = NID_sect409k1;
    m_namedCurveMap["urn:oid:1.3.132.0.37"] = NID_sect409r1;
    m_namedCurveMap["urn:oid:1.3.132.0.38"] = NID_sect571k1;
    m_namedCurveMap["urn:oid:1.3.132.0.39"] = NID_sect571r1;

    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.1"] = NID_X9_62_c2pnb163v1;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.2"] = NID_X9_62_c2pnb163v2;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.3"] = NID_X9_62_c2pnb163v3;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.4"] = NID_X9_62_c2pnb176v1;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.5"] = NID_X9_62_c2tnb191v1;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.6"] = NID_X9_62_c2tnb191v2;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.7"] = NID_X9_62_c2tnb191v3;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.8"] = NID_X9_62_c2onb191v4;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.9"] = NID_X9_62_c2onb191v5;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.10"] = NID_X9_62_c2pnb208w1;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.11"] = NID_X9_62_c2tnb239v1;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.12"] = NID_X9_62_c2tnb239v2;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.13"] = NID_X9_62_c2tnb239v3;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.14"] = NID_X9_62_c2onb239v4;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.15"] = NID_X9_62_c2onb239v5;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.16"] = NID_X9_62_c2pnb272w1;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.17"] = NID_X9_62_c2pnb304w1;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.18"] = NID_X9_62_c2tnb359v1;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.19"] = NID_X9_62_c2pnb368w1;
    m_namedCurveMap["urn:oid:1.2.840.10045.3.0.20"] = NID_X9_62_c2tnb431r1;

    m_namedCurveMap["urn:oid:2.23.43.1.4.1"] = NID_wap_wsg_idm_ecid_wtls1;
    m_namedCurveMap["urn:oid:2.23.43.1.4.3"] = NID_wap_wsg_idm_ecid_wtls3;
    m_namedCurveMap["urn:oid:2.23.43.1.4.4"] = NID_wap_wsg_idm_ecid_wtls4;
    m_namedCurveMap["urn:oid:2.23.43.1.4.5"] = NID_wap_wsg_idm_ecid_wtls5;
    m_namedCurveMap["urn:oid:2.23.43.1.4.6"] = NID_wap_wsg_idm_ecid_wtls6;
    m_namedCurveMap["urn:oid:2.23.43.1.4.7"] = NID_wap_wsg_idm_ecid_wtls7;
    m_namedCurveMap["urn:oid:2.23.43.1.4.8"] = NID_wap_wsg_idm_ecid_wtls8;
    m_namedCurveMap["urn:oid:2.23.43.1.4.9"] = NID_wap_wsg_idm_ecid_wtls9;
    m_namedCurveMap["urn:oid:2.23.43.1.4.10"] = NID_wap_wsg_idm_ecid_wtls10;
    m_namedCurveMap["urn:oid:2.23.43.1.4.11"] = NID_wap_wsg_idm_ecid_wtls11;
    m_namedCurveMap["urn:oid:2.23.43.1.4.12"] = NID_wap_wsg_idm_ecid_wtls12;
#endif
}


OpenSSLCryptoProvider::~OpenSSLCryptoProvider() {

    EVP_cleanup();
    ERR_free_strings();
    /* As suggested by Jesse Pelton */
#if defined(XSEC_OPENSSL_HAVE_CRYPTO_CLEANUP_ALL_EX_DATA)
    CRYPTO_cleanup_all_ex_data();
#endif
    RAND_cleanup();
    X509_TRUST_cleanup();
    ERR_remove_state(0);
}

#ifdef XSEC_OPENSSL_HAVE_EC
int OpenSSLCryptoProvider::curveNameToNID(const char* curveName) const {

    std::map<std::string,int>::const_iterator i = m_namedCurveMap.find(curveName);
    if (i == m_namedCurveMap.end())
        throw XSECCryptoException(XSECCryptoException::UnsupportedError,
            "OpenSSLCryptoProvider::curveNameToNID - curve name not recognized");
    return i->second;

}
#endif

const XMLCh * OpenSSLCryptoProvider::getProviderName() const {

    return DSIGConstants::s_unicodeStrPROVOpenSSL;

}
    // Hashing classes

unsigned int OpenSSLCryptoProvider::getMaxHashSize() const {
    return 128;
}

XSECCryptoHash  * OpenSSLCryptoProvider::hash(XSECCryptoHash::HashType type) const {
	OpenSSLCryptoHash* ret;

	XSECnew(ret, OpenSSLCryptoHash(type));

	return ret;
}

XSECCryptoHash * OpenSSLCryptoProvider::HMAC(XSECCryptoHash::HashType type) const {
	OpenSSLCryptoHashHMAC* ret;

	XSECnew(ret, OpenSSLCryptoHashHMAC(type));

	return ret;
}

XSECCryptoKeyHMAC * OpenSSLCryptoProvider::keyHMAC(void) const {
    OpenSSLCryptoKeyHMAC * ret;

    XSECnew(ret, OpenSSLCryptoKeyHMAC);

    return ret;

}

XSECCryptoKeyDSA * OpenSSLCryptoProvider::keyDSA() const {
    OpenSSLCryptoKeyDSA * ret;

    XSECnew(ret, OpenSSLCryptoKeyDSA());

    return ret;

}

XSECCryptoKeyRSA * OpenSSLCryptoProvider::keyRSA() const {
    OpenSSLCryptoKeyRSA * ret;

    XSECnew(ret, OpenSSLCryptoKeyRSA());

    return ret;
}

XSECCryptoKeyEC * OpenSSLCryptoProvider::keyEC() const {
    
#ifdef XSEC_OPENSSL_HAVE_EC
    OpenSSLCryptoKeyEC * ret;

    XSECnew(ret, OpenSSLCryptoKeyEC());

    return ret;
#else
    throw XSECCryptoException(XSECCryptoException::UnsupportedError,
        "OpenSSLCryptoProvider::keyEC - EC support not available");
#endif
}

XSECCryptoKey* OpenSSLCryptoProvider::keyDER(const char* buf, unsigned long len, bool base64) const {

    EVP_PKEY* pkey = NULL;

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

        /* Had to move to our own Base64 decoder because it handles non-wrapped b64
           better.  Grrr. */

        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);

        BIO* b = BIO_new_mem_buf((void*)outBuf, bufLen);
        pkey = d2i_PUBKEY_bio(b, NULL);
        BIO_free(b);

    }
    else {

        BIO* b = BIO_new_mem_buf((void*)buf, len);
        pkey = d2i_PUBKEY_bio(b, NULL);
        BIO_free(b);

    }

    if (pkey) {
        XSECCryptoKey* ret = NULL;
        try {
            switch (EVP_PKEY_id(pkey)) {
                case EVP_PKEY_RSA:
                    ret = new OpenSSLCryptoKeyRSA(pkey);
                    break;

                case EVP_PKEY_DSA:
                    ret = new OpenSSLCryptoKeyDSA(pkey);
                    break;

#if defined(XSEC_OPENSSL_HAVE_EC)
                case EVP_PKEY_EC:
                    ret = new OpenSSLCryptoKeyEC(pkey);
                    break;
#endif
            }
        }
        catch (const XSECCryptoException&) {
            EVP_PKEY_free(pkey);
            throw;
        }

        EVP_PKEY_free(pkey);
        return ret;
    }

    throw XSECCryptoException(XSECCryptoException::UnsupportedError,
        "OpenSSLCryptoProvider::keyDER - Error decoding public key"); 
}


XSECCryptoX509 * OpenSSLCryptoProvider::X509() const {
    OpenSSLCryptoX509 * ret;

    XSECnew(ret, OpenSSLCryptoX509());

    return ret;
}

XSECCryptoBase64 * OpenSSLCryptoProvider::base64() const {
    XSCryptCryptoBase64 *ret;

    XSECnew(ret, XSCryptCryptoBase64);

    return ret;
}

bool OpenSSLCryptoProvider::algorithmSupported(XSECCryptoSymmetricKey::SymmetricKeyType alg) const {
    switch (alg) {

    case (XSECCryptoSymmetricKey::KEY_AES_128) :
    case (XSECCryptoSymmetricKey::KEY_AES_192) :
    case (XSECCryptoSymmetricKey::KEY_AES_256) :

#if !defined (XSEC_OPENSSL_HAVE_AES)
        return false;
#endif
    case (XSECCryptoSymmetricKey::KEY_3DES_192) :

        return true;

    default:

        return false;

    }

    return false;
}

bool OpenSSLCryptoProvider::algorithmSupported(XSECCryptoHash::HashType alg) const {
    switch (alg) {

    case (XSECCryptoHash::HASH_SHA1) :
    case (XSECCryptoHash::HASH_MD5) :
        return true;

    case (XSECCryptoHash::HASH_SHA224) :
    case (XSECCryptoHash::HASH_SHA256) :
#if defined(XSEC_OPENSSL_HAVE_SHA2) && !defined(OPENSSL_NO_SHA256)
        return true;
#else
        return false;
#endif

    case (XSECCryptoHash::HASH_SHA384) :
    case (XSECCryptoHash::HASH_SHA512) :
#if defined(XSEC_OPENSSL_HAVE_SHA2) && !defined(OPENSSL_NO_SHA512)
        return true;
#else
        return false;
#endif

    default:
        return false;
    }

    return false;
}


XSECCryptoSymmetricKey  * OpenSSLCryptoProvider::keySymmetric(XSECCryptoSymmetricKey::SymmetricKeyType alg) const {
    OpenSSLCryptoSymmetricKey * ret;

    XSECnew(ret, OpenSSLCryptoSymmetricKey(alg));

    return ret;
}

unsigned int OpenSSLCryptoProvider::getRandom(unsigned char * buffer, unsigned int numOctets) const {
    if (RAND_status() != 1) {

        throw XSECCryptoException(XSECCryptoException::GeneralError,
            "OpenSSLCryptoProvider::getRandom - OpenSSL random not properly initialised"); 
    }

    int res = RAND_bytes(buffer, numOctets);

    if (res == 0) {

        throw XSECCryptoException(XSECCryptoException::GeneralError,
            "OpenSSLCryptoProvider::getRandom - Error obtaining random octets"); 
    
    }

    return numOctets;
}


#endif /* XSEC_HAVE_OPENSSL */
