aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Hu <EHu@directv.com>2013-05-16 20:26:42 +0200
committerDaniel Stenberg <daniel@haxx.se>2013-05-16 20:26:42 +0200
commit100a33f7ff8bd7dec1fe4b50bed57626a86c6b87 (patch)
tree051e116e8636d237af23df884d57653110648bd0
parent7ed25ccf0d1e5b8c7fd3bd90f0375a06011cd394 (diff)
axtls: prevent memleaks on SSL handshake failures
-rw-r--r--lib/axtls.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/lib/axtls.c b/lib/axtls.c
index d512950c2..59c8a835e 100644
--- a/lib/axtls.c
+++ b/lib/axtls.c
@@ -131,6 +131,16 @@ static CURLcode map_error_to_curl(int axtls_err)
static Curl_recv axtls_recv;
static Curl_send axtls_send;
+static void free_ssl_structs(SSL_CTX *ssl_ctx, SSL *ssl)
+{
+ if(ssl) {
+ ssl_free (ssl);
+ }
+ if(ssl_ctx) {
+ ssl_ctx_free(ssl_ctx);
+ }
+}
+
/*
* This function is called after the TCP connect has completed. Setup the TLS
* layer and do all necessary magic.
@@ -142,7 +152,7 @@ Curl_axtls_connect(struct connectdata *conn,
{
struct SessionHandle *data = conn->data;
SSL_CTX *ssl_ctx;
- SSL *ssl;
+ SSL *ssl = NULL;
int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
int i, ssl_fcn_return;
@@ -192,6 +202,7 @@ Curl_axtls_connect(struct connectdata *conn,
data->set.ssl.CAfile);
if(data->set.ssl.verifypeer) {
Curl_axtls_close(conn, sockindex);
+ free_ssl_structs(ssl_ctx, ssl);
return CURLE_SSL_CACERT_BADFILE;
}
}
@@ -226,6 +237,7 @@ Curl_axtls_connect(struct connectdata *conn,
failf(data, "%s is not x509 or pkcs12 format",
data->set.str[STRING_CERT]);
Curl_axtls_close(conn, sockindex);
+ free_ssl_structs(ssl_ctx, ssl);
return CURLE_SSL_CERTPROBLEM;
}
}
@@ -251,6 +263,7 @@ Curl_axtls_connect(struct connectdata *conn,
failf(data, "Failure: %s is not a supported key file",
data->set.str[STRING_KEY]);
Curl_axtls_close(conn, sockindex);
+ free_ssl_structs(ssl_ctx, ssl);
return CURLE_SSL_CONNECT_ERROR;
}
}
@@ -275,6 +288,7 @@ Curl_axtls_connect(struct connectdata *conn,
ssl_fcn_return = ssl_handshake_status(ssl);
if(ssl_fcn_return != SSL_OK) {
Curl_axtls_close(conn, sockindex);
+ free_ssl_structs(ssl_ctx, ssl);
ssl_display_error(ssl_fcn_return); /* goes to stdout. */
return map_error_to_curl(ssl_fcn_return);
}
@@ -288,6 +302,7 @@ Curl_axtls_connect(struct connectdata *conn,
if(data->set.ssl.verifypeer) {
if(ssl_verify_cert(ssl) != SSL_OK) {
Curl_axtls_close(conn, sockindex);
+ free_ssl_structs(ssl_ctx, ssl);
failf(data, "server cert verify failed");
return CURLE_SSL_CONNECT_ERROR;
}
@@ -328,6 +343,7 @@ Curl_axtls_connect(struct connectdata *conn,
if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
/* Break connection ! */
Curl_axtls_close(conn, sockindex);
+ free_ssl_structs(ssl_ctx, ssl);
failf(data, "\tsubjectAltName(s) do not match %s\n", conn->host.dispname);
return CURLE_PEER_FAILED_VERIFICATION;
}
@@ -338,6 +354,7 @@ Curl_axtls_connect(struct connectdata *conn,
if(peer_CN == NULL) {
/* Similar behaviour to the OpenSSL interface */
Curl_axtls_close(conn, sockindex);
+ free_ssl_structs(ssl_ctx, ssl);
failf(data, "unable to obtain common name from peer certificate");
return CURLE_PEER_FAILED_VERIFICATION;
}
@@ -346,6 +363,7 @@ Curl_axtls_connect(struct connectdata *conn,
if(data->set.ssl.verifyhost) {
/* Break connection ! */
Curl_axtls_close(conn, sockindex);
+ free_ssl_structs(ssl_ctx, ssl);
failf(data, "\tcommon name \"%s\" does not match \"%s\"\n",
peer_CN, conn->host.dispname);
return CURLE_PEER_FAILED_VERIFICATION;