CURLOPT_ISSUERCERT_BLOB(3)
π CURLOPT_ISSUERCERT_BLOB(3) β the libcurl manual page, but make it make sense
okay so bestie, welcome to the CURLOPT_ISSUERCERT_BLOB page π this thing lives in the libcurl Library Functions Manual and it's literally about handing curl an issuer SSL certificate straight from memory. no files, no drama, just vibes and a blob. let's get into it π
β¨ NAME β¨
CURLOPT_ISSUERCERT_BLOB β issuer SSL certificate from memory blob π¦
β¨ SYNOPSIS β¨
#include <curl/curl.h>
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_ISSUERCERT_BLOB,
struct curl_blob *stblob);
β¨ DESCRIPTION β¨
So what you're doing here is passing a pointer to a curl_blob structure β and that struct is literally just holding the pointer and the size of a memory block containing the binary data of a CA certificate in PEM format. cute, right? πΈ
If you set this option, an additional check gets run against the peer certificate to verify that the issuer really is the one associated with the certificate you provided through this option. and likeβ¦ this extra check is genuinely useful in multi-level PKI situations where you need to enforce that the peer certificate comes from a specific branch of the tree. no cap, that's the whole point π«Ά
bestie pls use this option together with the CURLOPT_SSL_VERIFYPEER(3) option. otherwise the result of the check is not considered a failure. it's giving "check ran but nobody cared" π
There's a specific error code β CURLE_SSL_ISSUER_ERROR β defined alongside this option, which is returned if setting up the SSL/TLS session failed because of a mismatch with the issuer of the peer certificate. (heads up: CURLOPT_SSL_VERIFYPEER(3) has to be set too for the check to actually fail.)
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. the copy is handled for you, iconic π
This option is an alternative to CURLOPT_ISSUERCERT(3), which instead expects a filename as input. same energy, different input type, iykyk β
β¨ DEFAULT β¨
NULL
β¨ PROTOCOLS β¨
This functionality affects all TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. π
This option works only with the following TLS backends: OpenSSL
β¨ EXAMPLE β¨
extern char *certificateData;
extern size_t filesize;
int main(void)
{
CURL *curl = curl_easy_init();
if(curl) {
CURLcode result;
struct curl_blob blob;
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
blob.data = certificateData;
blob.len = filesize;
blob.flags = CURL_BLOB_COPY;
curl_easy_setopt(curl, CURLOPT_ISSUERCERT_BLOB, &blob);
result = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
}
like look at that, the CURL_BLOB_COPY flag is right there doing its little job so you don't have to babysit the buffer afterward π§
β¨ AVAILABILITY β¨
Added in curl 7.71.0 π
β¨ RETURN VALUE β¨
curl_easy_setopt(3) returns a CURLcode indicating success or error.
CURLE_OK (0) means everything was OK, non-zero means an error occurred β go peek at libcurl-errors(3) for the deets π₯
β¨ SEE ALSO β¨
and that's the whole page, bestie, you ate that π this iconic little number comes from libcurl, dated 2026-10-12, and it's filed under CURLOPT_ISSUERCERT_BLOB(3). go forth and verify those issuers ππ
π¦ 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