2017-04-07 1 views
1

version Qt: 5.8.0Qt C++ SSL/TLS serveur avec Python client

Python version: 2.7.13

version OpenSSL: OpenSSL 1.0.1c

Système d'exploitation: Windows 10

J'essaie de créer un serveur SSL/TLS g Qt C++ et un client écrit en Python. J'utilise le projet exemple sslechoserver fourni avec Qt. Pour un exemple de client Python, j'utilise celui que j'ai obtenu de cette documentation Python: https://docs.python.org/2/library/ssl.html. J'ai copié le CERT de l'exemple de serveur mentionné ci-dessus et l'ai placé à côté du script Python et spécifié que dans les scripts de test j'ai essayé.

J'ai également essayé divers exemples de clients Python J'ai trouvé sur internet (comme ici: https://carlo-hamalainen.net/blog/2013/1/24/python-ssl-socket-echo-test-with-self-signed-certificate), mais aucun n'a été en mesure de se connecter pleinement au serveur d'écho Qt (il n'a jamais imprimé client connecté: comme il le fait quand j'utilise l'exemple sslechoclient qui a également été livré avec Qt). Le client dans le lien ci-dessus fonctionne avec le serveur Python à partir du même lien, donc je sais qu'il fonctionne toujours avec quelque chose.

le code de serveur de Qt C

sslechoserver.cpp

/**************************************************************************** 
** 
** Copyright (C) 2016 Kurt Pattyn <[email protected]>. 
** Contact: https://www.qt.io/licensing/ 
** 
** This file is part of the QtWebSockets module of the Qt Toolkit. 
** 
** $QT_BEGIN_LICENSE:BSD$ 
** Commercial License Usage 
** Licensees holding valid commercial Qt licenses may use this file in 
** accordance with the commercial license agreement provided with the 
** Software or, alternatively, in accordance with the terms contained in 
** a written agreement between you and The Qt Company. For licensing terms 
** and conditions see https://www.qt.io/terms-conditions. For further 
** information use the contact form at https://www.qt.io/contact-us. 
** 
** BSD License Usage 
** Alternatively, you may use this file under the terms of the BSD license 
** as follows: 
** 
** "Redistribution and use in source and binary forms, with or without 
** modification, are permitted provided that the following conditions are 
** met: 
** * Redistributions of source code must retain the above copyright 
**  notice, this list of conditions and the following disclaimer. 
** * Redistributions in binary form must reproduce the above copyright 
**  notice, this list of conditions and the following disclaimer in 
**  the documentation and/or other materials provided with the 
**  distribution. 
** * Neither the name of The Qt Company Ltd nor the names of its 
**  contributors may be used to endorse or promote products derived 
**  from this software without specific prior written permission. 
** 
** 
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 
** 
** $QT_END_LICENSE$ 
** 
****************************************************************************/ 
#include "sslechoserver.h" 
#include "QtWebSockets/QWebSocketServer" 
#include "QtWebSockets/QWebSocket" 
#include <QtCore/QDebug> 
#include <QtCore/QFile> 
#include <QtNetwork/QSslCertificate> 
#include <QtNetwork/QSslKey> 

QT_USE_NAMESPACE 

//! [constructor] 
SslEchoServer::SslEchoServer(quint16 port, QObject *parent) : 
    QObject(parent), 
    m_pWebSocketServer(Q_NULLPTR) 
{ 
    m_pWebSocketServer = new QWebSocketServer(QStringLiteral("SSL Echo Server"), 
               QWebSocketServer::SecureMode, 
               this); 
    QSslConfiguration sslConfiguration; 
    QFile certFile(QStringLiteral(":/localhost.cert")); 
    QFile keyFile(QStringLiteral(":/localhost.key")); 
    certFile.open(QIODevice::ReadOnly); 
    keyFile.open(QIODevice::ReadOnly); 
    QSslCertificate certificate(&certFile, QSsl::Pem); 
    QSslKey sslKey(&keyFile, QSsl::Rsa, QSsl::Pem); 
    certFile.close(); 
    keyFile.close(); 
    sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone); 
    sslConfiguration.setLocalCertificate(certificate); 
    sslConfiguration.setPrivateKey(sslKey); 
    sslConfiguration.setProtocol(QSsl::TlsV1SslV3); 
// sslConfiguration.setProtocol(QSsl::TlsV1_2OrLater); 
    m_pWebSocketServer->setSslConfiguration(sslConfiguration); 

    if (m_pWebSocketServer->listen(QHostAddress::Any, port)) 
    { 
     qDebug() << "SSL Echo Server listening on port" << port; 
     connect(m_pWebSocketServer, &QWebSocketServer::newConnection, 
       this, &SslEchoServer::onNewConnection); 
     connect(m_pWebSocketServer, &QWebSocketServer::sslErrors, 
       this, &SslEchoServer::onSslErrors); 
    } 
} 
//! [constructor] 

