mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
PolarSSL: Implement public key pinning
This commit is contained in:
parent
7639a9cfc9
commit
33623d7196
13
docs/curl.1
13
docs/curl.1
@ -589,9 +589,16 @@ 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.
|
||||
|
||||
Added in 7.39.0 for OpenSSL, GnuTLS and GSKit. Added in 7.43.0 for NSS and
|
||||
wolfSSL/CyaSSL. sha256 support added in 7.44.0 for OpenSSL,
|
||||
GnuTLS, NSS and wolfSSL/CyaSSL. Other SSL backends not supported.
|
||||
PEM/DER support:
|
||||
7.39.0: OpenSSL, GnuTLS and GSKit
|
||||
7.43.0: NSS and wolfSSL/CyaSSL
|
||||
7.47.0: mbedtls
|
||||
7.49.0: PolarSSL
|
||||
sha256 support:
|
||||
7.44.0: OpenSSL, GnuTLS, NSS and wolfSSL/CyaSSL.
|
||||
7.47.0: mbedtls
|
||||
7.49.0: PolarSSL
|
||||
Other SSL backends not supported.
|
||||
|
||||
If this option is used several times, the last one will be used.
|
||||
.IP "--cert-status"
|
||||
|
@ -90,10 +90,16 @@ footer:
|
||||
-----END PUBLIC KEY-----
|
||||
.fi
|
||||
.SH AVAILABILITY
|
||||
Added in 7.39.0 for OpenSSL, GnuTLS and GSKit. Added in 7.43.0 for
|
||||
NSS and wolfSSL/CyaSSL. Added for mbedtls in 7.47.0, sha256 support
|
||||
added in 7.44.0 for OpenSSL, GnuTLS, NSS and wolfSSL/CyaSSL. Other
|
||||
SSL backends not supported.
|
||||
PEM/DER support:
|
||||
7.39.0: OpenSSL, GnuTLS and GSKit
|
||||
7.43.0: NSS and wolfSSL/CyaSSL
|
||||
7.47.0: mbedtls
|
||||
7.49.0: PolarSSL
|
||||
sha256 support:
|
||||
7.44.0: OpenSSL, GnuTLS, NSS and wolfSSL/CyaSSL.
|
||||
7.47.0: mbedtls
|
||||
7.49.0: PolarSSL
|
||||
Other SSL backends not supported.
|
||||
.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.
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <polarssl/certs.h>
|
||||
#include <polarssl/x509.h>
|
||||
#include <polarssl/version.h>
|
||||
#include <polarssl/sha256.h>
|
||||
|
||||
#if POLARSSL_VERSION_NUMBER < 0x01030000
|
||||
#error too old PolarSSL
|
||||
@ -60,6 +61,15 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/* See https://tls.mbed.org/discussions/generic/
|
||||
howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der
|
||||
*/
|
||||
#define RSA_PUB_DER_MAX_BYTES (38 + 2 * POLARSSL_MPI_MAX_SIZE)
|
||||
#define ECP_PUB_DER_MAX_BYTES (30 + 2 * POLARSSL_ECP_MAX_BYTES)
|
||||
|
||||
#define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
|
||||
RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES)
|
||||
|
||||
/* apply threading? */
|
||||
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||
#define THREADING_SUPPORT
|
||||
@ -453,6 +463,61 @@ polarssl_connect_step2(struct connectdata *conn,
|
||||
infof(data, "Dumping cert info:\n%s\n", buffer);
|
||||
}
|
||||
|
||||
/* adapted from mbedtls.c */
|
||||
if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
|
||||
int size;
|
||||
CURLcode result;
|
||||
x509_crt *p;
|
||||
unsigned char pubkey[PUB_DER_MAX_BYTES];
|
||||
const x509_crt *peercert;
|
||||
|
||||
peercert = ssl_get_peer_cert(&connssl->ssl);
|
||||
|
||||
if(!peercert || !peercert->raw.p || !peercert->raw.len) {
|
||||
failf(data, "Failed due to missing peer certificate");
|
||||
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
||||
}
|
||||
|
||||
p = calloc(1, sizeof(*p));
|
||||
|
||||
if(!p)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
x509_crt_init(p);
|
||||
|
||||
/* Make a copy of our const peercert because pk_write_pubkey_der
|
||||
needs a non-const key, for now.
|
||||
https://github.com/ARMmbed/mbedtls/issues/396 */
|
||||
if(x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) {
|
||||
failf(data, "Failed copying peer certificate");
|
||||
x509_crt_free(p);
|
||||
free(p);
|
||||
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
||||
}
|
||||
|
||||
size = pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES);
|
||||
|
||||
if(size <= 0) {
|
||||
failf(data, "Failed copying public key from peer certificate");
|
||||
x509_crt_free(p);
|
||||
free(p);
|
||||
return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
|
||||
}
|
||||
|
||||
/* pk_write_pubkey_der writes data at the end of the buffer. */
|
||||
result = Curl_pin_peer_pubkey(data,
|
||||
data->set.str[STRING_SSL_PINNEDPUBLICKEY],
|
||||
&pubkey[PUB_DER_MAX_BYTES - size], size);
|
||||
if(result) {
|
||||
x509_crt_free(p);
|
||||
free(p);
|
||||
return result;
|
||||
}
|
||||
|
||||
x509_crt_free(p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
#ifdef HAS_ALPN
|
||||
if(data->set.ssl_enable_alpn) {
|
||||
const char *next_protocol = ssl_get_alpn_protocol(&connssl->ssl);
|
||||
|
@ -26,6 +26,8 @@
|
||||
|
||||
#ifdef USE_POLARSSL
|
||||
|
||||
#include <polarssl/sha256.h>
|
||||
|
||||
/* Called on first use PolarSSL, setup threading if supported */
|
||||
int Curl_polarssl_init(void);
|
||||
void Curl_polarssl_cleanup(void);
|
||||
@ -65,6 +67,7 @@ int Curl_polarssl_shutdown(struct connectdata *conn, int sockindex);
|
||||
#define curlssl_version Curl_polarssl_version
|
||||
#define curlssl_check_cxn(x) ((void)x, -1)
|
||||
#define curlssl_data_pending(x,y) ((void)x, (void)y, 0)
|
||||
#define curlssl_sha256sum(a,b,c,d) sha256(a,b,c,0)
|
||||
|
||||
/* This might cause libcurl to use a weeker random!
|
||||
TODO: implement proper use of Polarssl's CTR-DRBG or HMAC-DRBG and use that
|
||||
|
@ -2358,6 +2358,7 @@ sub checksystem {
|
||||
}
|
||||
elsif ($libcurl =~ /polarssl/i) {
|
||||
$has_polarssl=1;
|
||||
$has_sslpinning=1;
|
||||
$ssllib="polarssl";
|
||||
}
|
||||
elsif ($libcurl =~ /axtls/i) {
|
||||
|
Loading…
Reference in New Issue
Block a user