1--- 2c: Copyright (C) Daniel Stenberg, <daniel.se>, et al. 3SPDX-License-Identifier: curl 4Title: CURLOPT_PROXY_PINNEDPUBLICKEY 5Section: 3 6Source: libcurl 7See-also: 8 - CURLOPT_PINNEDPUBLICKEY (3) 9 - CURLOPT_PROXY_CAINFO (3) 10 - CURLOPT_PROXY_CAPATH (3) 11 - CURLOPT_PROXY_SSL_VERIFYHOST (3) 12 - CURLOPT_PROXY_SSL_VERIFYPEER (3) 13--- 14 15# NAME 16 17CURLOPT_PROXY_PINNEDPUBLICKEY - pinned public key for https proxy 18 19# SYNOPSIS 20 21~~~c 22#include <curl/curl.h> 23 24CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PROXY_PINNEDPUBLICKEY, 25 char *pinnedpubkey); 26~~~ 27 28# DESCRIPTION 29 30Pass a pointer to a null-terminated string as parameter. The string can be the 31filename of your pinned public key. The file format expected is "PEM" or 32"DER". The string can also be any number of base64 encoded sha256 hashes 33preceded by "sha256//" and separated by ";" 34 35When negotiating a TLS or SSL connection, the https proxy sends a certificate 36indicating its identity. A public key is extracted from this certificate and 37if it does not exactly match the public key provided to this option, libcurl 38aborts the connection before sending or receiving any data. 39 40On mismatch, *CURLE_SSL_PINNEDPUBKEYNOTMATCH* is returned. 41 42The application does not have to keep the string around after setting this 43option. 44 45# DEFAULT 46 47NULL 48 49# PROTOCOLS 50 51All TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc. 52 53# EXAMPLE 54 55~~~c 56int main(void) 57{ 58 CURL *curl = curl_easy_init(); 59 if(curl) { 60 curl_easy_setopt(curl, CURLOPT_URL, "https://example.com"); 61 curl_easy_setopt(curl, CURLOPT_PROXY, "https://proxy:443"); 62 curl_easy_setopt(curl, CURLOPT_PROXY_PINNEDPUBLICKEY, 63 "sha256//YhKJKSzoTt2b5FP18fvpHo7fJYqQCjA" 64 "a3HWY3tvRMwE=;sha256//t62CeU2tQiqkexU74" 65 "Gxa2eg7fRbEgoChTociMee9wno="); 66 67 /* Perform the request */ 68 curl_easy_perform(curl); 69 } 70} 71~~~ 72 73# PUBLIC KEY EXTRACTION 74 75If you do not have the https proxy server's public key file you can extract it 76from the https proxy server's certificate. 77~~~c 78# retrieve the server's certificate if you do not already have it 79# 80# be sure to examine the certificate to see if it is what you expected 81# 82# Windows-specific: 83# - Use NUL instead of /dev/null. 84# - OpenSSL may wait for input instead of disconnecting. Hit enter. 85# - If you do not have sed, then just copy the certificate into a file: 86# Lines from -----BEGIN CERTIFICATE----- to -----END CERTIFICATE-----. 87# 88openssl s_client -servername www.example.com -connect www.example.com:443 \ 89 < /dev/null | sed -n "/-----BEGIN/,/-----END/p" > www.example.com.pem 90 91# extract public key in pem format from certificate 92openssl x509 -in www.example.com.pem -pubkey -noout > www.example.com.pubkey.pem 93 94# convert public key from pem to der 95openssl asn1parse -noout -inform pem -in www.example.com.pubkey.pem \ 96 -out www.example.com.pubkey.der 97 98# sha256 hash and base64 encode der to string for use 99openssl dgst -sha256 -binary www.example.com.pubkey.der | openssl base64 100~~~ 101The public key in PEM format contains a header, base64 data and a 102footer: 103~~~c 104-----BEGIN PUBLIC KEY----- 105[BASE 64 DATA] 106-----END PUBLIC KEY----- 107~~~ 108 109# AVAILABILITY 110 111PEM/DER support: 112 113 7.52.0: GnuTLS, OpenSSL, mbedTLS, wolfSSL 114 115sha256 support: 116 117 7.52.0: GnuTLS, OpenSSL, mbedTLS, wolfSSL 118 119Other SSL backends not supported. 120 121# RETURN VALUE 122 123Returns CURLE_OK if TLS enabled, CURLE_UNKNOWN_OPTION if not, or 124CURLE_OUT_OF_MEMORY if there was insufficient heap space. 125