softpedia s_client para descargar c++ c openssl

c++ - s_client - openssl softpedia



Manejando SSL_shutdown correctamente (1)

openssl es un poco de arte oscuro.

En primer lugar, la página a la que hizo referencia tiene HTML-ified los valores de retorno mal. Esto es lo que dice la página de manual:

RETURN VALUES The following return values can occur: 0 The shutdown is not yet finished. Call SSL_shutdown() for a second time, if a bidirectional shutdown shall be performed. The output of SSL_get_error(3) may be misleading, as an erroneous SSL_ERROR_SYSCALL may be flagged even though no error occurred. 1 The shutdown was successfully completed. The "close notify" alert was sent and the peer''s "close notify" alert was received. -1 The shutdown was not successful because a fatal error occurred either at the protocol level or a connection failure occurred. It can also occur if action is need to continue the operation for non- blocking BIOs. Call SSL_get_error(3) with the return value ret to find out the reason.

Si tiene bloqueo de BIO, las cosas son relativamente simples. Un 0 en la primera llamada significa que debe volver a llamar a SSL_shutdown si desea un apagado bidireccional. A 1 significa que has terminado. A -1 significa un error. En la segunda llamada (que solo haces si tienes un 0 de vuelta), se inicia un cierre bidireccional. La lógica dicta que no puede volver a obtener un 0 (porque es un BIO de bloqueo y habrá completado el primer paso). A -1 indica un error, y un 1 indica que se ha completado.

Si tiene BIO sin bloqueo, aplica lo mismo, excepto por el hecho de que necesita pasar por todo el SSL_ERROR_WANT_READ y SSL_ERROR_WANT_WRITE , es decir:

If the underlying BIO is non-blocking, SSL_shutdown() will also return when the underlying BIO could not satisfy the needs of SSL_shutdown() to continue the handshake. In this case a call to SSL_get_error() with the return value of SSL_shutdown() will yield SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE. The calling process then must repeat the call after taking appropriate action to satisfy the needs of SSL_shutdown(). The action depends on the underlying BIO. When using a non-blocking socket, nothing is to be done, but select() can be used to check for the required condition. When using a buffering BIO, like a BIO pair, data must be written into or retrieved out of the BIO before being able to continue.

Entonces tienes dos niveles de repetición. Llama a SSL_shutdown la ''primera'' vez, pero repita si obtiene SSL_ERROR_WANT_READ o SSL_ERROR_WANT_WRITE después de recorrer el ciclo select() de la manera normal, y solo cuente el ''primer'' SSL_shutdown como hecho si obtiene un código de error SSL_ERROR_WANT_ (en el cual caso de que fallara), o usted obtiene un retorno de 0 o 1 . Si obtienes 1 devolución, lo has hecho. Si obtiene un retorno de 0 , y desea un cierre bidireccional, entonces tiene que hacer la segunda llamada, en la que nuevamente deberá verificar SSL_ERROR_WANT_READ o SSL_ERROR_WANT_WRITE y volver a intentar seleccionar; eso no debería devolver 1 , pero puede devolver 0 o un error.

No es simple.

La documentación de openssl en SSL_shutdown establece que: Por lo tanto, se recomienda verificar el valor de retorno de SSL_shutdown () y volver a llamar a SSL_shutdown (), si el cierre bidireccional aún no se ha completado (el valor de retorno de la primera llamada es 0).

https://www.openssl.org/docs/ssl/SSL_shutdown.html

Tengo un fragmento de código a continuación donde compruebo el valor de retorno 0 de SSL_shutdown y llamo de nuevo, que he estado usando. Mi pregunta es, ¿está bien ignorar el valor de retorno de SSL_shutdown en la segunda llamada o deberíamos seguir intentando de nuevo SSL_shutdown hasta que se devuelva 1 (cierre bidireccional completo).

int r = SSL_shutdown(ssl); //error handling here if r < 0 if(!r) { shutdown(fd,1); SSL_shutdown(ssl); //how should I handle return value and error handling here is it required?? } SSL_free(ssl); SSLMap.erase(fd); shutdown(fd,2); close(fd);