mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
cyassl: Implement public key pinning
Also add public key extraction example to CURLOPT_PINNEDPUBLICKEY doc.
This commit is contained in:
parent
26cbd7a1d9
commit
0675abbc75
@ -548,11 +548,10 @@ 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
|
if it does not exactly match the public key provided to this option, curl will
|
||||||
abort the connection before sending or receiving any data.
|
abort the connection before sending or receiving any data.
|
||||||
|
|
||||||
This is currently only implemented in the OpenSSL, GnuTLS, NSS and GSKit
|
Added in 7.39.0 for OpenSSL, GnuTLS and GSKit. Added in 7.43.0 for NSS and
|
||||||
backends.
|
wolfSSL/CyaSSL. Other SSL backends not supported.
|
||||||
|
|
||||||
If this option is used several times, the last one will be used.
|
If this option is used several times, the last one will be used.
|
||||||
(Added in 7.39.0)
|
|
||||||
.IP "--cert-status"
|
.IP "--cert-status"
|
||||||
(SSL) Tells curl to verify the status of the server certificate by using the
|
(SSL) Tells curl to verify the status of the server certificate by using the
|
||||||
Certificate Status Request (aka. OCSP stapling) TLS extension.
|
Certificate Status Request (aka. OCSP stapling) TLS extension.
|
||||||
|
@ -50,11 +50,22 @@ if(curl) {
|
|||||||
curl_easy_perform(curl);
|
curl_easy_perform(curl);
|
||||||
}
|
}
|
||||||
.fi
|
.fi
|
||||||
|
.SH PUBLIC KEY EXTRACTION
|
||||||
|
If you do not have the server's public key file you can extract it from the
|
||||||
|
server's certificate.
|
||||||
|
.nf
|
||||||
|
openssl x509 -in www.test.com.pem -pubkey -noout > www.test.com.pubkey.pem
|
||||||
|
.fi
|
||||||
|
The public key is output in PEM format and contains a header, base64 data and a
|
||||||
|
footer:
|
||||||
|
.nf
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
[BASE 64 DATA]
|
||||||
|
-----END PUBLIC KEY-----
|
||||||
|
.fi
|
||||||
.SH AVAILABILITY
|
.SH AVAILABILITY
|
||||||
If built TLS enabled. This is currently only implemented in the OpenSSL,
|
Added in 7.39.0 for OpenSSL, GnuTLS and GSKit. Added in 7.43.0 for
|
||||||
GnuTLS, NSS and GSKit backends.
|
NSS and wolfSSL/CyaSSL. Other SSL backends not supported.
|
||||||
|
|
||||||
Added in libcurl 7.39.0
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
Returns CURLE_OK if TLS enabled, CURLE_UNKNOWN_OPTION if not, or
|
Returns CURLE_OK if TLS enabled, CURLE_UNKNOWN_OPTION if not, or
|
||||||
CURLE_OUT_OF_MEMORY if there was insufficient heap space.
|
CURLE_OUT_OF_MEMORY if there was insufficient heap space.
|
||||||
|
@ -57,6 +57,7 @@ and that's a problem since options.h hasn't been included yet. */
|
|||||||
#include "connect.h" /* for the connect timeout */
|
#include "connect.h" /* for the connect timeout */
|
||||||
#include "select.h"
|
#include "select.h"
|
||||||
#include "rawstr.h"
|
#include "rawstr.h"
|
||||||
|
#include "x509asn1.h"
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
|
|
||||||
#include <cyassl/ssl.h>
|
#include <cyassl/ssl.h>
|
||||||
@ -403,6 +404,44 @@ cyassl_connect_step2(struct connectdata *conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
|
||||||
|
X509 *x509;
|
||||||
|
const char *x509_der;
|
||||||
|
int x509_der_len;
|
||||||
|
curl_X509certificate x509_parsed;
|
||||||
|
curl_asn1Element *pubkey;
|
||||||
|
CURLcode result;
|
||||||
|
|
||||||
|
x509 = SSL_get_peer_certificate(conssl->handle);
|
||||||
|
if(!x509) {
|
||||||
|
failf(data, "SSL: failed retrieving server certificate");
|
||||||
|
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
x509_der = (const char *)CyaSSL_X509_get_der(x509, &x509_der_len);
|
||||||
|
if(!x509_der) {
|
||||||
|
failf(data, "SSL: failed retrieving ASN.1 server certificate");
|
||||||
|
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&x509_parsed, 0, sizeof x509_parsed);
|
||||||
|
Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len);
|
||||||
|
|
||||||
|
pubkey = &x509_parsed.subjectPublicKeyInfo;
|
||||||
|
if(!pubkey->header || pubkey->end <= pubkey->header) {
|
||||||
|
failf(data, "SSL: failed retrieving public key from server certificate");
|
||||||
|
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = Curl_pin_peer_pubkey(data->set.str[STRING_SSL_PINNEDPUBLICKEY],
|
||||||
|
(const unsigned char *)pubkey->header,
|
||||||
|
(size_t)(pubkey->end - pubkey->header));
|
||||||
|
if(result) {
|
||||||
|
failf(data, "SSL: public key does not match pinned public key!");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
conssl->connecting_state = ssl_connect_3;
|
conssl->connecting_state = ssl_connect_3;
|
||||||
infof(data, "SSL connected\n");
|
infof(data, "SSL connected\n");
|
||||||
|
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
|
|
||||||
#include "curl_setup.h"
|
#include "curl_setup.h"
|
||||||
|
|
||||||
#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS)
|
#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
|
||||||
|
defined(USE_CYASSL)
|
||||||
|
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
@ -1023,7 +1024,7 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn,
|
|||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS */
|
#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL */
|
||||||
|
|
||||||
#if defined(USE_GSKIT)
|
#if defined(USE_GSKIT)
|
||||||
|
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
|
|
||||||
#include "curl_setup.h"
|
#include "curl_setup.h"
|
||||||
|
|
||||||
#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS)
|
#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
|
||||||
|
defined(USE_CYASSL)
|
||||||
|
|
||||||
#include "urldata.h"
|
#include "urldata.h"
|
||||||
|
|
||||||
@ -127,5 +128,5 @@ CURLcode Curl_extract_certinfo(struct connectdata * conn, int certnum,
|
|||||||
CURLcode Curl_verifyhost(struct connectdata * conn,
|
CURLcode Curl_verifyhost(struct connectdata * conn,
|
||||||
const char * beg, const char * end);
|
const char * beg, const char * end);
|
||||||
|
|
||||||
#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS */
|
#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL */
|
||||||
#endif /* HEADER_CURL_X509ASN1_H */
|
#endif /* HEADER_CURL_X509ASN1_H */
|
||||||
|
@ -156,7 +156,7 @@ static const char *const helptext[] = {
|
|||||||
" --pass PASS Pass phrase for the private key (SSL/SSH)",
|
" --pass PASS Pass phrase for the private key (SSL/SSH)",
|
||||||
" --path-as-is Do not squash .. sequences in URL path",
|
" --path-as-is Do not squash .. sequences in URL path",
|
||||||
" --pinnedpubkey FILE Public key (PEM/DER) to verify peer against "
|
" --pinnedpubkey FILE Public key (PEM/DER) to verify peer against "
|
||||||
"(OpenSSL/GnuTLS/NSS/GSKit only)",
|
"(OpenSSL/GnuTLS/NSS/wolfSSL/CyaSSL/GSKit only)",
|
||||||
" --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 "
|
||||||
|
@ -2351,6 +2351,7 @@ sub checksystem {
|
|||||||
}
|
}
|
||||||
elsif ($libcurl =~ /(yassl|wolfssl)/i) {
|
elsif ($libcurl =~ /(yassl|wolfssl)/i) {
|
||||||
$has_yassl=1;
|
$has_yassl=1;
|
||||||
|
$has_sslpinning=1;
|
||||||
$ssllib="yassl";
|
$ssllib="yassl";
|
||||||
}
|
}
|
||||||
elsif ($libcurl =~ /polarssl/i) {
|
elsif ($libcurl =~ /polarssl/i) {
|
||||||
|
Loading…
Reference in New Issue
Block a user