1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-21 23:58:49 -05:00

mbedtls: Fix session resume

This also fixes PolarSSL session resume.

Prior to this change the TLS session information wasn't properly
saved and restored for PolarSSL and mbedTLS.

Bug: https://curl.haxx.se/mail/lib-2016-01/0070.html
Reported-by: Thomas Glanzmann

Bug: https://curl.haxx.se/mail/lib-2016-04/0095.html
Reported-by: Moti Avrahami
This commit is contained in:
Jay Satiro 2016-04-28 02:57:12 -04:00
parent ba06adc4c5
commit 9f498de9a2
5 changed files with 63 additions and 75 deletions

View File

@ -80,9 +80,9 @@ as well:
.IP axTLS .IP axTLS
SSL * SSL *
.IP mbedTLS .IP mbedTLS
mbedtls_ssl_session * mbedtls_ssl_context *
.IP PolarSSL .IP PolarSSL
ssl_session * ssl_context *
.IP "Secure Channel (WinSSL)" .IP "Secure Channel (WinSSL)"
CtxtHandle * CtxtHandle *
.IP "Secure Transport (DarwinSSL)" .IP "Secure Transport (DarwinSSL)"

View File

@ -307,7 +307,7 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
#elif defined(USE_GSKIT) #elif defined(USE_GSKIT)
tsi->internals = (void *)conn->ssl[i].handle; tsi->internals = (void *)conn->ssl[i].handle;
#elif defined(USE_MBEDTLS) #elif defined(USE_MBEDTLS)
tsi->internals = (void *)&conn->ssl[i].ssn; tsi->internals = (void *)&conn->ssl[i].ssl;
#elif defined(USE_NSS) #elif defined(USE_NSS)
tsi->internals = (void *)conn->ssl[i].handle; tsi->internals = (void *)conn->ssl[i].handle;
#elif defined(USE_OPENSSL) #elif defined(USE_OPENSSL)
@ -316,7 +316,7 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
(void *)conn->ssl[i].ctx : (void *)conn->ssl[i].ctx :
(void *)conn->ssl[i].handle); (void *)conn->ssl[i].handle);
#elif defined(USE_POLARSSL) #elif defined(USE_POLARSSL)
tsi->internals = (void *)&conn->ssl[i].ssn; tsi->internals = (void *)&conn->ssl[i].ssl;
#elif defined(USE_SCHANNEL) #elif defined(USE_SCHANNEL)
tsi->internals = (void *)&conn->ssl[i].ctxt->ctxt_handle; tsi->internals = (void *)&conn->ssl[i].ctxt->ctxt_handle;
#elif defined(USE_SSL) #elif defined(USE_SSL)

View File

