examples: improve OpenSSL certificate examples

- add/fix/synchronize error messages and comments.
- consistently return error from the callback on failure.
- fix potential leaks on OpenSSL API failures.
- fix to not pass the nul-terminator to BIO read.
- scope a variable.
- sync code/formatting between the two examples.

Closes #20807
This commit is contained in:
Viktor Szakats 2026-03-03 18:44:29 +01:00
parent 7079f1d39c
commit 38ee35353c
No known key found for this signature in database
2 changed files with 53 additions and 30 deletions

View file

@ -79,23 +79,31 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *pointer)
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"-----END CERTIFICATE-----\n";
BIO *cbio = BIO_new_mem_buf(mypem, sizeof(mypem));
X509_STORE *cts = SSL_CTX_get_cert_store((SSL_CTX *)sslctx);
CURLcode result = CURLE_ABORTED_BY_CALLBACK;
BIO *cbio = NULL;
X509_STORE *cts;
ossl_valsize_t i;
STACK_OF(X509_INFO) * inf;
(void)curl;
(void)pointer;
if(!cts || !cbio) {
return CURLE_ABORTED_BY_CALLBACK;
cts = SSL_CTX_get_cert_store((SSL_CTX *)sslctx);
if(!cts) {
printf("SSL_CTX_get_cert_store() failed\n");
goto out;
}
cbio = BIO_new_mem_buf(mypem, sizeof(mypem) - 1);
if(!cbio) {
printf("BIO_new_mem_buf() failed\n");
goto out;
}
inf = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL);
if(!inf) {
BIO_free(cbio);
return CURLE_ABORTED_BY_CALLBACK;
printf("PEM_X509_INFO_read_bio() failed\n");
goto out;
}
for(i = 0; i < sk_X509_INFO_num(inf); i++) {
@ -109,9 +117,15 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *pointer)
}
sk_X509_INFO_pop_free(inf, X509_INFO_free);
BIO_free(cbio);
return CURLE_OK;
result = CURLE_OK;
out:
if(cbio)
BIO_free(cbio);
return result;
}
int main(void)

View file

@ -51,14 +51,9 @@ static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *stream)
static CURLcode sslctx_function(CURL *curl, void *sslctx, void *pointer)
{
X509 *cert = NULL;
BIO *bio = NULL;
BIO *kbio = NULL;
EVP_PKEY *pkey;
int ret;
const char *mypem =
/* replace the XXX with the actual CA certificate */
/** This example uses a (fake) certificate and private key **/
/* replace the XXX with the actual client/user certificate */
static const char mypem[] =
"-----BEGIN CERTIFICATE-----\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
@ -71,54 +66,68 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *pointer)
"-----END CERTIFICATE-----\n";
/* replace the XXX with the actual private key */
const char *mykey =
static const char mykey[] =
"-----BEGIN PRIVATE KEY-----\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"-----END PRIVATE KEY-----\n";
CURLcode result = CURLE_ABORTED_BY_CALLBACK;
X509 *cert = NULL;
BIO *bio = NULL;
BIO *kbio = NULL;
EVP_PKEY *pkey = NULL;
int ret;
(void)curl;
(void)pointer;
/* get a BIO */
bio = BIO_new_mem_buf(mypem, -1);
bio = BIO_new_mem_buf(mypem, sizeof(mypem) - 1);
if(!bio) {
printf("BIO_new_mem_buf failed\n");
printf("BIO_new_mem_buf() failed\n");
goto out;
}
/* use it to read the PEM formatted certificate from memory into an X509
* structure that SSL can use
*/
structure that SSL can use. */
cert = PEM_read_bio_X509(bio, NULL, 0, NULL);
if(!cert) {
printf("PEM_read_bio_X509 failed...\n");
printf("PEM_read_bio_X509() failed\n");
goto out;
}
/* tell SSL to use the X509 certificate */
ret = SSL_CTX_use_certificate((SSL_CTX *)sslctx, cert);
if(ret != 1) {
printf("Use certificate failed\n");
printf("SSL_CTX_use_certificate() failed\n");
goto out;
}
/* create a bio for the private key */
kbio = BIO_new_mem_buf(mykey, -1);
kbio = BIO_new_mem_buf(mykey, sizeof(mykey) - 1);
if(!kbio) {
printf("BIO_new_mem_buf failed\n");
printf("BIO_new_mem_buf() failed\n");
goto out;
}
pkey = PEM_read_bio_PrivateKey(kbio, NULL, NULL, NULL);
if(!pkey) {
printf("Failed EVP_PKEY_new()\n");
printf("PEM_read_bio_PrivateKey() failed\n");
goto out;
}
/* tell SSL to use the private key from memory */
ret = SSL_CTX_use_PrivateKey((SSL_CTX *)sslctx, pkey);
if(ret != 1) {
printf("Use Key failed\n");
printf("SSL_CTX_use_PrivateKey() failed\n");
goto out;
}
result = CURLE_OK;
out:
/* free resources that have been allocated by OpenSSL functions */
if(bio)
BIO_free(bio);
@ -133,7 +142,7 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *pointer)
X509_free(cert);
/* all set to go */
return CURLE_OK;
return result;
}
int main(void)