Commit 2518eb81a2de64996362249a22995bd84fb68c49

Etienne Samson 2017-11-24T14:04:10

openssl: merge all the exit paths of verify_server_cert This makes it easier to cleanup allocated resources on exit.

diff --git a/src/streams/openssl.c b/src/streams/openssl.c
index 2b24600..49a551b 100644
--- a/src/streams/openssl.c
+++ b/src/streams/openssl.c
@@ -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,20 @@ 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:
 	OPENSSL_free(peer_cn);
-	giterr_set(GITERR_SSL, "hostname does not match certificate");
-	return GIT_ECERTIFICATE;
+	return error;
 }
 
 typedef struct {