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