mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -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:
parent
ba06adc4c5
commit
9f498de9a2
@ -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)"
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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,39 +599,33 @@ 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);
|
||||||
|
|
||||||
|
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 there's already a matching session in the cache, delete it */
|
||||||
|
if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL))
|
||||||
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
|
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
|
||||||
incache = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!incache) {
|
|
||||||
void *new_session = malloc(sizeof(mbedtls_ssl_session));
|
|
||||||
|
|
||||||
if(new_session) {
|
|
||||||
memcpy(new_session, our_ssl_sessionid,
|
|
||||||
sizeof(mbedtls_ssl_session));
|
|
||||||
|
|
||||||
retcode = Curl_ssl_addsessionid(conn, new_session,
|
|
||||||
sizeof(mbedtls_ssl_session));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
retcode = CURLE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0);
|
||||||
if(retcode) {
|
if(retcode) {
|
||||||
|
free(our_ssl_sessionid);
|
||||||
failf(data, "failed to store ssl session");
|
failf(data, "failed to store ssl session");
|
||||||
return retcode;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
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 there's already a matching session in the cache, delete it */
|
||||||
|
if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL))
|
||||||
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
|
Curl_ssl_delsessionid(conn, old_ssl_sessionid);
|
||||||
incache = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!incache) {
|
retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0);
|
||||||
void *new_session = malloc(sizeof(ssl_session));
|
if(retcode) {
|
||||||
|
free(our_ssl_sessionid);
|
||||||
if(new_session) {
|
|
||||||
memcpy(new_session, our_ssl_sessionid, sizeof(ssl_session));
|
|
||||||
|
|
||||||
result = Curl_ssl_addsessionid(conn, new_session, sizeof(ssl_session));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result = CURLE_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
if(result) {
|
|
||||||
failf(data, "failed to store ssl session");
|
failf(data, "failed to store ssl session");
|
||||||
return result;
|
return retcode;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user