/**
 * 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
 *
 * OpenSSLCryptoKeyRSA := RSA Keys
 *
 * Author(s): Berin Lautenbach
 *
 * $Id$
 *
 */

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

#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>
#include <xsec/enc/OpenSSL/OpenSSLCryptoBase64.hpp>
#include <xsec/enc/OpenSSL/OpenSSLSupport.hpp>
#include <xsec/enc/XSECCryptoException.hpp>
#include <xsec/enc/XSECCryptoUtils.hpp>
#include <xsec/framework/XSECError.hpp>

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

#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>

#include <xercesc/util/Janitor.hpp>

XSEC_USING_XERCES(ArrayJanitor);

#include <memory.h>

namespace {

    // This code is modified from OpenSSL to implement SHA-2 hashing with OAEP.
    // The MGF code is limited to SHA-1 in accordance with the XML Encryption spec.
    // 0.9.8+ has a public MGF routine to call, this is a copy of it for older versions.

#ifndef XSEC_OPENSSL_HAVE_MGF1
    int PKCS1_MGF1(unsigned char *mask, long len,
            const unsigned char *seed, long seedlen, const EVP_MD *dgst)
    {
        long i, outlen = 0;
        unsigned char cnt[4];
        EVP_MD_CTX c;
        unsigned char md[EVP_MAX_MD_SIZE];
        int mdlen;
        int rv = -1;

        EVP_MD_CTX_init(&c);
        mdlen = EVP_MD_size(dgst);
        if (mdlen < 0)
            goto err;
        for (i = 0; outlen < len; i++)
            {
            cnt[0] = (unsigned char)((i >> 24) & 255);
            cnt[1] = (unsigned char)((i >> 16) & 255);
            cnt[2] = (unsigned char)((i >> 8)) & 255;
            cnt[3] = (unsigned char)(i & 255);
            if (!EVP_DigestInit_ex(&c,dgst, NULL)
                || !EVP_DigestUpdate(&c, seed, seedlen)
                || !EVP_DigestUpdate(&c, cnt, 4))
                goto err;
            if (outlen + mdlen <= len)
                {
                if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL))
                    goto err;
                outlen += mdlen;
                }
            else
                {
                if (!EVP_DigestFinal_ex(&c, md, NULL))
                    goto err;
                memcpy(mask + outlen, md, len - outlen);
                outlen = len;
                }
            }
        rv = 0;
    err:
        EVP_MD_CTX_cleanup(&c);
        return rv;
    }
