Dear all,

I wrote a function like this:


DLL_INT ECryptEncryptData(char* certFile, char* dataFile, char*
encryptedFile, char* errMsg, int errMsgLen)
{
    static char* func = "ECryptEncryptData";
    int rc = 0;
    char msg[MSG_LEN];
    BIO *in = NULL, *out = NULL;//, *tbio = NULL;//, *dout = NULL;
    BIO *bio_err_out = NULL;
    X509 *rcert = NULL;
    STACK_OF(X509) *recips = NULL;
    CMS_ContentInfo *cms = NULL;
    EVP_PKEY *publickey = NULL;

    EVP_CIPHER *eAlgt = NULL;
    int flags = CMS_BINARY;// | CMS_STREAM;// | CMS_DETACHED;
    if (errMsg == NULL || errMsgLen <= 0) {
        WriteLog(ERROR, "%s[%d] invalid input\n", func, __LINE__);
        return -1;
    }
    errMsg[0] = 0;
    printf_s("%s[%d] Infor dataFile[%s] encryptedFile[%s]\n", func,
__LINE__, dataFile, encryptedFile);

    //OpenSSL_add_all_algorithms();
    //ERR_load_crypto_strings();

        eAlgt = (EVP_CIPHER*)EVP_des_ede3_cbc();

    /* Read in recipient certificate */

    if ((publickey = getPublicKey(certFile, &rcert, msg, sizeof(msg), &rc))
== NULL) {
        sprintf_s(errMsg, errMsgLen, "%s[%d] getPublicKey fail %s\n", func,
__LINE__, msg);
        goto cleanup;
    }
    else {
        EVP_PKEY_free(publickey);
    }
    /* Create recipient STACK and add recipient cert to it */
    if ((recips = sk_X509_new_null()) == NULL || !sk_X509_push(recips,
rcert)) {
        sprintf_s(errMsg, errMsgLen, "%s[%d] sk_X509_new_null fail\n",
func, __LINE__);
        goto cleanup;
    }
    /* sk_X509_pop_free will free up recipient STACK and its contents
    * so set rcert to NULL so it isn't freed up twice.
    */
    rcert = NULL;

    /* Open content being encrypted */
    if ((in = BIO_new_file(dataFile, "r")) == NULL) {
        sprintf_s(errMsg, errMsgLen, "%s[%d] BIO_new_file fail\n", func,
__LINE__);
        goto cleanup;
    }
    /* encrypt content */
    else if ((cms = CMS_encrypt(recips, in, eAlgt, flags)) == NULL) {
        sprintf_s(errMsg, errMsgLen, "%s[%d] CMS_encrypt_WithHeader
fail\n", func, __LINE__);
        goto cleanup;
    }

    else if ((out = BIO_new_file(encryptedFile, "wb")) == NULL) {
        sprintf_s(errMsg, errMsgLen, "%s[%d] BIO_new_file fail\n", func,
__LINE__);
        goto cleanup;
    }
    /* Write out S/MIME message */
    else if (!i2d_CMS_bio_stream(out, cms, in, flags)) {
        sprintf_s(errMsg, errMsgLen, "%s[%d] i2d_CMS_bio_stream fail\n",
func, __LINE__);
        goto cleanup;
    }

cleanup:
    if (strlen(errMsg)) {
        WriteLog(ERROR, "%s", errMsg);
        if (!rc)
            rc = -1;
        bio_err_out = OpenLog();
    }
    if (cms)
        CMS_ContentInfo_free(cms);
    if (rcert)
        X509_free(rcert);
    if (recips)
        sk_X509_pop_free(recips, X509_free);
    if (in)
        BIO_free(in);
    if (out)
        BIO_free(out);
    /*if (dout)
    BIO_free(dout);*/
    /*if (tbio)
    BIO_free(tbio);*/
    if (bio_err_out) {
        if (MEM_LEAK_CHEK)
            CRYPTO_mem_leaks(bio_err_out);
        ERR_print_errors(bio_err_out);
        BIO_free(bio_err_out);
    }
    return rc;
}

I export it to an external dll for other application to call it.

Everything is OK for a single call to it. But when it be called concurrent
in multi threads (one thread proceeded a difference file), the return
encrypted file will fail (the file size some times has 0 bytes...).
I also try not use it in multi threads. I ran many applications at the same
time to encrypt multiple files (one application proceeded a difference
file) but it still failed.

I very much appreciate for any help
Thank you,

Vu Le

Reply via email to