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