#endif

    static int MGF1(unsigned char *mask, long len, const unsigned char *seed, long seedlen, const EVP_MD* digest)
    {
        return PKCS1_MGF1(mask, len, seed, seedlen, digest);
    }

    int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
        const unsigned char *from, int flen,
        const unsigned char *param, int plen,
        const EVP_MD* digest,
        const EVP_MD* mgf_digest)
    {
        int i, digestlen = EVP_MD_size(digest), emlen = tlen - 1;
        unsigned char *db, *seed;
        unsigned char *dbmask, seedmask[EVP_MAX_MD_SIZE];   // accomodate largest hash size

        if (flen > emlen - 2 * digestlen - 1)
            {
            RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP,
               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
            return 0;
            }

        if (emlen < 2 * digestlen + 1)
            {
            RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, RSA_R_KEY_SIZE_TOO_SMALL);
            return 0;
            }

        to[0] = 0;
        seed = to + 1;
        db = to + digestlen + 1;

        if (!EVP_Digest((void *)param, plen, db, NULL, digest, NULL))
            return 0;
        memset(db + digestlen, 0,
            emlen - flen - 2 * digestlen - 1);
        db[emlen - flen - digestlen - 1] = 0x01;
        memcpy(db + emlen - flen - digestlen, from, (unsigned int) flen);
        if (RAND_bytes(seed, digestlen) <= 0)
            return 0;

        dbmask = (unsigned char*) OPENSSL_malloc(emlen - digestlen);
        if (dbmask == NULL)
            {
            RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
            return 0;
            }

        if (MGF1(dbmask, emlen - digestlen, seed, digestlen, mgf_digest) < 0)
            return 0;
        for (i = 0; i < emlen - digestlen; i++)
            db[i] ^= dbmask[i];

        if (MGF1(seedmask, digestlen, db, emlen - digestlen, mgf_digest) < 0)
            return 0;
        for (i = 0; i < digestlen; i++)
            seed[i] ^= seedmask[i];

        OPENSSL_free(dbmask);
        return 1;
    }

    int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
        const unsigned char *from, int flen, int num,
        const unsigned char *param, int plen,
        const EVP_MD* digest,
        const EVP_MD* mgf_digest)
    {
        int i, digestlen = EVP_MD_size(digest), dblen, mlen = -1;
        const unsigned char *maskeddb;
        int lzero;
        unsigned char *db = NULL, seed[EVP_MAX_MD_SIZE], phash[EVP_MAX_MD_SIZE];
        unsigned char *padded_from;
        int bad = 0;

        if (--num < 2 * digestlen + 1)
            /* 'num' is the length of the modulus, i.e. does not depend on the
             * particular ciphertext. */
            goto decoding_err;

        lzero = num - flen;
        if (lzero < 0)
            {
            /* signalling this error immediately after detection might allow
             * for side-channel attacks (e.g. timing if 'plen' is huge
             * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
             * Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001),
             * so we use a 'bad' flag */
            bad = 1;
            lzero = 0;
            flen = num; /* don't overflow the memcpy to padded_from */
            }

        dblen = num - digestlen;
        db = (unsigned char*) OPENSSL_malloc(dblen + num);
        if (db == NULL)
            {
            RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
            return -1;
            }

        /* Always do this zero-padding copy (even when lzero == 0)
         * to avoid leaking timing info about the value of lzero. */
        padded_from = db + dblen;
        memset(padded_from, 0, lzero);
        memcpy(padded_from + lzero, from, flen);

        maskeddb = padded_from + digestlen;

        if (MGF1(seed, digestlen, maskeddb, dblen, mgf_digest))
            return -1;
        for (i = 0; i < digestlen; i++)
            seed[i] ^= padded_from[i];
  
        if (MGF1(db, dblen, seed, digestlen, mgf_digest))
            return -1;
        for (i = 0; i < dblen; i++)
            db[i] ^= maskeddb[i];

        if (!EVP_Digest((void *)param, plen, phash, NULL, digest, NULL))
            return -1;

        if (memcmp(db, phash, digestlen) != 0 || bad)
            goto decoding_err;
        else
            {
            for (i = digestlen; i < dblen; i++)
                if (db[i] != 0x00)
                    break;
            if (i == dblen || db[i] != 0x01)
                goto decoding_err;
            else
                {
                /* everything looks OK */

                mlen = dblen - ++i;
                if (tlen < mlen)
                    {
                    RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
                    mlen = -1;
                    }
                else
                    memcpy(to, db + i, mlen);
                }
            }
        OPENSSL_free(db);
        return mlen;

    decoding_err:
        /* to avoid chosen ciphertext attacks, the error message should not reveal
         * which kind of decoding error happened */
        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR);
        if (db != NULL) OPENSSL_free(db);
        return -1;
    }

};

const EVP_MD* getDigestFromHashType(XSECCryptoHash::HashType type) {

    const EVP_MD* evp_md = NULL;

    switch (type) {
        case XSECCryptoHash::HASH_SHA1:
            evp_md = EVP_get_digestbyname("SHA1");
            break;
        case XSECCryptoHash::HASH_SHA224:
            evp_md = EVP_get_digestbyname("SHA224");
            break;
        case XSECCryptoHash::HASH_SHA256:
            evp_md = EVP_get_digestbyname("SHA256");
            break;
        case XSECCryptoHash::HASH_SHA384:
            evp_md = EVP_get_digestbyname("SHA384");
            break;
        case XSECCryptoHash::HASH_SHA512:
            evp_md = EVP_get_digestbyname("SHA512");
            break;

        default:
            ;
    }

    return evp_md;
}


OpenSSLCryptoKeyRSA::OpenSSLCryptoKeyRSA() :
    mp_rsaKey(NULL),
    mp_accumE(NULL),
    mp_accumN(NULL)
{
};

OpenSSLCryptoKeyRSA::~OpenSSLCryptoKeyRSA() {
    // If we have a RSA, delete it (OpenSSL will clear the memory)

    if (mp_rsaKey)
        RSA_free(mp_rsaKey);

    if (mp_accumE)
        BN_free(mp_accumE);

    if (mp_accumN)
        BN_free(mp_accumN);
};

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


// Generic key functions

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

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

    const BIGNUM *n, *d;
    RSA_get0_key(mp_rsaKey, &n, NULL, &d);

    if (n != NULL && d != NULL)
        return KEY_RSA_PAIR;

    if (d != NULL)
        return KEY_RSA_PRIVATE;

    if (n != NULL)
        return KEY_RSA_PUBLIC;

    return KEY_NONE;
}

