Skip to content

Commit 9f7ad3c

Browse files
authored
Merge pull request libgit2#4430 from tiennou/fix/openssl-x509-leak
Free OpenSSL peer certificate
2 parents 30d9176 + 8be2a79 commit 9f7ad3c

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

src/streams/openssl.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ static int check_host_name(const char *name, const char *host)
332332

333333
static int verify_server_cert(SSL *ssl, const char *host)
334334
{
335-
X509 *cert;
335+
X509 *cert = NULL;
336336
X509_NAME *peer_name;
337337
ASN1_STRING *str;
338338
unsigned char *peer_cn = NULL;
@@ -341,7 +341,7 @@ static int verify_server_cert(SSL *ssl, const char *host)
341341
struct in6_addr addr6;
342342
struct in_addr addr4;
343343
void *addr;
344-
int i = -1,j;
344+
int i = -1, j, error = 0;
345345

346346
if (SSL_get_verify_result(ssl) != X509_V_OK) {
347347
giterr_set(GITERR_SSL, "the SSL certificate is invalid");
@@ -362,8 +362,9 @@ static int verify_server_cert(SSL *ssl, const char *host)
362362

363363
cert = SSL_get_peer_certificate(ssl);
364364
if (!cert) {
365+
error = -1;
365366
giterr_set(GITERR_SSL, "the server did not provide a certificate");
366-
return -1;
367+
goto cleanup;
367368
}
368369

369370
/* Check the alternative names */
@@ -401,8 +402,9 @@ static int verify_server_cert(SSL *ssl, const char *host)
401402
if (matched == 0)
402403
goto cert_fail_name;
403404

404-
if (matched == 1)
405-
return 0;
405+
if (matched == 1) {
406+
goto cleanup;
407+
}
406408

407409
/* If no alternative names are available, check the common name */
408410
peer_name = X509_get_subject_name(cert);
@@ -444,18 +446,21 @@ static int verify_server_cert(SSL *ssl, const char *host)
444446
if (check_host_name((char *)peer_cn, host) < 0)
445447
goto cert_fail_name;
446448

447-
OPENSSL_free(peer_cn);
449+
goto cleanup;
448450

449-
return 0;
451+
cert_fail_name:
452+
error = GIT_ECERTIFICATE;
453+
giterr_set(GITERR_SSL, "hostname does not match certificate");
454+
goto cleanup;
450455

451456
on_error:
452-
OPENSSL_free(peer_cn);
453-
return ssl_set_error(ssl, 0);
457+
error = ssl_set_error(ssl, 0);
458+
goto cleanup;
454459

455-
cert_fail_name:
460+
cleanup:
461+
X509_free(cert);
456462
OPENSSL_free(peer_cn);
457-
giterr_set(GITERR_SSL, "hostname does not match certificate");
458-
return GIT_ECERTIFICATE;
463+
return error;
459464
}
460465

461466
typedef struct {

0 commit comments

Comments
 (0)