diff --git a/core/signatureutils.h b/core/signatureutils.h index 4cbc6118b..7e96b0afd 100644 --- a/core/signatureutils.h +++ b/core/signatureutils.h @@ -1,261 +1,261 @@ /*************************************************************************** * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef OKULAR_SIGNATUREINFO_H #define OKULAR_SIGNATUREINFO_H #include "okularcore_export.h" #include #include #include #include #include namespace Okular { class CertificateInfoPrivate; class SignatureInfoPrivate; /** * @short A helper class to store information x509 digital certificate */ class OKULARCORE_EXPORT CertificateInfo { public: /** * The algorithm of public key. */ enum PublicKeyType { RsaKey, DsaKey, EcKey, OtherKey }; /** * Certificate key usage. */ enum KeyUsage { KuNone = 0, KuDigitalSignature = 1, KuNonRepudiation = 2, KuKeyEncipherment = 4, KuDataEncipherment = 8, KuKeyAgreement = 16, KuKeyCertSign = 32, KuClrSign = 64, KuEncipherOnly = 128 }; Q_DECLARE_FLAGS( KeyUsages, KeyUsage ) /** * Destructor */ virtual ~CertificateInfo(); /** * The certificate version string in hex encoding. */ virtual QByteArray version() const; /** * The common name of certificate issuer. */ virtual QString issuerName() const; /** * The distinguished name of certificate issuer. */ virtual QString issuerDN() const; /** The hex encoded certificate serial number. */ virtual QByteArray serialNumber() const; /** The date-time when certificate becomes valid. */ virtual QDateTime validityStart() const; /** * The date-time when certificate expires. */ virtual QDateTime validityEnd() const; /** * The key usages of certificate. */ virtual KeyUsages keyUsages() const; /** * The public key value. */ virtual QByteArray publicKey() const; /** * The public key type. */ virtual PublicKeyType publicKeyType() const; /** * The strength of public key in bits or -1 in case * key type is 'OtherKey'. */ virtual int publicKeyStrength() const; /** * Returns true if certificate is self signed; otherwise returns false. */ virtual bool isSelfSigned() const; /** * The DER encoded certificate. */ virtual QByteArray certificateData() const; protected: CertificateInfo(); private: Q_DISABLE_COPY( CertificateInfo ) }; /** * @short A helper class to store information about digital signature */ class OKULARCORE_EXPORT SignatureInfo { public: /** * The verfication result of the signature. */ enum SignatureStatus { SignatureStatusUnknown, ///< The signature status is unknown for some reason. SignatureValid, ///< The signature is cryptographically valid. SignatureInvalid, ///< The signature is cryptographically invalid. SignatureDigestMismatch, ///< The document content was changed after the signature was applied. - SignatureDecodingError, ///< The signature CMS/PKCS7 structure is malformed. + SignatureDecodingError, ///< The signature CMS/PKCS7 classure is malformed. SignatureGenericError, ///< The signature could not be verified. SignatureNotFound, ///< The requested signature is not present in the document. SignatureNotVerified ///< The signature is not yet verified. }; /** * The verification result of the certificate. */ enum CertificateStatus { CertificateStatusUnknown, ///< The certificate status is unknown for some reason. CertificateTrusted, ///< The certificate is considered trusted. CertificateUntrustedIssuer, ///< The issuer of this certificate has been marked as untrusted by the user. CertificateUnknownIssuer, ///< The certificate trust chain has not finished in a trusted root certificate. CertificateRevoked, ///< The certificate was revoked by the issuing certificate authority. CertificateExpired, ///< The signing time is outside the validity bounds of this certificate. CertificateGenericError, ///< The certificate could not be verified. CertificateNotVerified ///< The certificate is not yet verified. }; /** * The hash algorithm of the signature */ enum HashAlgorithm { HashAlgorithmUnknown, HashAlgorithmMd2, HashAlgorithmMd5, HashAlgorithmSha1, HashAlgorithmSha256, HashAlgorithmSha384, HashAlgorithmSha512, HashAlgorithmSha224 }; /** * Destructor. */ virtual ~SignatureInfo(); /** * The signature status of the signature. */ virtual SignatureStatus signatureStatus() const; /** * The certificate status of the signature. */ virtual CertificateStatus certificateStatus() const; /** * The signer subject common name associated with the signature. */ virtual QString subjectName() const; /** * The signer subject distinguished name associated with the signature. */ virtual QString subjectDN() const; /** * The the hash algorithm used for the signature. */ virtual HashAlgorithm hashAlgorithm() const; /** * The signing time associated with the signature. */ virtual QDateTime signingTime() const; /** * Get the signature binary data. */ virtual QByteArray signature() const; /** * Get the bounds of the ranges of the document which are signed. */ virtual QList signedRangeBounds() const; /** * Checks whether the signature authenticates the total document * except for the signature itself. */ virtual bool signsTotalDocument() const; /** * Get location. */ virtual QString location() const; /** * Get signing reason. */ virtual QString reason() const; /** * Get certificate details. */ virtual CertificateInfo *certificateInfo() const; protected: SignatureInfo(); private: Q_DISABLE_COPY( SignatureInfo ) }; } #endif diff --git a/ui/signaturewidgets.cpp b/ui/signaturewidgets.cpp index 2ac4310b1..d4514bcae 100644 --- a/ui/signaturewidgets.cpp +++ b/ui/signaturewidgets.cpp @@ -1,301 +1,229 @@ /*************************************************************************** * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "signaturewidgets.h" #include #include #include #include #include #include #include #include -#include -#include - -#include static QString getReadableSigState( Okular::SignatureInfo::SignatureStatus sigStatus ) { switch ( sigStatus ) { case Okular::SignatureInfo::SignatureValid: - return i18n("The signature is cryptographically valid."); + return i18n("Signature is Valid."); case Okular::SignatureInfo::SignatureInvalid: - return i18n("The signature is cryptographically invalid."); + return i18n("Signature is Invalid."); case Okular::SignatureInfo::SignatureDigestMismatch: - return i18n("Digest Mismatch occurred."); + return i18n("Digest Mismatch."); case Okular::SignatureInfo::SignatureDecodingError: - return i18n("The signature CMS/PKCS7 structure is malformed."); - case Okular::SignatureInfo::SignatureNotFound: - return i18n("The requested signature is not present in the document."); + return i18n("Document isn't signed or corrupted data."); + case Okular::SignatureInfo::SignatureNotVerified: + return i18n("Signature has not yet been verified."); default: - return i18n("The signature could not be verified."); + return i18n("Unknown Validation Failure."); } } static QString getReadableCertState( Okular::SignatureInfo::CertificateStatus certStatus ) { switch ( certStatus ) { case Okular::SignatureInfo::CertificateTrusted: return i18n("Certificate is Trusted."); case Okular::SignatureInfo::CertificateUntrustedIssuer: return i18n("Certificate issuer isn't Trusted."); case Okular::SignatureInfo::CertificateUnknownIssuer: return i18n("Certificate issuer is unknown."); case Okular::SignatureInfo::CertificateRevoked: return i18n("Certificate has been Revoked."); case Okular::SignatureInfo::CertificateExpired: return i18n("Certificate has Expired."); case Okular::SignatureInfo::CertificateNotVerified: return i18n("Certificate has not yet been verified."); default: return i18n("Unknown issue with Certificate or corrupted data."); } } static QString getReadableHashAlgorithm( Okular::SignatureInfo::HashAlgorithm hashAlg ) { switch ( hashAlg ) { case Okular::SignatureInfo::HashAlgorithmMd2: return i18n("MD2"); case Okular::SignatureInfo::HashAlgorithmMd5: return i18n("MD5"); case Okular::SignatureInfo::HashAlgorithmSha1: return i18n("SHA1"); case Okular::SignatureInfo::HashAlgorithmSha256: return i18n("SHA256"); case Okular::SignatureInfo::HashAlgorithmSha384: return i18n("SHA384"); case Okular::SignatureInfo::HashAlgorithmSha512: return i18n("SHA512"); case Okular::SignatureInfo::HashAlgorithmSha224: return i18n("SHA224"); default: return i18n("Unknown"); } } SignaturePropertiesModel::SignaturePropertiesModel( Okular::SignatureInfo *sigInfo, QObject * parent ) : QAbstractTableModel( parent ) { m_sigProperties.append( qMakePair( i18n("Subject Name"), sigInfo->subjectName() ) ); m_sigProperties.append( qMakePair( i18n("Subject Distinguished Name"), sigInfo->subjectDN() ) ); m_sigProperties.append( qMakePair( i18n("Signing Time"), sigInfo->signingTime().toString( QStringLiteral("MMM dd yyyy hh:mm:ss") ) ) ); m_sigProperties.append( qMakePair( i18n("Hash Algorithm"), getReadableHashAlgorithm( sigInfo->hashAlgorithm() ) ) ); m_sigProperties.append( qMakePair( i18n("Signature Status"), getReadableSigState( sigInfo->signatureStatus() ) ) ); m_sigProperties.append( qMakePair( i18n("Certificate Status"), getReadableCertState( sigInfo->certificateStatus() ) ) ); m_sigProperties.append( qMakePair( i18n("Signature Data"), QString::fromUtf8( sigInfo->signature().toHex(' ') ) ) ); - m_sigProperties.append( qMakePair( i18n("Location"), QString( sigInfo->location() ) ) ); - m_sigProperties.append( qMakePair( i18n("Reason"), QString( sigInfo->reason() ) ) ); m_sigProperties.append( qMakePair( QStringLiteral("----------"), QString("------Certificate Properties--------") ) ); Okular::CertificateInfo *certInfo = sigInfo->certificateInfo(); m_sigProperties.append( qMakePair( i18n("Version"), certInfo->version() ) ); m_sigProperties.append( qMakePair( i18n("Issuer Name"), certInfo->issuerName() ) ); m_sigProperties.append( qMakePair( i18n("Issuer Distinguished Name"), certInfo->issuerDN() ) ); m_sigProperties.append( qMakePair( i18n("Serial Number"), certInfo->serialNumber() ) ); m_sigProperties.append( qMakePair( i18n("Validity Start"), certInfo->validityStart().toString( QStringLiteral("MMM dd yyyy hh:mm:ss") ) ) ); m_sigProperties.append( qMakePair( i18n("Validity End"), certInfo->validityEnd().toString( QStringLiteral("MMM dd yyyy hh:mm:ss") ) ) ); m_sigProperties.append( qMakePair( i18n("Public Key"), certInfo->publicKey() ) ); m_sigProperties.append( qMakePair( i18n("Is Self Signed"), certInfo->isSelfSigned() ? QString("true") : QString("false") ) ); } int SignaturePropertiesModel::columnCount( const QModelIndex &parent ) const { return parent.isValid() ? 0 : 2; } int SignaturePropertiesModel::rowCount( const QModelIndex &parent ) const { return parent.isValid() ? 0 : m_sigProperties.size(); } QVariant SignaturePropertiesModel::data( const QModelIndex &index, int role ) const { int row = index.row(); if ( !index.isValid() || row < 0 || row >= m_sigProperties.count() ) return QVariant(); switch ( role ) { case Qt::DisplayRole: case Qt::ToolTipRole: switch ( index.column() ) { case 0: return m_sigProperties[row].first; case 1: return m_sigProperties[row].second; default: return QString(); } case PropertyValueRole: return m_sigProperties[row].second; } return QVariant(); } QVariant SignaturePropertiesModel::headerData( int section, Qt::Orientation orientation, int role ) const { if ( role == Qt::TextAlignmentRole ) return QVariant( Qt::AlignLeft ); if ( orientation != Qt::Horizontal || role != Qt::DisplayRole) return QVariant(); switch ( section ) { case 0: return i18n("Property"); case 1: return i18n("Value"); default: return QVariant(); } } SignaturePropertiesDialog::SignaturePropertiesDialog( Okular::SignatureInfo *sigInfo, QWidget *parent ) : QDialog( parent ), m_sigInfo( sigInfo ) { setModal( true ); setFixedSize( QSize( 450, 500 )); setWindowTitle( i18n("Signature Properties") ); auto sigPropLabel = new QLabel( this ); sigPropLabel->setText( i18n("Signature Properties:") ); auto sigPropTree = new QTreeView( this ); sigPropTree->setIndentation( 0 ); m_sigPropModel = new SignaturePropertiesModel( m_sigInfo, this ); sigPropTree->setModel( m_sigPropModel ); connect( sigPropTree, &QTreeView::clicked, this, &SignaturePropertiesDialog::updateText ); m_sigPropText = new QTextEdit( this ); m_sigPropText->setReadOnly( true ); auto btnBox = new QDialogButtonBox( QDialogButtonBox::Close, this ); btnBox->button( QDialogButtonBox::Close )->setDefault( true ); connect( btnBox, &QDialogButtonBox::rejected, this, &SignatureSummaryDialog::reject ); auto mainLayout = new QVBoxLayout( this ); mainLayout->addWidget( sigPropLabel ); mainLayout->addWidget( sigPropTree ); mainLayout->addWidget( m_sigPropText ); mainLayout->addWidget( btnBox ); setLayout( mainLayout ); } void SignaturePropertiesDialog::updateText( const QModelIndex &index ) { m_sigPropText->setText( m_sigPropModel->data( index, SignaturePropertiesModel::PropertyValueRole ).toString() ); } SignatureSummaryDialog::SignatureSummaryDialog( Okular::SignatureInfo *sigInfo, QWidget *parent ) : QDialog( parent ), m_sigInfo( sigInfo ) { setModal( true ); - setWindowTitle( i18n("Signature Properties") ); + setFixedSize( QSize(250, 100) ); + setWindowTitle( i18n("Signature Validation Status") ); - auto mainLayout = new QVBoxLayout; + auto sigStatusLabel = new QLabel( this ); + sigStatusLabel->setText( getReadableSigState( m_sigInfo->signatureStatus() ) ); - // signature validation status - auto sigStatusBox = new QGroupBox( i18n("Validity Status") ); - auto hBoxLayout = new QHBoxLayout; - auto pixmapLabel = new QLabel; - pixmapLabel->setPixmap( KIconLoader::global()->loadIcon( QLatin1String("application-certificate"), - KIconLoader::Desktop, KIconLoader::SizeSmallMedium ) ); - hBoxLayout->addWidget( pixmapLabel ); - - auto sigStatusFormLayout = new QFormLayout; - const Okular::SignatureInfo::SignatureStatus sigStatus = m_sigInfo->signatureStatus(); - sigStatusFormLayout->addRow( i18n("Signature Validity:"), new QLabel( getReadableSigState( sigStatus ) ) ); - QString modString; - if ( sigStatus == Okular::SignatureInfo::SignatureValid ) - { - const bool signsTotalDoc = m_sigInfo->signsTotalDocument(); - if ( signsTotalDoc ) - { - modString = i18n("The document has not been modified since it was signed."); - } - else - { - modString = i18n("The revision of the document that was covered by this signature has not been modified;\n" - "however there have been subsequent changes to the document."); - } - - } - else if ( sigStatus == Okular::SignatureInfo::SignatureDigestMismatch ) - { - modString = i18n("The document has been modified in a way not permitted by a previous signer."); - } - else - { - modString = i18n("The document integrity verification could not be completed."); - } - sigStatusFormLayout->addRow( i18n("Document Modifications:"), new QLabel( modString ) ); - hBoxLayout->addLayout( sigStatusFormLayout ); - sigStatusBox->setLayout( hBoxLayout ); - mainLayout->addWidget( sigStatusBox ); - - // additional information - auto extraInfoBox = new QGroupBox( i18n("Additional Information") ); - auto extraInfoFormLayout = new QFormLayout; - extraInfoFormLayout->addRow( i18n("Signed By:"), new QLabel( m_sigInfo->subjectName() ) ); - extraInfoFormLayout->addRow( i18n("Signing Time:"), new QLabel( m_sigInfo->signingTime().toString( QStringLiteral("MMM dd yyyy hh:mm:ss") ) ) ); - auto getValidString = [=]( const QString &str ) -> QString { - return !str.isEmpty() ? str : i18n("Not Available"); - }; - // optional info - extraInfoFormLayout->addRow( i18n("Reason:"), new QLabel( getValidString( m_sigInfo->reason() ) ) ); - extraInfoFormLayout->addRow( i18n("Location:"), new QLabel( getValidString( m_sigInfo->location() ) ) ); - extraInfoBox->setLayout( extraInfoFormLayout ); - mainLayout->addWidget( extraInfoBox ); - - // document version - auto revisionBox = new QGroupBox( i18n("Document Version") ); - auto revisionLayout = new QHBoxLayout; - revisionLayout->addWidget( new QLabel( i18n("Document Revision 1 of 1") ) ); - revisionLayout->addStretch(); - auto revisionBtn = new QPushButton( i18n( "View Signed Version...") ); - connect( revisionBtn, &QPushButton::clicked, this, &SignatureSummaryDialog::reject ); - revisionLayout->addWidget( revisionBtn ); - revisionBox->setLayout( revisionLayout ); - mainLayout->addWidget( revisionBox ); - - // button box auto btnBox = new QDialogButtonBox( QDialogButtonBox::Close, this ); - auto certPropBtn = new QPushButton( i18n( "Vew Certificate..."), this ); + auto sigPropBtn = new QPushButton( i18n( "Signature Properties"), this ); btnBox->button( QDialogButtonBox::Close )->setDefault( true ); - btnBox->addButton( certPropBtn, QDialogButtonBox::ActionRole ); + btnBox->addButton( sigPropBtn, QDialogButtonBox::ActionRole ); connect( btnBox, &QDialogButtonBox::rejected, this, &SignatureSummaryDialog::reject ); - connect( certPropBtn, &QPushButton::clicked, this, &SignatureSummaryDialog::viewCertificateProperties ); - mainLayout->addWidget( btnBox ); + connect( sigPropBtn, &QPushButton::clicked, this, &SignatureSummaryDialog::showSignatureProperties ); + auto mainLayout = new QVBoxLayout( this ); + mainLayout->addWidget( sigStatusLabel ); + mainLayout->addWidget( btnBox ); setLayout( mainLayout ); - resize( mainLayout->sizeHint() ); } -void SignatureSummaryDialog::viewCertificateProperties() +void SignatureSummaryDialog::showSignatureProperties() { + reject(); SignaturePropertiesDialog sigPropDlg( m_sigInfo, this ); sigPropDlg.exec(); } -void SignatureSummaryDialog::viewSignedVersion() -{ - reject(); -} - #include "moc_signaturewidgets.cpp" diff --git a/ui/signaturewidgets.h b/ui/signaturewidgets.h index e6afaa3b2..0a2ae10c4 100644 --- a/ui/signaturewidgets.h +++ b/ui/signaturewidgets.h @@ -1,76 +1,75 @@ /*************************************************************************** * Copyright (C) 2018 by Chinmoy Ranjan Pradhan * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef OKULAR_SIGNATUREWIDGETS_H #define OKULAR_SIGNATUREWIDGETS_H #include #include #include #include "core/signatureutils.h" class QTextEdit; namespace Okular { class SignatureInfo; } class SignaturePropertiesModel : public QAbstractTableModel { Q_OBJECT public: explicit SignaturePropertiesModel( Okular::SignatureInfo *sigInfo, QObject * parent = nullptr ); enum { PropertyValueRole = Qt::UserRole }; int columnCount( const QModelIndex &parent = QModelIndex() ) const override; int rowCount( const QModelIndex &parent = QModelIndex() ) const override; QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override; QVariant headerData( int section, Qt::Orientation orientation, int role ) const override; private: QVector< QPair > m_sigProperties; }; class SignaturePropertiesDialog : public QDialog { Q_OBJECT public: SignaturePropertiesDialog( Okular::SignatureInfo *sigInfo, QWidget *parent ); private Q_SLOTS: void updateText( const QModelIndex &index ); private: SignaturePropertiesModel *m_sigPropModel; QTextEdit *m_sigPropText; Okular::SignatureInfo *m_sigInfo; }; class SignatureSummaryDialog : public QDialog { Q_OBJECT public: SignatureSummaryDialog( Okular::SignatureInfo *sigInfo, QWidget *parent ); private Q_SLOTS: - void viewSignedVersion(); - void viewCertificateProperties(); + void showSignatureProperties(); private: Okular::SignatureInfo *m_sigInfo; }; #endif