void OpenSSLCryptoKeyRSA::loadPublicModulusBase64BigNums(const char* b64, unsigned int len) {
    setNBase(OpenSSLCryptoBase64::b642BN((char *) b64, len));
}

void OpenSSLCryptoKeyRSA::setNBase(BIGNUM *nBase) {

    if (mp_rsaKey == NULL)
        mp_rsaKey = RSA_new();

#if (OPENSSL_VERSION_NUMBER < 0x10100000L)

    mp_rsaKey->n = nBase;

#else

    if (mp_accumN)
        BN_free(mp_accumN);

    mp_accumN = nBase;
    commitEN();
#endif
}


void OpenSSLCryptoKeyRSA::loadPublicExponentBase64BigNums(const char* b64, unsigned int len) {
    setEBase(OpenSSLCryptoBase64::b642BN((char *) b64, len));
}


void OpenSSLCryptoKeyRSA::setEBase(BIGNUM *eBase) {

    if (mp_rsaKey == NULL)
        mp_rsaKey = RSA_new();

#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
    mp_rsaKey->e = eBase;
#else

    if (mp_accumE)
        BN_free(mp_accumE);

    mp_accumE = eBase;
    commitEN();
#endif
}

#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
void OpenSSLCryptoKeyRSA::commitEN() {

    if (NULL == mp_accumN || NULL == mp_accumE)
        return;


    RSA_set0_key(mp_rsaKey, mp_accumN, mp_accumE, NULL);

    mp_accumN = NULL;
    mp_accumE = NULL;
}
#endif

// "Hidden" OpenSSL functions

OpenSSLCryptoKeyRSA::OpenSSLCryptoKeyRSA(EVP_PKEY *k) :
    mp_rsaKey(NULL),
    mp_accumE(NULL),
    mp_accumN(NULL)
{

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

    mp_rsaKey = RSA_new();

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

    RSA *rsa = EVP_PKEY_get0_RSA(k);

    const BIGNUM *n=NULL, *e=NULL, *d=NULL;
    RSA_get0_key(rsa, &n, &e, &d);
    if (n && e) // Do not dup unless setter will work
        RSA_set0_key(mp_rsaKey, DUP_NON_NULL(n), DUP_NON_NULL(e), DUP_NON_NULL(d));

    const BIGNUM *p=NULL, *q=NULL;
    RSA_get0_factors(rsa, &p, &q);
    if (p && q)
        RSA_set0_factors(mp_rsaKey, DUP_NON_NULL(p), DUP_NON_NULL(q));

    const BIGNUM *dmp1=NULL, *dmq1=NULL, *iqmp=NULL;
    RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
    if (dmp1 && dmq1 &&  iqmp)
        RSA_set0_crt_params(mp_rsaKey, DUP_NON_NULL(dmp1), DUP_NON_NULL(dmq1), DUP_NON_NULL(iqmp));
}

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

bool OpenSSLCryptoKeyRSA::verifySHA1PKCS1Base64Signature(
        const unsigned char* hashBuf,
        unsigned int hashLen,
        const char * base64Signature,
        unsigned int sigLen,
        XSECCryptoHash::HashType type) const {

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

    if (mp_rsaKey == NULL) {
        throw XSECCryptoException(XSECCryptoException::RSAError,
            "OpenSSL:RSA - 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::RSAError,
            "OpenSSL:RSA - 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::RSAError,
            "OpenSSL:RSA - Error during Base64 Decode");
    }
    int t = 0;

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

    sigValLen += t;

    // OpenSSL allows the signature size to be less than the key size.
    // Java does not and the spec requires that this fail, so we have to
    // perform this check.

    int keySize = RSA_size(mp_rsaKey);
    if (keySize != sigValLen) {
            throw XSECCryptoException(XSECCryptoException::RSAError,
                "OpenSSL:RSA - Signature size does not match key size");
    }

    // Now decrypt

    unsigned char* decryptBuf;

    // Decrypt will always be longer than (RSA_len(key) - 11)
    decryptBuf = new unsigned char[RSA_size(mp_rsaKey)];
    ArrayJanitor<unsigned char> j_decryptBuf(decryptBuf);

    // Note at this time only supports PKCS1 padding
    // As that is what is defined in the standard.
    // If this ever changes we will need to pass some paramaters
    // into this function to allow it to determine what the
    // padding should be and what the message digest OID should
    // be.

    int decryptSize = RSA_public_decrypt(sigValLen,
                                             sigVal,
                                             decryptBuf,
                                             mp_rsaKey,
                                             RSA_PKCS1_PADDING);

    if (decryptSize < 0) {
        // Really - this is a failed signature check, not an exception!
        return false;
    }

    /* Check the OID */
    int oidLen = 0;
    unsigned char * oid = getRSASigOID(type, oidLen);

    if (oid == NULL) {
        throw XSECCryptoException(XSECCryptoException::RSAError,
            "OpenSSL:RSA::verify() - Unsupported HASH algorithm for RSA");
    }

    if (decryptSize != (int) (oidLen + hashLen) || hashLen != oid[oidLen-1]) {
        return false;
    }

    for (t = 0; t < oidLen; ++t) {
        if (oid[t] != decryptBuf[t]) {
            return false;
        }
    }

    for (;t < decryptSize; ++t) {
        if (hashBuf[t-oidLen] != decryptBuf[t]) {
            return false;
        }
    }

    // All OK
    return true;
}

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


