CURLOPT_CAINFO_BLOB(3)
π CURLOPT_CAINFO_BLOB(3) π
okay bestie, welcome to the libcurl manual page for CURLOPT_CAINFO_BLOB β yes it's a Library Functions Manual page, yes it's iconic, let's go β¨
β¨ NAME β¨
CURLOPT_CAINFO_BLOB β your Certificate Authority (CA) bundle, but make it PEM format π¦
πΈ SYNOPSIS πΈ
#include <curl/curl.h>
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_CAINFO_BLOB,
struct curl_blob *stblob);
π DESCRIPTION π
So what you're doing here is passing a pointer to a curl_blob struct, right? That struct holds the info (a pointer and a size) about a memory block containing binary data of PEM encoded content β and that content holds one or more certificates you'll use to verify the HTTPS server with. No cap, that's the whole vibe. π
Here's the slay detail: if the blob is initialized with the flags member of struct curl_blob set to CURL_BLOB_COPY, then the application does not have to keep the buffer around after setting this. Copy it and forget it, main character energy fr fr π
Also, if CURLOPT_SSL_VERIFYPEER(3) is zero and you avoid verifying the server's certificate, then CURLOPT_CAINFO_BLOB(3) is not needed. Like, at all. Skip it. π€·ββοΈ
π¨ lowkey important: this option overrides CURLOPT_CAINFO(3). It's giving "there can only be one" β so know which one you're actually setting bestie.
π DEFAULT π
NULL
π PROTOCOLS π
This functionality affects all TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. basically the whole secure squad π«Ά
This option works only with the following TLS backends: GnuTLS, OpenSSL, Rustls, Schannel, mbedTLS and wolfSSL. Check your backend bestie, iykyk β
π§ EXAMPLE π§
#include <string.h>
int main(void)
{
char *strpem = "PEMDATA"; /* strpem must point to a PEM string */
CURL *curl = curl_easy_init();
if(curl) {
CURLcode result;
struct curl_blob blob;
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
blob.data = strpem;
blob.len = strlen(strpem);
blob.flags = CURL_BLOB_COPY;
curl_easy_setopt(curl, CURLOPT_CAINFO_BLOB, &blob);
result = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
}
see how blob.flags = CURL_BLOB_COPY is right there? that's the moment, that's the whole thing π₯
π¦ HISTORY π¦
This option is supported by the mbedTLS backend (since 7.81.0), the Rustls backend (since 7.82.0), the wolfSSL backend (since 8.2.0), the GnuTLS backend (since 8.18.0), and also the OpenSSL and Schannel backends. Look at this timeline, it's giving growth arc π
π AVAILABILITY π
Added in curl 7.77.0. vintage-ish but not vintage, we love a classic π
π RETURN VALUE π
curl_easy_setopt(3) returns a CURLcode indicating success or error.
CURLE_OK (0) means everything was OK π β and non-zero means an error occurred, so go see libcurl-errors(3) for the tea. Don't ignore the non-zero, bestie, that's how you end up crying at 3am π
β SEE ALSO β
and that's the page!! π«Ά this came to you from libcurl, dated 2026-10-12, titled CURLOPT_CAINFO_BLOB(3) β go forth and verify those certs, you absolute icon ππ
π¦ where this page comes from
- fedora 44: libcurl-devel 8.18.0-14.fc44 Β· curl
- fedora 44: libcurl-devel 8.18.0-14.fc44 Β· curl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms