diff ui/certificate.cpp @ 338:64e38886f903

Use certhelp for certificate parsing and add some dummy info
author Andre Heinecke <aheinecke@intevation.de>
date Wed, 09 Apr 2014 14:26:53 +0000
parents 825b42da1855
children a49766196a7d b0a274f4f9e2
line wrap: on
line diff
--- a/ui/certificate.cpp	Wed Apr 09 14:25:54 2014 +0000
+++ b/ui/certificate.cpp	Wed Apr 09 14:26:53 2014 +0000
@@ -3,18 +3,68 @@
 #include <QStringList>
 #include <QObject>
 
-#include <polarssl/x509_crt.h>
+#include "certhelp.h"
 
-#define POLARSSL_INFO_BUF_SIZE 2000
+/* Qt wrapper around certhelp functions. */
+QString getX509Value(x509_name *namebuf, unsigned char *oid) {
+    QString retval;
+    char * buf = get_oid_valstr(namebuf, oid);
+    if (buf == NULL) {
+        return retval;
+    }
+    retval = QString::fromUtf8(buf, -1);
+    free(buf);
+    return retval;
+}
+
+void Certificate::parseDetails(const QByteArray& cert) {
+    x509_crt chain;
+
+    x509_crt_init(&chain);
+    if (x509_crt_parse_der(&chain, (const unsigned char *)cert.data(),
+                cert.size()) != 0) {
+        qDebug() << "Failed to parse cert..";
+        return;
+    }
+
+    mValidFrom = QDateTime(QDate(chain.valid_from.year,
+                                 chain.valid_from.mon,
+                                 chain.valid_from.day),
+                           QTime(chain.valid_from.hour,
+                                 chain.valid_from.min,
+                                 chain.valid_from.sec));
+
+    mValidTo = QDateTime(QDate(chain.valid_to.year,
+                               chain.valid_to.mon,
+                               chain.valid_to.day),
+                         QTime(chain.valid_to.hour,
+                               chain.valid_to.min,
+                               chain.valid_to.sec));
+
+    mSubjectCN = getX509Value(&(chain.subject), CERT_OID_CN);
+    mSubjectOU = getX509Value(&(chain.subject), CERT_OID_OU);
+    mSubjectO = getX509Value(&(chain.subject), CERT_OID_O);
+    mSubjectSN = getX509Value(&(chain.subject), CERT_OID_SN);
+    x509_crt_free(&chain);
+
+    mDetails = QObject::tr("Certificate:\n"
+            "    <bold>%1</bold>\n"
+            "    %2, %3\n\n"
+            "Serial number:\n"
+            "%4\n"
+            "Valid from: <bold>%5</bold> to <bold>%6</bold>\n\n"
+            "Issued by: ..")
+            .arg(mSubjectCN)
+            .arg(mSubjectO)
+            .arg(mSubjectOU)
+            .arg(mSubjectSN)
+            .arg(QLocale::system().toString(mValidFrom))
+            .arg(QLocale::system().toString(mValidTo));
+}
 
 Certificate::Certificate(const QString& b64Line) :
     mValid(false)
 {
-    int ret = -1;
-    char buf[POLARSSL_INFO_BUF_SIZE];
-
-    x509_crt x509cert;
-
     if (b64Line.isEmpty()) {
         return;
     }
@@ -23,66 +73,27 @@
     QByteArray asn1data = QByteArray::fromBase64(
             b64Line.right(b64Line.size() - 2).toLatin1());
 
-    x509_crt_init(&x509cert);
-    ret = x509_crt_parse(&x509cert,
-                         (const unsigned char*) asn1data.constData(),
-                         asn1data.size());
-    if (ret != 0) {
-        qDebug() << "Parsing certificate failed with error: " << ret;
-        qDebug() << "Failed cert: " << asn1data.toBase64();
-        x509_crt_free(&x509cert);
-        return;
-    }
-
-    /* Get a full details string */
-    ret = x509_crt_info(buf, POLARSSL_INFO_BUF_SIZE, "", &x509cert);
-
-    if (ret <= 0) {
-        qDebug() << "Getting certificate info failed with error: " << ret;
-        return;
-    }
-
-    /* In case of success the return value is the size of the information
-     * written into buf */
-    mDetails = QString::fromUtf8(buf, ret);
-
-    /* Get the subject */
-    ret = x509_dn_gets(buf, POLARSSL_INFO_BUF_SIZE, &(x509cert.subject));
+    parseDetails(asn1data);
 
-    if (ret <= 0) {
-        qDebug() << "Getting certificate subject failed with error: " << ret;
-        return;
-    }
-
-    /* TODO check that all asn encodings are handled */
-    QString subject = QString::fromUtf8(buf, ret);
-
-    /* TODO check that escaped , are not possible */
-    QStringList attrs = subject.split(", ");
-
-    foreach (const QString& attr, attrs) {
-        QStringList kv = attr.split("=");
-        if (kv.size() != 2) {
-            qDebug() << "Failed to parse subject element: " << attr;
-            continue;
-        }
-        mSubjectAttrs.insert(kv[0], kv[1]);
-    }
-
-    /* For more information to get from a x509_crt see
-     * https://polarssl.org/api/x509_8h.html */
-
-    x509_crt_free(&x509cert);
-
-    mValid = true;
+    /* If the subject CN is set then at least one x509parse
+     * in polarssl was successfull. And a root certificate
+     * always needs to have a subject CN */
+    mValid = !mSubjectCN.isEmpty();
 
     mBaseLine = b64Line;
 }
 
-QString Certificate::getSubjectAttr (const QString& attrName) const {
-    return mSubjectAttrs.value(attrName);
+QString Certificate::shortDescription() const {
+    if (!isValid()) {
+        return QObject::tr("Failed to parse certificate");
+    }
+
+    QString ret = mSubjectCN; /* Necessary by definition */
+    if (!mSubjectO.isEmpty()) {
+        ret += " - " + mSubjectO;
+    }
+    if (!mSubjectOU.isEmpty()) {
+        ret += ", " + mSubjectOU;
+    }
+    return ret;
 }
-
-QString Certificate::shortDescription() const {
-    return getSubjectAttr("CN");
-}

http://wald.intevation.org/projects/trustbridge/