SslEchoServer::~SslEchoServer() 
{ 
    m_pWebSocketServer->close(); 
    qDeleteAll(m_clients.begin(), m_clients.end()); 
} 

//! [onNewConnection] 
void SslEchoServer::onNewConnection() 
{ 
    QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection(); 

    qDebug() << "Client connected:" << pSocket->peerName() << pSocket->origin(); 

    connect(pSocket, &QWebSocket::textMessageReceived, this, &SslEchoServer::processTextMessage); 
    connect(pSocket, &QWebSocket::binaryMessageReceived, 
      this, &SslEchoServer::processBinaryMessage); 
    connect(pSocket, &QWebSocket::disconnected, this, &SslEchoServer::socketDisconnected); 

    m_clients << pSocket; 
} 
//! [onNewConnection] 

//! [processTextMessage] 
void SslEchoServer::processTextMessage(QString message) 
{ 
    QWebSocket *pClient = qobject_cast<QWebSocket *>(sender()); 
    if (pClient) 
    { 
     pClient->sendTextMessage(message); 
    } 
} 
//! [processTextMessage] 

//! [processBinaryMessage] 
void SslEchoServer::processBinaryMessage(QByteArray message) 
{ 
    QWebSocket *pClient = qobject_cast<QWebSocket *>(sender()); 
    if (pClient) 
    { 
     pClient->sendBinaryMessage(message); 
    } 
} 
//! [processBinaryMessage] 

//! [socketDisconnected] 
void SslEchoServer::socketDisconnected() 
{ 
    qDebug() << "Client disconnected"; 
    QWebSocket *pClient = qobject_cast<QWebSocket *>(sender()); 
    if (pClient) 
    { 
     m_clients.removeAll(pClient); 
     pClient->deleteLater(); 
    } 
} 

void SslEchoServer::onSslErrors(const QList<QSslError> &) 
{ 
    qDebug() << "Ssl errors occurred"; 
} 
//! [socketDisconnected] 

sslechoserver.h

/**************************************************************************** 
** 
** Copyright (C) 2016 Kurt Pattyn <[email protected]>. 
** Contact: https://www.qt.io/licensing/ 
** 
** This file is part of the QtWebSockets module of the Qt Toolkit. 
** 
** $QT_BEGIN_LICENSE:BSD$ 
** Commercial License Usage 
** Licensees holding valid commercial Qt licenses may use this file in 
** accordance with the commercial license agreement provided with the 
** Software or, alternatively, in accordance with the terms contained in 
** a written agreement between you and The Qt Company. For licensing terms 
** and conditions see https://www.qt.io/terms-conditions. For further 
** information use the contact form at https://www.qt.io/contact-us. 
** 
** BSD License Usage 
** Alternatively, you may use this file under the terms of the BSD license 
** as follows: 
** 
** "Redistribution and use in source and binary forms, with or without 
** modification, are permitted provided that the following conditions are 
** met: 
** * Redistributions of source code must retain the above copyright 
**  notice, this list of conditions and the following disclaimer. 
** * Redistributions in binary form must reproduce the above copyright 
**  notice, this list of conditions and the following disclaimer in 
**  the documentation and/or other materials provided with the 
**  distribution. 
** * Neither the name of The Qt Company Ltd nor the names of its 
**  contributors may be used to endorse or promote products derived 
**  from this software without specific prior written permission. 
** 
** 
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 
** 
** $QT_END_LICENSE$ 
** 
****************************************************************************/ 
#ifndef SSLECHOSERVER_H 
#define SSLECHOSERVER_H 

