From 049007051ecfe880daaef9925c588d3e81bcff5e Mon Sep 17 00:00:00 2001 From: Chinmoy Ranjan Pradhan Date: Tue, 17 Jul 2018 17:47:34 +0000 Subject: [PATCH 2/2] Expose X509CertificateInfo in qt5 frontend --- qt5/src/poppler-form.cc | 234 +++++++++++++++++++++++++++++++++++++++- qt5/src/poppler-form.h | 133 +++++++++++++++++++++++ 2 files changed, 363 insertions(+), 4 deletions(-) diff --git a/qt5/src/poppler-form.cc b/qt5/src/poppler-form.cc index 58b2e57e..c998d2f9 100644 --- a/qt5/src/poppler-form.cc +++ b/qt5/src/poppler-form.cc @@ -32,6 +32,7 @@ #include #include #include +#include #include "poppler-form.h" #include "poppler-page-private.h" @@ -465,7 +466,7 @@ void FormFieldChoice::setCurrentChoices( const QList &choice ) QString FormFieldChoice::editChoice() const { FormWidgetChoice* fwc = static_cast(m_formData->fm); - + if ( fwc->isCombo() && fwc->hasEdit() ) return UnicodeParsedString(fwc->getEditChoice()); else @@ -475,7 +476,7 @@ QString FormFieldChoice::editChoice() const void FormFieldChoice::setEditChoice(const QString& text) { FormWidgetChoice* fwc = static_cast(m_formData->fm); - + if ( fwc->isCombo() && fwc->hasEdit() ) { GooString* goo = QStringToUnicodeGooString( text ); @@ -496,9 +497,188 @@ bool FormFieldChoice::canBeSpellChecked() const } +struct CertificateInfoPrivate { + + struct EntityInfo + { + QString common_name; + QString email_address; + QString org_name; + QString distinguished_name; + }; + + EntityInfo issuer_info; + EntityInfo subject_info; + QByteArray certificate_der; + QByteArray serial_number; + QByteArray public_key; + QDateTime validity_start; + QDateTime validity_end; + int public_key_type; + int public_key_strength; + int ku_extensions; + int version; + bool is_self_signed; + bool is_null; +}; + +CertificateInfo::CertificateInfo(CertificateInfoPrivate* priv) + : d_ptr(priv) +{ +} + +CertificateInfo::CertificateInfo(const CertificateInfo &other) + : d_ptr( other.d_ptr ) +{ +} + +CertificateInfo::~CertificateInfo() +{ +} + +CertificateInfo &CertificateInfo::operator=(const CertificateInfo &other) +{ + if ( this != &other ) + d_ptr = other.d_ptr; + + return *this; +} + +bool CertificateInfo::isNull() const +{ + Q_D(const CertificateInfo); + return d->is_null; +} + +int CertificateInfo::version() const +{ + Q_D(const CertificateInfo); + return d->version; +} + +QByteArray CertificateInfo::serialNumber() const +{ + Q_D(const CertificateInfo); + return d->serial_number; +} + +QString CertificateInfo::issuerInfo(EntityInfoKey key) const +{ + Q_D(const CertificateInfo); + switch (key) + { + case CommonName: + return d->issuer_info.common_name; + case DistinguishedName: + return d->issuer_info.distinguished_name; + case EmailAddress: + return d->issuer_info.email_address; + case Organization: + return d->issuer_info.org_name; + default: + return QString(); + } +} + +QString CertificateInfo::subjectInfo(EntityInfoKey key) const +{ + Q_D(const CertificateInfo); + switch (key) + { + case CommonName: + return d->subject_info.common_name; + case DistinguishedName: + return d->subject_info.distinguished_name; + case EmailAddress: + return d->subject_info.email_address; + case Organization: + return d->subject_info.org_name; + default: + return QString(); + } +} + +QDateTime CertificateInfo::validityStart() const +{ + Q_D(const CertificateInfo); + return d->validity_start; +} + +QDateTime CertificateInfo::validityEnd() const +{ + Q_D(const CertificateInfo); + return d->validity_end; +} + +CertificateInfo::KeyUsageExtensions CertificateInfo::keyUsageExtensions() const +{ + Q_D(const CertificateInfo); + + KeyUsageExtensions kuExtensions = KuNone; + if (d->ku_extensions & KU_DIGITAL_SIGNATURE) + kuExtensions |= KuDigitalSignature; + if (d->ku_extensions & KU_NON_REPUDIATION) + kuExtensions |= KuNonRepudiation; + if (d->ku_extensions & KU_KEY_ENCIPHERMENT) + kuExtensions |= KuKeyEncipherment; + if (d->ku_extensions & KU_DATA_ENCIPHERMENT) + kuExtensions |= KuDataEncipherment; + if (d->ku_extensions & KU_KEY_AGREEMENT) + kuExtensions |= KuKeyAgreement; + if (d->ku_extensions & KU_KEY_CERT_SIGN) + kuExtensions |= KuKeyCertSign; + if (d->ku_extensions & KU_CRL_SIGN) + kuExtensions |= KuClrSign; + if (d->ku_extensions & KU_ENCIPHER_ONLY) + kuExtensions |= KuEncipherOnly; + + return kuExtensions; +} + +QByteArray CertificateInfo::publicKey() const +{ + Q_D(const CertificateInfo); + return d->public_key; +} + +CertificateInfo::PublicKeyType CertificateInfo::publicKeyType() const +{ + Q_D(const CertificateInfo); + switch (d->public_key_type) + { + case RSAKEY: + return RsaKey; + case DSAKEY: + return DsaKey; + case ECKEY: + return EcKey; + default: + return OtherKey; + } +} + +int CertificateInfo::publicKeyStrength() const +{ + Q_D(const CertificateInfo); + return d->public_key_strength; +} + +bool CertificateInfo::isSelfSigned() const +{ + Q_D(const CertificateInfo); + return d->is_self_signed; +} + +QByteArray CertificateInfo::certificateData() const +{ + Q_D(const CertificateInfo); + return d->certificate_der; +} + struct SignatureValidationInfoPrivate { - SignatureValidationInfo::SignatureStatus signature_status; - SignatureValidationInfo::CertificateStatus certificate_status; + SignatureValidationInfo::SignatureStatus signature_status; + SignatureValidationInfo::CertificateStatus certificate_status; + QSharedPointer cert_info; QByteArray signature; QString signer_name; @@ -627,6 +807,12 @@ bool SignatureValidationInfo::signsTotalDocument() const return false; } +CertificateInfo SignatureValidationInfo::certificateInfo() const +{ + Q_D(const SignatureValidationInfo); + return *(d->cert_info.data()); +} + SignatureValidationInfo &SignatureValidationInfo::operator=(const SignatureValidationInfo &other) { if ( this != &other ) @@ -749,6 +935,46 @@ SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime& v } delete checkedSignature; + // set certificate info + X509CertificateInfo* ci = si->getCertificateInfo(); + CertificateInfoPrivate* certPriv = new CertificateInfoPrivate; + certPriv->is_null = true; + if (ci) + { + certPriv->version = ci->getVersion(); + certPriv->ku_extensions = ci->getKeyUsageExtensions(); + + X509CertificateInfo::CertItem certSerial = ci->getSerialNumber(); + certPriv->serial_number = QByteArray(certSerial.data, certSerial.len); + + X509CertificateInfo::EntityInfo issuerInfo = ci->getIssuerInfo(); + certPriv->issuer_info.common_name = issuerInfo.commonName; + certPriv->issuer_info.distinguished_name = issuerInfo.distinguishedName; + certPriv->issuer_info.email_address = issuerInfo.email; + certPriv->issuer_info.org_name = issuerInfo.organization; + + X509CertificateInfo::EntityInfo subjectInfo = ci->getSubjectInfo(); + certPriv->subject_info.common_name = subjectInfo.commonName; + certPriv->subject_info.distinguished_name = subjectInfo.distinguishedName; + certPriv->subject_info.email_address = subjectInfo.email; + certPriv->subject_info.org_name = subjectInfo.organization; + + X509CertificateInfo::Validity certValidity = ci->getValidity(); + certPriv->validity_start = QDateTime::fromTime_t(certValidity.notBefore, Qt::UTC); + certPriv->validity_end = QDateTime::fromTime_t(certValidity.notAfter, Qt::UTC); + + X509CertificateInfo::PublicKeyInfo pkInfo = ci->getPublicKeyInfo(); + certPriv->public_key = QByteArray::fromRawData(pkInfo.publicKey.data, pkInfo.publicKey.len); + certPriv->public_key_type = static_cast(pkInfo.publicKeyType); + certPriv->public_key_strength = pkInfo.publicKeyStrength; + + X509CertificateInfo::CertItem certDer = ci->getCertificateDER(); + certPriv->certificate_der = QByteArray(certDer.data, certDer.len); + + certPriv->is_null = false; + } + priv->cert_info = QSharedPointer(new CertificateInfo(certPriv)); + return SignatureValidationInfo(priv); } diff --git a/qt5/src/poppler-form.h b/qt5/src/poppler-form.h index ac28a4c6..15d02d3b 100644 --- a/qt5/src/poppler-form.h +++ b/qt5/src/poppler-form.h @@ -403,6 +403,132 @@ namespace Poppler { Q_DISABLE_COPY(FormFieldChoice) }; + /** + A helper class to store x509 certificate information. + + \since 0.66 + */ + class CertificateInfoPrivate; + class POPPLER_QT5_EXPORT CertificateInfo { + public: + + /** + The algorithm of public key. + */ + enum PublicKeyType + { + RsaKey, + DsaKey, + EcKey, + OtherKey + }; + + /** + Certificate key usage extensions. + */ + enum KeyUsageExtension + { + KuDigitalSignature = 0x80, + KuNonRepudiation = 0x40, + KuKeyEncipherment = 0x20, + KuDataEncipherment = 0x10, + KuKeyAgreement = 0x08, + KuKeyCertSign = 0x04, + KuClrSign = 0x02, + KuEncipherOnly = 0x01, + KuNone = 0x00 + }; + Q_DECLARE_FLAGS(KeyUsageExtensions, KeyUsageExtension) + + /** + Predefined keys for elements in an entity's distinguished name. + */ + enum EntityInfoKey + { + CommonName, + DistinguishedName, + EmailAddress, + Organization, + }; + + CertificateInfo(CertificateInfoPrivate *priv); + ~CertificateInfo(); + + /** + Returns true if certificate has no contents; otherwise returns false + */ + bool isNull() const; + + /** + The certificate version string. + */ + int version() const; + + /** + The certificate serial number. + */ + QByteArray serialNumber() const; + + /** + Information about the issuer. + */ + QString issuerInfo(EntityInfoKey key) const; + + /** + Information about the subject + */ + QString subjectInfo(EntityInfoKey key) const; + + /** + The date-time when certificate becomes valid. + */ + QDateTime validityStart() const; + + /** + The date-time when certificate expires. + */ + QDateTime validityEnd() const; + + /** + The uses allowed for the certificate. + */ + KeyUsageExtensions keyUsageExtensions() const; + + /** + The public key value. + */ + QByteArray publicKey() const; + + /** + The public key type. + */ + PublicKeyType publicKeyType() const; + + /** + The strength of public key in bits. + */ + int publicKeyStrength() const; + + /** + Returns true if certificate is self-signed otherwise returns false. + */ + bool isSelfSigned() const; + + /** + The DER encoded certificate. + */ + QByteArray certificateData() const; + + CertificateInfo(const CertificateInfo &other); + CertificateInfo &operator=(const CertificateInfo &other); + + private: + Q_DECLARE_PRIVATE(CertificateInfo) + + QSharedPointer d_ptr; + }; + Q_DECLARE_OPERATORS_FOR_FLAGS(CertificateInfo::KeyUsageExtensions) + /** A signature validation info helper class. @@ -522,6 +648,13 @@ namespace Poppler { */ bool signsTotalDocument() const; + /** + The signer certificate info. + + \since 0.66 + */ + CertificateInfo certificateInfo() const; + SignatureValidationInfo(const SignatureValidationInfo &other); SignatureValidationInfo &operator=(const SignatureValidationInfo &other); -- 2.17.0