From bfec8198f2a4f1a9229f5118bb0c344cec2b7ed1 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> Date: Tue, 4 Feb 2020 00:18:08 +0900 Subject: [PATCH] Add API to remember the TLS error --- crypto/openssl/openssl.c | 2 ++ examples/client.cc | 3 +++ examples/server.cc | 3 +++ lib/includes/ngtcp2/ngtcp2.h | 21 +++++++++++++++++++++ lib/ngtcp2_conn.c | 8 ++++++++ lib/ngtcp2_conn.h | 2 ++ lib/ngtcp2_err.c | 1 + 7 files changed, 40 insertions(+) diff --git a/crypto/openssl/openssl.c b/crypto/openssl/openssl.c index 17320ae9..5e6a8493 100644 --- a/crypto/openssl/openssl.c +++ b/crypto/openssl/openssl.c @@ -381,11 +381,13 @@ int ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn *conn, void *tls, rv = ngtcp2_decode_transport_params(¶ms, exttype, tp, tplen); if (rv != 0) { + ngtcp2_conn_set_tls_error(conn, rv); return -1; } rv = ngtcp2_conn_set_remote_transport_params(conn, ¶ms); if (rv != 0) { + ngtcp2_conn_set_tls_error(conn, rv); return -1; } diff --git a/examples/client.cc b/examples/client.cc index 84253fe1..d25c54db 100644 --- a/examples/client.cc +++ b/examples/client.cc @@ -475,6 +475,9 @@ int recv_crypto_data(ngtcp2_conn *conn, ngtcp2_crypto_level crypto_level, auto c = static_cast<Client *>(user_data); if (c->recv_crypto_data(crypto_level, data, datalen) != 0) { + if (auto err = ngtcp2_conn_get_tls_error(conn); err) { + return err; + } return NGTCP2_ERR_CRYPTO; } diff --git a/examples/server.cc b/examples/server.cc index 427a3d29..8797fe1c 100644 --- a/examples/server.cc +++ b/examples/server.cc @@ -772,6 +772,9 @@ int recv_crypto_data(ngtcp2_conn *conn, ngtcp2_crypto_level crypto_level, auto h = static_cast<Handler *>(user_data); if (h->recv_crypto_data(crypto_level, data, datalen) != 0) { + if (auto err = ngtcp2_conn_get_tls_error(conn); err) { + return err; + } return NGTCP2_ERR_CRYPTO; } diff --git a/lib/includes/ngtcp2/ngtcp2.h b/lib/includes/ngtcp2/ngtcp2.h index 917cbb6f..936b876e 100644 --- a/lib/includes/ngtcp2/ngtcp2.h +++ b/lib/includes/ngtcp2/ngtcp2.h @@ -1932,6 +1932,27 @@ NGTCP2_EXTERN int ngtcp2_conn_install_key( NGTCP2_EXTERN int ngtcp2_conn_initiate_key_update(ngtcp2_conn *conn, ngtcp2_tstamp ts); +/** + * @function + * + * `ngtcp2_conn_set_tls_error` sets the TLS related error in |conn|. + * In general, error code should be propagated via return value, but + * sometimes ngtcp2 API is called inside callback function of TLS + * stack and it does not allow to return ngtcp2 error code directly. + * In this case, implementation can set the error code (e.g., + * NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM) using this function. + */ +NGTCP2_EXTERN void ngtcp2_conn_set_tls_error(ngtcp2_conn *conn, int liberr); + +/** + * @function + * + * `ngtcp2_conn_get_tls_error` returns the value set by + * `ngtcp2_conn_set_tls_error`. If no value is set, this function + * returns 0. + */ +NGTCP2_EXTERN int ngtcp2_conn_get_tls_error(ngtcp2_conn *conn); + /** * @function * diff --git a/lib/ngtcp2_conn.c b/lib/ngtcp2_conn.c index 4daf7914..bda3fde1 100644 --- a/lib/ngtcp2_conn.c +++ b/lib/ngtcp2_conn.c @@ -9261,6 +9261,14 @@ void ngtcp2_conn_get_connection_close_error_code( *ccec = conn->rx.ccec; } +void ngtcp2_conn_set_tls_error(ngtcp2_conn *conn, int liberr) { + conn->crypto.tls_error = liberr; +} + +int ngtcp2_conn_get_tls_error(ngtcp2_conn *conn) { + return conn->crypto.tls_error; +} + void ngtcp2_path_challenge_entry_init(ngtcp2_path_challenge_entry *pcent, const uint8_t *data) { memcpy(pcent->data, data, sizeof(pcent->data)); diff --git a/lib/ngtcp2_conn.h b/lib/ngtcp2_conn.h index ba3a61a8..3b17a3d2 100644 --- a/lib/ngtcp2_conn.h +++ b/lib/ngtcp2_conn.h @@ -422,6 +422,8 @@ struct ngtcp2_conn { ngtcp2_vec decrypt_buf; /* retry_aead is AEAD to verify Retry packet integrity. */ ngtcp2_crypto_aead retry_aead; + /* tls_error is TLS related error. */ + int tls_error; } crypto; /* pkt contains the packet intermediate construction data to support diff --git a/lib/ngtcp2_err.c b/lib/ngtcp2_err.c index 10b6ef81..ae2edb35 100644 --- a/lib/ngtcp2_err.c +++ b/lib/ngtcp2_err.c @@ -122,6 +122,7 @@ uint64_t ngtcp2_err_infer_quic_transport_error_code(int liberr) { return NGTCP2_FINAL_SIZE_ERROR; case NGTCP2_ERR_REQUIRED_TRANSPORT_PARAM: case NGTCP2_ERR_MALFORMED_TRANSPORT_PARAM: + case NGTCP2_ERR_TRANSPORT_PARAM: return NGTCP2_TRANSPORT_PARAMETER_ERROR; case NGTCP2_ERR_INVALID_ARGUMENT: return NGTCP2_INTERNAL_ERROR; -- GitLab