2017-01-30 2 views
1

Ich verwende OpenSSL 1.0.0-fips unter Linux. Das Problem, das ich habe, ist, dass SSL_connect() -1 zurückgibt und SSL_get_error()SSL_ERROR_WANT_READ zurückgibt. Ich legte dann den Dateideskriptor in eine select() mit einer timeval Struktur auf 10 Sekunden und die select() gerade Time out.Nicht blockierende E/A mit OpenSSL BIO

Ich feuerte Wireshark und ich sehe den "Client Hallo" ausgehen und ich sehe die ServerHello kommen zurück zum Client, aber es "wacht" nie in der select(). Es läuft einfach ab.

Meine Fragen sind: mit SSL_set_bio()

  1. Muß ich ein BIO-Objekt erstellen BIO_new_socket() verwenden und dann das BIO Objekt zu meinem SSL-Objekt zuweisen? Die man-Seite für SSL_set_fd() sagt, es wird automatisch ein BIO-Objekt erstellen, so scheint es zu implizieren, dass SSL_set_bio() ist eine Art von einer nutzlosen Funktion, die Sie nie wirklich anrufen müssen.

  2. Angenommen wir verwenden SSL_set_fd() und weisen einen verbundenen TCP-Dateideskriptor zu, der blockiert. Nehmen wir an, dass wir später diesen Dateideskriptor unter Verwendung von fcntl() zu nicht blockierend ändern. Wird das SSL-Objekt (oder das zugrundeliegende BIO-Objekt) dadurch beschädigt?

+0

Sie sollten wahrscheinlich etwas Code zeigen, einschließlich, wie Sie den Kontext einrichten. Asynchrone E/A- und nicht-blockierende Sockets geben Leuten eine Menge Ärger, weil die Bibliothek nicht zu entgegenkommend ist. Lesen Sie den Quellcode für ['apps/ocsp.c'] (https://github.com/openssl/openssl/blob/master/apps/ocsp.c), um zu sehen, wie OpenSSL es tut. Ich erinnere mich, dass ein normaler Kontext im Blocking-Modus eingerichtet ist, dann wechseln die Dinge mit dem zugrunde liegenden Socket in den nicht-blockierenden Modus. Suchen Sie nach Code, der 'BIO_get_fd' und' select' aufruft. AFAIK, es ist das einzige Beispiel für nicht blockierende E/A im selbst dokumentierenden Code :) – jww

+1

Ich habe den Code nicht veröffentlicht, weil die gesamte Verbindungsfunktion für meine implementierte C++ - SSL-Socket-Klasse ziemlich groß ist. Ich habe jedoch mein Problem gefunden. Ich habe vergessen, 1 zu dem Argument maxfd hinzuzufügen, um() auszuwählen. –

Antwort

1

1) Muß ich ein BIO-Objekt BIO_new_socket() erstellen und dann das BIO Objekt zu meinem SSL-Objekt zuzuweisen SSL_set_bio() verwenden? Der Mann Seite für SSL_set_fd() sagt, es wird automatisch erstellen ein BIO-Objekt , so scheint zu implizieren, dass SSL_set_bio() ist eine Art von einer nutzlosen Funktion, die Sie nie wirklich anrufen müssen.

Wenn das Standard-BIO-Objekt für Ihre Anforderungen ausreicht, müssen Sie Ihr eigenes BIO-Objekt nicht manuell erstellen und installieren. Der SSL_set_bio() - Aufruf ist nur für den Fall, dass Sie ein BIO-Objekt erstellen/verwenden möchten, das sich von dem Standard-Objekt unterscheidet, das SSL_set_bio() in Ihrem Namen erstellt.

2) Lassen Sie uns sagen, dass wir SSL_set_fd() verwenden, und weisen einen angeschlossenen TCP-Datei Beschreiber, die Sperrung wird. Nehmen wir an, wir ändern später den Dateideskriptor mit Hilfe von fcntl() in nicht blockierend. Wird das SSL-Objekt (oder das zugrunde liegende BIO-Objekt) trotzdem beschädigt?

Ja, ich glaube, es wird brechen. Die Anrufmuster für nicht-blockierende OpenSSL unterscheiden sich sehr von denen, die mit der Blockierung von OpenSSL verwendet werden, und ich glaube nicht, dass Sie während des Betriebs einfach von einem Modus zum anderen wechseln können. Das heißt, ich habe es nicht selbst ausprobiert, daher könnte ich mich irren, aber ich denke, um auf der sicheren Seite zu sein (und um konsistent zu sein), sollten Sie im Voraus wählen, ob Sie blockierend oder nicht blockierend verwenden wollen. O und bleibe dabei für die Dauer der Verbindung.

Insbesondere dieses Zitat aus der Manpage:

Die BIO und damit das SSL-Engine das Verhalten von fd erben.

...schlagen Sie vor, dass die SSL-Setup-Aufrufe den Zustand Ihrer fd untersuchen und private Variablen innerhalb der BIO- und der SSL-Objekte basierend auf dem blockierenden/nicht-blockierenden Status der fd festlegen. Wenn Sie dann "hinter OpenSSL zurück gehen" und das Verhalten des fd ändern, werden die Routinen von OpenSSL dies nicht erwarten und sehr wahrscheinlich das Falsche tun und nicht richtig funktionieren.

+0

Also, meine connect-Funktion, die ich in meine C++ - SSL-Socket-Klasse geschrieben habe, weist den Dateideskriptor dem SSL-Objekt mit SSL_set_fd() zu und stellt anschließend den Dateideskriptor mithilfe von fnctl() auf nicht blockierend ein. Ich kann es sogar zurück zum Blockieren schalten und die SSL-Schicht verhält sich, wie ich erwarten würde, dass sie sich verhält. Diese Dokumentation scheint also irreführend zu sein, oder es könnte einfach pures Glück sein, dass es so funktioniert, wie ich es möchte. –