mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
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:
parent
d1b56d0043
commit
93e450793c
15
docs/curl.1
15
docs/curl.1
@ -530,6 +530,19 @@ OpenSSL-powered curl to make SSL-connections much more efficiently than using
|
|||||||
|
|
||||||
If this option is set, the default capath value will be ignored, and if it is
|
If this option is set, the default capath value will be ignored, and if it is
|
||||||
used several times, the last one will be used.
|
used several times, the last one will be used.
|
||||||
|
.IP "--pinnedpubkey <pinned public key>"
|
||||||
|
(SSL) Tells curl to use the specified public key file to verify the peer. The
|
||||||
|
file must contain a single public key in DER format.
|
||||||
|
|
||||||
|
When negotiating a TLS or SSL connection, the server sends a certificate
|
||||||
|
indicating its identity. A public key is extracted from this certificate
|
||||||
|
and if it does not exactly match the public key provided to this option,
|
||||||
|
curl will abort the connection before sending or receiving any data.
|
||||||
|
|
||||||
|
This is currently only implemented in the OpenSSL backend, with more backends
|
||||||
|
expected to follow shortly.
|
||||||
|
|
||||||
|
If this option is used several times, the last one will be used.
|
||||||
.IP "-f, --fail"
|
.IP "-f, --fail"
|
||||||
(HTTP) Fail silently (no output at all) on server errors. This is mostly done
|
(HTTP) Fail silently (no output at all) on server errors. This is mostly done
|
||||||
to better enable scripts etc to better deal with failed attempts. In
|
to better enable scripts etc to better deal with failed attempts. In
|
||||||
@ -2180,6 +2193,8 @@ unable to parse FTP file list
|
|||||||
FTP chunk callback reported error
|
FTP chunk callback reported error
|
||||||
.IP 89
|
.IP 89
|
||||||
No connection available, the session will be queued
|
No connection available, the session will be queued
|
||||||
|
.IP 90
|
||||||
|
SSL public key does not matched pinned public key
|
||||||
.IP XX
|
.IP XX
|
||||||
More error codes will appear here in future releases. The existing ones
|
More error codes will appear here in future releases. The existing ones
|
||||||
are meant to never change.
|
are meant to never change.
|
||||||
|
51
docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3
Normal file
51
docs/libcurl/opts/CURLOPT_PINNEDPUBLICKEY.3
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
.\" **************************************************************************
|
||||||
|
.\" * _ _ ____ _
|
||||||
|
.\" * Project ___| | | | _ \| |
|
||||||
|
.\" * / __| | | | |_) | |
|
||||||
|
.\" * | (__| |_| | _ <| |___
|
||||||
|
.\" * \___|\___/|_| \_\_____|
|
||||||
|
.\" *
|
||||||
|
.\" * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is licensed as described in the file COPYING, which
|
||||||
|
.\" * you should have received as part of this distribution. The terms
|
||||||
|
.\" * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
.\" *
|
||||||
|
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
.\" * copies of the Software, and permit persons to whom the Software is
|
||||||
|
.\" * furnished to do so, under the terms of the COPYING file.
|
||||||
|
.\" *
|
||||||
|
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
.\" * KIND, either express or implied.
|
||||||
|
.\" *
|
||||||
|
.\" **************************************************************************
|
||||||
|
.\"
|
||||||
|
.TH CURLOPT_PINNEDPUBLICKEY 3 "27 Aug 2014" "libcurl 7.38.0" "curl_easy_setopt options"
|
||||||
|
.SH NAME
|
||||||
|
CURLOPT_PINNEDPUBLICKEY \- set pinned public key
|
||||||
|
.SH SYNOPSIS
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_PINNEDPUBLICKEY, char *pinnedpubkey);
|
||||||
|
.SH DESCRIPTION
|
||||||
|
Pass a pointer to a zero terminated string as parameter. The string should be
|
||||||
|
the file name of your pinned public key. The format expected is "DER".
|
||||||
|
|
||||||
|
When negotiating a TLS or SSL connection, the server sends a certificate
|
||||||
|
indicating its identity. A public key is extracted from this certificate
|
||||||
|
and if it does not exactly match the public key provided to this option,
|
||||||
|
curl will abort the connection before sending or receiving any data.
|
||||||
|
|
||||||
|
This is currently only implemented in the OpenSSL backend, with more backends
|
||||||
|
expected to follow shortly.
|
||||||
|
.SH DEFAULT
|
||||||
|
NULL
|
||||||
|
.SH PROTOCOLS
|
||||||
|
All TLS based protocols: HTTPS, FTPS, IMAPS, POP3, SMTPS etc.
|
||||||
|
.SH EXAMPLE
|
||||||
|
TODO
|
||||||
|
.SH AVAILABILITY
|
||||||
|
If built TLS enabled.
|
||||||
|
.SH RETURN VALUE
|
||||||
|
Returns CURLE_OK if TLS enabled, CURLE_UNKNOWN_OPTION if not, or
|
||||||
|
CURLE_OUT_OF_MEMORY if there was insufficient heap space.
|
@ -74,12 +74,12 @@ CURLE_FTP_WEIRD_USER_REPLY 7.1 7.17.0
|
|||||||
CURLE_FTP_WRITE_ERROR 7.1 7.17.0
|
CURLE_FTP_WRITE_ERROR 7.1 7.17.0
|
||||||
CURLE_FUNCTION_NOT_FOUND 7.1
|
CURLE_FUNCTION_NOT_FOUND 7.1
|
||||||
CURLE_GOT_NOTHING 7.9.1
|
CURLE_GOT_NOTHING 7.9.1
|
||||||
|
CURLE_HTTP2 7.38.0
|
||||||
CURLE_HTTP_NOT_FOUND 7.1
|
CURLE_HTTP_NOT_FOUND 7.1
|
||||||
CURLE_HTTP_PORT_FAILED 7.3 7.12.0
|
CURLE_HTTP_PORT_FAILED 7.3 7.12.0
|
||||||
CURLE_HTTP_POST_ERROR 7.1
|
CURLE_HTTP_POST_ERROR 7.1
|
||||||
CURLE_HTTP_RANGE_ERROR 7.1 7.17.0
|
CURLE_HTTP_RANGE_ERROR 7.1 7.17.0
|
||||||
CURLE_HTTP_RETURNED_ERROR 7.10.3
|
CURLE_HTTP_RETURNED_ERROR 7.10.3
|
||||||
CURLE_HTTP2 7.38.0
|
|
||||||
CURLE_INTERFACE_FAILED 7.12.0
|
CURLE_INTERFACE_FAILED 7.12.0
|
||||||
CURLE_LDAP_CANNOT_BIND 7.1
|
CURLE_LDAP_CANNOT_BIND 7.1
|
||||||
CURLE_LDAP_INVALID_URL 7.10.8
|
CURLE_LDAP_INVALID_URL 7.10.8
|
||||||
@ -120,6 +120,7 @@ CURLE_SSL_ENGINE_NOTFOUND 7.9.3
|
|||||||
CURLE_SSL_ENGINE_SETFAILED 7.9.3
|
CURLE_SSL_ENGINE_SETFAILED 7.9.3
|
||||||
CURLE_SSL_ISSUER_ERROR 7.19.0
|
CURLE_SSL_ISSUER_ERROR 7.19.0
|
||||||
CURLE_SSL_PEER_CERTIFICATE 7.8 7.17.1
|
CURLE_SSL_PEER_CERTIFICATE 7.8 7.17.1
|
||||||
|
CURLE_SSL_PINNEDPUBKEYNOTMATCH 7.39.0
|
||||||
CURLE_SSL_SHUTDOWN_FAILED 7.16.1
|
CURLE_SSL_SHUTDOWN_FAILED 7.16.1
|
||||||
CURLE_TELNET_OPTION_SYNTAX 7.7
|
CURLE_TELNET_OPTION_SYNTAX 7.7
|
||||||
CURLE_TFTP_DISKFULL 7.15.0 7.17.0
|
CURLE_TFTP_DISKFULL 7.15.0 7.17.0
|
||||||
@ -429,6 +430,7 @@ CURLOPT_PASSWDDATA 7.4.2 7.11.1 7.15.5
|
|||||||
CURLOPT_PASSWDFUNCTION 7.4.2 7.11.1 7.15.5
|
CURLOPT_PASSWDFUNCTION 7.4.2 7.11.1 7.15.5
|
||||||
CURLOPT_PASSWORD 7.19.1
|
CURLOPT_PASSWORD 7.19.1
|
||||||
CURLOPT_PASV_HOST 7.12.1 7.16.0 7.15.5
|
CURLOPT_PASV_HOST 7.12.1 7.16.0 7.15.5
|
||||||
|
CURLOPT_PINNEDPUBLICKEY 7.39.0
|
||||||
CURLOPT_PORT 7.1
|
CURLOPT_PORT 7.1
|
||||||
CURLOPT_POST 7.1
|
CURLOPT_POST 7.1
|
||||||
CURLOPT_POST301 7.17.1 7.19.1
|
CURLOPT_POST301 7.17.1 7.19.1
|
||||||
|
@ -521,6 +521,8 @@ typedef enum {
|
|||||||
CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
|
CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
|
||||||
CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
|
CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
|
||||||
session will be queued */
|
session will be queued */
|
||||||
|
CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not
|
||||||
|
match */
|
||||||
CURL_LAST /* never use! */
|
CURL_LAST /* never use! */
|
||||||
} CURLcode;
|
} CURLcode;
|
||||||
|
|
||||||
@ -1611,6 +1613,10 @@ typedef enum {
|
|||||||
/* Pass in a bitmask of "header options" */
|
/* Pass in a bitmask of "header options" */
|
||||||
CINIT(HEADEROPT, LONG, 229),
|
CINIT(HEADEROPT, LONG, 229),
|
||||||
|
|
||||||
|
/* The public key in DER form used to validate the peer public key
|
||||||
|
this option is used only if SSL_VERIFYPEER is true */
|
||||||
|
CINIT(PINNEDPUBLICKEY, OBJECTPOINT, 230),
|
||||||
|
|
||||||
CURLOPT_LASTENTRY /* the last unused */
|
CURLOPT_LASTENTRY /* the last unused */
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
|
|
||||||
|
@ -298,6 +298,9 @@ curl_easy_strerror(CURLcode error)
|
|||||||
case CURLE_NO_CONNECTION_AVAILABLE:
|
case CURLE_NO_CONNECTION_AVAILABLE:
|
||||||
return "The max connection limit is reached";
|
return "The max connection limit is reached";
|
||||||
|
|
||||||
|
case CURLE_SSL_PINNEDPUBKEYNOTMATCH:
|
||||||
|
return "SSL public key does not matched pinned public key";
|
||||||
|
|
||||||
/* error codes not used by current libcurl */
|
/* error codes not used by current libcurl */
|
||||||
case CURLE_OBSOLETE20:
|
case CURLE_OBSOLETE20:
|
||||||
case CURLE_OBSOLETE24:
|
case CURLE_OBSOLETE24:
|
||||||
|
@ -1991,6 +1991,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
|
|||||||
result = CURLE_NOT_BUILT_IN;
|
result = CURLE_NOT_BUILT_IN;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
case CURLOPT_PINNEDPUBLICKEY:
|
||||||
|
/*
|
||||||
|
* Set pinned public key for SSL connection.
|
||||||
|
* Specify file name of the public key in DER format.
|
||||||
|
*/
|
||||||
|
result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY],
|
||||||
|
va_arg(param, char *));
|
||||||
|
break;
|
||||||
case CURLOPT_CAINFO:
|
case CURLOPT_CAINFO:
|
||||||
/*
|
/*
|
||||||
* Set CA info for SSL connection. Specify file name of the CA certificate
|
* Set CA info for SSL connection. Specify file name of the CA certificate
|
||||||
|
@ -1385,6 +1385,7 @@ enum dupstring {
|
|||||||
STRING_SET_URL, /* what original URL to work on */
|
STRING_SET_URL, /* what original URL to work on */
|
||||||
STRING_SSL_CAPATH, /* CA directory name (doesn't work on windows) */
|
STRING_SSL_CAPATH, /* CA directory name (doesn't work on windows) */
|
||||||
STRING_SSL_CAFILE, /* certificate file to verify peer against */
|
STRING_SSL_CAFILE, /* certificate file to verify peer against */
|
||||||
|
STRING_SSL_PINNEDPUBLICKEY, /* public key file to verify peer against */
|
||||||
STRING_SSL_CIPHER_LIST, /* list of ciphers to use */
|
STRING_SSL_CIPHER_LIST, /* list of ciphers to use */
|
||||||
STRING_SSL_EGDSOCKET, /* path to file containing the EGD daemon socket */
|
STRING_SSL_EGDSOCKET, /* path to file containing the EGD daemon socket */
|
||||||
STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */
|
STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */
|
||||||
|
@ -2362,6 +2362,107 @@ static CURLcode get_cert_chain(struct connectdata *conn,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Heavily modified from:
|
||||||
|
* https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
|
||||||
|
*/
|
||||||
|
static int pkp_pin_peer_pubkey(X509* cert, char *pinnedpubkey)
|
||||||
|
{
|
||||||
|
/* Scratch */
|
||||||
|
FILE* fp = NULL;
|
||||||
|
int len1 = 0, len2 = 0;
|
||||||
|
unsigned char *buff1 = NULL, *buff2 = NULL, *temp = NULL;
|
||||||
|
long size = 0;
|
||||||
|
|
||||||
|
/* Result is returned to caller */
|
||||||
|
int ret = 0, result = FALSE;
|
||||||
|
|
||||||
|
/* if a path wasn't specified, don't pin */
|
||||||
|
if(NULL == pinnedpubkey) return TRUE;
|
||||||
|
if(NULL == cert) return FALSE;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* Begin Gyrations to get the subjectPublicKeyInfo */
|
||||||
|
/* Thanks to Viktor Dukhovni on the OpenSSL mailing list */
|
||||||
|
|
||||||
|
/* http://groups.google.com/group/mailing.openssl.users/browse_thread
|
||||||
|
/thread/d61858dae102c6c7 */
|
||||||
|
len1 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL);
|
||||||
|
if(len1 < 1)
|
||||||
|
break; /* failed */
|
||||||
|
|
||||||
|
/* http://www.openssl.org/docs/crypto/buffer.html */
|
||||||
|
buff1 = temp = OPENSSL_malloc(len1);
|
||||||
|
if(NULL == buff1)
|
||||||
|
break; /* failed */
|
||||||
|
|
||||||
|
/* http://www.openssl.org/docs/crypto/d2i_X509.html */
|
||||||
|
len2 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &temp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These checks are verifying we got back the same values as when we
|
||||||
|
* sized the buffer.Its pretty weak since they should always be the
|
||||||
|
* same. But it gives us something to test.
|
||||||
|
*/
|
||||||
|
if(len1 != len2 || temp == NULL || ((temp - buff1) != len1))
|
||||||
|
break; /* failed */
|
||||||
|
|
||||||
|
/* End Gyrations */
|
||||||
|
|
||||||
|
/* See the warning above!!! */
|
||||||
|
fp = fopen(pinnedpubkey, "r");
|
||||||
|
|
||||||
|
if(NULL == fp)
|
||||||
|
break; /* failed */
|
||||||
|
|
||||||
|
/* Seek to eof to determine the file's size */
|
||||||
|
ret = fseek(fp, 0, SEEK_END);
|
||||||
|
if(0 != ret)
|
||||||
|
break; /* failed */
|
||||||
|
|
||||||
|
/* Fetch the file's size */
|
||||||
|
size = ftell(fp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if the size of our certificate doesn't match the size of
|
||||||
|
* the file, they can't be the same, don't bother reading it
|
||||||
|
*/
|
||||||
|
if(len2 != size)
|
||||||
|
break; /* failed */
|
||||||
|
|
||||||
|
/* Rewind to beginning to perform the read */
|
||||||
|
ret = fseek(fp, 0, SEEK_SET);
|
||||||
|
if(0 != ret)
|
||||||
|
break; /* failed */
|
||||||
|
|
||||||
|
/* http://www.openssl.org/docs/crypto/buffer.html */
|
||||||
|
buff2 = OPENSSL_malloc(len2);
|
||||||
|
if(NULL == buff2)
|
||||||
|
break; /* failed */
|
||||||
|
|
||||||
|
/* Returns number of elements read, which should be 1 */
|
||||||
|
ret = (int)fread(buff2, (size_t)len2, 1, fp);
|
||||||
|
if(1 != ret)
|
||||||
|
break; /* failed */
|
||||||
|
|
||||||
|
/* The one good exit point */
|
||||||
|
result = (0 == memcmp(buff1, buff2, (size_t)len2));
|
||||||
|
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
if(NULL != fp)
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
/* http://www.openssl.org/docs/crypto/buffer.html */
|
||||||
|
if(NULL != buff2)
|
||||||
|
OPENSSL_free(buff2);
|
||||||
|
|
||||||
|
if(NULL != buff1)
|
||||||
|
OPENSSL_free(buff1);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the server cert, verify it and show it etc, only call failf() if the
|
* Get the server cert, verify it and show it etc, only call failf() if the
|
||||||
* 'strict' argument is TRUE as otherwise all this is for informational
|
* 'strict' argument is TRUE as otherwise all this is for informational
|
||||||
@ -2485,6 +2586,13 @@ static CURLcode servercert(struct connectdata *conn,
|
|||||||
infof(data, "\t SSL certificate verify ok.\n");
|
infof(data, "\t SSL certificate verify ok.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(data->set.str[STRING_SSL_PINNEDPUBLICKEY] != NULL &&
|
||||||
|
TRUE != pkp_pin_peer_pubkey(connssl->server_cert,
|
||||||
|
data->set.str[STRING_SSL_PINNEDPUBLICKEY])) {
|
||||||
|
failf(data, "SSL: public key does not matched pinned public key!");
|
||||||
|
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
X509_free(connssl->server_cert);
|
X509_free(connssl->server_cert);
|
||||||
connssl->server_cert = NULL;
|
connssl->server_cert = NULL;
|
||||||
connssl->connecting_state = ssl_connect_done;
|
connssl->connecting_state = ssl_connect_done;
|
||||||
|
@ -101,6 +101,7 @@ static void free_config_fields(struct OperationConfig *config)
|
|||||||
Curl_safefree(config->cacert);
|
Curl_safefree(config->cacert);
|
||||||
Curl_safefree(config->capath);
|
Curl_safefree(config->capath);
|
||||||
Curl_safefree(config->crlfile);
|
Curl_safefree(config->crlfile);
|
||||||
|
Curl_safefree(config->pinnedpubkey);
|
||||||
Curl_safefree(config->key);
|
Curl_safefree(config->key);
|
||||||
Curl_safefree(config->key_type);
|
Curl_safefree(config->key_type);
|
||||||
Curl_safefree(config->key_passwd);
|
Curl_safefree(config->key_passwd);
|
||||||
|
@ -110,6 +110,7 @@ struct OperationConfig {
|
|||||||
char *cacert;
|
char *cacert;
|
||||||
char *capath;
|
char *capath;
|
||||||
char *crlfile;
|
char *crlfile;
|
||||||
|
char *pinnedpubkey;
|
||||||
char *key;
|
char *key;
|
||||||
char *key_type;
|
char *key_type;
|
||||||
char *key_passwd;
|
char *key_passwd;
|
||||||
|
@ -215,6 +215,7 @@ static const struct LongShort aliases[]= {
|
|||||||
{"Em", "tlsauthtype", TRUE},
|
{"Em", "tlsauthtype", TRUE},
|
||||||
{"En", "ssl-allow-beast", FALSE},
|
{"En", "ssl-allow-beast", FALSE},
|
||||||
{"Eo", "login-options", TRUE},
|
{"Eo", "login-options", TRUE},
|
||||||
|
{"Ep", "pinnedpubkey", TRUE},
|
||||||
{"f", "fail", FALSE},
|
{"f", "fail", FALSE},
|
||||||
{"F", "form", TRUE},
|
{"F", "form", TRUE},
|
||||||
{"Fs", "form-string", TRUE},
|
{"Fs", "form-string", TRUE},
|
||||||
@ -1353,6 +1354,11 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
GetStr(&config->login_options, nextarg);
|
GetStr(&config->login_options, nextarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'p': /* Pinned public key DER file */
|
||||||
|
/* Pinned public key DER file */
|
||||||
|
GetStr(&config->pinnedpubkey, nextarg);
|
||||||
|
break;
|
||||||
|
|
||||||
default: /* certificate file */
|
default: /* certificate file */
|
||||||
{
|
{
|
||||||
char *certname, *passphrase;
|
char *certname, *passphrase;
|
||||||
|
@ -152,6 +152,7 @@ static const char *const helptext[] = {
|
|||||||
" --oauth2-bearer TOKEN OAuth 2 Bearer Token (IMAP, POP3, SMTP)",
|
" --oauth2-bearer TOKEN OAuth 2 Bearer Token (IMAP, POP3, SMTP)",
|
||||||
" -o, --output FILE Write to FILE instead of stdout",
|
" -o, --output FILE Write to FILE instead of stdout",
|
||||||
" --pass PASS Pass phrase for the private key (SSL/SSH)",
|
" --pass PASS Pass phrase for the private key (SSL/SSH)",
|
||||||
|
" --pinnedpubkey FILE Public key (DER) to verify peer against (OpenSSL)",
|
||||||
" --post301 "
|
" --post301 "
|
||||||
"Do not switch to GET after following a 301 redirect (H)",
|
"Do not switch to GET after following a 301 redirect (H)",
|
||||||
" --post302 "
|
" --post302 "
|
||||||
|
@ -1025,6 +1025,9 @@ static CURLcode operate_do(struct GlobalConfig *global,
|
|||||||
if(config->crlfile)
|
if(config->crlfile)
|
||||||
my_setopt_str(curl, CURLOPT_CRLFILE, 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(curlinfo->features & CURL_VERSION_SSL) {
|
||||||
if(config->insecure_ok) {
|
if(config->insecure_ok) {
|
||||||
my_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
my_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||||
|
BIN
tests/certs/Server-localhost-sv.pub.der
Normal file
BIN
tests/certs/Server-localhost-sv.pub.der
Normal file
Binary file not shown.
BIN
tests/certs/Server-localhost.nn-sv.pub.der
Normal file
BIN
tests/certs/Server-localhost.nn-sv.pub.der
Normal file
Binary file not shown.
BIN
tests/certs/Server-localhost0h-sv.pub.der
Normal file
BIN
tests/certs/Server-localhost0h-sv.pub.der
Normal file
Binary file not shown.
@ -75,6 +75,9 @@ echo "openssl rsa -in $PREFIX-sv.key -out $PREFIX-sv.key"
|
|||||||
$OPENSSL rsa -in $PREFIX-sv.key -out $PREFIX-sv.key -passin pass:secret
|
$OPENSSL rsa -in $PREFIX-sv.key -out $PREFIX-sv.key -passin pass:secret
|
||||||
echo pseudo secrets generated
|
echo pseudo secrets generated
|
||||||
|
|
||||||
|
echo "openssl rsa -in $PREFIX-sv.key -pubout -outform DER -out $PREFIX-sv.pub.der"
|
||||||
|
$OPENSSL rsa -in $PREFIX-sv.key -pubout -outform DER -out $PREFIX-sv.pub.der
|
||||||
|
|
||||||
echo "openssl x509 -set_serial $SERIAL -extfile $PREFIX-sv.prm -days $DURATION -CA $CAPREFIX-ca.cacert -CAkey $CAPREFIX-ca.key -in $PREFIX-sv.csr -req -out $PREFIX-sv.crt -text -nameopt multiline -sha1"
|
echo "openssl x509 -set_serial $SERIAL -extfile $PREFIX-sv.prm -days $DURATION -CA $CAPREFIX-ca.cacert -CAkey $CAPREFIX-ca.key -in $PREFIX-sv.csr -req -out $PREFIX-sv.crt -text -nameopt multiline -sha1"
|
||||||
|
|
||||||
$OPENSSL x509 -set_serial $SERIAL -extfile $PREFIX-sv.prm -days $DURATION -CA $CAPREFIX-ca.cacert -CAkey $CAPREFIX-ca.key -in $PREFIX-sv.csr -req -out $PREFIX-sv.crt -text -nameopt multiline -sha1
|
$OPENSSL x509 -set_serial $SERIAL -extfile $PREFIX-sv.prm -days $DURATION -CA $CAPREFIX-ca.cacert -CAkey $CAPREFIX-ca.key -in $PREFIX-sv.csr -req -out $PREFIX-sv.crt -text -nameopt multiline -sha1
|
||||||
|
@ -138,7 +138,7 @@ test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
|
|||||||
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
|
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
|
||||||
test2016 test2017 test2018 test2019 test2020 test2021 test2022 test2023 \
|
test2016 test2017 test2018 test2019 test2020 test2021 test2022 test2023 \
|
||||||
test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \
|
test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \
|
||||||
test2032 test2033
|
test2032 test2033 test2034 test2035
|
||||||
|
|
||||||
EXTRA_DIST = $(TESTCASES) DISABLED
|
EXTRA_DIST = $(TESTCASES) DISABLED
|
||||||
|
|
||||||
|
57
tests/data/test2034
Normal file
57
tests/data/test2034
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
HTTPS
|
||||||
|
HTTP GET
|
||||||
|
PEM certificate
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data>
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Content-Length: 7
|
||||||
|
|
||||||
|
MooMoo
|
||||||
|
</data>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<features>
|
||||||
|
SSL
|
||||||
|
</features>
|
||||||
|
<server>
|
||||||
|
https Server-localhost-sv.pem
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
simple HTTPS GET with public key pinning
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey %SRCDIR/certs/Server-localhost-sv.pub.der https://localhost:%HTTPSPORT/2034
|
||||||
|
</command>
|
||||||
|
# Ensure that we're running on localhost because we're checking the host name
|
||||||
|
<precheck>
|
||||||
|
perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0.0.1' );"
|
||||||
|
</precheck>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
GET /2034 HTTP/1.1
|
||||||
|
Host: localhost:%HTTPSPORT
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
43
tests/data/test2035
Normal file
43
tests/data/test2035
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
HTTPS
|
||||||
|
HTTP GET
|
||||||
|
PEM certificate
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<features>
|
||||||
|
SSL
|
||||||
|
</features>
|
||||||
|
<server>
|
||||||
|
https Server-localhost-sv.pem
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
HTTPS wrong pinnedpubkey but right CN
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt --pinnedpubkey %SRCDIR/certs/Server-localhost-sv.der https://localhost:%HTTPSPORT/2035
|
||||||
|
</command>
|
||||||
|
# Ensure that we're running on localhost because we're checking the host name
|
||||||
|
<precheck>
|
||||||
|
perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0.0.1' );"
|
||||||
|
</precheck>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<errorcode>
|
||||||
|
90
|
||||||
|
</errorcode>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
Loading…
Reference in New Issue
Block a user