SSL: implement public key pinning

Option --pinnedpubkey takes a path to a public key in DER format and
only connect if it matches (currently only implemented with OpenSSL).

Provides CURLOPT_PINNEDPUBLICKEY for curl_easy_setopt().

Extract a public RSA key from a website like so:
openssl s_client -connect google.com:443 2>&1 < /dev/null | \
sed -n '/-----BEGIN/,/-----END/p' | openssl x509 -noout -pubkey \
| openssl rsa -pubin -outform DER > google.com.der
This commit is contained in:
moparisthebest 2014-09-30 22:31:17 -04:00 committed by Daniel Stenberg
parent d1b56d0043
commit 93e450793c
20 changed files with 311 additions and 2 deletions

View file

@ -101,6 +101,7 @@ static void free_config_fields(struct OperationConfig *config)
Curl_safefree(config->cacert);
Curl_safefree(config->capath);
Curl_safefree(config->crlfile);
Curl_safefree(config->pinnedpubkey);
Curl_safefree(config->key);
Curl_safefree(config->key_type);
Curl_safefree(config->key_passwd);

View file

@ -110,6 +110,7 @@ struct OperationConfig {
char *cacert;
char *capath;
char *crlfile;
char *pinnedpubkey;
char *key;
char *key_type;
char *key_passwd;

View file

@ -215,6 +215,7 @@ static const struct LongShort aliases[]= {
{"Em", "tlsauthtype", TRUE},
{"En", "ssl-allow-beast", FALSE},
{"Eo", "login-options", TRUE},
{"Ep", "pinnedpubkey", TRUE},
{"f", "fail", FALSE},
{"F", "form", TRUE},
{"Fs", "form-string", TRUE},
@ -1353,6 +1354,11 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
GetStr(&config->login_options, nextarg);
break;
case 'p': /* Pinned public key DER file */
/* Pinned public key DER file */
GetStr(&config->pinnedpubkey, nextarg);
break;
default: /* certificate file */
{
char *certname, *passphrase;

View file

@ -152,6 +152,7 @@ static const char *const helptext[] = {
" --oauth2-bearer TOKEN OAuth 2 Bearer Token (IMAP, POP3, SMTP)",
" -o, --output FILE Write to FILE instead of stdout",
" --pass PASS Pass phrase for the private key (SSL/SSH)",
" --pinnedpubkey FILE Public key (DER) to verify peer against (OpenSSL)",
" --post301 "
"Do not switch to GET after following a 301 redirect (H)",
" --post302 "

View file

@ -1025,6 +1025,9 @@ static CURLcode operate_do(struct GlobalConfig *global,
if(config->crlfile)
my_setopt_str(curl, CURLOPT_CRLFILE, config->crlfile);
if(config->pinnedpubkey)
my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey);
if(curlinfo->features & CURL_VERSION_SSL) {
if(config->insecure_ok) {
my_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);