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