#include <QtCore/QObject> 
#include <QtCore/QList> 
#include <QtCore/QByteArray> 
#include <QtNetwork/QSslError> 

QT_FORWARD_DECLARE_CLASS(QWebSocketServer) 
QT_FORWARD_DECLARE_CLASS(QWebSocket) 

class SslEchoServer : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit SslEchoServer(quint16 port, QObject *parent = Q_NULLPTR); 
    virtual ~SslEchoServer(); 

private Q_SLOTS: 
    void onNewConnection(); 
    void processTextMessage(QString message); 
    void processBinaryMessage(QByteArray message); 
    void socketDisconnected(); 
    void onSslErrors(const QList<QSslError> &errors); 

private: 
    QWebSocketServer *m_pWebSocketServer; 
    QList<QWebSocket *> m_clients; 
}; 

#endif //SSLECHOSERVER_H 

main.cpp

/**************************************************************************** 
** 
** Copyright (C) 2016 Kurt Pattyn <[email protected]>. 
** Contact: https://www.qt.io/licensing/ 
** 
** This file is part of the QtWebSockets module of the Qt Toolkit. 
** 
** $QT_BEGIN_LICENSE:BSD$ 
** Commercial License Usage 
** Licensees holding valid commercial Qt licenses may use this file in 
** accordance with the commercial license agreement provided with the 
** Software or, alternatively, in accordance with the terms contained in 
** a written agreement between you and The Qt Company. For licensing terms 
** and conditions see https://www.qt.io/terms-conditions. For further 
** information use the contact form at https://www.qt.io/contact-us. 
** 
** BSD License Usage 
** Alternatively, you may use this file under the terms of the BSD license 
** as follows: 
** 
** "Redistribution and use in source and binary forms, with or without 
** modification, are permitted provided that the following conditions are 
** met: 
** * Redistributions of source code must retain the above copyright 
**  notice, this list of conditions and the following disclaimer. 
** * Redistributions in binary form must reproduce the above copyright 
**  notice, this list of conditions and the following disclaimer in 
**  the documentation and/or other materials provided with the 
**  distribution. 
** * Neither the name of The Qt Company Ltd nor the names of its 
**  contributors may be used to endorse or promote products derived 
**  from this software without specific prior written permission. 
** 
** 
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 
** 
** $QT_END_LICENSE$ 
** 
****************************************************************************/ 
#include <QtCore/QCoreApplication> 
#include "sslechoserver.h" 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 
    SslEchoServer server(1234); 

    Q_UNUSED(server); 

    return a.exec(); 
} 

Python code client (juste un de ceux que j'ai essayé)

import socket, ssl 

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 
context.verify_mode = ssl.CERT_REQUIRED 
context.check_hostname = True 
context.load_verify_locations("localhost.cert") 
# context.load_default_certs() 

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
ssl_sock = context.wrap_socket(s, server_hostname='localhost') 
ssl_sock.connect(('localhost', 1234)) 

Répondre

0

Il s'avère que je devais faire mon client Python connecter utilisation WSS. J'ai installé Websocket (version 0.40) de https://pypi.python.org/pypi/websocket-client et utilisé l'exemple de script ci-dessous. J'ai utilisé Python 3.6.1, mais je pense que 2.7.x pourrait fonctionner aussi bien.

import websocket 
import time 
import ssl 

if __name__ == "__main__": 
    websocket.enableTrace(True) 
    ws = websocket.WebSocket(sslopt={"ca_certs": "localhost.cert", 
             "cert_reqs": ssl.CERT_REQUIRED}) 
    ws.connect("wss://localhost:1234") 
    print ("Sending 'Hello, World'...") 
    ws.send("Hello, World") 
    print ("Sent") 
    print ("Receiving...") 
    result = ws.recv() 
    print ("Received '%s'" % result) 
    ws.close()