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.gustafs...@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

Reply via email to