Skip to content
This repository was archived by the owner on Apr 28, 2022. It is now read-only.

Commit 14646e7

Browse files
committed
Merge branch 'jb40089' into 'master'
Allow certificate model to decode in-memory PEMs See merge request mer-core/nemo-qml-plugin-systemsettings!116
2 parents 4bbaa50 + c2dc492 commit 14646e7

File tree

2 files changed

+74
-24
lines changed

2 files changed

+74
-24
lines changed

src/certificatemodel.cpp

Lines changed: 65 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (C) 2016 Jolla Ltd.
3-
* COntact: Matt Vogt <[email protected]>
2+
* Copyright (c) 2016 - 2019 Jolla Ltd.
3+
* Copyright (c) 2019 Open Mobile Platform LLC.
44
*
55
* You may use this file under the terms of the BSD license as follows:
66
*
@@ -426,28 +426,47 @@ struct PKCS7File
426426
if (BIO_read_filename(input, const_cast<char *>(filename.constData())) <= 0) {
427427
qWarning() << "Unable to open PKCS7 file:" << path;
428428
} else {
429-
STACK_OF(X509_INFO) *certificateStack = PEM_X509_INFO_read_bio(input, NULL, NULL, NULL);
430-
if (!certificateStack) {
431-
qWarning() << "Unable to read PKCS7 file:" << path;
432-
} else {
433-
while (sk_X509_INFO_num(certificateStack)) {
434-
X509_INFO *certificateInfo = sk_X509_INFO_shift(certificateStack);
435-
if (certificateInfo->x509 != NULL) {
436-
certs.append(certificateInfo->x509);
437-
certificateInfo->x509 = NULL;
438-
}
439-
X509_INFO_free(certificateInfo);
440-
}
441-
442-
sk_X509_INFO_free(certificateStack);
443-
}
429+
read_pem_from_bio(input);
444430
}
445431

446432
BIO_free(input);
447433
}
448434
}
449435
}
450436

437+
explicit PKCS7File(const QByteArray &pem)
438+
{
439+
if (!isValid()) {
440+
qWarning() << "Unable to prepare X509 certificates structure";
441+
} else {
442+
BIO *input = BIO_new_mem_buf(pem.constData(), pem.length());
443+
if (!input) {
444+
qWarning() << "Unable to allocate new BIO while importing in-memory PEM";
445+
} else {
446+
read_pem_from_bio(input);
447+
BIO_free(input);
448+
}
449+
}
450+
}
451+
452+
void read_pem_from_bio(BIO *input) {
453+
STACK_OF(X509_INFO) *certificateStack = PEM_X509_INFO_read_bio(input, NULL, NULL, NULL);
454+
if (!certificateStack) {
455+
qWarning() << "Unable to read PKCS7 data";
456+
} else {
457+
while (sk_X509_INFO_num(certificateStack)) {
458+
X509_INFO *certificateInfo = sk_X509_INFO_shift(certificateStack);
459+
if (certificateInfo->x509 != NULL) {
460+
certs.append(certificateInfo->x509);
461+
certificateInfo->x509 = NULL;
462+
}
463+
X509_INFO_free(certificateInfo);
464+
}
465+
466+
sk_X509_INFO_free(certificateStack);
467+
}
468+
}
469+
451470
~PKCS7File()
452471
{
453472
}
@@ -498,11 +517,17 @@ class LibCrypto
498517
static Initializer init;
499518

500519
public:
501-
static QList<Certificate> getCertificates(const QString &bundlePath)
520+
template<class T>
521+
static QList<Certificate> getCertificates(const T &bundleData)
502522
{
503-
QList<Certificate> certificates;
523+
PKCS7File bundle(bundleData);
504524

505-
PKCS7File bundle(bundlePath);
525+
return bundleToCertificates(bundle);
526+
}
527+
private:
528+
static QList<Certificate> bundleToCertificates(PKCS7File &bundle)
529+
{
530+
QList<Certificate> certificates;
506531
if (bundle.isValid() && bundle.count() > 0) {
507532
certificates.reserve(bundle.count());
508533
bundle.getCertificates().for_each([&certificates](const X509Certificate &cert) {
@@ -514,6 +539,7 @@ class LibCrypto
514539
}
515540
};
516541

542+
517543
LibCrypto::Initializer LibCrypto::init;
518544

519545
const QList<QPair<QString, CertificateModel::BundleType> > &bundlePaths()
@@ -579,9 +605,24 @@ Certificate::Certificate(const X509Certificate &cert)
579605
}
580606
}
581607

608+
// Matches QSslCertificate::issuerDisplayName() introducd in Qt 5.12
609+
// Returns a name that describes the issuer. It returns the CommonName if
610+
// available, otherwise falls back to the Organization or the first
611+
// OrganizationalUnitName.
612+
m_issuerDisplayName = cert.issuerElement(NID_commonName);
613+
if (m_issuerDisplayName.isEmpty()) {
614+
m_issuerDisplayName = cert.issuerElement(NID_countryName);
615+
}
616+
if (m_issuerDisplayName.isEmpty()) {
617+
m_issuerDisplayName = cert.issuerElement(NID_organizationName);
618+
}
619+
582620
// Populate the details map
583621
m_details.insert(QStringLiteral("Version"), QVariant(cert.version()));
584622
m_details.insert(QStringLiteral("SerialNumber"), QVariant(cert.serialNumber()));
623+
m_details.insert(QStringLiteral("SubjectDisplayName"), QVariant(m_primaryName));
624+
m_details.insert(QStringLiteral("OrganizationName"), QVariant(m_organizationName));
625+
m_details.insert(QStringLiteral("IssuerDisplayName"), QVariant(m_issuerDisplayName));
585626

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

797+
QList<Certificate> CertificateModel::getCertificates(const QByteArray &pem)
798+
{
799+
return LibCrypto::getCertificates(pem);
800+
}

src/certificatemodel.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (C) 2016 Jolla Ltd.
3-
* Contact: Matt Vogt <[email protected]>
2+
* Copyright (c) 2016 - 2019 Jolla Ltd.
3+
* Copyright (c) 2019 Open Mobile Platform LLC.
44
*
55
* You may use this file under the terms of the BSD license as follows:
66
*
@@ -38,7 +38,7 @@
3838
#include <QList>
3939
#include <QVariantMap>
4040

41-
#include <systemsettingsglobal.h>
41+
#include "systemsettingsglobal.h"
4242

4343

4444
struct X509Certificate;
@@ -60,6 +60,8 @@ class SYSTEMSETTINGS_EXPORT Certificate
6060

6161
QVariantMap details() const { return m_details; }
6262

63+
QString issuerDisplayName() const { return m_issuerDisplayName; }
64+
6365
private:
6466
QString m_commonName;
6567
QString m_countryName;
@@ -71,6 +73,8 @@ class SYSTEMSETTINGS_EXPORT Certificate
7173
QDateTime m_notValidBefore;
7274
QDateTime m_notValidAfter;
7375

76+
QString m_issuerDisplayName;
77+
7478
QVariantMap m_details;
7579
};
7680

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

117121
static QList<Certificate> getCertificates(const QString &bundlePath);
122+
static QList<Certificate> getCertificates(const QByteArray &pem);
118123

119-
signals:
124+
Q_SIGNALS:
120125
void bundleTypeChanged();
121126
void bundlePathChanged();
122127

0 commit comments

Comments
 (0)