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 SslCertificateMonitor::socketReady(QObject *sockobj) { QSslSocket *sock = qobject_cast<QSslSocket *>(sockobj); if (!sock) return; QString peerName = sock->peerName(); QSslCertificate certificate = sock->peerCertificate(); if (*(d->acceptedCache.object(peerName)) == certificate) return; // Fast path for most recently accepted certificates // Have we been here before? QSslCertificate previousCertificate = cachedCertificate(peerName); if (!previousCertificate.isNull()) { if (certificate == previousCertificate) { // We need to add the certificate to the cache here as well as when we add to // the on-disk cache so that we don't hit the disk again for this site. d->acceptedCache.insert(peerName,new QSslCertificate(certificate)); return; // All is well } // Cert has changed QString message = evaluateCertificateChange( peerName, previousCertificate, certificate, sock->sslErrors().isEmpty() ); d->acceptCurrent = false; emit certificateWarning(sock, message); } else { // The certificate is new. We don't show anything to user because then // we're simply training them to click through our warning message without // thinking. d->acceptCurrent = true; } // If the user has chosen to accept the certificate or the certficate is new // then we store the updated entry. if (d->acceptCurrent) { d->acceptedCache.insert(peerName,new QSslCertificate(certificate)); addCertificate(peerName, certificate); } else { // Certficate has been considered dangerous by the user sock->abort(); } }
QList<QSslError> SslTlsSocket::sslErrors() const { QSslSocket *sock = qobject_cast<QSslSocket *>(d); Q_ASSERT(sock); return sock->sslErrors(); }