const bool verifyhost = conn_config->verifyhost;
CURLcode ret;
unsigned version_min, version_max;
+ int session_set = 0;
#ifdef ENABLE_IPV6
struct in6_addr addr;
#else
#endif
DEBUGASSERT(backend);
+ CURL_TRC_CF(data, cf, "connect_step1");
switch(conn_config->version) {
case CURL_SSLVERSION_SSLv2:
source.data = ca_info_blob->data;
source.len = ca_info_blob->len;
+ CURL_TRC_CF(data, cf, "connect_step1, load ca_info_blob");
ret = load_cafile(&source, &backend->anchors, &backend->anchors_len);
if(ret != CURLE_OK) {
failf(data, "error importing CA certificate blob");
source.data = ssl_cafile;
source.len = 0;
+ CURL_TRC_CF(data, cf, "connect_step1, load cafile");
ret = load_cafile(&source, &backend->anchors, &backend->anchors_len);
if(ret != CURLE_OK) {
failf(data, "error setting certificate verify locations."
if(conn_config->cipher_list) {
/* Override the ciphers as specified. For the default cipher list see the
BearSSL source code of br_ssl_client_init_full() */
+ CURL_TRC_CF(data, cf, "connect_step1, set ciphers");
ret = bearssl_set_selected_ciphers(data, &backend->ctx.eng,
conn_config->cipher_list);
if(ret)
if(ssl_config->primary.sessionid) {
void *session;
+ CURL_TRC_CF(data, cf, "connect_step1, check session cache");
Curl_ssl_sessionid_lock(data);
if(!Curl_ssl_getsessionid(cf, data, &session, NULL)) {
br_ssl_engine_set_session_parameters(&backend->ctx.eng, session);
+ session_set = 1;
infof(data, "BearSSL: re-using session ID");
}
Curl_ssl_sessionid_unlock(data);
return CURLE_SSL_CONNECT_ERROR;
}
hostname = snihost;
+ CURL_TRC_CF(data, cf, "connect_step1, SNI set");
}
/* give application a chance to interfere with SSL set up. */
}
}
- if(!br_ssl_client_reset(&backend->ctx, hostname, 1))
+ if(!br_ssl_client_reset(&backend->ctx, hostname, session_set))
return CURLE_FAILED_INIT;
backend->active = TRUE;
return CURLE_OK;
}
+static int bearssl_get_select_socks(struct Curl_cfilter *cf,
+ struct Curl_easy *data,
+ curl_socket_t *socks)
+{
+ struct ssl_connect_data *connssl = cf->ctx;
+ curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data);
+
+ if(sock == CURL_SOCKET_BAD)
+ return GETSOCK_BLANK;
+ else {
+ struct bearssl_ssl_backend_data *backend =
+ (struct bearssl_ssl_backend_data *)connssl->backend;
+ unsigned state = br_ssl_engine_current_state(&backend->ctx.eng);
+ if(state & BR_SSL_SENDREC) {
+ socks[0] = sock;
+ return GETSOCK_WRITESOCK(0);
+ }
+ }
+ socks[0] = sock;
+ return GETSOCK_READSOCK(0);
+}
+
static CURLcode bearssl_run_until(struct Curl_cfilter *cf,
struct Curl_easy *data,
unsigned target)
if(state & BR_SSL_SENDREC) {
buf = br_ssl_engine_sendrec_buf(&backend->ctx.eng, &len);
ret = Curl_conn_cf_send(cf->next, data, (char *)buf, len, &result);
+ CURL_TRC_CF(data, cf, "ssl_send(len=%zu) -> %zd, %d", len, ret, result);
if(ret <= 0) {
return result;
}
else if(state & BR_SSL_RECVREC) {
buf = br_ssl_engine_recvrec_buf(&backend->ctx.eng, &len);
ret = Curl_conn_cf_recv(cf->next, data, (char *)buf, len, &result);
+ CURL_TRC_CF(data, cf, "ssl_recv(len=%zu) -> %zd, %d", len, ret, result);
if(ret == 0) {
failf(data, "SSL: EOF without close notify");
return CURLE_READ_ERROR;
CURLcode ret;
DEBUGASSERT(backend);
+ CURL_TRC_CF(data, cf, "connect_step2");
ret = bearssl_run_until(cf, data, BR_SSL_SENDAPP | BR_SSL_RECVAPP);
if(ret == CURLE_AGAIN)
return CURLE_OK;
if(ret == CURLE_OK) {
+ unsigned int tver;
if(br_ssl_engine_current_state(&backend->ctx.eng) == BR_SSL_CLOSED) {
failf(data, "SSL: connection closed during handshake");
return CURLE_SSL_CONNECT_ERROR;
}
connssl->connecting_state = ssl_connect_3;
+ /* Informational message */
+ tver = br_ssl_engine_get_version(&backend->ctx.eng);
+ if(tver == 0x0303)
+ infof(data, "SSL connection using TLSv1.2");
+ else if(tver == 0x0304)
+ infof(data, "SSL connection using TLSv1.3");
+ else
+ infof(data, "SSL connection using TLS 0x%x", tver);
}
return ret;
}
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
DEBUGASSERT(backend);
+ CURL_TRC_CF(data, cf, "connect_step3");
if(connssl->alpn) {
const char *proto;
timediff_t timeout_ms;
int what;
+ CURL_TRC_CF(data, cf, "connect_common(blocking=%d)", !nonblocking);
/* check if the connection has already been established */
if(ssl_connection_complete == connssl->state) {
+ CURL_TRC_CF(data, cf, "connect_common, connected");
*done = TRUE;
return CURLE_OK;
}
curl_socket_t readfd = ssl_connect_2_reading ==
connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+ CURL_TRC_CF(data, cf, "connect_common, check socket");
what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
nonblocking?0:timeout_ms);
+ CURL_TRC_CF(data, cf, "connect_common, check socket -> %d", what);
if(what < 0) {
/* fatal error */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
Curl_none_cert_status_request, /* cert_status_request */
bearssl_connect, /* connect */
bearssl_connect_nonblocking, /* connect_nonblocking */
- Curl_ssl_get_select_socks, /* getsock */
+ bearssl_get_select_socks, /* getsock */
bearssl_get_internals, /* get_internals */
bearssl_close, /* close_one */
Curl_none_close_all, /* close_all */
struct ssl_connect_data *connssl = cf->ctx;
curl_socket_t sock = Curl_conn_cf_get_socket(cf->next, data);
- if(sock != CURL_SOCKET_BAD) {
- if(connssl->connecting_state == ssl_connect_2_writing) {
- /* write mode */
- socks[0] = sock;
- return GETSOCK_WRITESOCK(0);
- }
- if(connssl->connecting_state == ssl_connect_2_reading) {
- /* read mode */
- socks[0] = sock;
- return GETSOCK_READSOCK(0);
- }
+ if(sock == CURL_SOCKET_BAD)
+ return GETSOCK_BLANK;
+
+ if(connssl->connecting_state == ssl_connect_2_writing) {
+ /* we are only interested in writing */
+ socks[0] = sock;
+ return GETSOCK_WRITESOCK(0);
}
- return GETSOCK_BLANK;
+ socks[0] = sock;
+ return GETSOCK_READSOCK(0);
}
/* Selects an SSL crypto engine
}
CF_DATA_SAVE(save, cf, data);
+ CURL_TRC_CF(data, cf, "cf_connect()");
(void)connssl;
DEBUGASSERT(data->conn);
DEBUGASSERT(data->conn == cf->conn);
DEBUGASSERT(connssl->state == ssl_connection_complete);
}
out:
+ CURL_TRC_CF(data, cf, "cf_connect() -> %d, done=%d", result, *done);
CF_DATA_RESTORE(cf, save);
return result;
}
curl_socket_t *socks)
{
struct cf_call_data save;
- int result;
+ int fds = GETSOCK_BLANK;
- CF_DATA_SAVE(save, cf, data);
- result = Curl_ssl->get_select_socks(cf, data, socks);
- CF_DATA_RESTORE(cf, save);
- return result;
+ if(!cf->next->connected) {
+ fds = cf->next->cft->get_select_socks(cf->next, data, socks);
+ }
+ else if(!cf->connected) {
+ CF_DATA_SAVE(save, cf, data);
+ fds = Curl_ssl->get_select_socks(cf, data, socks);
+ CF_DATA_RESTORE(cf, save);
+ }
+ return fds;
}
static CURLcode ssl_cf_cntrl(struct Curl_cfilter *cf,