mirror of https://github.com/getdnsapi/getdns.git
tls_do_handshake: move handshake and check for new session into abstraction layer.
This commit is contained in:
parent
ffd1136e94
commit
e22c01e212
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <openssl/err.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/bio.h>
|
#include <openssl/bio.h>
|
||||||
|
@ -342,6 +343,43 @@ _getdns_tls_session* _getdns_tls_connection_get_session(_getdns_tls_connection*
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getdns_return_t _getdns_tls_connection_do_handshake(_getdns_tls_connection* conn)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!conn || !conn->ssl)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
ERR_clear_error();
|
||||||
|
r = SSL_do_handshake(conn->ssl);
|
||||||
|
if (r == 1)
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
err = SSL_get_error(conn->ssl, r);
|
||||||
|
switch(err)
|
||||||
|
{
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
return GETDNS_RETURN_TLS_WANT_READ;
|
||||||
|
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
return GETDNS_RETURN_TLS_WANT_WRITE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return GETDNS_RETURN_GENERIC_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getdns_return_t _getdns_tls_connection_is_session_reused(_getdns_tls_connection* conn)
|
||||||
|
{
|
||||||
|
if (!conn || !conn->ssl)
|
||||||
|
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (SSL_session_reused(conn->ssl))
|
||||||
|
return GETDNS_RETURN_GOOD;
|
||||||
|
else
|
||||||
|
return GETDNS_RETURN_TLS_CONNECTION_FRESH;
|
||||||
|
}
|
||||||
|
|
||||||
getdns_return_t _getdns_tls_session_free(_getdns_tls_session* s)
|
getdns_return_t _getdns_tls_session_free(_getdns_tls_session* s)
|
||||||
{
|
{
|
||||||
if (!s || !s->ssl)
|
if (!s || !s->ssl)
|
||||||
|
|
|
@ -47,6 +47,11 @@
|
||||||
#define HAVE_TLS_CONN_CURVES_LIST (HAVE_DECL_SSL_SET1_CURVES_LIST)
|
#define HAVE_TLS_CONN_CURVES_LIST (HAVE_DECL_SSL_SET1_CURVES_LIST)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Additional return codes required by TLS abstraction. Internal use only. */
|
||||||
|
#define GETDNS_RETURN_TLS_WANT_READ ((getdns_return_t) 420)
|
||||||
|
#define GETDNS_RETURN_TLS_WANT_WRITE ((getdns_return_t) 421)
|
||||||
|
#define GETDNS_RETURN_TLS_CONNECTION_FRESH ((getdns_return_t) 422)
|
||||||
|
|
||||||
typedef struct _getdns_tls_context {
|
typedef struct _getdns_tls_context {
|
||||||
SSL_CTX* ssl;
|
SSL_CTX* ssl;
|
||||||
} _getdns_tls_context;
|
} _getdns_tls_context;
|
||||||
|
@ -78,6 +83,28 @@ getdns_return_t _getdns_tls_connection_set_curves_list(_getdns_tls_connection* c
|
||||||
getdns_return_t _getdns_tls_connection_set_session(_getdns_tls_connection* conn, _getdns_tls_session* s);
|
getdns_return_t _getdns_tls_connection_set_session(_getdns_tls_connection* conn, _getdns_tls_session* s);
|
||||||
_getdns_tls_session* _getdns_tls_connection_get_session(_getdns_tls_connection* conn);
|
_getdns_tls_session* _getdns_tls_connection_get_session(_getdns_tls_connection* conn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt TLS handshake.
|
||||||
|
*
|
||||||
|
* @param conn the connection.
|
||||||
|
* @return GETDNS_RETURN_GOOD if handshake is complete.
|
||||||
|
* @return GETDNS_RETURN_INVALID_PARAMETER if conn is null or has no SSL.
|
||||||
|
* @return GETDNS_RETURN_TLS_WANT_READ if handshake needs to read to proceed.
|
||||||
|
* @return GETDNS_RETURN_TLS_WANT_WRITE if handshake needs to write to proceed.
|
||||||
|
* @return GETDNS_RETURN_GENERIC_ERROR if handshake failed.
|
||||||
|
*/
|
||||||
|
getdns_return_t _getdns_tls_connection_do_handshake(_getdns_tls_connection* conn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See whether the connection is reusing a session.
|
||||||
|
*
|
||||||
|
* @param conn the connection.
|
||||||
|
* @return GETDNS_RETURN_GOOD if connection is being reused.
|
||||||
|
* @return GETDNS_RETURN_INVALID_PARAMETER if conn is null or has no SSL.
|
||||||
|
* @return GETDNS_RETURN_TLS_CONNECTION_FRESH if connection is not being reused.
|
||||||
|
*/
|
||||||
|
getdns_return_t _getdns_tls_connection_is_session_reused(_getdns_tls_connection* conn);
|
||||||
|
|
||||||
getdns_return_t _getdns_tls_session_free(_getdns_tls_session* s);
|
getdns_return_t _getdns_tls_session_free(_getdns_tls_session* s);
|
||||||
|
|
||||||
getdns_return_t _getdns_tls_get_api_information(getdns_dict* dict);
|
getdns_return_t _getdns_tls_get_api_information(getdns_dict* dict);
|
||||||
|
|
15
src/stub.c
15
src/stub.c
|
@ -1093,13 +1093,10 @@ tls_do_handshake(getdns_upstream *upstream)
|
||||||
DEBUG_STUB("%s %-35s: FD: %d \n", STUB_DEBUG_SETUP_TLS,
|
DEBUG_STUB("%s %-35s: FD: %d \n", STUB_DEBUG_SETUP_TLS,
|
||||||
__FUNC__, upstream->fd);
|
__FUNC__, upstream->fd);
|
||||||
int r;
|
int r;
|
||||||
int want;
|
while ((r = _getdns_tls_connection_do_handshake(upstream->tls_obj)) != GETDNS_RETURN_GOOD)
|
||||||
ERR_clear_error();
|
|
||||||
while ((r = SSL_do_handshake(upstream->tls_obj->ssl)) != 1)
|
|
||||||
{
|
{
|
||||||
want = SSL_get_error(upstream->tls_obj->ssl, r);
|
switch (r) {
|
||||||
switch (want) {
|
case GETDNS_RETURN_TLS_WANT_READ:
|
||||||
case SSL_ERROR_WANT_READ:
|
|
||||||
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
||||||
upstream->event.read_cb = upstream_read_cb;
|
upstream->event.read_cb = upstream_read_cb;
|
||||||
upstream->event.write_cb = NULL;
|
upstream->event.write_cb = NULL;
|
||||||
|
@ -1107,7 +1104,7 @@ tls_do_handshake(getdns_upstream *upstream)
|
||||||
upstream->fd, TIMEOUT_TLS, &upstream->event);
|
upstream->fd, TIMEOUT_TLS, &upstream->event);
|
||||||
upstream->tls_hs_state = GETDNS_HS_READ;
|
upstream->tls_hs_state = GETDNS_HS_READ;
|
||||||
return STUB_TCP_RETRY;
|
return STUB_TCP_RETRY;
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case GETDNS_RETURN_TLS_WANT_WRITE:
|
||||||
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
|
||||||
upstream->event.read_cb = NULL;
|
upstream->event.read_cb = NULL;
|
||||||
upstream->event.write_cb = upstream_write_cb;
|
upstream->event.write_cb = upstream_write_cb;
|
||||||
|
@ -1123,7 +1120,7 @@ tls_do_handshake(getdns_upstream *upstream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* A re-used session is not verified so need to fix up state in that case */
|
/* A re-used session is not verified so need to fix up state in that case */
|
||||||
if (SSL_session_reused(upstream->tls_obj->ssl))
|
if (!_getdns_tls_connection_is_session_reused(upstream->tls_obj))
|
||||||
upstream->tls_auth_state = upstream->last_tls_auth_state;
|
upstream->tls_auth_state = upstream->last_tls_auth_state;
|
||||||
|
|
||||||
else if (upstream->tls_pubkey_pinset || upstream->tls_auth_name[0]) {
|
else if (upstream->tls_pubkey_pinset || upstream->tls_auth_name[0]) {
|
||||||
|
@ -1232,7 +1229,7 @@ tls_do_handshake(getdns_upstream *upstream)
|
||||||
DEBUG_STUB("%s %-35s: FD: %d Handshake succeeded with auth state %s. Session is %s.\n",
|
DEBUG_STUB("%s %-35s: FD: %d Handshake succeeded with auth state %s. Session is %s.\n",
|
||||||
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd,
|
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd,
|
||||||
_getdns_auth_str(upstream->tls_auth_state),
|
_getdns_auth_str(upstream->tls_auth_state),
|
||||||
SSL_session_reused(upstream->tls_obj) ?"re-used":"new");
|
_getdns_tls_connection_is_session_reused(upstream->tls_obj) ? "new" : "re-used");
|
||||||
upstream->tls_hs_state = GETDNS_HS_DONE;
|
upstream->tls_hs_state = GETDNS_HS_DONE;
|
||||||
upstream->conn_state = GETDNS_CONN_OPEN;
|
upstream->conn_state = GETDNS_CONN_OPEN;
|
||||||
upstream->conn_completed++;
|
upstream->conn_completed++;
|
||||||
|
|
Loading…
Reference in New Issue