aboutsummaryrefslogtreecommitdiff
path: root/lib/vtls/gtls.c
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2017-06-21 12:41:18 +0200
committerDaniel Stenberg <daniel@haxx.se>2017-08-28 14:56:58 +0200
commitd65e6cc4fc9f68da4cbf8788c27714622ef9eead (patch)
tree83999835de729324d3c447d3b3135835885bc84f /lib/vtls/gtls.c
parent20c6cf7e951e70d4c456bd4171b9f25f04f23a87 (diff)
vtls: prepare the SSL backends for encapsulated private data
At the moment, cURL's SSL backend needs to be configured at build time. As such, it is totally okay for them to hard-code their backend-specific data in the ssl_connect_data struct. In preparation for making the SSL backend a runtime option, let's make the access of said private data a bit more abstract so that it can be adjusted later in an easy manner. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Diffstat (limited to 'lib/vtls/gtls.c')
-rw-r--r--lib/vtls/gtls.c96
1 files changed, 52 insertions, 44 deletions
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index 1e57b4588..48de842a8 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -107,6 +107,8 @@ static bool gtls_inited = FALSE;
# include <gnutls/ocsp.h>
#endif
+#define BACKEND connssl
+
/*
* Custom push and pull callback functions used by GNU TLS to read and write
* to the socket. These functions are simple wrappers to send() and recv()
@@ -276,7 +278,7 @@ static CURLcode handshake(struct connectdata *conn,
{
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
- gnutls_session_t session = conn->ssl[sockindex].session;
+ gnutls_session_t session = BACKEND->session;
curl_socket_t sockfd = conn->sock[sockindex];
time_t timeout_ms;
int rc;
@@ -474,6 +476,7 @@ gtls_connect_step1(struct connectdata *conn,
int sockindex)
{
struct Curl_easy *data = conn->data;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
unsigned int init_flags;
gnutls_session_t session;
int rc;
@@ -509,7 +512,7 @@ gtls_connect_step1(struct connectdata *conn,
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
conn->host.name;
- if(conn->ssl[sockindex].state == ssl_connection_complete)
+ if(connssl->state == ssl_connection_complete)
/* to make us tolerant against being called more than once for the
same connection */
return CURLE_OK;
@@ -525,7 +528,7 @@ gtls_connect_step1(struct connectdata *conn,
sni = FALSE; /* SSLv3 has no SNI */
/* allocate a cred struct */
- rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred);
+ rc = gnutls_certificate_allocate_credentials(&BACKEND->cred);
if(rc != GNUTLS_E_SUCCESS) {
failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
return CURLE_SSL_CONNECT_ERROR;
@@ -536,15 +539,14 @@ gtls_connect_step1(struct connectdata *conn,
infof(data, "Using TLS-SRP username: %s\n", SSL_SET_OPTION(username));
rc = gnutls_srp_allocate_client_credentials(
- &conn->ssl[sockindex].srp_client_cred);
+ &BACKEND->srp_client_cred);
if(rc != GNUTLS_E_SUCCESS) {
failf(data, "gnutls_srp_allocate_client_cred() failed: %s",
gnutls_strerror(rc));
return CURLE_OUT_OF_MEMORY;
}
- rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex].
- srp_client_cred,
+ rc = gnutls_srp_set_client_credentials(BACKEND->srp_client_cred,
SSL_SET_OPTION(username),
SSL_SET_OPTION(password));
if(rc != GNUTLS_E_SUCCESS) {
@@ -557,10 +559,10 @@ gtls_connect_step1(struct connectdata *conn,
if(SSL_CONN_CONFIG(CAfile)) {
/* set the trusted CA cert bundle file */
- gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred,
+ gnutls_certificate_set_verify_flags(BACKEND->cred,
GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
- rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred,
+ rc = gnutls_certificate_set_x509_trust_file(BACKEND->cred,
SSL_CONN_CONFIG(CAfile),
GNUTLS_X509_FMT_PEM);
if(rc < 0) {
@@ -577,7 +579,7 @@ gtls_connect_step1(struct connectdata *conn,
#ifdef HAS_CAPATH
if(SSL_CONN_CONFIG(CApath)) {
/* set the trusted CA cert directory */
- rc = gnutls_certificate_set_x509_trust_dir(conn->ssl[sockindex].cred,
+ rc = gnutls_certificate_set_x509_trust_dir(BACKEND->cred,
SSL_CONN_CONFIG(CApath),
GNUTLS_X509_FMT_PEM);
if(rc < 0) {
@@ -596,13 +598,13 @@ gtls_connect_step1(struct connectdata *conn,
/* use system ca certificate store as fallback */
if(SSL_CONN_CONFIG(verifypeer) &&
!(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath))) {
- gnutls_certificate_set_x509_system_trust(conn->ssl[sockindex].cred);
+ gnutls_certificate_set_x509_system_trust(BACKEND->cred);
}
#endif
if(SSL_SET_OPTION(CRLfile)) {
/* set the CRL list file */
- rc = gnutls_certificate_set_x509_crl_file(conn->ssl[sockindex].cred,
+ rc = gnutls_certificate_set_x509_crl_file(BACKEND->cred,
SSL_SET_OPTION(CRLfile),
GNUTLS_X509_FMT_PEM);
if(rc < 0) {
@@ -623,14 +625,14 @@ gtls_connect_step1(struct connectdata *conn,
init_flags |= GNUTLS_NO_TICKETS;
#endif
- rc = gnutls_init(&conn->ssl[sockindex].session, init_flags);
+ rc = gnutls_init(&BACKEND->session, init_flags);
if(rc != GNUTLS_E_SUCCESS) {
failf(data, "gnutls_init() failed: %d", rc);
return CURLE_SSL_CONNECT_ERROR;
}
/* convenient assign */
- session = conn->ssl[sockindex].session;
+ session = BACKEND->session;
if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
#ifdef ENABLE_IPV6
@@ -787,7 +789,7 @@ gtls_connect_step1(struct connectdata *conn,
GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 |
GNUTLS_PKCS_USE_PBES2_AES_256;
rc = gnutls_certificate_set_x509_key_file2(
- conn->ssl[sockindex].cred,
+ BACKEND->cred,
SSL_SET_OPTION(cert),
SSL_SET_OPTION(key) ?
SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
@@ -807,7 +809,7 @@ gtls_connect_step1(struct connectdata *conn,
}
else {
if(gnutls_certificate_set_x509_key_file(
- conn->ssl[sockindex].cred,
+ BACKEND->cred,
SSL_SET_OPTION(cert),
SSL_SET_OPTION(key) ?
SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
@@ -823,7 +825,7 @@ gtls_connect_step1(struct connectdata *conn,
/* put the credentials to the current session */
if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
- conn->ssl[sockindex].srp_client_cred);
+ BACKEND->srp_client_cred);
if(rc != GNUTLS_E_SUCCESS) {
failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
return CURLE_SSL_CONNECT_ERROR;
@@ -833,7 +835,7 @@ gtls_connect_step1(struct connectdata *conn,
#endif
{
rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
- conn->ssl[sockindex].cred);
+ BACKEND->cred);
if(rc != GNUTLS_E_SUCCESS) {
failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
return CURLE_SSL_CONNECT_ERROR;
@@ -966,7 +968,8 @@ gtls_connect_step3(struct connectdata *conn,
time_t certclock;
const char *ptr;
struct Curl_easy *data = conn->data;
- gnutls_session_t session = conn->ssl[sockindex].session;
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ gnutls_session_t session = BACKEND->session;
int rc;
#ifdef HAS_ALPN
gnutls_datum_t proto;
@@ -1516,13 +1519,15 @@ static CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex)
static bool Curl_gtls_data_pending(const struct connectdata *conn,
int connindex)
{
+ const struct ssl_connect_data *connssl = &conn->ssl[connindex];
bool res = FALSE;
- if(conn->ssl[connindex].session &&
- 0 != gnutls_record_check_pending(conn->ssl[connindex].session))
+ if(BACKEND->session &&
+ 0 != gnutls_record_check_pending(BACKEND->session))
res = TRUE;
- if(conn->proxy_ssl[connindex].session &&
- 0 != gnutls_record_check_pending(conn->proxy_ssl[connindex].session))
+ connssl = &conn->proxy_ssl[connindex];
+ if(BACKEND->session &&
+ 0 != gnutls_record_check_pending(BACKEND->session))
res = TRUE;
return res;
@@ -1534,7 +1539,8 @@ static ssize_t gtls_send(struct connectdata *conn,
size_t len,
CURLcode *curlcode)
{
- ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len);
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+ ssize_t rc = gnutls_record_send(BACKEND->session, mem, len);
if(rc < 0) {
*curlcode = (rc == GNUTLS_E_AGAIN)
@@ -1547,21 +1553,21 @@ static ssize_t gtls_send(struct connectdata *conn,
return rc;
}
-static void close_one(struct ssl_connect_data *ssl)
+static void close_one(struct ssl_connect_data *connssl)
{
- if(ssl->session) {
- gnutls_bye(ssl->session, GNUTLS_SHUT_RDWR);
- gnutls_deinit(ssl->session);
- ssl->session = NULL;
+ if(BACKEND->session) {
+ gnutls_bye(BACKEND->session, GNUTLS_SHUT_RDWR);
+ gnutls_deinit(BACKEND->session);
+ BACKEND->session = NULL;
}
- if(ssl->cred) {
- gnutls_certificate_free_credentials(ssl->cred);
- ssl->cred = NULL;
+ if(BACKEND->cred) {
+ gnutls_certificate_free_credentials(BACKEND->cred);
+ BACKEND->cred = NULL;
}
#ifdef USE_TLS_SRP
- if(ssl->srp_client_cred) {
- gnutls_srp_free_client_credentials(ssl->srp_client_cred);
- ssl->srp_client_cred = NULL;
+ if(BACKEND->srp_client_cred) {
+ gnutls_srp_free_client_credentials(BACKEND->srp_client_cred);
+ BACKEND->srp_client_cred = NULL;
}
#endif
}
@@ -1578,6 +1584,7 @@ static void Curl_gtls_close(struct connectdata *conn, int sockindex)
*/
static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
{
+ struct ssl_connect_data *connssl = &conn->ssl[sockindex];
ssize_t result;
int retval = 0;
struct Curl_easy *data = conn->data;
@@ -1590,16 +1597,16 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
we do not send one. Let's hope other servers do the same... */
if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
- gnutls_bye(conn->ssl[sockindex].session, GNUTLS_SHUT_WR);
+ gnutls_bye(BACKEND->session, GNUTLS_SHUT_WR);
- if(conn->ssl[sockindex].session) {
+ if(BACKEND->session) {
while(!done) {
int what = SOCKET_READABLE(conn->sock[sockindex],
SSL_SHUTDOWN_TIMEOUT);
if(what > 0) {
/* Something to read, let's do it and hope that it is the close
notify alert from the server */
- result = gnutls_record_recv(conn->ssl[sockindex].session,
+ result = gnutls_record_recv(BACKEND->session,
buf, sizeof(buf));
switch(result) {
case 0:
@@ -1630,18 +1637,18 @@ static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
done = 1;
}
}
- gnutls_deinit(conn->ssl[sockindex].session);
+ gnutls_deinit(BACKEND->session);
}
- gnutls_certificate_free_credentials(conn->ssl[sockindex].cred);
+ gnutls_certificate_free_credentials(BACKEND->cred);
#ifdef USE_TLS_SRP
if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
&& SSL_SET_OPTION(username) != NULL)
- gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred);
+ gnutls_srp_free_client_credentials(BACKEND->srp_client_cred);
#endif
- conn->ssl[sockindex].cred = NULL;
- conn->ssl[sockindex].session = NULL;
+ BACKEND->cred = NULL;
+ BACKEND->session = NULL;
return retval;
}
@@ -1652,9 +1659,10 @@ static ssize_t gtls_recv(struct connectdata *conn, /* connection data */
size_t buffersize, /* max amount to read */
CURLcode *curlcode)
{
+ struct ssl_connect_data *connssl = &conn->ssl[num];
ssize_t ret;
- ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize);
+ ret = gnutls_record_recv(BACKEND->session, buf, buffersize);
if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
*curlcode = CURLE_AGAIN;
return -1;
@@ -1786,7 +1794,7 @@ static void *Curl_gtls_get_internals(struct ssl_connect_data *connssl,
CURLINFO info UNUSED_PARAM)
{
(void)info;
- return connssl->session;
+ return BACKEND->session;
}
const struct Curl_ssl Curl_ssl_gnutls = {