diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2017-12-23 10:55:13 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-23 10:55:13 +0000 |
commit | 9f7ad3c5d34d35a5ec2f34fa9cd8c92eff439329 (patch) | |
tree | 9877e032979e1e47dc1f29dfc277bcd6efc7416e | |
parent | 30d9176013cbaaced4b94f11717d259909bb8f81 (diff) | |
parent | 8be2a79099e636a05ddbc2a2f923afc27ca1e019 (diff) | |
download | libgit2-9f7ad3c5d34d35a5ec2f34fa9cd8c92eff439329.tar.gz |
Merge pull request #4430 from tiennou/fix/openssl-x509-leak
Free OpenSSL peer certificate
-rw-r--r-- | src/streams/openssl.c | 29 |
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 { |