@ -290,7 +290,6 @@ struct ssl_connect_data {
mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_context entropy; mbedtls_entropy_context entropy;
mbedtls_ssl_context ssl; mbedtls_ssl_context ssl;
mbedtls_ssl_session ssn;
int server_fd; int server_fd;
mbedtls_x509_crt cacert; mbedtls_x509_crt cacert;
mbedtls_x509_crt clicert; mbedtls_x509_crt clicert;
@ -302,7 +301,6 @@ struct ssl_connect_data {
ctr_drbg_context ctr_drbg; ctr_drbg_context ctr_drbg;
entropy_context entropy; entropy_context entropy;
ssl_context ssl; ssl_context ssl;
ssl_session ssn;
int server_fd; int server_fd;
x509_crt cacert; x509_crt cacert;
x509_crt clicert; x509_crt clicert;

View File

@ -170,7 +170,6 @@ mbed_connect_step1(struct connectdata *conn,
struct in_addr addr; struct in_addr addr;
#endif #endif
void *old_session = NULL; void *old_session = NULL;
size_t old_session_size = 0;
char errorbuf[128]; char errorbuf[128];
errorbuf[0]=0; errorbuf[0]=0;
@ -187,8 +186,7 @@ mbed_connect_step1(struct connectdata *conn,
mbedtls_ctr_drbg_init(&connssl->ctr_drbg); mbedtls_ctr_drbg_init(&connssl->ctr_drbg);
ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, entropy_func_mutex, ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, entropy_func_mutex,
&entropy, connssl->ssn.id, &entropy, NULL, 0);
connssl->ssn.id_len);
if(ret) { if(ret) {
#ifdef MBEDTLS_ERROR_C #ifdef MBEDTLS_ERROR_C
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
@ -201,8 +199,7 @@ mbed_connect_step1(struct connectdata *conn,
mbedtls_ctr_drbg_init(&connssl->ctr_drbg); mbedtls_ctr_drbg_init(&connssl->ctr_drbg);
ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, mbedtls_entropy_func, ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, mbedtls_entropy_func,
&connssl->entropy, connssl->ssn.id, &connssl->entropy, NULL, 0);
connssl->ssn.id_len);
if(ret) { if(ret) {
#ifdef MBEDTLS_ERROR_C #ifdef MBEDTLS_ERROR_C
mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
@ -377,14 +374,15 @@ mbed_connect_step1(struct connectdata *conn,
mbedtls_ssl_conf_ciphersuites(&connssl->config, mbedtls_ssl_conf_ciphersuites(&connssl->config,
mbedtls_ssl_list_ciphersuites()); mbedtls_ssl_list_ciphersuites());
if(!Curl_ssl_getsessionid(conn, &old_session, &old_session_size)) { if(!Curl_ssl_getsessionid(conn, &old_session, NULL)) {
memcpy(&connssl->ssn, old_session, old_session_size); ret = mbedtls_ssl_set_session(&connssl->ssl, old_session);
if(ret) {
failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret);
return CURLE_SSL_CONNECT_ERROR;
}
infof(data, "mbedTLS re-using session\n"); infof(data, "mbedTLS re-using session\n");
} }
mbedtls_ssl_set_session(&connssl->ssl,
&connssl->ssn);
mbedtls_ssl_conf_ca_chain(&connssl->config, mbedtls_ssl_conf_ca_chain(&connssl->config,
&connssl->cacert, &connssl->cacert,
&connssl->crl); &connssl->crl);
@ -601,38 +599,32 @@ mbed_connect_step3(struct connectdata *conn,
struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
void *old_ssl_sessionid = NULL; void *old_ssl_sessionid = NULL;
mbedtls_ssl_session *our_ssl_sessionid = &conn->ssl[sockindex].ssn; mbedtls_ssl_session *our_ssl_sessionid;
int incache; int ret;
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
/* Save the current session data for possible re-use */ our_ssl_sessionid = malloc(sizeof(mbedtls_ssl_session));
incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL)); if(!our_ssl_sessionid)
if(incache) { return CURLE_OUT_OF_MEMORY;
if(old_ssl_sessionid != our_ssl_sessionid) {
infof(data, "old SSL session ID is stale, removing\n"); mbedtls_ssl_session_init(our_ssl_sessionid);
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
incache = FALSE; ret = mbedtls_ssl_get_session(&connssl->ssl, our_ssl_sessionid);
} if(ret) {
failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret);
return CURLE_SSL_CONNECT_ERROR;
} }
if(!incache) {
void *new_session = malloc(sizeof(mbedtls_ssl_session));
if(new_session) { /* If there's already a matching session in the cache, delete it */
memcpy(new_session, our_ssl_sessionid, if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL))
sizeof(mbedtls_ssl_session)); Curl_ssl_delsessionid(conn, old_ssl_sessionid);
retcode = Curl_ssl_addsessionid(conn, new_session, retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0);
sizeof(mbedtls_ssl_session)); if(retcode) {
} free(our_ssl_sessionid);
else { failf(data, "failed to store ssl session");
retcode = CURLE_OUT_OF_MEMORY; return retcode;
}
if(retcode) {
failf(data, "failed to store ssl session");
return retcode;
}
} }
connssl->connecting_state = ssl_connect_done; connssl->connecting_state = ssl_connect_done;
@ -704,6 +696,7 @@ static ssize_t mbed_recv(struct connectdata *conn, int num,
void Curl_mbedtls_session_free(void *ptr) void Curl_mbedtls_session_free(void *ptr)
{ {
mbedtls_ssl_session_free(ptr);
free(ptr); free(ptr);
} }

View File

@ -151,7 +151,6 @@ polarssl_connect_step1(struct connectdata *conn,
struct in_addr addr; struct in_addr addr;
#endif #endif
void *old_session = NULL; void *old_session = NULL;
size_t old_session_size = 0;
char errorbuf[128]; char errorbuf[128];
errorbuf[0]=0; errorbuf[0]=0;
@ -167,7 +166,7 @@ polarssl_connect_step1(struct connectdata *conn,
entropy_init_mutex(&entropy); entropy_init_mutex(&entropy);
if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func_mutex, &entropy, if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func_mutex, &entropy,
connssl->ssn.id, connssl->ssn.length)) != 0) { NULL, 0)) != 0) {
#ifdef POLARSSL_ERROR_C #ifdef POLARSSL_ERROR_C
error_strerror(ret, errorbuf, sizeof(errorbuf)); error_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* POLARSSL_ERROR_C */ #endif /* POLARSSL_ERROR_C */
@ -178,7 +177,7 @@ polarssl_connect_step1(struct connectdata *conn,
entropy_init(&connssl->entropy); entropy_init(&connssl->entropy);
if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func, &connssl->entropy, if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func, &connssl->entropy,
connssl->ssn.id, connssl->ssn.length)) != 0) { NULL, 0)) != 0) {
#ifdef POLARSSL_ERROR_C #ifdef POLARSSL_ERROR_C
error_strerror(ret, errorbuf, sizeof(errorbuf)); error_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* POLARSSL_ERROR_C */ #endif /* POLARSSL_ERROR_C */
@ -338,14 +337,15 @@ polarssl_connect_step1(struct connectdata *conn,
net_send, &conn->sock[sockindex]); net_send, &conn->sock[sockindex]);
ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites()); ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites());
if(!Curl_ssl_getsessionid(conn, &old_session, &old_session_size)) { if(!Curl_ssl_getsessionid(conn, &old_session, NULL)) {
memcpy(&connssl->ssn, old_session, old_session_size); ret = ssl_set_session(&connssl->ssl, old_session);
if(ret) {
failf(data, "ssl_set_session returned -0x%x", -ret);
return CURLE_SSL_CONNECT_ERROR;
}
infof(data, "PolarSSL re-using session\n"); infof(data, "PolarSSL re-using session\n");
} }
ssl_set_session(&connssl->ssl,
&connssl->ssn);
ssl_set_ca_chain(&connssl->ssl, ssl_set_ca_chain(&connssl->ssl,
&connssl->cacert, &connssl->cacert,
&connssl->crl, &connssl->crl,
@ -551,40 +551,36 @@ static CURLcode
polarssl_connect_step3(struct connectdata *conn, polarssl_connect_step3(struct connectdata *conn,
int sockindex) int sockindex)
{ {
CURLcode result = CURLE_OK; CURLcode retcode = CURLE_OK;
struct ssl_connect_data *connssl = &conn->ssl[sockindex]; struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
void *old_ssl_sessionid = NULL; void *old_ssl_sessionid = NULL;
ssl_session *our_ssl_sessionid = &conn->ssl[sockindex].ssn; ssl_session *our_ssl_sessionid;
bool incache; int ret;
DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
/* Save the current session data for possible re-use */ our_ssl_sessionid = malloc(sizeof(ssl_session));
incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL)); if(!our_ssl_sessionid)
if(incache) { return CURLE_OUT_OF_MEMORY;
if(old_ssl_sessionid != our_ssl_sessionid) {
infof(data, "old SSL session ID is stale, removing\n"); ssl_session_init(our_ssl_sessionid);
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
incache = FALSE; ret = ssl_get_session(&connssl->ssl, our_ssl_sessionid);
} if(ret) {
failf(data, "ssl_get_session returned -0x%x", -ret);
return CURLE_SSL_CONNECT_ERROR;
} }
if(!incache) { /* If there's already a matching session in the cache, delete it */
void *new_session = malloc(sizeof(ssl_session)); if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL))
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
if(new_session) { retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0);
memcpy(new_session, our_ssl_sessionid, sizeof(ssl_session)); if(retcode) {
free(our_ssl_sessionid);
result = Curl_ssl_addsessionid(conn, new_session, sizeof(ssl_session)); failf(data, "failed to store ssl session");
} return retcode;
else
result = CURLE_OUT_OF_MEMORY;
if(result) {
failf(data, "failed to store ssl session");
return result;
}
} }
connssl->connecting_state = ssl_connect_done; connssl->connecting_state = ssl_connect_done;
@ -649,6 +645,7 @@ static ssize_t polarssl_recv(struct connectdata *conn,
void Curl_polarssl_session_free(void *ptr) void Curl_polarssl_session_free(void *ptr)
{ {
ssl_session_free(ptr);
free(ptr); free(ptr);
} }