2016-06-23 16 views
2

Ist dies der richtige Weg zur Fehlerbehandlung in OpenSSL? Und was ist der Unterschied zwischen SSL_get_error und ERR_get_error? Die Dokumente sind in dieser Hinsicht ziemlich vage.OpenSSL-Fehlerbehandlung

int ssl_shutdown(SSL *ssl_connection) 
{ 
    int rv, err; 
    ERR_clear_error(); 
    rv = SSL_shutdown(ssl_connection); 

    if (rv == 0) 
     SSL_shutdown(ssl_connection); 

    if (rv < 0) 
    { 
     err = SSL_get_error(ssl_connection, rv); 

     if (err == SSL_ERROR_SSL) 
      fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL)); 

     fprintf(stderr, "%s\n", SSL_state_string(ssl_connection)); 

     return 1; 
    } 

    SSL_free(ssl_connection); 
    return 0; 
} 

Antwort

1

SSL_get_error:

SSL_get_error() gibt einen Ergebniscode (geeignet für die C "switch" Anweisung) für einen vorhergehenden Anruf an SSL_connect(), SSL_accept(), SSL_do_handshake() , SSL_read(), SSL_peek() oder SSL_write() auf ssl. Der von dieser TLS/SSL-E/A-Funktion zurückgegebene Wert muss an SSL_get_error() im Parameter ret übergeben werden.

ERR_get_error:

ERR_get_error() gibt den frühesten Fehlercode von dem Fehler Warteschlangen des Thread und entfernt den Eintrag. Diese Funktion kann wiederholt aufgerufen werden, bis keine Fehlercodes mehr zurückgegeben werden.

So letzteres ist für allgemeinere Verwendung und diese sollten nicht zusammen verwendet werden, denn:

Die Fehler-Queue des aktuellen Threads leer sein muss, bevor die TLS/SSL-I/O-Operation versucht wird, oder SSL_get_error() funktioniert nicht zuverlässig.

So haben Sie alle Fehler lesen ERR_get_error verwenden und mit ihnen umgehen (oder sie durch Entfernen zu ignorieren, wie Sie mit ERR_clear_error in Ihrem Codebeispiel hat) und dann den IO-Vorgang durchführen. Ihre Herangehensweise scheint korrekt zu sein, obwohl ich derzeit nicht alle Aspekte selbst überprüfen kann.

Weitere Informationen finden Sie unter this answer und this post.

EDIT: nach this tutorial, BIO_ Routinen einen Fehler erzeugen und beeinflussen Fehlerwarteschlange:

Das dritte Feld ist der Name des Pakets, das den Fehler erzeugte, wie „BIO-Routinen“ oder "bignum routinen".

+0

Haben BIO_ * -Aufrufe auch Auswirkungen auf die Fehlerwarteschlange? – Red

+0

Es scheint wie @Red. Ich habe meine Antwort bearbeitet. Weitere Informationen finden Sie unter [diese Website] (https://www.safaribooksonline.com/library/view/network-security-with/059600270X/ch04s02.html). – Jezor

2

Und was ist der Unterschied zwischen SSL_get_error und ERR_get_error?

Es gibt zwei logische Teile zu OpenSSL. Zuerst ist die SSL-Bibliothek, libssl.a (und libssl.so), und es enthält die Kommunikation bezogenen Sachen. Zweitens ist die Kryptographie-Bibliothek, libcrypto.a (und libcrypto.so), und es enthält große Zahlen, Konfiguration, Eingabe/Ausgabe usw.

libssl.a auf libcrypto.a abhängt, und das, warum der Link-Befehl wird als -lssl -lcrypto bestellt.

Sie verwenden SSL_get_error, um die meisten Fehler aus der SSL-Teilbibliothek abzurufen, und Sie verwenden ERR_get_error, um Fehler abzurufen, die sich nicht im SSL-Teil der Bibliothek befinden.


Ist dies der richtige Weg, die Fehlerbehandlung in OpenSSL zu tun?

Der Code, den Sie zeigte näher an "Wie Shutdown Sie eine SSL-Socket". Letztendlich kontrollieren die Drehungen zwei Fälle. Die erste ist eine halb offene Verbindung, wenn der Client herunterfährt, ohne die Close Notify-Nachricht zu senden. Die zweite ist das Verhalten Ihres Programms beim Senden der Close Notify-Nachricht.

Es ist schwer zu beantworten "ist es richtig", weil wir nicht wissen, was Sie wollen. Wenn es Ihnen egal ist, ob die Close Notify gesendet wird, dann glaube ich, dass Sie nur SSL_shutdown einmal aufrufen müssen, unabhängig davon, was der Client tut.

+0

Mein beabsichtigtes Verhalten ist, auf nahe Benachrichtigung zu warten. Ist meine Verwendung von SSL_get_error und ERR_get_error korrekt? Ich habe kein SSL_ * -Äquivalent von ERR_error_string gefunden, also nahm ich an, SSL_state_string würde die gleiche Funktionalität liefern, aber ich bin mir nicht sicher. – Red