summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2017-12-23 10:55:13 +0000
committerGitHub <noreply@github.com>2017-12-23 10:55:13 +0000
commit9f7ad3c5d34d35a5ec2f34fa9cd8c92eff439329 (patch)
tree9877e032979e1e47dc1f29dfc277bcd6efc7416e
parent30d9176013cbaaced4b94f11717d259909bb8f81 (diff)
parent8be2a79099e636a05ddbc2a2f923afc27ca1e019 (diff)
downloadlibgit2-9f7ad3c5d34d35a5ec2f34fa9cd8c92eff439329.tar.gz
Merge pull request #4430 from tiennou/fix/openssl-x509-leak
Free OpenSSL peer certificate
-rw-r--r--src/streams/openssl.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/src/streams/openssl.c b/src/streams/openssl.c
index 2b246002f..9d566074c 100644
--- a/src/streams/openssl.c
+++ b/src/streams/openssl.c
@@ -332,7 +332,7 @@ static int check_host_name(const char *name, const char *host)
static int verify_server_cert(SSL *ssl, const char *host)
{
- X509 *cert;
+ X509 *cert = NULL;
X509_NAME *peer_name;
ASN1_STRING *str;
unsigned char *peer_cn = NULL;
@@ -341,7 +341,7 @@ static int verify_server_cert(SSL *ssl, const char *host)
struct in6_addr addr6;
struct in_addr addr4;
void *addr;
- int i = -1,j;
+ int i = -1, j, error = 0;
if (SSL_get_verify_result(ssl) != X509_V_OK) {
giterr_set(GITERR_SSL, "the SSL certificate is invalid");
@@ -362,8 +362,9 @@ static int verify_server_cert(SSL *ssl, const char *host)
cert = SSL_get_peer_certificate(ssl);
if (!cert) {
+ error = -1;
giterr_set(GITERR_SSL, "the server did not provide a certificate");
- return -1;
+ goto cleanup;
}
/* Check the alternative names */
@@ -401,8 +402,9 @@ static int verify_server_cert(SSL *ssl, const char *host)
if (matched == 0)
goto cert_fail_name;
- if (matched == 1)
- return 0;
+ if (matched == 1) {
+ goto cleanup;
+ }
/* If no alternative names are available, check the common name */
peer_name = X509_get_subject_name(cert);
@@ -444,18 +446,21 @@ static int verify_server_cert(SSL *ssl, const char *host)
if (check_host_name((char *)peer_cn, host) < 0)
goto cert_fail_name;
- OPENSSL_free(peer_cn);
+ goto cleanup;
- return 0;
+cert_fail_name:
+ error = GIT_ECERTIFICATE;
+ giterr_set(GITERR_SSL, "hostname does not match certificate");
+ goto cleanup;
on_error:
- OPENSSL_free(peer_cn);
- return ssl_set_error(ssl, 0);
+ error = ssl_set_error(ssl, 0);
+ goto cleanup;
-cert_fail_name:
+cleanup:
+ X509_free(cert);
OPENSSL_free(peer_cn);
- giterr_set(GITERR_SSL, "hostname does not match certificate");
- return GIT_ECERTIFICATE;
+ return error;
}
typedef struct {