2016-07-16 8 views
0

Ich entwickelte eine App von C++ und OpenSSL, um MySQL-Pakete zu überwachen. Meine App fungiert als Proxy. In keiner SSL-Verbindung ist alles in Ordnung, aber wenn ich eine SSL-Verbindung benutze, wird es mit "Handshake-Fehler" genau nach dem Empfang von Client Hello konfrontiert.Handshake Fehler nach Client Hallo

Ich entwickelte einen ssl-Server mit openssl und machen es blockieren und warten zur richtigen Zeit für die Annahme SSL-Verbindung.

Wireshark Screenshot

Wireshark Screenshot Openssl Ausgang:

140167999850080:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1352:

140167999850080:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1352:


Edited: Dies ist ein Teil des Codes, der mit dem Kunden interagieren, wenn es ssl Verbindungsoption On ist erkennen. Nach dem Erhalt des Anmeldeanforderungspakets wird dieser Code ausgeführt.

void mysqlNegotiation(X509* cert, EVP_PKEY* key, int fd) { 
    SSL_library_init(); 
    SSL_load_error_strings(); 
    OpenSSL_add_all_algorithms(); 

    SSL_CTX* context = SSL_CTX_new(TLSv1_server_method()); 

    SSL_CTX_use_certificate(context, cert); 
    SSL_CTX_use_PrivateKey(context, key); 
    SSL_CTX_check_private_key(context); 

    SSL_CTX_set_ecdh_auto(context, 1); 
    SSL_CTX_set_verify(context, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0); 
    SSL_CTX_set_verify_depth(context, 4); 
    SSL_CTX_load_verify_locations(context, "ca-cert.pem", "/etc/mysql/"); 

    SSL* ssl = SSL_new(context); 
    SSL_set_fd(ssl, fd); 

    int r = SSL_accept(ssl); 
    if (r != 1) { 
     ERR_print_errors_fp(stderr); 
     int err_SSL_get_error = SSL_get_error(ssl, r); 

     switch (err_SSL_get_error) { 
      case SSL_ERROR_NONE: 
       printf("%d", 0); 
       break; 
      case SSL_ERROR_SSL: 
       printf("%d", 1); 
       break; 
      case SSL_ERROR_WANT_READ: 
       printf("%d", 2); 
       break; 
      case SSL_ERROR_WANT_WRITE: 
       printf("%d", 3); 
       break; 
      default: 
       printf("%d", -1); 
       break; 
     } 
    } 
} 
+1

Ich bezweifle, dass dieser Code korrekt ist: 'SSL_CTX * Kontext = = SSL_CTX_new (TLSv1_server_method()); '. Es kompiliert wahrscheinlich nicht einmal. Bitte machen Sie ein tatsächlich funktionierendes Beispiel, mit dem das Problem reproduziert werden kann. –

+0

Haben Sie sich angesehen, welche Verschlüsselungen der Kunde anbietet? Vielleicht eine Paketerfassung machen?Wenn der Client beispielsweise nur DH-Verschlüsselungen anbietet, wird dies fehlschlagen, weil Sie keinen DH-Parameter (nicht ECDH) festlegen. –

+0

Quellcode geändert! Ja, beide bieten dieselbe Verschlüsselungsliste – mitrc

Antwort

1

Dafür kann es mehrere Gründe für diesen Fehler sein, was darauf hindeutet, wie gesagt, dass der Client und der Server keine gemeinsame Chiffre implementieren, die ausgehandelt werden können. Einige der Gründe sind:

  1. TLS-Protokoll Pegelkonflikt. Möglicherweise haben Sie beispielsweise SSLv23_methodSSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1 über SSL_CTX_set_options() verwendet, was bedeutet, dass nur TLS 1.2 oder höher unterstützt wird, der Client jedoch nichts über TLS 1.1 unterstützt. Dies ist nur ein Beispiel, eine Protokollfehlanpassung kann auch auf viele andere Arten auftreten.

  2. Die SSL-Verschlüsselungsliste, die über SSL_CTX_set_cipher_list() konfiguriert wurde, enthält keine vom Peer unterstützten Verschlüsselungen.

  3. Der SSL-Kontext wurde nicht mit DH-Parametern initialisiert und unterstützt daher forward secrecy nicht und der Peer unterstützt nur Chiffren, die Forward Secrecy unterstützen.

Es könnte auch andere Gründe geben. Es ist nicht möglich, eine autoritative Antwort zu liefern, ohne die Konfiguration sowohl des Clients als auch des Servers zu prüfen. Da nur Sie Zugriff auf den Code des Clients und des Servers haben, liegt es an Ihnen, es herauszufinden. Die einzige wirkliche Antwort hier: Suchen Sie einen anderen Servercode, der mit Ihrem Client zusammenarbeitet, und schauen Sie sich seinen Code an, um herauszufinden, was er anders macht als Ihr Code.

+0

Sowohl Client als auch Server verwenden TLSv1 und beide verwenden dieselbe Verschlüsselungsliste. Ich initialisierte auch DH-Parameter, aber es geht auf die gleiche Weise. Eine Sache, die mich verwirrt, ist, warum sofort nach dem Kunden Hallo und vor jeder Verhandlung es auftritt? – mitrc

+0

Diese Fehlermeldung wird aufgrund einer fehlgeschlagenen Verhandlung zurückgegeben. Es gibt keine separate Fehlermeldung für die Verhandlungsphase. "Keine geteilte Chiffre" bedeutet eine gescheiterte Chiffrierungsverhandlung. –

1

Ein häufiger Fehler ist, dass Ihr Mann in der mittleren App keine Zertifikate einrichtet, was bedeutet, dass keine Chiffren verwendet werden können, die Authentifizierung erfordern, d. H. Wahrscheinlich alle Verschlüsselungen, die der Client anbietet. Dies führt dann zu einer "no shared chipher" Warnung als Antwort auf den ClientHello. Natürlich ist das nur Spekulation, da der Code Ihres Mannes im mittleren Proxy nicht bekannt ist.

Wenn diese Spekulation falsch ist, schlage ich vor, dass Sie mehr Informationen zur Verfügung stellen, d. H. create a Minimal, Complete, and Verifiable example, damit andere die Details Ihrer Einrichtung tatsächlich sehen können und möglicherweise sogar Ihr Problem reproduzieren.

+0

Ich fügte weitere Informationen hinzu, wie Sie sagten – mitrc

+0

@Heil_Me: Es gibt keine Fehlerüberprüfung für die Einstellung von Zertifikat und privaten Schlüssel, so dass es gut möglich sein kann, dass diese Operationen fehlgeschlagen sind. –

+0

In der ursprünglichen Code-Fehlerüberprüfung implementiert, ist dieser Code nur ein einfacher Code, um zu zeigen, was ich im ursprünglichen Code getan habe. Ich kann Originalcode nicht genau wegen meiner Jobrichtlinie teilen. – mitrc