2017-04-07 1 views
1

Qt-Version: 5.8.0Qt C++ SSL/TLS-Server mit Python-Client

Python-Version: 2.7.13

OpenSSL-Version: OpenSSL 1.0.1c

Betriebssystem: Windows 10

Ich versuche, einen SSL/TLS-Server usin zu erstellen g Qt C++ und ein in Python geschriebener Client. Ich verwende das Beispielprojekt sslechoserver, das mit Qt ausgeliefert wurde. Für einen Beispiel-Python-Client verwende ich den, den ich aus dieser Python-Dokumentation erhalten habe: https://docs.python.org/2/library/ssl.html. Ich habe das Zertifikat aus dem oben erwähnten Serverbeispiel kopiert und neben das Python-Skript gestellt und in den Testskripten, die ich ausprobiert habe, angegeben.

Ich habe auch verschiedene Python Client Beispiele versucht haben, die ich im Internet gefunden (wie hier: https://carlo-hamalainen.net/blog/2013/1/24/python-ssl-socket-echo-test-with-self-signed-certificate), aber keiner konnte vollständig auf die Qt verbinden Echo-Server (es ausgedruckt nie -Client verbunden: wie es funktioniert wenn ich das sslechoclient Beispiel verwende, das auch mit Qt geliefert wurde). Der Client in dem obigen Link funktioniert mit dem Python-Server von demselben Link, also weiß ich, dass er immer noch mit etwas funktioniert.

Qt C++ Servercode

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-Client-Code (nur einer von denen, die ich versuchte)

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)) 

Antwort

0

Stellt sich heraus, ich musste meinen Python-Client verwendet WSS verbinden machen. Ich installierte Websocket (Version 0.40) von https://pypi.python.org/pypi/websocket-client und verwendete das folgende Beispielskript. Ich habe Python 3.6.1 verwendet, aber ich denke, 2.7.x könnte auch funktionieren.

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()