bool FvUpdater::checkSslFingerPrint(QUrl urltoCheck) { if(urltoCheck.scheme()!="https") { qWarning()<<tr("SSL fingerprint check: The url %1 is not a ssl connection!").arg(urltoCheck.toString()); return false; } QSslSocket *socket = new QSslSocket(this); socket->connectToHostEncrypted(urltoCheck.host(), 443); if( !socket->waitForEncrypted(1000)) // waits until ssl emits encrypted(), max 1000msecs { qWarning()<<"SSL fingerprint check: Unable to connect SSL server: "<<socket->sslErrors(); return false; } QSslCertificate cert = socket->peerCertificate(); if(cert.isNull()) { qWarning()<<"SSL fingerprint check: Unable to retrieve SSL server certificate."; return false; } // COmpare digests if(cert.digest().toHex() != m_requiredSslFingerprint) { qWarning()<<"SSL fingerprint check: FINGERPRINT MISMATCH! Server digest="<<cert.digest().toHex()<<", requiered ssl digest="<<m_requiredSslFingerprint; return false; } return true; }
void SslInfoDlg::setCurrentCert(int index) { QSslCertificate cert = socket()->peerCertificateChain().at(index); ui.subjectCommonName->setText(cert.subjectInfo(QSslCertificate::CommonName)); ui.subjectOrganization->setText(cert.subjectInfo(QSslCertificate::Organization)); ui.subjectOrganizationalUnit->setText(cert.subjectInfo(QSslCertificate::OrganizationalUnitName)); ui.subjectCountry->setText(cert.subjectInfo(QSslCertificate::CountryName)); ui.subjectState->setText(cert.subjectInfo(QSslCertificate::StateOrProvinceName)); ui.subjectCity->setText(cert.subjectInfo(QSslCertificate::LocalityName)); ui.issuerCommonName->setText(cert.issuerInfo(QSslCertificate::CommonName)); ui.issuerOrganization->setText(cert.issuerInfo(QSslCertificate::Organization)); ui.issuerOrganizationalUnit->setText(cert.issuerInfo(QSslCertificate::OrganizationalUnitName)); ui.issuerCountry->setText(cert.issuerInfo(QSslCertificate::CountryName)); ui.issuerState->setText(cert.issuerInfo(QSslCertificate::StateOrProvinceName)); ui.issuerCity->setText(cert.issuerInfo(QSslCertificate::LocalityName)); if (socket()->sslErrors().isEmpty()) ui.trusted->setText(tr("Yes")); else { QString errorString = tr("No, for the following reasons:<ul>"); foreach(const QSslError &error, socket()->sslErrors()) errorString += "<li>" + error.errorString() + "</li>"; errorString += "</ul>"; ui.trusted->setText(errorString); } ui.validity->setText(tr("%1 to %2").arg(cert.effectiveDate().date().toString(Qt::ISODate), cert.expiryDate().date().toString(Qt::ISODate))); ui.md5Digest->setText(prettyDigest(cert.digest(QCryptographicHash::Md5))); ui.sha1Digest->setText(prettyDigest(cert.digest(QCryptographicHash::Sha1))); }
void QWebdav::sslErrors(QNetworkReply *reply, const QList<QSslError> &errors) { #ifdef DEBUG_WEBDAV qDebug() << "QWebdav::sslErrors() reply->url == " << reply->url().toString(QUrl::RemoveUserInfo); #endif QSslCertificate sslcert = errors[0].certificate(); if ( ( sslcert.digest(QCryptographicHash::Md5) == m_sslCertDigestMd5 ) && ( sslcert.digest(QCryptographicHash::Sha1) == m_sslCertDigestSha1) ) { // user accepted this SSL certifcate already ==> ignore SSL errors reply->ignoreSslErrors(); } else { // user has to check the SSL certificate and has to accept manually emit checkSslCertifcate(errors); reply->abort(); } }
bool DVRServer::isKnownCertificate(const QSslCertificate &certificate) const { if (m_configuration.sslDigest().isEmpty()) { /* If we don't know a certificate yet, we treat the first one we see as * correct. This is insecure, obviously, but it's a much nicer way to behave * for what we're doing here. */ const_cast<DVRServer*>(this)->setKnownCertificate(certificate); return true; } return (certificate.digest(QCryptographicHash::Sha1) == m_configuration.sslDigest()); }
QDebug operator<<(QDebug debug, const QSslCertificate &certificate) { debug << "QSslCertificate(" << certificate.version() << "," << certificate.serialNumber() << "," << certificate.digest() << "," << certificate.issuerInfo(QSslCertificate::Organization) << "," << certificate.subjectInfo(QSslCertificate::Organization) << "," << certificate.alternateSubjectNames() #ifndef QT_NO_TEXTSTREAM << "," << certificate.effectiveDate() << "," << certificate.expiryDate() #endif << ")"; return debug; }
QDebug operator<<(QDebug debug, const QSslCertificate &certificate) { debug << "QSslCertificate(" << certificate.version() << ',' << certificate.serialNumber() << ',' << certificate.digest().toBase64() << ',' << certificate.issuerInfo(QSslCertificate::Organization) << ',' << certificate.subjectInfo(QSslCertificate::Organization) << ',' << certificate.subjectAlternativeNames() #ifndef QT_NO_DATESTRING << ',' << certificate.effectiveDate() << ',' << certificate.expiryDate() #endif << ')'; return debug; }
void CheckCloudConnection::sslErrors(QList<QSslError> errorList) { if (verbose) { qDebug() << "Received error response trying to set up https connection with cloud storage backend:"; Q_FOREACH (QSslError err, errorList) { qDebug() << err.errorString(); } } QSslConfiguration conf = reply->sslConfiguration(); QSslCertificate cert = conf.peerCertificate(); QByteArray hexDigest = cert.digest().toHex(); if (reply->url().toString().contains(prefs.cloud_base_url) && hexDigest == "13ff44c62996cfa5cd69d6810675490e") { if (verbose) qDebug() << "Overriding SSL check as I recognize the certificate digest" << hexDigest; reply->ignoreSslErrors(); } else { if (verbose) qDebug() << "got invalid SSL certificate with hex digest" << hexDigest; } }
void LeechCraft::SslErrorsDialog::PopulateTree (const QSslError& error) { QTreeWidgetItem *item = new QTreeWidgetItem (Ui_.Errors_, QStringList ("Error:") << error.errorString ()); QSslCertificate cer = error.certificate (); if (cer.isNull ()) { new QTreeWidgetItem (item, QStringList (tr ("Certificate")) << tr ("(No certificate available for this error)")); return; } new QTreeWidgetItem (item, QStringList (tr ("Valid:")) << (cer.isValid () ? tr ("yes") : tr ("no"))); new QTreeWidgetItem (item, QStringList (tr ("Effective date:")) << cer.effectiveDate ().toString ()); new QTreeWidgetItem (item, QStringList (tr ("Expiry date:")) << cer.expiryDate ().toString ()); new QTreeWidgetItem (item, QStringList (tr ("Version:")) << cer.version ()); new QTreeWidgetItem (item, QStringList (tr ("Serial number:")) << cer.serialNumber ()); new QTreeWidgetItem (item, QStringList (tr ("MD5 digest:")) << cer.digest ().toHex ()); new QTreeWidgetItem (item, QStringList (tr ("SHA1 digest:")) << cer.digest (QCryptographicHash::Sha1).toHex ()); QTreeWidgetItem *issuer = new QTreeWidgetItem (item, QStringList (tr ("Issuer info"))); QString tmpString; #if QT_VERSION >= 0x050000 auto cvt = [] (const QStringList& list) { return list.join ("; "); }; #else auto cvt = [] (const QString& str) { return str; }; #endif tmpString = cvt (cer.issuerInfo (QSslCertificate::Organization)); if (!tmpString.isEmpty ()) new QTreeWidgetItem (issuer, QStringList (tr ("Organization:")) << tmpString); tmpString = cvt (cer.issuerInfo (QSslCertificate::CommonName)); if (!tmpString.isEmpty ()) new QTreeWidgetItem (issuer, QStringList (tr ("Common name:")) << tmpString); tmpString = cvt (cer.issuerInfo (QSslCertificate::LocalityName)); if (!tmpString.isEmpty ()) new QTreeWidgetItem (issuer, QStringList (tr ("Locality:")) << tmpString); tmpString = cvt (cer.issuerInfo (QSslCertificate::OrganizationalUnitName)); if (!tmpString.isEmpty ()) new QTreeWidgetItem (issuer, QStringList (tr ("Organizational unit name:")) << tmpString); tmpString = cvt (cer.issuerInfo (QSslCertificate::CountryName)); if (!tmpString.isEmpty ()) new QTreeWidgetItem (issuer, QStringList (tr ("Country name:")) << tmpString); tmpString = cvt (cer.issuerInfo (QSslCertificate::StateOrProvinceName)); if (!tmpString.isEmpty ()) new QTreeWidgetItem (issuer, QStringList (tr ("State or province name:")) << tmpString); QTreeWidgetItem *subject = new QTreeWidgetItem (item, QStringList (tr ("Subject info"))); tmpString = cvt (cer.subjectInfo (QSslCertificate::Organization)); if (!tmpString.isEmpty ()) new QTreeWidgetItem (subject, QStringList (tr ("Organization:")) << tmpString); tmpString = cvt (cer.subjectInfo (QSslCertificate::CommonName)); if (!tmpString.isEmpty ()) new QTreeWidgetItem (subject, QStringList (tr ("Common name:")) << tmpString); tmpString = cvt (cer.subjectInfo (QSslCertificate::LocalityName)); if (!tmpString.isEmpty ()) new QTreeWidgetItem (subject, QStringList (tr ("Locality:")) << tmpString); tmpString = cvt (cer.subjectInfo (QSslCertificate::OrganizationalUnitName)); if (!tmpString.isEmpty ()) new QTreeWidgetItem (subject, QStringList (tr ("Organizational unit name:")) << tmpString); tmpString = cvt (cer.subjectInfo (QSslCertificate::CountryName)); if (!tmpString.isEmpty ()) new QTreeWidgetItem (subject, QStringList (tr ("Country name:")) << tmpString); tmpString = cvt (cer.subjectInfo (QSslCertificate::StateOrProvinceName)); if (!tmpString.isEmpty ()) new QTreeWidgetItem (subject, QStringList (tr ("State or province name:")) << tmpString); }
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); }
QString dumpCertificateFingerprint(const QSslCertificate &cert, const QCryptographicHash::Algorithm &algorithm) { if(cert.isNull()) return ""; return dumpHexPresentation(cert.digest(algorithm).toHex()); }
void DVRServer::setKnownCertificate(const QSslCertificate &certificate) { m_configuration.setSslDigest(certificate.digest(QCryptographicHash::Sha1)); }
bool WebDavCommandEntity::startWork() { if (!CommandEntity::startWork()) { abortWork(); return false; } if (!this->m_client) { qWarning() << "No valid client object available, aborting"; abortWork(); return false; } if (this->m_reply) { QObject::connect(this->m_reply, &QNetworkReply::destroyed, this, [=](){ QObject::disconnect(this->m_reply, 0, 0, 0); this->m_reply = Q_NULLPTR; }); QObject::connect(this->m_reply, static_cast<void(QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error), this, [=](QNetworkReply::NetworkError error) { qWarning() << "Aborting due to network error:" << error; // TODO: stale files when aborting? // Aborting due to network error: QNetworkReply::ContentNotFoundError // abortWork(); Q_EMIT aborted(); }); QObject::connect(this->m_reply, &QNetworkReply::finished, this, [=]() { qDebug() << "WebDav request complete:" << this->m_reply->url().toString(); qDebug() << this->m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (this->m_reply->error() != QNetworkReply::NoError) return; Q_EMIT done(); }); QObject::connect(this->m_reply, &QNetworkReply::downloadProgress, this, [=](qint64 bytesReceived, qint64 bytesTotal) { if (bytesTotal < 1) return; const qreal newProgress = ((qreal)bytesReceived/(qreal)bytesTotal); setProgress(newProgress); }); QObject::connect(this->m_reply, &QNetworkReply::uploadProgress, this, [=](qint64 bytesSent, qint64 bytesTotal) { if (bytesTotal < 1) return; const qreal newProgress = ((qreal)bytesSent/(qreal)bytesTotal); setProgress(newProgress); }); } QObject::connect(this->m_client, &QWebdav::checkSslCertifcate, this, [=](const QList<QSslError> &errors) { qWarning() << "SSL error occured"; if (errors.length() > 0) { QSslCertificate sslcert = errors[0].certificate(); const QString md5Digest = sslcert.digest(QCryptographicHash::Md5); const QString sha1Digest = sslcert.digest(QCryptographicHash::Sha1); Q_EMIT sslErrorOccured(md5Digest, sha1Digest); } abortWork(); }); return true; }