diff --git a/docs/tutorial.rst b/docs/tutorial.rst index db52c93..dd0692d 100644 --- a/docs/tutorial.rst +++ b/docs/tutorial.rst @@ -317,7 +317,7 @@ Other required engine callbacks are a set of stream and connection callbacks tha /* --- 8< --- snip --- 8< --- */ .ea_stream_if = &stream_callbacks, .ea_stream_if_ctx = &some_context, - .ea_get_ssl_ctx = get_ssl_ctx, /* Server only */ + .ea_get_ssl_ctx = get_ssl_ctx, }; diff --git a/src/liblsquic/lsquic_enc_sess.h b/src/liblsquic/lsquic_enc_sess.h index ca2d65f..072fc90 100644 --- a/src/liblsquic/lsquic_enc_sess.h +++ b/src/liblsquic/lsquic_enc_sess.h @@ -264,7 +264,7 @@ struct enc_session_funcs_iquic const struct ver_neg *, void *(crypto_streams)[4], const struct crypto_stream_if *, const unsigned char *, size_t, - struct lsquic_alarmset *, unsigned); + struct lsquic_alarmset *, unsigned, void*); void (*esfi_destroy) (enc_session_t *); diff --git a/src/liblsquic/lsquic_enc_sess_ietf.c b/src/liblsquic/lsquic_enc_sess_ietf.c index 71c9e4a..e9af0b4 100644 --- a/src/liblsquic/lsquic_enc_sess_ietf.c +++ b/src/liblsquic/lsquic_enc_sess_ietf.c @@ -817,10 +817,11 @@ iquic_esfi_create_client (const char *hostname, const lsquic_cid_t *dcid, const struct ver_neg *ver_neg, void *crypto_streams[4], const struct crypto_stream_if *cryst_if, const unsigned char *sess_resume, size_t sess_resume_sz, - struct lsquic_alarmset *alset, unsigned max_streams_uni) + struct lsquic_alarmset *alset, unsigned max_streams_uni, void* peer_ctx) { struct enc_sess_iquic *enc_sess; SSL_CTX *ssl_ctx = NULL; + int set_app_ctx = 0; SSL_SESSION *ssl_session; const struct alpn_map *am; int transpa_len; @@ -884,29 +885,39 @@ iquic_esfi_create_client (const char *hostname, enc_sess->esi_alpn = am->alpn; } - LSQ_DEBUG("Create new SSL_CTX"); - ssl_ctx = SSL_CTX_new(TLS_method()); + ssl_ctx = enc_sess->esi_enpub->enp_get_ssl_ctx( peer_ctx ); if (!ssl_ctx) { - LSQ_ERROR("cannot create SSL context: %s", - ERR_error_string(ERR_get_error(), errbuf)); - goto err; + LSQ_DEBUG("Create new SSL_CTX"); + ssl_ctx = SSL_CTX_new(TLS_method()); + if (!ssl_ctx) + { + LSQ_ERROR("cannot create SSL context: %s", + ERR_error_string(ERR_get_error(), errbuf)); + goto err; + } + SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION); + SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION); + SSL_CTX_set_default_verify_paths(ssl_ctx); + SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_CLIENT); + if (enc_sess->esi_enpub->enp_stream_if->on_sess_resume_info) + SSL_CTX_sess_set_new_cb(ssl_ctx, iquic_new_session_cb); + if (enc_sess->esi_enpub->enp_kli) + SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback); + if (enc_sess->esi_enpub->enp_verify_cert + || LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT) + || LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_QLOG)) + SSL_CTX_set_custom_verify(ssl_ctx, SSL_VERIFY_PEER, + verify_server_cert_callback); + SSL_CTX_set_early_data_enabled(ssl_ctx, 1); + set_app_ctx = 0; } - SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_3_VERSION); - SSL_CTX_set_max_proto_version(ssl_ctx, TLS1_3_VERSION); - SSL_CTX_set_default_verify_paths(ssl_ctx); - SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_CLIENT); - if (enc_sess->esi_enpub->enp_stream_if->on_sess_resume_info) - SSL_CTX_sess_set_new_cb(ssl_ctx, iquic_new_session_cb); - if (enc_sess->esi_enpub->enp_kli) - SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback); - if (enc_sess->esi_enpub->enp_verify_cert - || LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_EVENT) - || LSQ_LOG_ENABLED_EXT(LSQ_LOG_DEBUG, LSQLM_QLOG)) - SSL_CTX_set_custom_verify(ssl_ctx, SSL_VERIFY_PEER, - verify_server_cert_callback); - SSL_CTX_set_early_data_enabled(ssl_ctx, 1); - + else + { + set_app_ctx = 1; + } + + enc_sess->esi_ssl = SSL_new(ssl_ctx); if (!enc_sess->esi_ssl) { @@ -975,13 +986,14 @@ iquic_esfi_create_client (const char *hostname, lsquic_alarmset_init_alarm(enc_sess->esi_alset, AL_SESS_TICKET, no_sess_ticket, enc_sess); - SSL_CTX_free(ssl_ctx); + if( !set_app_ctx ) + SSL_CTX_free(ssl_ctx); return enc_sess; err: if (enc_sess) iquic_esfi_destroy(enc_sess); - if (ssl_ctx) + if (!set_app_ctx && ssl_ctx) SSL_CTX_free(ssl_ctx); return NULL; } diff --git a/src/liblsquic/lsquic_engine.c b/src/liblsquic/lsquic_engine.c index 279bbed..1ce6e33 100644 --- a/src/liblsquic/lsquic_engine.c +++ b/src/liblsquic/lsquic_engine.c @@ -1747,7 +1747,7 @@ lsquic_engine_connect (lsquic_engine_t *engine, enum lsquic_version version, if (versions & LSQUIC_IETF_VERSIONS) conn = lsquic_ietf_full_conn_client_new(&engine->pub, versions, flags, hostname, base_plpmtu, - is_ipv4, sess_resume, sess_resume_len, token, token_sz); + is_ipv4, sess_resume, sess_resume_len, token, token_sz, peer_ctx); else conn = lsquic_gquic_full_conn_client_new(&engine->pub, versions, flags, hostname, base_plpmtu, is_ipv4, diff --git a/src/liblsquic/lsquic_full_conn.h b/src/liblsquic/lsquic_full_conn.h index d809a0e..c5ee1c5 100644 --- a/src/liblsquic/lsquic_full_conn.h +++ b/src/liblsquic/lsquic_full_conn.h @@ -19,7 +19,7 @@ lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *, unsigned flags /* Only FC_SERVER and FC_HTTP */, const char *hostname, unsigned short base_plpmtu, int is_ipv4, const unsigned char *sess_resume, size_t, - const unsigned char *token, size_t); + const unsigned char *token, size_t, void* peer_ctx); typedef struct lsquic_conn * (*server_conn_ctor_f) (struct lsquic_engine_public *, diff --git a/src/liblsquic/lsquic_full_conn_ietf.c b/src/liblsquic/lsquic_full_conn_ietf.c index 7917809..14afeaa 100644 --- a/src/liblsquic/lsquic_full_conn_ietf.c +++ b/src/liblsquic/lsquic_full_conn_ietf.c @@ -1303,7 +1303,7 @@ lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub, unsigned versions, unsigned flags, const char *hostname, unsigned short base_plpmtu, int is_ipv4, const unsigned char *sess_resume, size_t sess_resume_sz, - const unsigned char *token, size_t token_sz) + const unsigned char *token, size_t token_sz, void* peer_ctx) { const struct transport_params *params; const struct enc_session_funcs_iquic *esfi; @@ -1397,7 +1397,7 @@ lsquic_ietf_full_conn_client_new (struct lsquic_engine_public *enpub, &conn->ifc_u.cli.ifcli_ver_neg, (void **) conn->ifc_u.cli.crypto_streams, &crypto_stream_if, sess_resume, sess_resume_sz, &conn->ifc_alset, - conn->ifc_max_streams_in[SD_UNI]); + conn->ifc_max_streams_in[SD_UNI], peer_ctx); if (!conn->ifc_conn.cn_enc_session) goto err2;