CURLOPT_SSLKEY_BLOB(3)
π CURLOPT_SSLKEY_BLOB β bestie's guide to private keys that live in memory π
Okay so real talk, this is a page from libcurl's manual, and today's main character is CURLOPT_SSLKEY_BLOB β the option that lets you hand curl your client cert's private key straight from memory instead of making it go dig around in your filesystem like some kind of raccoon. π¦
β¨ NAME β¨
CURLOPT_SSLKEY_BLOB β private key for client cert from memory blob π
πΈ SYNOPSIS πΈ
#include <curl/curl.h>
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SSLKEY_BLOB,
struct curl_blob *blob);
π DESCRIPTION π
So you pass a pointer to a curl_blob structure β that's the little guy that holds a pointer and a size for your private key. It's compatible with OpenSSL, and the format (like "PEM") must be specified with CURLOPT_SSLKEYTYPE(3). No guessing games, bestie, curl wants to be told. π«Ά
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, iconic behavior honestly. β¨
This option is an alternative to CURLOPT_SSLKEY(3), which instead expects a filename as input. So one is "here's a path, go look", and this one is "here's the actual bytes, take them, they're yours". π
π₯ DEFAULT π₯
NULL
π PROTOCOLS π
This functionality affects all TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. All of them. Every last one. π
This option works only with the following TLS backends: OpenSSL and wolfSSL.
π§ EXAMPLE π§
extern char *certificateData; /* point to cert */
extern size_t filesize; /* size of cert */
extern char *privateKeyData; /* point to key */
extern size_t privateKeySize; /* size of key */
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_SSLCERT_BLOB, &blob);
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");
blob.data = privateKeyData;
blob.len = privateKeySize;
curl_easy_setopt(curl, CURLOPT_SSLKEY_BLOB, &blob);
curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "s3cret");
curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM");
result = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
}
Obsessed with how the same blob gets reused for the cert and then the key, no cap. π
β AVAILABILITY β
Added in curl 7.71.0 β so if you're on something older, sorry babe, it's giving vintage. π
π 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, see libcurl-errors(3). Zero is the slay outcome, anything else means go read the error page. π
π¦ SEE ALSO π¦
Heads up bestie: the format must be set withCURLOPT_SSLKEYTYPE(3)or this whole thing is not gonna work. And if you want to stop worrying about keeping your buffer alive, setCURL_BLOB_COPYinflags. πΈ
And that's the whole page! This gem came from the libcurl manual, dated 2026-10-12, and yes the manpage header is literally CURLOPT_SSLKEY_BLOB(3) β say it with me. Now go forth and blob responsibly, you absolute key 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