GroupSocket::GroupSocket(GroupAuthority *authority, QObject *parent) : QObject(parent) , socket{this} , timer{this} , authority(authority) { timer.setInterval(FIVE_SECOND_TIMEOUT); timer.setSingleShot(true); connect(&timer, &QTimer::timeout, this, &GroupSocket::onTimeout); const auto get_ssl_config = [this, authority]() { auto config = socket.sslConfiguration(); config.setCaCertificates({}); config.setLocalCertificate(authority->getLocalCertificate()); config.setPrivateKey(authority->getPrivateKey()); config.setPeerVerifyMode(QSslSocket::QueryPeer); // CVE-2012-4929 forced the below option to be enabled by default but we can disable it because // the vulernability only impacts browsers config.setSslOption(QSsl::SslOption::SslOptionDisableCompression, false); return config; }; socket.setSslConfiguration(get_ssl_config()); socket.setPeerVerifyName(GROUP_COMMON_NAME); connect(&socket, &QAbstractSocket::hostFound, this, [this]() { emit sendLog("Host found..."); }); connect(&socket, &QAbstractSocket::connected, this, [this]() { socket.setSocketOption(QAbstractSocket::LowDelayOption, true); socket.setSocketOption(QAbstractSocket::KeepAliveOption, true); if (io::tuneKeepAlive(socket.socketDescriptor())) { emit sendLog("Tuned TCP keep alive parameters for socket"); } setProtocolState(ProtocolState::AwaitingLogin); emit sendLog("Connection established..."); emit connectionEstablished(this); }); connect(&socket, &QSslSocket::encrypted, this, [this]() { timer.stop(); secret = socket.peerCertificate().digest(QCryptographicHash::Algorithm::Sha1).toHex().toLower(); emit sendLog("Connection successfully encrypted..."); emit connectionEncrypted(this); }); connect(&socket, &QAbstractSocket::disconnected, this, [this]() { timer.stop(); emit connectionClosed(this); }); connect(&socket, &QIODevice::readyRead, this, &GroupSocket::onReadyRead); connect(&socket, static_cast<void (QAbstractSocket::*)(QAbstractSocket::SocketError)>( &QAbstractSocket::error), this, &GroupSocket::onError); connect(&socket, &QSslSocket::peerVerifyError, this, &GroupSocket::onPeerVerifyError); }
SslSocketBase::SslSocketBase(QObject *parent) : QSslSocket(parent) { // set peer (clients) verification mode setPeerVerifyMode(QSslSocket::VerifyPeer); // log SSL errors QObject::connect(this, static_cast<void (SslSocketBase::*)(const QList<QSslError>&)>(&SslSocketBase::sslErrors), [this](const QList<QSslError>& arg) { this->onSslErrors(arg); }); }
//Permet de renseigner le client avec qui le socket doit communiquer bool Socket::setDescriptor(int socketDescriptor) { if(this->state()==QAbstractSocket::ConnectedState) return false; if(!this->setSocketDescriptor(socketDescriptor)) return false; //On récupère la clé privée du serveur QFile file(PRIVATEKEY_FILE); if(!file.open(QIODevice::ReadOnly)) { qDebug("La clé privée du serveur est introuvable."); return false; } QSslKey key(&file, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "pass"); if (key.isNull()) { qDebug("La clé privée du serveur est nulle"); return false; } file.close(); setPrivateKey(key); //on charge le certificat du client setLocalCertificate( LOCALCERTIFICATE_FILE ); //on charge le certificat de notre ca if(!addCaCertificates(CACERTIFICATES_FILE)) { qDebug("Impossible de charger le certificat du CA."); return false; } //on supprime la vérification des certificats des clients //seuls ces derniers vérifient les clés et certificat du serveur setPeerVerifyMode(QSslSocket::VerifyNone); //on ignore les erreurs car on a un certificat auto signé ignoreSslErrors(); //on se connecte au serveur startServerEncryption(); //On attends au plus 30secondes pour que la connexion s'établisse bool result = waitForConnected(); if(!result) return result; result=waitForEncrypted(); return result; }
sslConnection::sslConnection( int socketDescriptor, QObject *parent ) : QSslSocket( parent ) { if( !setSocketDescriptor( socketDescriptor ) ) { qDebug() << "Couldn't set socket descriptor"; deleteLater(); return; } setPeerVerifyMode(QSslSocket::VerifyPeer); setLocalCertificate( "mycert.pem" ); setPrivateKey("mycert.pem"); startServerEncryption(); }
BoxitSocket::BoxitSocket(int sessionID, QObject *parent) : QSslSocket(parent), sessionID(sessionID) { setReadBufferSize(0); setPeerVerifyMode(QSslSocket::VerifyNone); readBlockSize = 0; readMSGID = 0; timeoutCount = 0; timeOutTimer.setInterval(5000); // Connect signals and slots connect(this, SIGNAL(readyRead()) , this, SLOT(readyReadData())); connect(this, SIGNAL(sslErrors(QList<QSslError>)) , this, SLOT(sslErrors(QList<QSslError>))); connect(this, SIGNAL(error(QAbstractSocket::SocketError)) , this, SLOT(socketError())); connect(&timeOutTimer, SIGNAL(timeout()) , this, SLOT(timeOutDestroy())); // Start timeout timer timeOutTimer.start(); }