unsigned int OpenSSLCryptoKeyRSA::signSHA1PKCS1Base64Signature(
        unsigned char* hashBuf,
        unsigned int hashLen,
        char * base64SignatureBuf,
        unsigned int base64SignatureBufLen,
        XSECCryptoHash::HashType type) const {

    // Sign a pre-calculated hash using this key

    if (mp_rsaKey == NULL) {
        throw XSECCryptoException(XSECCryptoException::RSAError,
            "OpenSSL:RSA - Attempt to sign data with empty key");
    }

    // Build the buffer to be encrypted by prepending the SHA1 OID to the hash

    unsigned char* encryptBuf;
    unsigned char* preEncryptBuf;
    unsigned char* oid;
    int oidLen;
    int encryptLen;
    int preEncryptLen;

    oid = getRSASigOID(type, oidLen);

    if (oid == NULL) {
        throw XSECCryptoException(XSECCryptoException::RSAError,
            "OpenSSL:RSA::sign() - Unsupported HASH algorithm for RSA");
    }

    if (hashLen != oid[oidLen-1]) {
        throw XSECCryptoException(XSECCryptoException::RSAError,
            "OpenSSL:RSA::sign() - hashLen incorrect for hash type");
    }

    preEncryptLen = hashLen + oidLen;
    preEncryptBuf = new unsigned char[preEncryptLen];
    encryptBuf = new unsigned char[RSA_size(mp_rsaKey)];

    memcpy(preEncryptBuf, oid, oidLen);
    memcpy(&preEncryptBuf[oidLen], hashBuf, hashLen);

    // Now encrypt

    encryptLen = RSA_private_encrypt(preEncryptLen,
                                     preEncryptBuf,
                                     encryptBuf,
                                     mp_rsaKey,
                                     RSA_PKCS1_PADDING);

    delete[] preEncryptBuf;

    if (encryptLen < 0) {
        delete[] encryptBuf;
        throw XSECCryptoException(XSECCryptoException::RSAError,
            "OpenSSL:RSA::sign() - Error encrypting hash");
    }

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

    // Translate signature to Base64

    BIO_write(b64, encryptBuf, encryptLen);
    BIO_flush(b64);

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

    BIO_free_all(b64);

    delete[] encryptBuf;

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

    return sigValLen;
}

// --------------------------------------------------------------------------------
//           decrypt a buffer
// --------------------------------------------------------------------------------

