[pan2: 195/268] added further details to certification info dialog



commit af30a8b4f1fa6608700900530feda46fbfda038e
Author: Heinrich MÃller <sphemuel stud informatik uni-erlangen de>
Date:   Thu Nov 10 16:06:31 2011 +0100

    added further details to certification info dialog

 pan/gui/gui.cc                |    3 +-
 pan/gui/server-ui.cc          |    7 +-
 pan/tasks/cert-store.cc       |  191 ----------------------------
 pan/tasks/cert-store.h        |    1 -
 pan/usenet-utils/mime-utils.h |    3 -
 pan/usenet-utils/ssl-utils.h  |  281 ++++++++++++++++++++++++++++++++++++++++-
 6 files changed, 288 insertions(+), 198 deletions(-)
---
diff --git a/pan/gui/gui.cc b/pan/gui/gui.cc
index 1916fae..7e02629 100644
--- a/pan/gui/gui.cc
+++ b/pan/gui/gui.cc
@@ -35,6 +35,7 @@ extern "C" {
 #include <pan/general/macros.h>
 #include <pan/usenet-utils/scorefile.h>
 #include <pan/usenet-utils/mime-utils.h>
+#include <pan/usenet-utils/ssl-utils.h>
 #include <pan/tasks/task-article.h>
 #include <pan/tasks/task-groups.h>
 #include <pan/tasks/task-xover.h>
@@ -1309,7 +1310,7 @@ bool GUI :: confirm_accept_new_cert_dialog(GtkWindow * parent, X509* cert, const
   bool ret(false);
 
   char buf[4096];
-  CertStore::pretty_print_x509(buf,sizeof(buf), server, cert);
+  pretty_print_x509(buf,sizeof(buf), server, cert,true);
   gdk_threads_enter();
     GtkWidget * d = gtk_message_dialog_new (
       parent,
diff --git a/pan/gui/server-ui.cc b/pan/gui/server-ui.cc
index 8d2bd47..8d7cb02 100644
--- a/pan/gui/server-ui.cc
+++ b/pan/gui/server-ui.cc
@@ -32,12 +32,14 @@ extern "C" {
 #include <pan/general/macros.h>
 #include <pan/general/quark.h>
 #include <pan/data/data.h>
+#include <pan/usenet-utils/ssl-utils.h>
 #include "server-ui.h"
 #include "pad.h"
 #include "hig.h"
 #include "gtk_compat.h"
 
 #ifdef HAVE_OPENSSL
+
   #include <pan/tasks/cert-store.h>
   #include <openssl/crypto.h>
   #include <openssl/x509.h>
@@ -656,13 +658,16 @@ namespace
       X509* cert = (X509*)d->queue.store().get_cert_to_server(addr);
       if (cert)
       {
-        CertStore::pretty_print_x509(buf,sizeof(buf),addr, cert);
+        pretty_print_x509(buf,sizeof(buf),addr, cert,false);
         if (!buf) g_snprintf(buf,sizeof(buf), "%s", _("No information available.")) ;
         GtkWidget * w = gtk_message_dialog_new_with_markup (
         0,
         GTK_DIALOG_MODAL,
         GTK_MESSAGE_INFO,
         GTK_BUTTONS_CLOSE, buf);
+//        g_snprintf(buf,sizeof(buf), _("Server Certificate for <b>'%s'</b>"), addr.c_str());
+//        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG(w), "%s", buf);
+//        gtk_window_set_title(GTK_WINDOW(w), buf);
         gtk_widget_show_all (w);
         g_signal_connect_swapped (w, "response", G_CALLBACK (gtk_widget_destroy), w);
       }
diff --git a/pan/tasks/cert-store.cc b/pan/tasks/cert-store.cc
index 7fa13d9..8baf2d2 100644
--- a/pan/tasks/cert-store.cc
+++ b/pan/tasks/cert-store.cc
@@ -213,197 +213,6 @@ CertStore :: get_cert_to_server(const Quark& server) const
   return ret;
 }
 
-namespace
-{
-  std::string
-  get_x509_fingerpint_md5(X509* cert)
-  {
-    std::string res;
-    unsigned char md[EVP_MAX_MD_SIZE];
-    unsigned int n;
-
-    if (! X509_digest(cert, EVP_md5(), md, &n))
-			res = _("Not available.");
-		else {
-			char hex[] = "0123456789ABCDEF";
-			char fp[EVP_MAX_MD_SIZE*3];
-			if (n < sizeof(fp)) {
-				unsigned int i;
-				for (i = 0; i < n; i++) {
-					fp[i*3+0] = hex[(md[i] >> 4) & 0xF];
-					fp[i*3+1] = hex[(md[i] >> 0) & 0xF];
-					fp[i*3+2] = i == n - 1 ? '\0' : ':';
-				}
-				res = fp;
-			}
-		}
-    return res;
-  }
-
-  std::string
-  get_x509_enddate(X509* cert)
-  {
-    std::string res;
-
-    return res;
-  }
-
-}
-
-time_t
-getTimeFromASN1(const ASN1_TIME * aTime)
-{
-  time_t lResult = 0;
-
-
-  char lBuffer[24];
-  char * pBuffer = lBuffer;
-
-
-  size_t lTimeLength = aTime->length;
-  char * pString = (char *)aTime->data;
-
-
-  if (aTime->type == V_ASN1_UTCTIME)
-  {
-    if ((lTimeLength < 11) || (lTimeLength > 17))
-    {
-      return 0;
-    }
-
-
-    memcpy(pBuffer, pString, 10);
-    pBuffer += 10;
-    pString += 10;
-  }
-  else
-  {
-    if (lTimeLength < 13)
-    {
-      return 0;
-    }
-
-
-    memcpy(pBuffer, pString, 12);
-    pBuffer += 12;
-    pString += 12;
-  }
-
-
-  if ((*pString == 'Z') || (*pString == '-') || (*pString == '+'))
-  {
-    *(pBuffer++) = '0';
-    *(pBuffer++) = '0';
-  }
-  else
-  {
-    *(pBuffer++) = *(pString++);
-    *(pBuffer++) = *(pString++);
-    // Skip any fractional seconds...
-    if (*pString == '.')
-    {
-      pString++;
-      while ((*pString >= '0') && (*pString <= '9'))
-      {
-        pString++;
-      }
-    }
-  }
-
-
-  *(pBuffer++) = 'Z';
-  *(pBuffer++) = '\0';
-
-
-  time_t lSecondsFromUCT;
-  if (*pString == 'Z')
-  {
-    lSecondsFromUCT = 0;
-  }
-  else
-  {
-    if ((*pString != '+') && (pString[5] != '-'))
-    {
-      return 0;
-    }
-
-
-    lSecondsFromUCT = ((pString[1]-'0') * 10 + (pString[2]-'0')) * 60;
-    lSecondsFromUCT += (pString[3]-'0') * 10 + (pString[4]-'0');
-    if (*pString == '-')
-    {
-      lSecondsFromUCT = -lSecondsFromUCT;
-    }
-  }
-
-
-  tm lTime;
-  lTime.tm_sec  = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0');
-  lTime.tm_min  = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0');
-  lTime.tm_hour = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0');
-  lTime.tm_mday = ((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0');
-  lTime.tm_mon  = (((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0')) - 1;
-  lTime.tm_year = ((lBuffer[0] - '0') * 10) + (lBuffer[1] - '0');
-  if (lTime.tm_year < 50)
-  {
-    lTime.tm_year += 100; // RFC 2459
-  }
-  lTime.tm_wday = 0;
-  lTime.tm_yday = 0;
-  lTime.tm_isdst = 0;  // No DST adjustment requested
-
-  lResult = mktime(&lTime);
-
-  if ((time_t)-1 != lResult)
-  {
-    if (0 != lTime.tm_isdst)
-      lResult -= 3600; // mktime may adjust for DST (OS dependent)
-    lResult += lSecondsFromUCT;
-  }
-  else
-    lResult = 0;
-
-  return lResult;
-}
-
-void
-CertStore :: pretty_print_x509 (char* buf, size_t size, const Quark& server, X509* cert)
-{
-  if (!cert) return;
-//  char buffer[4096];
-//  int len;
-//  int i = X509_get_ext_by_NID(cert, NID_invalidity_date, -1);
-//  BIO *bio = BIO_new(BIO_s_mem());
-//  X509_EXTENSION * ex = X509_get_ext( cert,i);
-//  std::cerr<<"pretty "<<i<<" "<<ex<<" "<<bio<<std::endl;
-//  if(!X509V3_EXT_print(bio, ex, 0, 0))
-//    M_ASN1_OCTET_STRING_print(bio,ex->value);
-//  len = BIO_read(bio, buffer, 4096);
-//  buffer[len] = '\0';
-//  BIO_free(bio);
-
-  time_t t = getTimeFromASN1(cert->cert_info->validity->notAfter);
-  time_t t2 = getTimeFromASN1(cert->cert_info->validity->notBefore);
-  EvolutionDateMaker date_maker;
-  char * until = date_maker.get_date_string (t);
-  char * before = date_maker.get_date_string (t2);
-
-  g_snprintf(buf,size, _("The current server <b>'%s'</b> sent this security certificate :\n\n"
-                              "<b>Issuer :</b>\n%s\n\n"
-                              "<b>Subject : </b>\n%s\n\n"
-                              "<b>Valid until : </b>%s\n\n"
-                              "<b>Not valid before : </b>%s\n\n"
-                              "<b>Fingerprint (MD5) : </b>\n%s\n\n"),
-                              server.c_str(),
-                              X509_NAME_oneline(cert->cert_info->issuer, 0, 0),
-                              X509_NAME_oneline(cert->cert_info->subject, 0, 0),
-                              until,
-                              before,
-                              get_x509_fingerpint_md5(cert).c_str());
-
-}
-
-
 
 }  // namespace pan
 
diff --git a/pan/tasks/cert-store.h b/pan/tasks/cert-store.h
index 3794acd..5d2149b 100644
--- a/pan/tasks/cert-store.h
+++ b/pan/tasks/cert-store.h
@@ -65,7 +65,6 @@ namespace pan
       X509_STORE* get_store() const { return _store; }
       int get_all_certs_from_disk(std::set<X509*>& setme);
       const X509* get_cert_to_server(const Quark& server) const;
-      static void pretty_print_x509 (char* buf, size_t size, const Quark& server, X509* cert);
       SSL_SESSION* get_session()
       {
         SSL_SESSION* ret(0);
diff --git a/pan/usenet-utils/mime-utils.h b/pan/usenet-utils/mime-utils.h
index 20aee85..fff1b47 100644
--- a/pan/usenet-utils/mime-utils.h
+++ b/pan/usenet-utils/mime-utils.h
@@ -55,9 +55,6 @@
 #define YENC_SHIFT             42
 #define YENC_QUOTE_SHIFT       64
 
-/* uudeview encoding defines */
-static int bpl[3] = { 45, 45, 128 };
-
 namespace pan
 {
   /**
diff --git a/pan/usenet-utils/ssl-utils.h b/pan/usenet-utils/ssl-utils.h
index d3ab163..f174796 100644
--- a/pan/usenet-utils/ssl-utils.h
+++ b/pan/usenet-utils/ssl-utils.h
@@ -28,6 +28,7 @@
 #ifdef HAVE_OPENSSL
 
 #include <pan/general/quark.h>
+#include <pan/general/e-util.h>
 #include <openssl/crypto.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
@@ -35,7 +36,8 @@
 #include <openssl/ssl.h>
 #include <openssl/err.h>
 #include <map>
-
+#include <iostream>
+#include <sstream>
 
 namespace pan
 {
@@ -271,6 +273,283 @@ namespace pan
     return ret;
   }
 
+  static time_t
+  getTimeFromASN1(const ASN1_TIME * aTime)
+  {
+    time_t lResult = 0;
+    char lBuffer[24];
+    char * pBuffer = lBuffer;
+    size_t lTimeLength = aTime->length;
+    char * pString = (char *)aTime->data;
+
+    if (aTime->type == V_ASN1_UTCTIME)
+    {
+      if ((lTimeLength < 11) || (lTimeLength > 17)) return 0;
+      memcpy(pBuffer, pString, 10);
+      pBuffer += 10;
+      pString += 10;
+    }
+    else
+    {
+      if (lTimeLength < 13) return 0;
+      memcpy(pBuffer, pString, 12);
+      pBuffer += 12;
+      pString += 12;
+    }
+
+
+    if ((*pString == 'Z') || (*pString == '-') || (*pString == '+'))
+    {
+      *(pBuffer++) = '0';
+      *(pBuffer++) = '0';
+    }
+    else
+    {
+      *(pBuffer++) = *(pString++);
+      *(pBuffer++) = *(pString++);
+      // Skip any fractional seconds...
+      if (*pString == '.')
+      {
+        pString++;
+        while ((*pString >= '0') && (*pString <= '9'))
+          pString++;
+      }
+    }
+
+    *(pBuffer++) = 'Z';
+    *(pBuffer++) = '\0';
+
+    time_t lSecondsFromUCT;
+    if (*pString == 'Z')
+      lSecondsFromUCT = 0;
+    else
+    {
+      if ((*pString != '+') && (pString[5] != '-')) return 0;
+      lSecondsFromUCT = ((pString[1]-'0') * 10 + (pString[2]-'0')) * 60;
+      lSecondsFromUCT += (pString[3]-'0') * 10 + (pString[4]-'0');
+      if (*pString == '-')
+        lSecondsFromUCT = -lSecondsFromUCT;
+    }
+
+    tm lTime;
+    lTime.tm_sec  = ((lBuffer[10] - '0') * 10) + (lBuffer[11] - '0');
+    lTime.tm_min  = ((lBuffer[8] - '0') * 10) + (lBuffer[9] - '0');
+    lTime.tm_hour = ((lBuffer[6] - '0') * 10) + (lBuffer[7] - '0');
+    lTime.tm_mday = ((lBuffer[4] - '0') * 10) + (lBuffer[5] - '0');
+    lTime.tm_mon  = (((lBuffer[2] - '0') * 10) + (lBuffer[3] - '0')) - 1;
+    lTime.tm_year = ((lBuffer[0] - '0') * 10) + (lBuffer[1] - '0');
+    if (lTime.tm_year < 50)
+      lTime.tm_year += 100; // RFC 2459
+    lTime.tm_wday = 0;
+    lTime.tm_yday = 0;
+    lTime.tm_isdst = 0;  // No DST adjustment requested
+
+    lResult = mktime(&lTime);
+
+    if ((time_t)-1 != lResult)
+    {
+      if (0 != lTime.tm_isdst)
+        lResult -= 3600; // mktime may adjust for DST (OS dependent)
+      lResult += lSecondsFromUCT;
+    }
+    else
+      lResult = 0;
+    return lResult;
+  }
+
+
+  static std::string
+  get_x509_fingerpint_md5(X509* cert)
+  {
+    std::string res;
+    unsigned char md[EVP_MAX_MD_SIZE];
+    unsigned int n;
+
+    if (! X509_digest(cert, EVP_md5(), md, &n))
+      res = _("Not available.");
+    else {
+      char hex[] = "0123456789ABCDEF";
+      char fp[EVP_MAX_MD_SIZE*3];
+      if (n < sizeof(fp)) {
+        unsigned int i;
+        for (i = 0; i < n; i++) {
+          fp[i*3+0] = hex[(md[i] >> 4) & 0xF];
+          fp[i*3+1] = hex[(md[i] >> 0) & 0xF];
+          fp[i*3+2] = i == n - 1 ? '\0' : ':';
+        }
+        res = fp;
+      }
+    }
+    return res;
+  }
+
+  typedef std::pair<Quark,Quark> quarks_p;
+  typedef std::map<Quark,Quark>::iterator tags_it;
+
+  const static char* tags_idx[] =
+  {
+    "/L=",
+    "/CN=",
+    "/C=",
+    "/OU=",
+    "/O=",
+    "/ST=",
+    "/EMAIL=",
+    "/emailAddress="
+  };
+
+  const static char* cleaned_tags[] =
+  {
+    "L", "CN", "C", "OU", "O", "ST", "EMAIL", "emailAdress"
+  };
+
+  struct CertParser
+  {
+    X509* cert;
+    std::map<Quark, Quark> tags;
+    char* issuer, * subject;
+    std::string iss, sub;
+    int pos1, pos2, tmp_pos1, idx;
+    char buf[256];
+    size_t num_tags;
+    const char delim;
+
+    CertParser(X509* c) : cert(c), delim('/'), pos1(0), pos2(0), idx(0), num_tags(G_N_ELEMENTS(tags_idx))
+    {
+      issuer  = X509_NAME_oneline(cert->cert_info->issuer,0,0);
+      subject = X509_NAME_oneline(cert->cert_info->subject, 0, 0);
+      iss = issuer;
+      sub = subject;
+      /* init map */
+      int i(0);
+      tags.insert(quarks_p(cleaned_tags[i++],"Locality"));
+      tags.insert(quarks_p(cleaned_tags[i++],"Common Name"));
+      tags.insert(quarks_p(cleaned_tags[i++],"Company"));
+      tags.insert(quarks_p(cleaned_tags[i++],"Organizational Unit"));
+      tags.insert(quarks_p(cleaned_tags[i++],"Organization"));
+      tags.insert(quarks_p(cleaned_tags[i++],"State"));
+      tags.insert(quarks_p(cleaned_tags[i++],"Email Address"));
+      tags.insert(quarks_p(cleaned_tags[i],"Email Address"));
+    }
+
+    void parse(std::vector<quarks_p>& i, std::vector<quarks_p>& s)
+    {
+
+      std::cerr<<iss<<"\n\n";
+
+      while(idx<num_tags)
+      {
+        std::string::size_type index = iss.find(tags_idx[idx]);
+        if(index != std::string::npos)
+        {
+          pos1 = (int)index + strlen(tags_idx[idx]);
+          pos2 = (int)iss.find(delim, pos1);
+          if (pos2<=0) goto _end;
+          if (!strcmp(cleaned_tags[idx],"CN"))
+          {
+            int tmp_pos = (int)iss.find("://",pos2-1);
+            if (tmp_pos == pos2-1)
+              pos2 = (int)iss.find(delim, pos2+2);
+          }
+          std::string tmp = iss.substr(pos1,pos2-pos1);
+          g_snprintf(buf, sizeof(buf), "%s (%s)", cleaned_tags[idx], tags[cleaned_tags[idx]].c_str() );
+          i.push_back(quarks_p(buf, tmp));
+        }
+        _end:
+          ++idx;
+      }
+
+      idx = 0;
+      std::cerr<<sub<<"\n\n";
+
+      while(idx<num_tags)
+      {
+        std::string::size_type index = sub.find(tags_idx[idx]);
+        if(index != std::string::npos)
+        {
+          pos1 = (int)index + strlen(tags_idx[idx]);
+          pos2 = (int)iss.find(delim, pos1);
+          if (pos2<=0) goto _end2;
+          if (!strcmp(cleaned_tags[idx],"CN"))
+          {
+            int tmp_pos = (int)iss.find("://",pos2-1);
+            if (tmp_pos == pos2-1)
+              pos2 = (int)iss.find(delim, pos2+2);
+          }
+          std::string tmp = sub.substr(pos1,pos2-pos1);
+          g_snprintf(buf, sizeof(buf), "%s(%s)", cleaned_tags[idx], tags[cleaned_tags[idx]].c_str() );
+          s.push_back(quarks_p(buf, tmp));
+        }
+        _end2:
+          ++idx;
+      }
+
+    }
+
+    std::string build_complete (std::vector<quarks_p>& v)
+    {
+      std::stringstream s;
+      for (int i=0;i<v.size(); ++i)
+      {
+        s << "\t<b>"<<v[i].first<<"</b> : "<<v[i].second<<"\n";
+      }
+      return s.str();
+    }
+
+    ~CertParser ()
+    {
+      free(issuer);
+      free(subject);
+    }
+  };
+
+
+  static void
+  pretty_print_x509 (char* buf, size_t size, const Quark& server, X509* cert, bool on_connect)
+  {
+
+    if (!cert)
+    {
+      g_snprintf(buf,size, _("Error printing the server certificate for '%s'"), server.c_str());
+      return;
+    }
+
+    struct CertParser* cp = new CertParser(cert);
+    std::vector<quarks_p> p_issuer, p_subject;
+    cp->parse(p_issuer, p_subject);
+
+
+    time_t t = getTimeFromASN1(cert->cert_info->validity->notAfter);
+    time_t t2 = getTimeFromASN1(cert->cert_info->validity->notBefore);
+    EvolutionDateMaker date_maker;
+    char * until = date_maker.get_date_string (t);
+    char * before = date_maker.get_date_string (t2);
+
+    char email1[2048], email2[2048];
+    char tmp1[2048], tmp2[2048];
+    g_snprintf(tmp1,sizeof(tmp1), "The current server <b>'%s'</b> sent this security certificate :\n\n", server.c_str());
+    g_snprintf(tmp2,sizeof(tmp2), "Certificate information for server <b>'%s'</b> :\n\n", server.c_str());
+
+    g_snprintf(buf,size, _(     "%s"
+                                "<b>Issuer information:</b>\n"
+                                "%s\n"
+                                "<b>Subject information: </b>\n"
+                                "%s\n"
+                                "<b>Valid until : </b>%s\n\n"
+                                "<b>Not valid before : </b>%s\n\n"
+                                "<b>Fingerprint (MD5) : </b>\n%s\n\n"),
+                                on_connect ? tmp1 : tmp2,
+                                cp->build_complete(p_issuer).c_str(),
+                                cp->build_complete(p_subject).c_str(),
+                                until,
+                                before,
+                                get_x509_fingerpint_md5(cert).c_str());
+
+    delete cp;
+
+  }
+
+
 }
 
 #endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]