#include "parsedate.h"
#include "connect.h" /* for the connect timeout */
#include "select.h"
-#include "rawstr.h"
+#include "strcase.h"
#include "polarssl_threadlock.h"
#include "curl_printf.h"
#include "curl_memory.h"
#define THREADING_SUPPORT
#endif
+#ifndef POLARSSL_ERROR_C
+#define error_strerror(x,y,z)
+#endif /* POLARSSL_ERROR_C */
+
+
#if defined(THREADING_SUPPORT)
static entropy_context entropy;
/* start of entropy_func_mutex() */
static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
{
- int ret;
- /* lock 1 = entropy_func_mutex() */
- Curl_polarsslthreadlock_lock_function(1);
- ret = entropy_func(data, output, len);
- Curl_polarsslthreadlock_unlock_function(1);
+ int ret;
+ /* lock 1 = entropy_func_mutex() */
+ Curl_polarsslthreadlock_lock_function(1);
+ ret = entropy_func(data, output, len);
+ Curl_polarsslthreadlock_unlock_function(1);
- return ret;
+ return ret;
}
/* end of entropy_func_mutex() */
static CURLcode
polarssl_connect_step1(struct connectdata *conn,
- int sockindex)
+ int sockindex)
{
struct Curl_easy *data = conn->data;
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
-
- bool sni = TRUE; /* default is SNI enabled */
+ const char *capath = SSL_CONN_CONFIG(CApath);
+ 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;
-#ifdef ENABLE_IPV6
- struct in6_addr addr;
-#else
- struct in_addr addr;
-#endif
char errorbuf[128];
errorbuf[0]=0;
/* PolarSSL only supports SSLv3 and TLSv1 */
- if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
+ if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
failf(data, "PolarSSL does not support SSLv2");
return CURLE_SSL_CONNECT_ERROR;
}
- else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
- sni = FALSE; /* SSLv3 has no SNI */
#ifdef THREADING_SUPPORT
entropy_init_mutex(&entropy);
if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func_mutex, &entropy,
NULL, 0)) != 0) {
-#ifdef POLARSSL_ERROR_C
- error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
- failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
- -ret, errorbuf);
+ error_strerror(ret, errorbuf, sizeof(errorbuf));
+ failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
+ -ret, errorbuf);
}
#else
entropy_init(&connssl->entropy);
if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func, &connssl->entropy,
NULL, 0)) != 0) {
-#ifdef POLARSSL_ERROR_C
- error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
- failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
- -ret, errorbuf);
+ error_strerror(ret, errorbuf, sizeof(errorbuf));
+ failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
+ -ret, errorbuf);
}
#endif /* THREADING_SUPPORT */
/* Load the trusted CA */
memset(&connssl->cacert, 0, sizeof(x509_crt));
- if(data->set.str[STRING_SSL_CAFILE]) {
+ if(SSL_CONN_CONFIG(CAfile)) {
ret = x509_crt_parse_file(&connssl->cacert,
- data->set.str[STRING_SSL_CAFILE]);
+ SSL_CONN_CONFIG(CAfile));
if(ret<0) {
-#ifdef POLARSSL_ERROR_C
error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s",
- data->set.str[STRING_SSL_CAFILE], -ret, errorbuf);
+ SSL_CONN_CONFIG(CAfile), -ret, errorbuf);
- if(data->set.ssl.verifypeer)
+ if(SSL_CONN_CONFIG(verifypeer))
return CURLE_SSL_CACERT_BADFILE;
}
}
- if(data->set.str[STRING_SSL_CAPATH]) {
- ret = x509_crt_parse_path(&connssl->cacert,
- data->set.str[STRING_SSL_CAPATH]);
+ if(capath) {
+ ret = x509_crt_parse_path(&connssl->cacert, capath);
if(ret<0) {
-#ifdef POLARSSL_ERROR_C
error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s",
- data->set.str[STRING_SSL_CAPATH], -ret, errorbuf);
+ capath, -ret, errorbuf);
- if(data->set.ssl.verifypeer)
+ if(SSL_CONN_CONFIG(verifypeer))
return CURLE_SSL_CACERT_BADFILE;
}
}
/* Load the client certificate */
memset(&connssl->clicert, 0, sizeof(x509_crt));
- if(data->set.str[STRING_CERT]) {
+ if(SSL_SET_OPTION(cert)) {
ret = x509_crt_parse_file(&connssl->clicert,
- data->set.str[STRING_CERT]);
+ SSL_SET_OPTION(cert));
if(ret) {
-#ifdef POLARSSL_ERROR_C
error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s",
- data->set.str[STRING_CERT], -ret, errorbuf);
+ SSL_SET_OPTION(cert), -ret, errorbuf);
return CURLE_SSL_CERTPROBLEM;
}
}
/* Load the client private key */
- if(data->set.str[STRING_KEY]) {
+ if(SSL_SET_OPTION(key)) {
pk_context pk;
pk_init(&pk);
- ret = pk_parse_keyfile(&pk, data->set.str[STRING_KEY],
- data->set.str[STRING_KEY_PASSWD]);
+ ret = pk_parse_keyfile(&pk, SSL_SET_OPTION(key),
+ SSL_SET_OPTION(key_passwd));
if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA))
ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
if(ret == 0)
pk_free(&pk);
if(ret) {
-#ifdef POLARSSL_ERROR_C
error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s",
- data->set.str[STRING_KEY], -ret, errorbuf);
+ SSL_SET_OPTION(key), -ret, errorbuf);
return CURLE_SSL_CERTPROBLEM;
}
/* Load the CRL */
memset(&connssl->crl, 0, sizeof(x509_crl));
- if(data->set.str[STRING_SSL_CRLFILE]) {
+ if(SSL_SET_OPTION(CRLfile)) {
ret = x509_crl_parse_file(&connssl->crl,
- data->set.str[STRING_SSL_CRLFILE]);
+ SSL_SET_OPTION(CRLfile));
if(ret) {
-#ifdef POLARSSL_ERROR_C
error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s",
- data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf);
+ SSL_SET_OPTION(CRLfile), -ret, errorbuf);
return CURLE_SSL_CRL_BADFILE;
}
}
- infof(data, "PolarSSL: Connecting to %s:%d\n",
- conn->host.name, conn->remote_port);
+ infof(data, "PolarSSL: Connecting to %s:%d\n", hostname, port);
if(ssl_init(&connssl->ssl)) {
failf(data, "PolarSSL: ssl_init failed");
return CURLE_SSL_CONNECT_ERROR;
}
- switch(data->set.ssl.version) {
- default:
+ switch(SSL_CONN_CONFIG(version)) {
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3,
SSL_MINOR_VERSION_3);
infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.2\n");
break;
+ case CURL_SSLVERSION_TLSv1_3:
+ failf(data, "PolarSSL: TLS 1.3 is not yet supported");
+ return CURLE_SSL_CONNECT_ERROR;
+ default:
+ failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+ return CURLE_SSL_CONNECT_ERROR;
}
ssl_set_endpoint(&connssl->ssl, SSL_IS_CLIENT);
ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites());
/* Check if there's a cached ID we can/should use here! */
- if(conn->ssl_config.sessionid) {
+ if(data->set.general_ssl.sessionid) {
void *old_session = NULL;
Curl_ssl_sessionid_lock(conn);
- if(!Curl_ssl_getsessionid(conn, &old_session, NULL)) {
+ if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
ret = ssl_set_session(&connssl->ssl, old_session);
- Curl_ssl_sessionid_unlock(conn);
if(ret) {
+ Curl_ssl_sessionid_unlock(conn);
failf(data, "ssl_set_session returned -0x%x", -ret);
return CURLE_SSL_CONNECT_ERROR;
}
infof(data, "PolarSSL re-using session\n");
}
+ Curl_ssl_sessionid_unlock(conn);
}
ssl_set_ca_chain(&connssl->ssl,
&connssl->cacert,
&connssl->crl,
- conn->host.name);
+ hostname);
ssl_set_own_cert_rsa(&connssl->ssl,
&connssl->clicert, &connssl->rsa);
- if(ssl_set_hostname(&connssl->ssl, conn->host.name)) {
+ if(ssl_set_hostname(&connssl->ssl, hostname)) {
/* 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. */
#ifdef HAS_ALPN
if(conn->bits.tls_enable_alpn) {
- static const char* protocols[3];
+ static const char *protocols[3];
int cur = 0;
#ifdef USE_NGHTTP2
static CURLcode
polarssl_connect_step2(struct connectdata *conn,
- int sockindex)
+ int sockindex)
{
int ret;
struct Curl_easy *data = conn->data;
struct ssl_connect_data* connssl = &conn->ssl[sockindex];
char buffer[1024];
+ const char * const pinnedpubkey = SSL_IS_PROXY() ?
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
+ data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+
char errorbuf[128];
errorbuf[0] = 0;
return CURLE_OK;
default:
-#ifdef POLARSSL_ERROR_C
error_strerror(ret, errorbuf, sizeof(errorbuf));
-#endif /* POLARSSL_ERROR_C */
failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s",
-ret, errorbuf);
return CURLE_SSL_CONNECT_ERROR;
ret = ssl_get_verify_result(&conn->ssl[sockindex].ssl);
- if(ret && data->set.ssl.verifypeer) {
+ if(ret && SSL_CONN_CONFIG(verifypeer)) {
if(ret & BADCERT_EXPIRED)
failf(data, "Cert verify failed: BADCERT_EXPIRED");
}
/* adapted from mbedtls.c */
- if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
+ if(pinnedpubkey) {
int size;
CURLcode result;
x509_crt *p;
/* pk_write_pubkey_der writes data at the end of the buffer. */
result = Curl_pin_peer_pubkey(data,
- data->set.str[STRING_SSL_PINNEDPUBLICKEY],
+ pinnedpubkey,
&pubkey[PUB_DER_MAX_BYTES - size], size);
if(result) {
x509_crt_free(p);
}
else
#endif
- if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) {
- conn->negnpn = CURL_HTTP_VERSION_1_1;
- }
+ if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) {
+ conn->negnpn = CURL_HTTP_VERSION_1_1;
+ }
}
else
infof(data, "ALPN, server did not agree to a protocol\n");
static CURLcode
polarssl_connect_step3(struct connectdata *conn,
- int sockindex)
+ int sockindex)
{
CURLcode retcode = CURLE_OK;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
- if(conn->ssl_config.sessionid) {
+ if(data->set.general_ssl.sessionid) {
int ret;
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))
+ if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex))
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
- retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0);
+ retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex);
Curl_ssl_sessionid_unlock(conn);
if(retcode) {
free(our_ssl_sessionid);
curl_socket_t readfd = ssl_connect_2_reading==
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
- what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms);
+ what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+ nonblocking?0:timeout_ms);
if(what < 0) {
/* fatal error */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
CURLcode
Curl_polarssl_connect_nonblocking(struct connectdata *conn,
- int sockindex,
- bool *done)
+ int sockindex,
+ bool *done)
{
return polarssl_connect_common(conn, sockindex, TRUE, done);
}
CURLcode
Curl_polarssl_connect(struct connectdata *conn,
- int sockindex)
+ int sockindex)
{
CURLcode result;
bool done = FALSE;
(void)Curl_polarsslthreadlock_thread_cleanup();
}
+
+int Curl_polarssl_data_pending(const struct connectdata *conn, int sockindex)
+{
+ return ssl_get_bytes_avail(&conn->ssl[sockindex].ssl) != 0;
+}
+
#endif /* USE_POLARSSL */