unsigned int OpenSSLCryptoKeyRSA::privateDecrypt(
        const unsigned char* inBuf,
        unsigned char* plainBuf,
        unsigned int inLength,
        unsigned int maxOutLength,
        PaddingType padding,
        const XMLCh* hashURI,
        const XMLCh* mgfURI,
        unsigned char* params,
        unsigned int paramslen) const {

    // Perform a decrypt
    if (mp_rsaKey == NULL) {
        throw XSECCryptoException(XSECCryptoException::RSAError,
            "OpenSSL:RSA - Attempt to decrypt data with empty key");
    }

#if 0
    /* normally commented out code to determine endian problems */
    unsigned int i;
    unsigned char e[2048];
    unsigned char * inBuf1 = (unsigned char *) inBuf;
    if (inLength < 2048) {
        memcpy(e, inBuf, inLength);
        for (i = 0; i < inLength;++i) {
            inBuf1[i] = e[inLength - 1 - i];
        }
    }
#endif

    int decryptSize;

    switch (padding) {

    case XSECCryptoKeyRSA::PAD_PKCS_1_5 :

        decryptSize = RSA_private_decrypt(inLength,
#if defined(XSEC_OPENSSL_CONST_BUFFERS)
                            inBuf,
#else
                            (unsigned char *) inBuf,
#endif
                            plainBuf,
                            mp_rsaKey,
                            RSA_PKCS1_PADDING);

        if (decryptSize < 0) {
            throw XSECCryptoException(XSECCryptoException::RSAError,
                "OpenSSL:RSA privateKeyDecrypt - Error Decrypting PKCS1_5 padded RSA encrypt");
        }

        break;

    case XSECCryptoKeyRSA::PAD_OAEP :
        {
            const EVP_MD* evp_md = getDigestFromHashType(XSECAlgorithmSupport::getHashType(hashURI));
            if (evp_md == NULL) {
                throw XSECCryptoException(XSECCryptoException::UnsupportedAlgorithm,
                    "OpenSSL:RSA - OAEP digest algorithm not supported");
            }


            const EVP_MD* mgf_md = getDigestFromHashType(XSECAlgorithmSupport::getMGF1HashType(mgfURI));
            if (mgf_md == NULL) {
                throw XSECCryptoException(XSECCryptoException::UnsupportedAlgorithm,
                    "OpenSSL:RSA - OAEP MGF algorithm not supported");
            }

            unsigned char * tBuf;
            int num = RSA_size(mp_rsaKey);
            XSECnew(tBuf, unsigned char[num]);
            ArrayJanitor<unsigned char> j_tBuf(tBuf);

            decryptSize = RSA_private_decrypt(inLength,
#if defined(XSEC_OPENSSL_CONST_BUFFERS)
                                inBuf,
#else
                                (unsigned char *) inBuf,
#endif
                                tBuf,
                                mp_rsaKey,
                                RSA_NO_PADDING);
            if (decryptSize < 0) {
                throw XSECCryptoException(XSECCryptoException::RSAError,
                    "OpenSSL:RSA privateKeyDecrypt - Error doing raw decrypt of RSA encrypted data");
            }

            // Clear out the "0"s at the front
            int i;
            for (i = 0; i < num && tBuf[i] == 0; ++i)
                --decryptSize;

            decryptSize = RSA_padding_check_PKCS1_OAEP(plainBuf,
                                                       maxOutLength,
                                                       &tBuf[i],
                                                       decryptSize,
                                                       num,
                                                       params,
                                                       paramslen,
                                                       evp_md,
                                                       mgf_md);

            if (decryptSize < 0) {
                throw XSECCryptoException(XSECCryptoException::RSAError,
                    "OpenSSL:RSA privateKeyDecrypt - Error removing OAEPadding");
            }

        }
        break;

    default :
        throw XSECCryptoException(XSECCryptoException::RSAError,
            "OpenSSL:RSA - Unknown padding method");
    }

#if 0
    /* normally commented out code to determine endian problems */
    int i;
    unsigned char t[512];
    if (decryptSize < 512) {
        memcpy(t, plainBuf, decryptSize);
        for (i = 0; i < decryptSize;++i) {
            plainBuf[i] = t[decryptSize - 1 - i];
        }
    }
#endif

    return decryptSize;
}

// --------------------------------------------------------------------------------
//           encrypt a buffer
// --------------------------------------------------------------------------------

