Create the SSL object for QUIC-TLS

The "user" SSL object which represents the QUIC connection should have an
"inner" SSL object to represent the TLS connection.

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19748)
This commit is contained in:
Matt Caswell 2022-11-08 16:20:08 +00:00
parent 342e3652c7
commit a7f41885b3
6 changed files with 40 additions and 23 deletions

View File

@ -118,6 +118,7 @@ SSL *ossl_quic_new(SSL_CTX *ctx)
{
QUIC_CONNECTION *qc = NULL;
SSL *ssl_base = NULL;
SSL_CONNECTION *sc = NULL;
qc = OPENSSL_zalloc(sizeof(*qc));
if (qc == NULL)
@ -125,15 +126,22 @@ SSL *ossl_quic_new(SSL_CTX *ctx)
/* Initialise the QUIC_CONNECTION's stub header. */
ssl_base = &qc->ssl;
if (!ossl_ssl_init(ssl_base, ctx, SSL_TYPE_QUIC_CONNECTION)) {
if (!ossl_ssl_init(ssl_base, ctx, ctx->method, SSL_TYPE_QUIC_CONNECTION)) {
ssl_base = NULL;
goto err;
}
qc->tls = ossl_ssl_connection_new_int(ctx, TLS_client_method());
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_base;
/* Channel is not created yet. */
qc->ssl_mode = qc->ssl.ctx->mode;
qc->last_error = SSL_ERROR_NONE;
qc->blocking = 1;
return ssl_base;
err:
@ -156,6 +164,8 @@ void ossl_quic_free(SSL *s)
BIO_free(qc->net_wbio);
/* Note: SSL_free calls OPENSSL_free(qc) for us */
SSL_free(qc->tls);
}
/* SSL method init */

View File

@ -337,7 +337,7 @@ static int min_max_proto(SSL_CONF_CTX *cctx, const char *value, int *bound)
if (cctx->ctx != NULL)
method_version = cctx->ctx->method->version;
else if (cctx->ssl != NULL)
method_version = cctx->ssl->ctx->method->version;
method_version = cctx->ssl->defltmeth->version;
else
return 0;
if ((new_version = protocol_from_string(value)) < 0)

View File

@ -644,9 +644,9 @@ int ossl_ssl_connection_reset(SSL *s)
* Check to see if we were changed into a different method, if so, revert
* back.
*/
if (s->method != SSL_CONNECTION_GET_CTX(sc)->method) {
if (s->method != s->defltmeth) {
s->method->ssl_deinit(s);
s->method = SSL_CONNECTION_GET_CTX(sc)->method;
s->method = s->defltmeth;
if (!s->method->ssl_init(s))
return 0;
} else {
@ -702,7 +702,7 @@ SSL *SSL_new(SSL_CTX *ctx)
return ctx->method->ssl_new(ctx);
}
int ossl_ssl_init(SSL *ssl, SSL_CTX *ctx, int type)
int ossl_ssl_init(SSL *ssl, SSL_CTX *ctx, const SSL_METHOD *method, int type)
{
ssl->type = type;
@ -714,7 +714,7 @@ int ossl_ssl_init(SSL *ssl, SSL_CTX *ctx, int type)
SSL_CTX_up_ref(ctx);
ssl->ctx = ctx;
ssl->method = ctx->method;
ssl->defltmeth = ssl->method = method;
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, ssl, &ssl->ex_data))
return 0;
@ -722,7 +722,7 @@ int ossl_ssl_init(SSL *ssl, SSL_CTX *ctx, int type)
return 1;
}
SSL *ossl_ssl_connection_new(SSL_CTX *ctx)
SSL *ossl_ssl_connection_new_int(SSL_CTX *ctx, const SSL_METHOD *method)
{
SSL_CONNECTION *s;
SSL *ssl;
@ -732,7 +732,7 @@ SSL *ossl_ssl_connection_new(SSL_CTX *ctx)
return NULL;
ssl = &s->ssl;
if (!ossl_ssl_init(ssl, ctx, SSL_TYPE_SSL_CONNECTION)) {
if (!ossl_ssl_init(ssl, ctx, method, SSL_TYPE_SSL_CONNECTION)) {
OPENSSL_free(s);
s = NULL;
goto sslerr;
@ -860,12 +860,12 @@ SSL *ossl_ssl_connection_new(SSL_CTX *ctx)
s->allow_early_data_cb = ctx->allow_early_data_cb;
s->allow_early_data_cb_data = ctx->allow_early_data_cb_data;
if (!ssl->method->ssl_init(ssl))
if (!method->ssl_init(ssl))
goto sslerr;
s->server = (ctx->method->ssl_accept == ssl_undefined_function) ? 0 : 1;
s->server = (method->ssl_accept == ssl_undefined_function) ? 0 : 1;
if (!SSL_clear(ssl))
if (!method->ssl_reset(ssl))
goto sslerr;
#ifndef OPENSSL_NO_PSK
@ -904,6 +904,11 @@ SSL *ossl_ssl_connection_new(SSL_CTX *ctx)
return NULL;
}
SSL *ossl_ssl_connection_new(SSL_CTX *ctx)
{
return ossl_ssl_connection_new_int(ctx, ctx->method);
}
int SSL_is_dtls(const SSL *s)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
@ -2887,13 +2892,13 @@ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
return 0;
case SSL_CTRL_SET_MIN_PROTO_VERSION:
return ssl_check_allowed_versions(larg, sc->max_proto_version)
&& ssl_set_version_bound(s->ctx->method->version, (int)larg,
&& ssl_set_version_bound(s->defltmeth->version, (int)larg,
&sc->min_proto_version);
case SSL_CTRL_GET_MIN_PROTO_VERSION:
return sc->min_proto_version;
case SSL_CTRL_SET_MAX_PROTO_VERSION:
return ssl_check_allowed_versions(sc->min_proto_version, larg)
&& ssl_set_version_bound(s->ctx->method->version, (int)larg,
&& ssl_set_version_bound(s->defltmeth->version, (int)larg,
&sc->max_proto_version);
case SSL_CTRL_GET_MAX_PROTO_VERSION:
return sc->max_proto_version;

View File

@ -1238,6 +1238,7 @@ typedef struct cert_pkey_st CERT_PKEY;
struct ssl_st {
int type;
SSL_CTX *ctx;
const SSL_METHOD *defltmeth;
const SSL_METHOD *method;
CRYPTO_REF_COUNT references;
CRYPTO_RWLOCK *lock;
@ -1841,6 +1842,7 @@ struct ssl_connection_st {
# define SSL_CONNECTION_FROM_CONST_SSL_ONLY(ssl) \
SSL_CONNECTION_FROM_SSL_ONLY_int(ssl, const)
# define SSL_CONNECTION_GET_CTX(sc) ((sc)->ssl.ctx)
# define SSL_CONNECTION_GET_SSL(sc) (&(sc)->ssl)
# ifndef OPENSSL_NO_QUIC
# include "quic/quic_local.h"
# define SSL_CONNECTION_FROM_SSL_int(ssl, c) \
@ -1854,13 +1856,11 @@ struct ssl_connection_st {
SSL_CONNECTION_FROM_SSL_int(ssl, SSL_CONNECTION_NO_CONST)
# define SSL_CONNECTION_FROM_CONST_SSL(ssl) \
SSL_CONNECTION_FROM_SSL_int(ssl, const)
# define SSL_CONNECTION_GET_SSL(sc) ((sc)->user_ssl)
# else
# define SSL_CONNECTION_FROM_SSL(ssl) \
SSL_CONNECTION_FROM_SSL_ONLY_int(ssl, SSL_CONNECTION_NO_CONST)
# define SSL_CONNECTION_FROM_CONST_SSL(ssl) \
SSL_CONNECTION_FROM_SSL_ONLY_int(ssl, const)
# define SSL_CONNECTION_GET_SSL(sc) (&(sc)->ssl)
# endif
/*
@ -2465,7 +2465,9 @@ static ossl_inline void tls1_get_peer_groups(SSL_CONNECTION *s,
# ifndef OPENSSL_UNIT_TEST
__owur int ossl_ssl_init(SSL *ssl, SSL_CTX *ctx, int type);
__owur int ossl_ssl_init(SSL *ssl, SSL_CTX *ctx, const SSL_METHOD *method,
int type);
__owur SSL *ossl_ssl_connection_new_int(SSL_CTX *ctx, const SSL_METHOD *method);
__owur SSL *ossl_ssl_connection_new(SSL_CTX *ctx);
void ossl_ssl_connection_free(SSL *ssl);
__owur int ossl_ssl_connection_reset(SSL *ssl);

View File

@ -854,8 +854,8 @@ int SSL_set_session(SSL *s, SSL_SESSION *session)
return 0;
ssl_clear_bad_session(sc);
if (s->ctx->method != s->method) {
if (!SSL_set_ssl_method(s, s->ctx->method))
if (s->defltmeth != s->method) {
if (!SSL_set_ssl_method(s, s->defltmeth))
return 0;
}

View File

@ -1657,23 +1657,23 @@ int ssl_check_version_downgrade(SSL_CONNECTION *s)
{
const version_info *vent;
const version_info *table;
SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s);
SSL *ssl = SSL_CONNECTION_GET_SSL(s);
/*
* Check that the current protocol is the highest enabled version
* (according to s->ctx->method, as version negotiation may have changed
* (according to ssl->defltmethod, as version negotiation may have changed
* s->method).
*/
if (s->version == sctx->method->version)
if (s->version == ssl->defltmeth->version)
return 1;
/*
* Apparently we're using a version-flexible SSL_METHOD (not at its
* highest protocol version).
*/
if (sctx->method->version == TLS_method()->version)
if (ssl->defltmeth->version == TLS_method()->version)
table = tls_version_table;
else if (sctx->method->version == DTLS_method()->version)
else if (ssl->defltmeth->version == DTLS_method()->version)
table = dtls_version_table;
else {
/* Unexpected state; fail closed. */