Replace SSL_read().

This commit is contained in:
Jim Hague 2018-11-15 14:50:00 +00:00
parent e22c01e212
commit e7453522d5
3 changed files with 65 additions and 25 deletions

View File

@ -284,8 +284,7 @@ getdns_return_t _getdns_tls_connection_shutdown(_getdns_tls_connection* conn)
if (!conn || !conn->ssl) if (!conn || !conn->ssl)
return GETDNS_RETURN_INVALID_PARAMETER; return GETDNS_RETURN_INVALID_PARAMETER;
switch(SSL_shutdown(conn->ssl)) switch (SSL_shutdown(conn->ssl)) {
{
case 0: return GETDNS_RETURN_CONTEXT_UPDATE_FAIL; case 0: return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
case 1: return GETDNS_RETURN_GOOD; case 1: return GETDNS_RETURN_GOOD;
default: return GETDNS_RETURN_GENERIC_ERROR; default: return GETDNS_RETURN_GENERIC_ERROR;
@ -356,8 +355,7 @@ getdns_return_t _getdns_tls_connection_do_handshake(_getdns_tls_connection* conn
if (r == 1) if (r == 1)
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
err = SSL_get_error(conn->ssl, r); err = SSL_get_error(conn->ssl, r);
switch(err) switch (err) {
{
case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_READ:
return GETDNS_RETURN_TLS_WANT_READ; return GETDNS_RETURN_TLS_WANT_READ;
@ -380,6 +378,32 @@ getdns_return_t _getdns_tls_connection_is_session_reused(_getdns_tls_connection*
return GETDNS_RETURN_TLS_CONNECTION_FRESH; return GETDNS_RETURN_TLS_CONNECTION_FRESH;
} }
getdns_return_t _getdns_tls_connection_read(_getdns_tls_connection* conn, uint8_t* buf, size_t to_read, size_t* read)
{
int sread;
if (!conn || !conn->ssl || !read)
return -GETDNS_RETURN_INVALID_PARAMETER;
ERR_clear_error();
sread = SSL_read(conn->ssl, buf, to_read);
if (sread <= 0) {
switch (SSL_get_error(conn->ssl, sread)) {
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;
}
}
*read = sread;
return GETDNS_RETURN_GOOD;
}
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)
@ -389,8 +413,6 @@ getdns_return_t _getdns_tls_session_free(_getdns_tls_session* s)
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }
getdns_return_t _getdns_tls_get_api_information(getdns_dict* dict) getdns_return_t _getdns_tls_get_api_information(getdns_dict* dict)
{ {
if (! getdns_dict_set_int( if (! getdns_dict_set_int(

View File

@ -105,6 +105,21 @@ getdns_return_t _getdns_tls_connection_do_handshake(_getdns_tls_connection* conn
*/ */
getdns_return_t _getdns_tls_connection_is_session_reused(_getdns_tls_connection* conn); getdns_return_t _getdns_tls_connection_is_session_reused(_getdns_tls_connection* conn);
/**
* Read from TLS.
*
* @param conn the connection.
* @param buf the buffer to read to.
* @param to_read the number of bytes to read.
* @param read pointer to holder for the number of bytes read.
* @return GETDNS_RETURN_GOOD if some bytes were read.
* @return GETDNS_RETURN_INVALID_PARAMETER if conn is null or has no SSL.
* @return GETDNS_RETURN_TLS_WANT_READ if the read needs to be retried.
* @return GETDNS_RETURN_TLS_WANT_WRITE if handshake isn't finished.
* @return GETDNS_RETURN_GENERIC_ERROR if read failed.
*/
getdns_return_t _getdns_tls_connection_read(_getdns_tls_connection* conn, uint8_t* buf, size_t to_read, size_t* read);
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);

View File

@ -1273,10 +1273,10 @@ static int
stub_tls_read(getdns_upstream *upstream, getdns_tcp_state *tcp, stub_tls_read(getdns_upstream *upstream, getdns_tcp_state *tcp,
struct mem_funcs *mf) struct mem_funcs *mf)
{ {
ssize_t read; size_t read;
uint8_t *buf; uint8_t *buf;
size_t buf_size; size_t buf_size;
SSL* tls_obj = upstream->tls_obj->ssl; _getdns_tls_connection* tls_obj = upstream->tls_obj;
int q = tls_connected(upstream); int q = tls_connected(upstream);
if (q != 0) if (q != 0)
@ -1292,15 +1292,16 @@ stub_tls_read(getdns_upstream *upstream, getdns_tcp_state *tcp,
tcp->to_read = 2; /* Packet size */ tcp->to_read = 2; /* Packet size */
} }
ERR_clear_error(); switch ((int)_getdns_tls_connection_read(tls_obj, tcp->read_pos, tcp->to_read, &read)) {
read = SSL_read(tls_obj, tcp->read_pos, tcp->to_read); case GETDNS_RETURN_GOOD:
if (read <= 0) { break;
/* TODO[TLS]: Handle SSL_ERROR_WANT_WRITE which means handshake
renegotiation. Need to keep handshake state to do that.*/ case GETDNS_RETURN_TLS_WANT_READ:
int want = SSL_get_error(tls_obj, read);
if (want == SSL_ERROR_WANT_READ) {
return STUB_TCP_RETRY; /* Come back later */ return STUB_TCP_RETRY; /* Come back later */
} else
default:
/* TODO[TLS]: Handle GETDNS_RETURN_TLS_WANT_WRITE which means handshake
renegotiation. Need to keep handshake state to do that.*/
return STUB_TCP_ERROR; return STUB_TCP_ERROR;
} }
tcp->to_read -= read; tcp->to_read -= read;
@ -1333,14 +1334,16 @@ stub_tls_read(getdns_upstream *upstream, getdns_tcp_state *tcp,
/* Ready to start reading the packet */ /* Ready to start reading the packet */
tcp->read_pos = tcp->read_buf; tcp->read_pos = tcp->read_buf;
read = SSL_read(tls_obj, tcp->read_pos, tcp->to_read); switch ((int)_getdns_tls_connection_read(tls_obj, tcp->read_pos, tcp->to_read, &read)) {
if (read <= 0) { case GETDNS_RETURN_GOOD:
/* TODO[TLS]: Handle SSL_ERROR_WANT_WRITE which means handshake break;
case GETDNS_RETURN_TLS_WANT_READ:
return STUB_TCP_RETRY; /* Come back later */
default:
/* TODO[TLS]: Handle GETDNS_RETURN_TLS_WANT_WRITE which means handshake
renegotiation. Need to keep handshake state to do that.*/ renegotiation. Need to keep handshake state to do that.*/
int want = SSL_get_error(tls_obj, read);
if (want == SSL_ERROR_WANT_READ) {
return STUB_TCP_RETRY; /* read more later */
} else
return STUB_TCP_ERROR; return STUB_TCP_ERROR;
} }
tcp->to_read -= read; tcp->to_read -= read;