Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'jb40089' into 'master'
Allow certificate model to decode in-memory PEMs

See merge request mer-core/nemo-qml-plugin-systemsettings!116
  • Loading branch information
llewelld committed Sep 24, 2019
2 parents 4bbaa50 + c2dc492 commit 14646e7
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 15 deletions.
67 changes: 56 additions & 11 deletions src/certificatemodel.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2016 Jolla Ltd.
* COntact: Matt Vogt <matthew.vogt@jollamobile.com>
* Copyright (c) 2016 - 2019 Jolla Ltd.
* Copyright (c) 2019 Open Mobile Platform LLC.
*
* You may use this file under the terms of the BSD license as follows:
*
Expand Down Expand Up @@ -426,9 +426,33 @@ struct PKCS7File
if (BIO_read_filename(input, const_cast<char *>(filename.constData())) <= 0) {
qWarning() << "Unable to open PKCS7 file:" << path;
} else {
read_pem_from_bio(input);
}

BIO_free(input);
}
}
}

explicit PKCS7File(const QByteArray &pem)
{
if (!isValid()) {
qWarning() << "Unable to prepare X509 certificates structure";
} else {
BIO *input = BIO_new_mem_buf(pem.constData(), pem.length());
if (!input) {
qWarning() << "Unable to allocate new BIO while importing in-memory PEM";
} else {
read_pem_from_bio(input);
BIO_free(input);
}
}
}

void read_pem_from_bio(BIO *input) {
STACK_OF(X509_INFO) *certificateStack = PEM_X509_INFO_read_bio(input, NULL, NULL, NULL);
if (!certificateStack) {
qWarning() << "Unable to read PKCS7 file:" << path;
qWarning() << "Unable to read PKCS7 data";
} else {
while (sk_X509_INFO_num(certificateStack)) {
X509_INFO *certificateInfo = sk_X509_INFO_shift(certificateStack);
Expand All @@ -443,11 +467,6 @@ struct PKCS7File
}
}

BIO_free(input);
}
}
}

~PKCS7File()
{
}
Expand Down Expand Up @@ -498,11 +517,17 @@ class LibCrypto
static Initializer init;

public:
static QList<Certificate> getCertificates(const QString &bundlePath)
template<class T>
static QList<Certificate> getCertificates(const T &bundleData)
{
QList<Certificate> certificates;
PKCS7File bundle(bundleData);

PKCS7File bundle(bundlePath);
return bundleToCertificates(bundle);
}
private:
static QList<Certificate> bundleToCertificates(PKCS7File &bundle)
{
QList<Certificate> certificates;
if (bundle.isValid() && bundle.count() > 0) {
certificates.reserve(bundle.count());
bundle.getCertificates().for_each([&certificates](const X509Certificate &cert) {
Expand All @@ -514,6 +539,7 @@ class LibCrypto
}
};


LibCrypto::Initializer LibCrypto::init;

const QList<QPair<QString, CertificateModel::BundleType> > &bundlePaths()
Expand Down Expand Up @@ -579,9 +605,24 @@ Certificate::Certificate(const X509Certificate &cert)
}
}

// Matches QSslCertificate::issuerDisplayName() introducd in Qt 5.12
// Returns a name that describes the issuer. It returns the CommonName if
// available, otherwise falls back to the Organization or the first
// OrganizationalUnitName.
m_issuerDisplayName = cert.issuerElement(NID_commonName);
if (m_issuerDisplayName.isEmpty()) {
m_issuerDisplayName = cert.issuerElement(NID_countryName);
}
if (m_issuerDisplayName.isEmpty()) {
m_issuerDisplayName = cert.issuerElement(NID_organizationName);
}

// Populate the details map
m_details.insert(QStringLiteral("Version"), QVariant(cert.version()));
m_details.insert(QStringLiteral("SerialNumber"), QVariant(cert.serialNumber()));
m_details.insert(QStringLiteral("SubjectDisplayName"), QVariant(m_primaryName));
m_details.insert(QStringLiteral("OrganizationName"), QVariant(m_organizationName));
m_details.insert(QStringLiteral("IssuerDisplayName"), QVariant(m_issuerDisplayName));

QVariantMap validity;
validity.insert(QStringLiteral("NotBefore"), QVariant(cert.notBefore()));
Expand Down Expand Up @@ -753,3 +794,7 @@ QList<Certificate> CertificateModel::getCertificates(const QString &bundlePath)
return LibCrypto::getCertificates(bundlePath);
}

QList<Certificate> CertificateModel::getCertificates(const QByteArray &pem)
{
return LibCrypto::getCertificates(pem);
}
13 changes: 9 additions & 4 deletions src/certificatemodel.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2016 Jolla Ltd.
* Contact: Matt Vogt <matthew.vogt@jollamobile.com>
* Copyright (c) 2016 - 2019 Jolla Ltd.
* Copyright (c) 2019 Open Mobile Platform LLC.
*
* You may use this file under the terms of the BSD license as follows:
*
Expand Down Expand Up @@ -38,7 +38,7 @@
#include <QList>
#include <QVariantMap>

#include <systemsettingsglobal.h>
#include "systemsettingsglobal.h"


struct X509Certificate;
Expand All @@ -60,6 +60,8 @@ class SYSTEMSETTINGS_EXPORT Certificate

QVariantMap details() const { return m_details; }

QString issuerDisplayName() const { return m_issuerDisplayName; }

private:
QString m_commonName;
QString m_countryName;
Expand All @@ -71,6 +73,8 @@ class SYSTEMSETTINGS_EXPORT Certificate
QDateTime m_notValidBefore;
QDateTime m_notValidAfter;

QString m_issuerDisplayName;

QVariantMap m_details;
};

Expand Down Expand Up @@ -115,8 +119,9 @@ class SYSTEMSETTINGS_EXPORT CertificateModel: public QAbstractListModel
virtual QVariant data(const QModelIndex &index, int role) const;

static QList<Certificate> getCertificates(const QString &bundlePath);
static QList<Certificate> getCertificates(const QByteArray &pem);

signals:
Q_SIGNALS:
void bundleTypeChanged();
void bundlePathChanged();

Expand Down

0 comments on commit 14646e7

Please sign in to comment.