# HG changeset patch # User Andre Heinecke # Date 1397135334 -7200 # Node ID a49766196a7dcf6a0d6d69d2369b9ad316db6112 # Parent e6aa82466420bca445aa918e2e5512879a27bfb3 Add certificateFromFile method Currently untested diff -r e6aa82466420 -r a49766196a7d ui/certificate.cpp --- a/ui/certificate.cpp Thu Apr 10 14:14:56 2014 +0200 +++ b/ui/certificate.cpp Thu Apr 10 15:08:54 2014 +0200 @@ -1,9 +1,11 @@ #include "certificate.h" #include +#include #include #include #include "certhelp.h" +#include "listutil.h" /* Qt wrapper around certhelp functions. */ QString getX509Value(x509_name *namebuf, unsigned char *oid) { @@ -62,6 +64,20 @@ .arg(QLocale::system().toString(mValidTo)); } +Certificate::Certificate(const QByteArray& derData) : + mValid(false) +{ + if (derData.isEmpty()) { + return; + } + + parseDetails(derData); + + mValid = !mSubjectCN.isEmpty(); + + mBaseLine = derData.toBase64(); +} + Certificate::Certificate(const QString& b64Line) : mValid(false) { @@ -70,10 +86,10 @@ } /* Cut of the first two chars (e.g. I: and decode) */ - QByteArray asn1data = QByteArray::fromBase64( + QByteArray derData = QByteArray::fromBase64( b64Line.right(b64Line.size() - 2).toLatin1()); - parseDetails(asn1data); + parseDetails(derData); /* If the subject CN is set then at least one x509parse * in polarssl was successfull. And a root certificate @@ -97,3 +113,54 @@ } return ret; } + +QList 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 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(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(iter->raw.p), + static_cast(iter->raw.len)); + retval << Certificate(derData); + iter = iter->next; + } + x509_crt_free(&chain); + + return retval; +} diff -r e6aa82466420 -r a49766196a7d ui/certificate.h --- a/ui/certificate.h Thu Apr 10 14:14:56 2014 +0200 +++ b/ui/certificate.h Thu Apr 10 15:08:54 2014 +0200 @@ -36,6 +36,12 @@ **/ Certificate(const QString& b64Line = QString()); + /** @brief construct a certificate from a byte array of DER data + * + * @param[in] derData a der encoded certificate. + **/ + Certificate(const QByteArray& derData); + /** @brief check if this certificate could be parsed */ bool isValid() const {return mValid;} @@ -88,6 +94,18 @@ /** @brief get the date the certificate expires */ QDateTime validTo() const {return mValidTo;} + /** @brief construct certificate objects from a file + * + * Constructs a new Certificate Object from a file containing either + * one DER encoded certificate or one or many PEM certificates. + * If no certificate could be parsed from that file an empty list is + * returned. + * + * The size restrictions for the certificate list file also apply + * for this file. + **/ + static QList fromFileName (const QString& file_name); + private: /** @brief Helper function to parse the details of a certificate **/ void parseDetails(const QByteArray& cert);