Mercurial > trustbridge
view ui/certificate.cpp @ 582:88c9bdc74175 trustbridge-refactor
New widgets to display certificates in lists.
author | Raimund Renkert <rrenkert@intevation.de> |
---|---|
date | Tue, 27 May 2014 16:16:21 +0200 |
parents | bf445b0e1126 |
children | 320a64d58e62 |
line wrap: on
line source
/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik * Software engineering by Intevation GmbH * * This file is Free Software under the GNU GPL (v>=2) * and comes with ABSOLUTELY NO WARRANTY! * See LICENSE.txt for details. */ #include "certificate.h" #include <QDebug> #include <QFile> #include <QStringList> #include <QObject> #include <polarssl/sha1.h> #include "certhelp.h" #include "listutil.h" /* 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); mIssuerCN = getX509Value(&(chain.issuer), CERT_OID_CN); mSubjectOU = getX509Value(&(chain.subject), CERT_OID_OU); mSubjectO = getX509Value(&(chain.subject), CERT_OID_O); mIssuerO = getX509Value(&(chain.issuer), CERT_OID_O); mSubjectSN = getX509Value(&(chain.subject), CERT_OID_SN); /* Calculate sha1 fingerprint */ unsigned char sha1sum[20]; sha1(chain.raw.p, chain.raw.len, sha1sum); for (int i=0; i < 20; i++) { mFingerprint += QString("%1").arg(sha1sum[i], 0, 16).rightJustified(2, '0'); if (i != 19) { mFingerprint += ":"; } mFingerprint = mFingerprint.toUpper(); } 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 QByteArray& derData) : mValid(false), mEditable(false) { if (derData.isEmpty()) { return; } parseDetails(derData); mValid = !mSubjectCN.isEmpty(); /* Default is installation for new certificates */ mBaseLine = QString::fromLatin1("I:") + derData.toBase64(); } Certificate::Certificate(const QString& b64Line) : mValid(false), mEditable(false) { if (b64Line.isEmpty()) { return; } /* Cut of the first two chars (e.g. I: and decode) */ QByteArray derData = QByteArray::fromBase64( b64Line.right(b64Line.size() - 2).toLatin1()); parseDetails(derData); /* 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::shortDescription() const { if (!isValid()) { return QObject::tr("Failed to parse certificate"); } QString ret = mSubjectCN; /* Necessary by definition */ /* if (!mSubjectO.isEmpty()) { ret += " - " + mSubjectO; } */ return ret; } QList<Certificate> Certificate::fromFileName(const QString& file_name) { /* We read the file using Qt to avoid filename encoding problems * on Windows */ /* TODO change qDebug errors into messageboxes */ QFile certificateFile(file_name); QByteArray fileContent; QList<Certificate> retval; x509_crt chain; int ret = 0; if (!certificateFile.open(QIODevice::ReadOnly)) { qDebug() << "Failed to read file."; return retval; } if (certificateFile.size() > MAX_LINE_LENGTH * MAX_LINES) { qDebug() << "File too large"; return retval; } fileContent = certificateFile.readAll(); x509_crt_init(&chain); ret = x509_crt_parse(&chain, reinterpret_cast<const unsigned char*>(fileContent.constData()), fileContent.size()); if (ret < 0) { qDebug() << "Failed to parse certificates."; return retval; } if (ret > 0) { qDebug() << "Some certificates could not be parsed."; /* Maybe return here? */ } x509_crt *iter = &chain; while (iter) { QByteArray derData(reinterpret_cast<const char*>(iter->raw.p), static_cast<int>(iter->raw.len)); retval << Certificate(derData); iter = iter->next; } x509_crt_free(&chain); return retval; } void Certificate::setInstallCert(bool install) { if (install && mBaseLine.startsWith("R:")) { mBaseLine.replace(0, 1, "I"); } else if (!install && mBaseLine.startsWith("I:")) { mBaseLine.replace(0, 1, "R"); } }