Commit b43a9e66 by Patrick Steinhardt

streams: openssl: fix memleak due to us not free'ing certs

When creating a `git_cert` from the OpenSSL X509 certificate of a given
stream, we do not call `X509_free()` on the certificate, leading to a
memory leak as soon as the certificate is requested e.g. by the
certificate check callback.

Fix the issue by properly calling `X509_free()`.
parent 51a2bc43
...@@ -655,15 +655,16 @@ static int openssl_connect(git_stream *stream) ...@@ -655,15 +655,16 @@ static int openssl_connect(git_stream *stream)
static int openssl_certificate(git_cert **out, git_stream *stream) static int openssl_certificate(git_cert **out, git_stream *stream)
{ {
openssl_stream *st = (openssl_stream *) stream; openssl_stream *st = (openssl_stream *) stream;
int len;
X509 *cert = SSL_get_peer_certificate(st->ssl); X509 *cert = SSL_get_peer_certificate(st->ssl);
unsigned char *guard, *encoded_cert; unsigned char *guard, *encoded_cert = NULL;
int error, len;
/* Retrieve the length of the certificate first */ /* Retrieve the length of the certificate first */
len = i2d_X509(cert, NULL); len = i2d_X509(cert, NULL);
if (len < 0) { if (len < 0) {
git_error_set(GIT_ERROR_NET, "failed to retrieve certificate information"); git_error_set(GIT_ERROR_NET, "failed to retrieve certificate information");
return -1; error = -1;
goto out;
} }
encoded_cert = git__malloc(len); encoded_cert = git__malloc(len);
...@@ -673,18 +674,23 @@ static int openssl_certificate(git_cert **out, git_stream *stream) ...@@ -673,18 +674,23 @@ static int openssl_certificate(git_cert **out, git_stream *stream)
len = i2d_X509(cert, &guard); len = i2d_X509(cert, &guard);
if (len < 0) { if (len < 0) {
git__free(encoded_cert);
git_error_set(GIT_ERROR_NET, "failed to retrieve certificate information"); git_error_set(GIT_ERROR_NET, "failed to retrieve certificate information");
return -1; error = -1;
goto out;
} }
st->cert_info.parent.cert_type = GIT_CERT_X509; st->cert_info.parent.cert_type = GIT_CERT_X509;
st->cert_info.data = encoded_cert; st->cert_info.data = encoded_cert;
st->cert_info.len = len; st->cert_info.len = len;
encoded_cert = NULL;
*out = &st->cert_info.parent; *out = &st->cert_info.parent;
error = 0;
return 0; out:
git__free(encoded_cert);
X509_free(cert);
return error;
} }
static int openssl_set_proxy(git_stream *stream, const git_proxy_options *proxy_opts) static int openssl_set_proxy(git_stream *stream, const git_proxy_options *proxy_opts)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment