From a6c2ba73d9b47d8c60fd9fca3a25ed54d8ff9b49 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20R=C3=BChsen?= <tim.ruehsen@gmx.de>
Date: Wed, 29 Oct 2014 16:36:18 +0100
Subject: [PATCH] fix memory leak in openssl.c

---
 src/ChangeLog | 10 ++++++++++
 src/openssl.c | 34 +++++++++++++++++++++++++++++-----
 2 files changed, 39 insertions(+), 5 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 58bf9054..22800359 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -3,6 +3,16 @@
 	* openssl.c (ssl_init) [! OPENSSL_NO_SSL3]: Add guard for OpenSSL
 	without SSLv3.
 
+2014-10-29  Tim Ruehsen  <tim.ruehsen@gmx.de>
+
+	* openssl.c: print cert subject and issuer RFC2253 compliant
+	* openssl.c (ssl_check_certificate): removed memory leak
+
+2014-10-28  Tim Ruehsen  <tim.ruehsen@gmx.de>
+
+	* utils.c: added strlcpy(), concat_strings() rewritten
+	* utils.h: added strlcpy()
+
 2014-10-28  Tim Ruehsen  <tim.ruehsen@gmx.de>
 
 	* ftp.c (ftp_loop_internal): Fix memory leak
diff --git a/src/openssl.c b/src/openssl.c
index 6f11650b..951ce0c6 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -40,6 +40,7 @@ as that of the covered work.  */
 #include <openssl/x509v3.h>
 #include <openssl/err.h>
 #include <openssl/rand.h>
+#include <openssl/bio.h>
 #if OPENSSL_VERSION_NUMBER >= 0x00907000
 #include <openssl/conf.h>
 #endif
@@ -572,6 +573,27 @@ pattern_match (const char *pattern, const char *string)
   return *n == '\0';
 }
 
+char *_get_rfc2253_formatted (X509_NAME *name)
+{
+  int len;
+  char *out = NULL;
+  BIO* b;
+
+  if ((b = BIO_new (BIO_s_mem ())))
+    {
+      if (X509_NAME_print_ex (b, name, 0, XN_FLAG_RFC2253) >= 0
+          && (len = BIO_number_written (b)) > 0)
+        {
+          out = xmalloc (len + 1);
+          BIO_read (b, out, len);
+          out[len] = 0;
+        }
+      BIO_free (b);
+    }
+
+  return out ? out : xstrdup("");
+}
+
 /* Verify the validity of the certificate presented by the server.
    Also check that the "common name" of the server, as presented by
    its certificate, corresponds to HOST.  (HOST typically comes from
@@ -615,23 +637,25 @@ ssl_check_certificate (int fd, const char *host)
 
   IF_DEBUG
     {
-      char *subject = X509_NAME_oneline (X509_get_subject_name (cert), 0, 0);
-      char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0);
+      char *subject = _get_rfc2253_formatted (X509_get_subject_name (cert));
+      char *issuer = _get_rfc2253_formatted (X509_get_issuer_name (cert));
       DEBUGP (("certificate:\n  subject: %s\n  issuer:  %s\n",
                quotearg_n_style (0, escape_quoting_style, subject),
                quotearg_n_style (1, escape_quoting_style, issuer)));
-      OPENSSL_free (subject);
-      OPENSSL_free (issuer);
+      xfree (subject);
+      xfree (issuer);
     }
 
   vresult = SSL_get_verify_result (conn);
   if (vresult != X509_V_OK)
     {
-      char *issuer = X509_NAME_oneline (X509_get_issuer_name (cert), 0, 0);
+      char *issuer = _get_rfc2253_formatted (X509_get_issuer_name (cert));
       logprintf (LOG_NOTQUIET,
                  _("%s: cannot verify %s's certificate, issued by %s:\n"),
                  severity, quotearg_n_style (0, escape_quoting_style, host),
                  quote_n (1, issuer));
+      xfree(issuer);
+
       /* Try to print more user-friendly (and translated) messages for
          the frequent verification errors.  */
       switch (vresult)