Browse Source

Fix a reference-leak in tor_tls_received_v3_certificate

We were calling SSL_get_peer_certificate but not X509_free.

This is a major part of bug4252; the bug has been in no released version.
Nick Mathewson 14 years ago
parent
commit
87a93917c3
1 changed files with 20 additions and 10 deletions
  1. 20 10
      src/common/tortls.c

+ 20 - 10
src/common/tortls.c

@@ -2229,33 +2229,43 @@ int
 tor_tls_received_v3_certificate(tor_tls_t *tls)
 tor_tls_received_v3_certificate(tor_tls_t *tls)
 {
 {
   X509 *cert = SSL_get_peer_certificate(tls->ssl);
   X509 *cert = SSL_get_peer_certificate(tls->ssl);
-  EVP_PKEY *key;
+  EVP_PKEY *key = NULL;
   X509_NAME *issuer_name, *subject_name;
   X509_NAME *issuer_name, *subject_name;
+  int is_v3 = 0;
 
 
   if (!cert) {
   if (!cert) {
     log_warn(LD_BUG, "Called on a connection with no peer certificate");
     log_warn(LD_BUG, "Called on a connection with no peer certificate");
-    return 0;
+    goto done;
   }
   }
 
 
   subject_name = X509_get_subject_name(cert);
   subject_name = X509_get_subject_name(cert);
   issuer_name = X509_get_issuer_name(cert);
   issuer_name = X509_get_issuer_name(cert);
 
 
-  if (X509_name_cmp(subject_name, issuer_name) == 0)
-    return 1; /* purportedly self signed */
+  if (X509_name_cmp(subject_name, issuer_name) == 0) {
+    is_v3 = 1; /* purportedly self signed */
+    goto done;
+  }
 
 
   if (dn_indicates_v3_cert(subject_name) ||
   if (dn_indicates_v3_cert(subject_name) ||
-      dn_indicates_v3_cert(issuer_name))
-    return 1; /* DN is fancy */
+      dn_indicates_v3_cert(issuer_name)) {
+    is_v3 = 1; /* DN is fancy */
+    goto done;
+  }
 
 
   key = X509_get_pubkey(cert);
   key = X509_get_pubkey(cert);
   if (EVP_PKEY_bits(key) != 1024 ||
   if (EVP_PKEY_bits(key) != 1024 ||
       EVP_PKEY_type(key->type) != EVP_PKEY_RSA) {
       EVP_PKEY_type(key->type) != EVP_PKEY_RSA) {
-    EVP_PKEY_free(key);
-    return 1; /* Key is fancy */
+    is_v3 = 1; /* Key is fancy */
+    goto done;
   }
   }
 
 
-  EVP_PKEY_free(key);
-  return 0;
+ done:
+  if (key)
+    EVP_PKEY_free(key);
+  if (cert)
+    X509_free(cert);
+
+  return is_v3;
 }
 }
 
 
 /** Return the number of server handshakes that we've noticed doing on
 /** Return the number of server handshakes that we've noticed doing on