* \___|\___/|_| \_\_____|
*
* Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
- * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2016, 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
#ifdef USE_MBEDTLS
-#include <mbedtls/version.h>
-#if MBEDTLS_VERSION_NUMBER >= 0x02040000
-#include <mbedtls/net_sockets.h>
-#else
#include <mbedtls/net.h>
-#endif
#include <mbedtls/ssl.h>
#include <mbedtls/certs.h>
#include <mbedtls/x509.h>
+#include <mbedtls/version.h>
#include <mbedtls/error.h>
#include <mbedtls/entropy.h>
#include "parsedate.h"
#include "connect.h" /* for the connect timeout */
#include "select.h"
+#include "rawstr.h"
#include "polarssl_threadlock.h"
/* The last 3 #include files should be in this order */
{
struct Curl_easy *data = conn->data;
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
- const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
- const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
- const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
- char * const ssl_cert = SSL_SET_OPTION(cert);
- const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
- const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
- conn->host.name;
- const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+
int ret = -1;
char errorbuf[128];
errorbuf[0]=0;
/* mbedTLS only supports SSLv3 and TLSv1 */
- if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
+ if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
failf(data, "mbedTLS does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
/* Load the trusted CA */
mbedtls_x509_crt_init(&connssl->cacert);
- if(ssl_cafile) {
- ret = mbedtls_x509_crt_parse_file(&connssl->cacert, ssl_cafile);
+ if(data->set.str[STRING_SSL_CAFILE]) {
+ ret = mbedtls_x509_crt_parse_file(&connssl->cacert,
+ data->set.str[STRING_SSL_CAFILE]);
if(ret<0) {
#ifdef MBEDTLS_ERROR_C
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s",
- ssl_cafile, -ret, errorbuf);
+ data->set.str[STRING_SSL_CAFILE], -ret, errorbuf);
- if(verifypeer)
+ if(data->set.ssl.verifypeer)
return CURLE_SSL_CACERT_BADFILE;
}
}
- if(ssl_capath) {
- ret = mbedtls_x509_crt_parse_path(&connssl->cacert, ssl_capath);
+ if(data->set.str[STRING_SSL_CAPATH]) {
+ ret = mbedtls_x509_crt_parse_path(&connssl->cacert,
+ data->set.str[STRING_SSL_CAPATH]);
if(ret<0) {
#ifdef MBEDTLS_ERROR_C
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s",
- ssl_capath, -ret, errorbuf);
+ data->set.str[STRING_SSL_CAPATH], -ret, errorbuf);
- if(verifypeer)
+ if(data->set.ssl.verifypeer)
return CURLE_SSL_CACERT_BADFILE;
}
}
/* Load the client certificate */
mbedtls_x509_crt_init(&connssl->clicert);
- if(ssl_cert) {
- ret = mbedtls_x509_crt_parse_file(&connssl->clicert, ssl_cert);
+ if(data->set.str[STRING_CERT]) {
+ ret = mbedtls_x509_crt_parse_file(&connssl->clicert,
+ data->set.str[STRING_CERT]);
if(ret) {
#ifdef MBEDTLS_ERROR_C
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s",
- ssl_cert, -ret, errorbuf);
+ data->set.str[STRING_CERT], -ret, errorbuf);
return CURLE_SSL_CERTPROBLEM;
}
/* Load the client private key */
mbedtls_pk_init(&connssl->pk);
- if(SSL_SET_OPTION(key)) {
- ret = mbedtls_pk_parse_keyfile(&connssl->pk, SSL_SET_OPTION(key),
- SSL_SET_OPTION(key_passwd));
+ if(data->set.str[STRING_KEY]) {
+ ret = mbedtls_pk_parse_keyfile(&connssl->pk, data->set.str[STRING_KEY],
+ data->set.str[STRING_KEY_PASSWD]);
if(ret == 0 && !mbedtls_pk_can_do(&connssl->pk, MBEDTLS_PK_RSA))
ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s",
- SSL_SET_OPTION(key), -ret, errorbuf);
+ data->set.str[STRING_KEY], -ret, errorbuf);
return CURLE_SSL_CERTPROBLEM;
}
/* Load the CRL */
mbedtls_x509_crl_init(&connssl->crl);
- if(ssl_crlfile) {
- ret = mbedtls_x509_crl_parse_file(&connssl->crl, ssl_crlfile);
+ if(data->set.str[STRING_SSL_CRLFILE]) {
+ ret = mbedtls_x509_crl_parse_file(&connssl->crl,
+ data->set.str[STRING_SSL_CRLFILE]);
if(ret) {
#ifdef MBEDTLS_ERROR_C
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s",
- ssl_crlfile, -ret, errorbuf);
+ data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf);
return CURLE_SSL_CRL_BADFILE;
}
}
- infof(data, "mbedTLS: Connecting to %s:%d\n", hostname, port);
+ infof(data, "mbedTLS: Connecting to %s:%d\n",
+ conn->host.name, conn->remote_port);
mbedtls_ssl_config_init(&connssl->config);
mbedtls_ssl_conf_cert_profile(&connssl->config,
&mbedtls_x509_crt_profile_fr);
- switch(SSL_CONN_CONFIG(version)) {
+ switch(data->set.ssl.version) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
MBEDTLS_SSL_MINOR_VERSION_3);
infof(data, "mbedTLS: Set SSL version to TLS 1.2\n");
break;
- case CURL_SSLVERSION_TLSv1_3:
- failf(data, "mbedTLS: TLS 1.3 is not yet supported");
- return CURLE_SSL_CONNECT_ERROR;
default:
- failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+ failf(data, "mbedTLS: Unsupported SSL protocol version");
return CURLE_SSL_CONNECT_ERROR;
}
mbedtls_ssl_conf_ciphersuites(&connssl->config,
mbedtls_ssl_list_ciphersuites());
-#if defined(MBEDTLS_SSL_SESSION_TICKETS)
- mbedtls_ssl_conf_session_tickets(&connssl->config,
- MBEDTLS_SSL_SESSION_TICKETS_DISABLED);
-#endif
-
/* Check if there's a cached ID we can/should use here! */
- if(data->set.general_ssl.sessionid) {
+ if(conn->ssl_config.sessionid) {
void *old_session = NULL;
Curl_ssl_sessionid_lock(conn);
- if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
+ if(!Curl_ssl_getsessionid(conn, &old_session, NULL)) {
ret = mbedtls_ssl_set_session(&connssl->ssl, old_session);
if(ret) {
Curl_ssl_sessionid_unlock(conn);
&connssl->cacert,
&connssl->crl);
- if(SSL_SET_OPTION(key)) {
+ if(data->set.str[STRING_KEY]) {
mbedtls_ssl_conf_own_cert(&connssl->config,
&connssl->clicert, &connssl->pk);
}
- if(mbedtls_ssl_set_hostname(&connssl->ssl, hostname)) {
+ if(mbedtls_ssl_set_hostname(&connssl->ssl, conn->host.name)) {
/* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and*
the name to set in the SNI extension. So even if curl connects to a
host specified as an IP address, this function must be used. */
struct Curl_easy *data = conn->data;
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
const mbedtls_x509_crt *peercert;
- const char * const pinnedpubkey = SSL_IS_PROXY() ?
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
- data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
#ifdef HAS_ALPN
- const char *next_protocol;
+ const char* next_protocol;
#endif
char errorbuf[128];
ret = mbedtls_ssl_get_verify_result(&conn->ssl[sockindex].ssl);
- if(ret && SSL_CONN_CONFIG(verifypeer)) {
+ if(ret && data->set.ssl.verifypeer) {
if(ret & MBEDTLS_X509_BADCERT_EXPIRED)
failf(data, "Cert verify failed: BADCERT_EXPIRED");
free(buffer);
}
- if(pinnedpubkey) {
+ if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
int size;
CURLcode result;
mbedtls_x509_crt *p;
/* mbedtls_pk_write_pubkey_der writes data at the end of the buffer. */
result = Curl_pin_peer_pubkey(data,
- pinnedpubkey,
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY],
&pubkey[PUB_DER_MAX_BYTES - size], size);
if(result) {
mbedtls_x509_crt_free(p);
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
- if(data->set.general_ssl.sessionid) {
+ if(conn->ssl_config.sessionid) {
int ret;
mbedtls_ssl_session *our_ssl_sessionid;
void *old_ssl_sessionid = NULL;
/* If there's already a matching session in the cache, delete it */
Curl_ssl_sessionid_lock(conn);
- if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex))
+ if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL))
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
- retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex);
+ retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0);
Curl_ssl_sessionid_unlock(conn);
if(retcode) {
free(our_ssl_sessionid);
(version>>16)&0xff, (version>>8)&0xff);
}
-CURLcode Curl_mbedtls_random(struct Curl_easy *data, unsigned char *entropy,
- size_t length)
-{
-#if defined(MBEDTLS_CTR_DRBG_C)
- int ret = -1;
- char errorbuf[128];
- mbedtls_entropy_context ctr_entropy;
- mbedtls_ctr_drbg_context ctr_drbg;
- mbedtls_entropy_init(&ctr_entropy);
- mbedtls_ctr_drbg_init(&ctr_drbg);
- errorbuf[0]=0;
-
- ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
- &ctr_entropy, NULL, 0);
-
- if(ret) {
-#ifdef MBEDTLS_ERROR_C
- mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* MBEDTLS_ERROR_C */
- failf(data, "Failed - mbedTLS: ctr_drbg_seed returned (-0x%04X) %s\n",
- -ret, errorbuf);
- }
- else {
- ret = mbedtls_ctr_drbg_random(&ctr_drbg, entropy, length);
-
- if(ret) {
-#ifdef MBEDTLS_ERROR_C
- mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* MBEDTLS_ERROR_C */
- failf(data, "mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
- -ret, errorbuf);
- }
- }
-
- mbedtls_ctr_drbg_free(&ctr_drbg);
- mbedtls_entropy_free(&ctr_entropy);
-
- return ret == 0 ? CURLE_OK : CURLE_FAILED_INIT;
-#elif defined(MBEDTLS_HAVEGE_C)
- mbedtls_havege_state hs;
- mbedtls_havege_init(&hs);
- mbedtls_havege_random(&hs, entropy, length);
- mbedtls_havege_free(&hs);
- return CURLE_OK;
-#else
- return CURLE_NOT_BUILT_IN;
-#endif
-}
-
static CURLcode
mbed_connect_common(struct connectdata *conn,
int sockindex,
curl_socket_t readfd = ssl_connect_2_reading==
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
- what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
- nonblocking ? 0 : timeout_ms);
+ what = Curl_socket_ready(readfd, writefd, nonblocking ? 0 : timeout_ms);
if(what < 0) {
/* fatal error */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
int Curl_mbedtls_data_pending(const struct connectdata *conn, int sockindex)
{
- return mbedtls_ssl_get_bytes_avail(&conn->ssl[sockindex].ssl) != 0;
+ mbedtls_ssl_context *ssl =
+ (mbedtls_ssl_context *)&conn->ssl[sockindex].ssl;
+ return ssl->in_msglen != 0;
}
#endif /* USE_MBEDTLS */