void CertificateDialog::exportCertificate() { const QSslCertificate certificate(m_certificates.value(m_ui->chainItemView->currentIndex().data(Qt::UserRole).toInt())); if (certificate.isNull()) { return; } QString filter; const QString path(QFileDialog::getSaveFileName(this, tr("Select File"), QStandardPaths::standardLocations(QStandardPaths::HomeLocation).value(0), Utils::formatFileTypes({tr("DER encoded X.509 certificates (*.der)"), tr("PEM encoded X.509 certificates (*.pem)"), tr("Text files (*.txt)")}), &filter)); if (!path.isEmpty()) { QFile file(path); if (!file.open(QIODevice::WriteOnly)) { QMessageBox::critical(this, tr("Error"), tr("Failed to open file for writing."), QMessageBox::Close); return; } if (filter.contains(QLatin1String(".der"))) { file.write(certificate.toDer()); } else if (filter.contains(QLatin1String(".pem"))) { file.write(certificate.toPem()); } else { QTextStream stream(&file); stream << certificate.toText(); } file.close(); } }
QString dumpCertificate(const QSslCertificate &cert) { if (cert.isNull()) return "\n-\n"; QString s = "\n"; #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) s += cert.toText(); #else QString s_none = QObject::tr("<Not Part of Certificate>"); #define CERTIFICATE_STR(x) ( ((x) == "" ) ? s_none : (x) ) s += "Certificate:\n"; s += "\nIssued To:\n"; s += "CommonName(CN): " + CERTIFICATE_STR(cert.subjectInfo(QSslCertificate::CommonName)) + "\n"; s += "Organization(O): " + CERTIFICATE_STR(cert.subjectInfo(QSslCertificate::Organization)) + "\n"; s += "OrganizationalUnitName(OU): " + CERTIFICATE_STR(cert.subjectInfo(QSslCertificate::OrganizationalUnitName)) + "\n"; s += "Serial Number: " + dumpHexPresentation(cert.serialNumber()) + "\n"; s += "\nIssued By:\n"; s += "CommonName(CN): " + CERTIFICATE_STR(cert.issuerInfo(QSslCertificate::CommonName)) + "\n"; s += "Organization(O): " + CERTIFICATE_STR(cert.issuerInfo(QSslCertificate::Organization)) + "\n"; s += "OrganizationalUnitName(OU): " + CERTIFICATE_STR(cert.issuerInfo(QSslCertificate::OrganizationalUnitName)) + "\n"; s += "\nPeriod Of Validity\n"; s += "Begins On: " + cert.effectiveDate().toString() + "\n"; s += "Expires On: " + cert.expiryDate().toString() + "\n"; s += "IsValid: " + (cert.isValid() ? QString("Yes") : QString("No")) + "\n"; s += "\nFingerprints\n"; s += "SHA1 Fingerprint:\n" + dumpCertificateFingerprint(cert, QCryptographicHash::Sha1) + "\n"; s += "MD5 Fingerprint:\n" + dumpCertificateFingerprint(cert, QCryptographicHash::Md5) + "\n"; #endif s += "\n\n"; s += cert.toPem(); return s; }
void CertificateDialog::updateValue() { const QSslCertificate certificate(m_certificates.value(m_ui->chainItemView->currentIndex().data(Qt::UserRole).toInt())); const CertificateField field(static_cast<CertificateField>(m_ui->detailsItemView->currentIndex().data(Qt::UserRole).toInt())); m_ui->valueTextEdit->clear(); switch (field) { case ValidityField: case PublicKeyField: case ExtensionsField: case DigestField: break; case VersionField: m_ui->valueTextEdit->setPlainText(QString(certificate.version())); break; case SerialNumberField: m_ui->valueTextEdit->setPlainText(formatHex(QString(certificate.serialNumber()), QLatin1Char(':'))); break; case SignatureAlgorithmField: m_ui->valueTextEdit->setPlainText(QRegularExpression(QLatin1String("Signature Algorithm:(.+)")).match(certificate.toText()).captured(1).trimmed()); break; case IssuerField: { const QList<QByteArray> attributes(certificate.issuerInfoAttributes()); for (int i = 0; i < attributes.count(); ++i) { m_ui->valueTextEdit->appendPlainText(QStringLiteral("%1 = %2").arg(QString(attributes.at(i))).arg(certificate.issuerInfo(attributes.at(i)).join(QLatin1String(", ")))); } } break; case ValidityNotBeforeField: m_ui->valueTextEdit->setPlainText(certificate.effectiveDate().toString(QLatin1String("yyyy-MM-dd hh:mm:ss t"))); break; case ValidityNotAfterField: m_ui->valueTextEdit->setPlainText(certificate.expiryDate().toString(QLatin1String("yyyy-MM-dd hh:mm:ss t"))); break; case SubjectField: { const QList<QByteArray> attributes(certificate.subjectInfoAttributes()); for (int i = 0; i < attributes.count(); ++i) { m_ui->valueTextEdit->appendPlainText(QStringLiteral("%1 = %2").arg(QString(attributes.at(i))).arg(certificate.subjectInfo(attributes.at(i)).join(QLatin1String(", ")))); } } break; case PublicKeyValueField: { const QRegularExpression expression(QLatin1String("Public-Key:[.\\s\\S]+Modulus:([.\\s\\S]+)Exponent:(.+)"), QRegularExpression::MultilineOption); const QRegularExpressionMatch match(expression.match(certificate.toText())); if (match.hasMatch()) { m_ui->valueTextEdit->setPlainText(tr("Modulus:\n%1\n\nExponent: %2").arg(formatHex(match.captured(1).trimmed().mid(3))).arg(match.captured(2).trimmed())); } } break; case PublicKeyAlgorithmField: m_ui->valueTextEdit->setPlainText(QRegularExpression(QLatin1String("Public Key Algorithm:(.+)")).match(certificate.toText()).captured(1).trimmed()); break; case ExtensionField: { const QSslCertificateExtension extension(certificate.extensions().value(m_ui->detailsItemView->currentIndex().data(Qt::UserRole + 1).toInt())); m_ui->valueTextEdit->setPlainText(extension.isCritical() ? tr("Critical") : tr("Not Critical")); m_ui->valueTextEdit->appendPlainText(tr("OID: %1").arg(extension.oid())); if (!extension.value().isNull()) { m_ui->valueTextEdit->appendPlainText(tr("Value:")); if (extension.value().type() == QVariant::List) { const QVariantList list(extension.value().toList()); for (int i = 0; i < list.count(); ++i) { m_ui->valueTextEdit->appendPlainText(list.at(i).toString()); } } else if (extension.value().type() == QVariant::Map) { const QVariantMap map(extension.value().toMap()); QVariantMap::const_iterator iterator; for (iterator = map.constBegin(); iterator != map.constEnd(); ++iterator) { m_ui->valueTextEdit->appendPlainText(QStringLiteral("%1 = %2").arg(iterator.key()).arg(iterator.value().toString())); } } else { m_ui->valueTextEdit->appendPlainText(extension.value().toString()); } } } break; case DigestSha1Field: m_ui->valueTextEdit->setPlainText(formatHex(QString(certificate.digest(QCryptographicHash::Sha1).toHex()))); break; case DigestSha256Field: m_ui->valueTextEdit->setPlainText(formatHex(QString(certificate.digest(QCryptographicHash::Sha256).toHex()))); break; default: break; } QTextCursor cursor(m_ui->valueTextEdit->textCursor()); cursor.setPosition(0); m_ui->valueTextEdit->setTextCursor(cursor); }