unsigned int OpenSSLCryptoKeyRSA::publicEncrypt(
        const unsigned char* inBuf,
        unsigned char* cipherBuf,
        unsigned int inLength,
        unsigned int maxOutLength,
        PaddingType padding,
        const XMLCh* hashURI,
        const XMLCh* mgfURI,
        unsigned char* params,
        unsigned int paramslen) const {

    // Perform an encrypt
    if (mp_rsaKey == NULL) {
        throw XSECCryptoException(XSECCryptoException::RSAError,
            "OpenSSL:RSA - Attempt to encrypt data with empty key");
    }

    int encryptSize;

    switch (padding) {

    case XSECCryptoKeyRSA::PAD_PKCS_1_5 :

        encryptSize = RSA_public_encrypt(inLength,
#if defined(XSEC_OPENSSL_CONST_BUFFERS)
                            inBuf,
#else
                            (unsigned char *) inBuf,
#endif
                            cipherBuf,
                            mp_rsaKey,
                            RSA_PKCS1_PADDING);

        if (encryptSize < 0) {
            throw XSECCryptoException(XSECCryptoException::RSAError,
                "OpenSSL:RSA publicKeyEncrypt - Error performing PKCS1_5 padded RSA encrypt");
        }

        break;

    case XSECCryptoKeyRSA::PAD_OAEP :
        {
            unsigned char * tBuf;
            unsigned int num = RSA_size(mp_rsaKey);
            if (maxOutLength < num) {
                throw XSECCryptoException(XSECCryptoException::RSAError,
                    "OpenSSL:RSA publicKeyEncrypt - Not enough space in cipherBuf");
            }

            const EVP_MD* evp_md = getDigestFromHashType(XSECAlgorithmSupport::getHashType(hashURI));
            if (evp_md == NULL) {
                throw XSECCryptoException(XSECCryptoException::UnsupportedAlgorithm,
                    "OpenSSL:RSA - OAEP digest algorithm not supported");
            }


            const EVP_MD* mgf_md = getDigestFromHashType(XSECAlgorithmSupport::getMGF1HashType(mgfURI));
            if (mgf_md == NULL) {
                throw XSECCryptoException(XSECCryptoException::UnsupportedAlgorithm,
                    "OpenSSL:RSA - OAEP MGF algorithm not supported");
            }

            XSECnew(tBuf, unsigned char[num]);
            ArrayJanitor<unsigned char> j_tBuf(tBuf);

            // First add the padding
            encryptSize = RSA_padding_add_PKCS1_OAEP(tBuf,
                                                     num,
//#if defined(XSEC_OPENSSL_CONST_BUFFERS)
                                                     inBuf,
//#else
//                                                   (unsigned char *) inBuf,
//#endif
                                                     inLength,
                                                     params,
                                                     paramslen,
                                                     evp_md,
                                                     mgf_md);

            if (encryptSize <= 0) {
                throw XSECCryptoException(XSECCryptoException::RSAError,
                    "OpenSSL:RSA publicKeyEncrypt - Error adding OAEPadding");
            }

            encryptSize = RSA_public_encrypt(num,
                                tBuf,
                                cipherBuf,
                                mp_rsaKey,
                                RSA_NO_PADDING);
            if (encryptSize < 0) {
                throw XSECCryptoException(XSECCryptoException::RSAError,
                    "OpenSSL:RSA publicKeyEncrypt - Error encrypting padded data");
            }
        }
        break;

    default :
        throw XSECCryptoException(XSECCryptoException::RSAError,
            "OpenSSL:RSA - Unknown padding method");
    }

    return encryptSize;
}

// --------------------------------------------------------------------------------
//           Size in bytes
// --------------------------------------------------------------------------------

unsigned int OpenSSLCryptoKeyRSA::getLength() const {

    if (mp_rsaKey != NULL)
        return RSA_size(mp_rsaKey);

    return 0;
}

// --------------------------------------------------------------------------------
//           Clone this key
// --------------------------------------------------------------------------------

XSECCryptoKey * OpenSSLCryptoKeyRSA::clone() const {

    OpenSSLCryptoKeyRSA * ret;

    XSECnew(ret, OpenSSLCryptoKeyRSA);

    ret->mp_rsaKey = RSA_new();

    // Duplicate parameters
    const BIGNUM *n=NULL, *e=NULL, *d=NULL;
    RSA_get0_key(mp_rsaKey, &n, &e, &d);
    if (n && e) // Do not dup unless setter will work
        RSA_set0_key(ret->mp_rsaKey, DUP_NON_NULL(n), DUP_NON_NULL(e), DUP_NON_NULL(d));

    const BIGNUM *p=NULL, *q=NULL;
    RSA_get0_factors(mp_rsaKey, &p, &q);
    if (p && q)
        RSA_set0_factors(ret->mp_rsaKey, DUP_NON_NULL(p), DUP_NON_NULL(q));

    const BIGNUM *dmp1=NULL, *dmq1=NULL, *iqmp=NULL;
    RSA_get0_crt_params(mp_rsaKey, &dmp1, &dmq1, &iqmp);
    if (dmp1 && dmq1 && iqmp)
        RSA_set0_crt_params(ret->mp_rsaKey, DUP_NON_NULL(dmp1), DUP_NON_NULL(dmq1), DUP_NON_NULL(iqmp));

    return ret;
}

#endif /* XSEC_HAVE_OPENSSL */
