From 38b051a1fedc79ebf24a96de2e9a326ad3665baf Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 20 Jun 2022 17:11:28 +0200 Subject: SSL object refactoring using SSL_CONNECTION object Make the SSL object polymorphic based on whether this is a traditional SSL connection, QUIC connection, or later to be implemented a QUIC stream. It requires adding if after every SSL_CONNECTION_FROM_SSL() call which itself has to be added to almost every public SSL_ API call. Reviewed-by: Richard Levitte Reviewed-by: Hugo Landau Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/18612) --- ssl/quic/quic_impl.c | 97 +++++++++++++++++++++++++++++++++++++++++++++------ ssl/quic/quic_local.h | 44 ++++++++++++++++++++--- 2 files changed, 126 insertions(+), 15 deletions(-) (limited to 'ssl/quic') diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index 5d0c861c76..31dc0b3369 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -11,16 +11,74 @@ #include #include "quic_local.h" -int ossl_quic_new(SSL *s) +SSL *ossl_quic_new(SSL_CTX *ctx) +{ + QUIC_CONNECTION *qc; + SSL *ssl = NULL; + SSL_CONNECTION *sc; + + qc = OPENSSL_zalloc(sizeof(*qc)); + if (qc == NULL) + goto err; + + ssl = &qc->ssl; + if (!ossl_ssl_init(ssl, ctx, SSL_TYPE_QUIC_CONNECTION)) { + OPENSSL_free(qc); + ssl = NULL; + goto err; + } + qc->tls = ossl_ssl_connection_new(ctx); + if (qc->tls == NULL || (sc = SSL_CONNECTION_FROM_SSL(qc->tls)) == NULL) + goto err; + /* override the user_ssl of the inner connection */ + sc->user_ssl = ssl; + + /* We'll need to set proper TLS method on qc->tls here */ + return ssl; +err: + ossl_quic_free(ssl); + return NULL; +} + +int ossl_quic_init(SSL *s) { return s->method->ssl_clear(s); } +void ossl_quic_deinit(SSL *s) +{ + return; +} + void ossl_quic_free(SSL *s) { + QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s); + + if (qc == NULL) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc != NULL) + ossl_ssl_connection_free(s); + return; + } + + SSL_free(qc->tls); return; } +int ossl_quic_reset(SSL *s) +{ + QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s); + + if (qc == NULL) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + return sc != NULL ? ossl_ssl_connection_reset(s) : 0; + } + + return ossl_ssl_connection_reset(qc->tls); +} + int ossl_quic_clear(SSL *s) { return 1; @@ -28,13 +86,23 @@ int ossl_quic_clear(SSL *s) int ossl_quic_accept(SSL *s) { - s->statem.in_init = 0; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_QUIC_SSL(s); + + if (sc == NULL) + return 0; + + sc->statem.in_init = 0; return 1; } int ossl_quic_connect(SSL *s) { - s->statem.in_init = 0; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_QUIC_SSL(s); + + if (sc == NULL) + return 0; + + sc->statem.in_init = 0; return 1; } @@ -42,14 +110,15 @@ int ossl_quic_read(SSL *s, void *buf, size_t len, size_t *readbytes) { int ret; BIO *rbio = SSL_get_rbio(s); + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_QUIC_SSL(s); - if (rbio == NULL) + if (sc == NULL || rbio == NULL) return 0; - s->rwstate = SSL_READING; + sc->rwstate = SSL_READING; ret = BIO_read_ex(rbio, buf, len, readbytes); if (ret > 0 || !BIO_should_retry(rbio)) - s->rwstate = SSL_NOTHING; + sc->rwstate = SSL_NOTHING; return ret <= 0 ? -1 : ret; } @@ -62,14 +131,15 @@ int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written) { BIO *wbio = SSL_get_wbio(s); int ret; + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_QUIC_SSL(s); - if (wbio == NULL) + if (sc == NULL || wbio == NULL) return 0; - s->rwstate = SSL_WRITING; + sc->rwstate = SSL_WRITING; ret = BIO_write_ex(wbio, buf, len, written); if (ret > 0 || !BIO_should_retry(wbio)) - s->rwstate = SSL_NOTHING; + sc->rwstate = SSL_NOTHING; return ret; } @@ -80,12 +150,17 @@ int ossl_quic_shutdown(SSL *s) long ossl_quic_ctrl(SSL *s, int cmd, long larg, void *parg) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_QUIC_SSL(s); + + if (sc == NULL) + return 0; + switch(cmd) { case SSL_CTRL_CHAIN: if (larg) - return ssl_cert_set1_chain(s, NULL, (STACK_OF(X509) *)parg); + return ssl_cert_set1_chain(sc, NULL, (STACK_OF(X509) *)parg); else - return ssl_cert_set0_chain(s, NULL, (STACK_OF(X509) *)parg); + return ssl_cert_set0_chain(sc, NULL, (STACK_OF(X509) *)parg); } return 0; } diff --git a/ssl/quic/quic_local.h b/ssl/quic/quic_local.h index 8bd40cf916..e0d172979f 100644 --- a/ssl/quic/quic_local.h +++ b/ssl/quic/quic_local.h @@ -13,6 +13,36 @@ # include # include "../ssl_local.h" +typedef struct quic_conn_st { + /* type identifier and common data */ + struct ssl_st ssl; + /* the associated tls-1.3 connection data */ + SSL *tls; + /* just an example member */ + uint64_t conn_id; +} QUIC_CONNECTION; + +# define QUIC_CONNECTION_FROM_SSL_int(ssl, c) \ + ((ssl) == NULL ? NULL \ + : ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \ + ? (c QUIC_CONNECTION *)(ssl) \ + : NULL)) + +# define SSL_CONNECTION_FROM_QUIC_SSL_int(ssl, c) \ + ((ssl) == NULL ? NULL \ + : ((ssl)->type == SSL_TYPE_QUIC_CONNECTION \ + ? (c SSL_CONNECTION *)((c QUIC_CONNECTION *)(ssl))->tls \ + : NULL)) + +# define QUIC_CONNECTION_FROM_SSL(ssl) \ + QUIC_CONNECTION_FROM_SSL_int(ssl, SSL_CONNECTION_NO_CONST) +# define QUIC_CONNECTION_FROM_CONST_SSL(ssl) \ + QUIC_CONNECTION_FROM_SSL_int(ssl, const) +# define SSL_CONNECTION_FROM_QUIC_SSL(ssl) \ + SSL_CONNECTION_FROM_QUIC_SSL_int(ssl, SSL_CONNECTION_NO_CONST) +# define SSL_CONNECTION_FROM_CONST_QUIC_SSL(ssl) \ + SSL_CONNECTION_FROM_CONST_QUIC_SSL_int(ssl, const) + # define OSSL_QUIC_ANY_VERSION 0xFFFFF # define IMPLEMENT_quic_meth_func(version, func_name, q_accept, \ @@ -24,8 +54,11 @@ const SSL_METHOD *func_name(void) \ 0, \ 0, \ ossl_quic_new, \ - ossl_quic_clear, \ ossl_quic_free, \ + ossl_quic_reset, \ + ossl_quic_init, \ + ossl_quic_clear, \ + ossl_quic_deinit, \ q_accept, \ q_connect, \ ossl_quic_read, \ @@ -53,8 +86,11 @@ const SSL_METHOD *func_name(void) \ return &func_name##_data; \ } -__owur int ossl_quic_new(SSL *s); +__owur SSL *ossl_quic_new(SSL_CTX *ctx); +__owur int ossl_quic_init(SSL *s); +void ossl_quic_deinit(SSL *s); void ossl_quic_free(SSL *s); +int ossl_quic_reset(SSL *s); int ossl_quic_clear(SSL *s); __owur int ossl_quic_accept(SSL *s); __owur int ossl_quic_connect(SSL *s); @@ -63,9 +99,9 @@ __owur int ossl_quic_peek(SSL *s, void *buf, size_t len, size_t *readbytes); __owur int ossl_quic_write(SSL *s, const void *buf, size_t len, size_t *written); __owur int ossl_quic_shutdown(SSL *s); __owur long ossl_quic_ctrl(SSL *s, int cmd, long larg, void *parg); -__owur long ossl_quic_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg); +__owur long ossl_quic_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); __owur long ossl_quic_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); -__owur long ossl_quic_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp) (void)); +__owur long ossl_quic_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)); __owur size_t ossl_quic_pending(const SSL *s); __owur long ossl_quic_default_timeout(void); __owur int ossl_quic_num_ciphers(void); -- cgit v1.2.1