curl / Mailing Lists / curl-library / Single Mail
Buy commercial curl support. We help you work out your issues, debug your libcurl applications, use the API, port to new platforms, add new features and more. With a team lead by the curl founder Daniel himself.

Curl callback question, porting from OpenSSL 1.x to 3.x and from 32bit plain to 64bit UTF16

From: Anders Gustafsson via curl-library <curl-library_at_lists.haxx.se>
Date: Wed, 20 Aug 2025 15:58:14 +0300

So, yes this is windows 😀 libcurl/8.15.0-DEV OpenSSL/3.5.2 zlib/1.3.1

I had some issues and I just want to check whether I am going about this the right way. The function calls an
API where the client certificate is used to authenticate the caller so in the original version I used the
sslctx_function(). To complicate matters does my app support PEM certificates and keys in two different ways:
1. As files (Say on a removable secure media) and 2. As strings in the database for ease of use.

The first way (filenames) worked right away, ie:

                        m_Certificate.Trim();
                        if (m_Certificate.IsEmpty())
                                curl_easy_setopt(curl, CURLOPT_SSLCERT, m_CertificateFile.GetString());

In the second scenario, PEM in database, I had some problems and I just wanted to check that the code I came
up with is sane. Ie the authentication will not happen unless I have both certificate and key, so:

                        if (!m_Certificate.IsEmpty())
                        {
                                curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctx_function);
                                curl_easy_setopt(curl, CURLOPT_SSL_CTX_DATA, m_Certificate.GetString());
                        }

Where m_Certificate and m_Key and regular (char) strings with the PEM coded data.

Then, below, which seems to work OK. I first used the example here:
https://curl.se/libcurl/c/CURLOPT_SSL_CTX_FUNCTION.html
but that one did not fix my key for me. Yes, this code still leaves allocated memory in case of errors.

Thanks in advance!

CURLcode CMyAPI::sslctx_function(CURL *curl, void *sslctx, void *parm)
{

        X509 *cert = NULL;
        BIO *bio = NULL;
        EVP_PKEY *pkey = NULL;

        FILE *errfile;
        CString errfilename;


        (void)curl; /* avoid warnings */
        (void)parm; /* avoid warnings */

        errfile = NULL;
        errfilename.Format(_T("%s\\sslerrs.txt"), theApp.LpGetEnv("TEMP").GetString());
        //
        errno_t fileerr = fopen_s(&errfile, CT2A(errfilename), "w+, ccs=UTF-8");

        bio = BIO_new_mem_buf(parm, -1);

        if (!bio) {
                printf("BIO_new_mem_buf failed\n");
        }

        /* use it to read the PEM formatted certificate from memory into an X509
         * structure that SSL can use
         */
        PEM_read_bio_X509(bio, &cert, 0, NULL);
        if (!cert) {
                printf("PEM_read_bio_X509 failed...\n");
                ERR_print_errors_fp(errfile);
                if(errfile != 0)fclose(errfile);
                return CURLE_SSL_CERTPROBLEM;
        }

        SSL_CTX_use_certificate((SSL_CTX*)sslctx, cert);
        // Read the private key
        BIO* mem;
        mem = BIO_new_mem_buf(m_Key.GetString(), -1); //pkey is of type char*
        if (!mem) {
                printf("BIO_new_mem_buf...\n");
                ERR_print_errors_fp(errfile);
                if (errfile != 0)fclose(errfile);
                return CURLE_SSL_CERTPROBLEM;
        }

        pkey = PEM_read_bio_PrivateKey(mem, NULL, NULL, 0);
        if (!pkey) {
                printf("EM_read_bio_PrivateKey...\n");
                ERR_print_errors_fp(errfile);
                if (errfile != 0)fclose(errfile);
                return CURLE_SSL_CERTPROBLEM;
        }

        SSL_CTX_use_PrivateKey((SSL_CTX*)sslctx, pkey);

        /* decrease reference counts */
        EVP_PKEY_free(pkey);
        BIO_free(mem);
        X509_free(cert);
        BIO_free(bio);

        if(errfile != NULL) fclose(errfile);
        return CURLE_OK;
}

-- 
Med vÀnlig hÀlsning
Anders Gustafsson, ingenjör
anders.gustafsson_at_pedago.fi  |  Support +358 18 12060  |  Direkt +358 9 315 45 121  |  Mobil +358 40506 7099
Pedago interaktiv ab, Nygatan 7 B , AX-22100 MARIEHAMN, ÅLAND, FINLAND
-- 
Unsubscribe: https://lists.haxx.se/mailman/listinfo/curl-library
Etiquette:   https://curl.se/mail/etiquette.html
Received on 2025-08-20