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