#include "internal/refcount.h"
#include "internal/ktls.h"
-static int ssl_undefined_function_1(SSL_CONNECTION *sc, SSL3_RECORD *r, size_t s,
- int t, SSL_MAC_BUF *mac, size_t macsize)
-{
- return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc));
-}
-
-static int ssl_undefined_function_2(SSL_CONNECTION *sc, SSL3_RECORD *r,
- unsigned char *s, int t)
-{
- return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc));
-}
-
static int ssl_undefined_function_3(SSL_CONNECTION *sc, unsigned char *r,
unsigned char *s, size_t t, size_t *u)
{
}
SSL3_ENC_METHOD ssl3_undef_enc_method = {
- ssl_undefined_function_1,
- ssl_undefined_function_2,
ssl_undefined_function_8,
ssl_undefined_function_3,
ssl_undefined_function_4,
void OPENSSL_VPROC_FUNC(void) {}
#endif
-
-static void clear_ciphers(SSL_CONNECTION *s)
+static int clear_record_layer(SSL_CONNECTION *s)
{
- /* clear the current cipher */
- ssl_clear_cipher_ctx(s);
- ssl_clear_hash_ctx(&s->read_hash);
- ssl_clear_hash_ctx(&s->write_hash);
+ int ret;
+
+ /* We try and reset both record layers even if one fails */
+
+ ret = ssl_set_new_record_layer(s,
+ SSL_CONNECTION_IS_DTLS(s) ? DTLS_ANY_VERSION
+ : TLS_ANY_VERSION,
+ OSSL_RECORD_DIRECTION_READ,
+ OSSL_RECORD_PROTECTION_LEVEL_NONE,
+ NULL, 0, NULL, 0, NULL, 0, NULL, 0,
+ NID_undef, NULL, NULL);
+
+ ret &= ssl_set_new_record_layer(s,
+ SSL_CONNECTION_IS_DTLS(s) ? DTLS_ANY_VERSION
+ : TLS_ANY_VERSION,
+ OSSL_RECORD_DIRECTION_WRITE,
+ OSSL_RECORD_PROTECTION_LEVEL_NONE,
+ NULL, 0, NULL, 0, NULL, 0, NULL, 0,
+ NID_undef, NULL, NULL);
+ /* SSLfatal already called in the event of failure */
+ return ret;
}
int SSL_clear(SSL *s)
BUF_MEM_free(sc->init_buf);
sc->init_buf = NULL;
- clear_ciphers(sc);
sc->first_packet = 0;
sc->key_update = SSL_KEY_UPDATE_NONE;
+ memset(sc->ext.compress_certificate_from_peer, 0,
+ sizeof(sc->ext.compress_certificate_from_peer));
+ sc->ext.compress_certificate_sent = 0;
EVP_MD_CTX_free(sc->pha_dgst);
sc->pha_dgst = NULL;
BIO_free(sc->rlayer.rrlnext);
sc->rlayer.rrlnext = NULL;
- if (!ssl_set_new_record_layer(sc,
- SSL_CONNECTION_IS_DTLS(sc) ? DTLS_ANY_VERSION : TLS_ANY_VERSION,
- OSSL_RECORD_DIRECTION_READ,
- OSSL_RECORD_PROTECTION_LEVEL_NONE,
- NULL, 0, NULL, 0, NULL, 0, NULL, 0,
- NID_undef, NULL, NULL)) {
- /* SSLfatal already called */
+ if (!clear_record_layer(sc))
return 0;
- }
- if (!ssl_set_new_record_layer(sc,
- SSL_CONNECTION_IS_DTLS(sc) ? DTLS_ANY_VERSION : TLS_ANY_VERSION,
- OSSL_RECORD_DIRECTION_WRITE,
- OSSL_RECORD_PROTECTION_LEVEL_NONE,
- NULL, 0, NULL, 0, NULL, 0, NULL, 0,
- NID_undef, NULL, NULL)) {
- /* SSLfatal already called */
- return 0;
- }
return 1;
}
s->job = NULL;
+#ifndef OPENSSL_NO_COMP_ALG
+ memcpy(s->cert_comp_prefs, ctx->cert_comp_prefs, sizeof(s->cert_comp_prefs));
+#endif
+
#ifndef OPENSSL_NO_CT
if (!SSL_set_ct_validation_callback(ssl, ctx->ct_validation_callback,
ctx->ct_validation_callback_arg))
/*
* Default SNI name. This rejects empty names, while set1_host below
- * accepts them and disables host name checks. To avoid side-effects with
+ * accepts them and disables hostname checks. To avoid side-effects with
* invalid input, set the SNI name first.
*/
if (sc->ext.hostname == NULL) {
RECORD_LAYER_clear(&s->rlayer);
- BIO_free_all(s->wbio);
- s->wbio = NULL;
- BIO_free_all(s->rbio);
- s->rbio = NULL;
-
BUF_MEM_free(s->init_buf);
/* add extra stuff */
SSL_SESSION_free(s->psksession);
OPENSSL_free(s->psksession_id);
- clear_ciphers(s);
-
ssl_cert_free(s->cert);
OPENSSL_free(s->shared_sigalgs);
/* Free up if allocated */
#ifndef OPENSSL_NO_SRTP
sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
#endif
+
+ /*
+ * We do this late. We want to ensure that any other references we held to
+ * these BIOs are freed first *before* we call BIO_free_all(), because
+ * BIO_free_all() will only free each BIO in the chain if the number of
+ * references to the first BIO have dropped to 0
+ */
+ BIO_free_all(s->wbio);
+ s->wbio = NULL;
+ BIO_free_all(s->rbio);
+ s->rbio = NULL;
}
void SSL_set0_rbio(SSL *s, BIO *rbio)
}
/* If we have an alert to send, lets send it */
- if (sc->s3.alert_dispatch) {
+ if (sc->s3.alert_dispatch > 0) {
ret = (ossl_ssize_t)s->method->ssl_dispatch_alert(s);
if (ret <= 0) {
/* SSLfatal() already called if appropriate */
sc->max_send_fragment = larg;
if (sc->max_send_fragment < sc->split_send_fragment)
sc->split_send_fragment = sc->max_send_fragment;
+ sc->rlayer.wrlmethod->set_max_frag_len(sc->rlayer.wrl, larg);
return 1;
case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT:
if ((size_t)larg > sc->max_send_fragment || larg == 0)
const SSL_METHOD *meth)
{
SSL_CTX *ret = NULL;
+#ifndef OPENSSL_NO_COMP_ALG
+ int i;
+#endif
if (meth == NULL) {
ERR_raise(ERR_LIB_SSL, SSL_R_NULL_SSL_METHOD_PASSED);
ERR_clear_error();
}
# endif
+#endif
+
+#ifndef OPENSSL_NO_COMP_ALG
+ /*
+ * Set the default order: brotli, zlib, zstd
+ * Including only those enabled algorithms
+ */
+ memset(ret->cert_comp_prefs, 0, sizeof(ret->cert_comp_prefs));
+ i = 0;
+ if (ossl_comp_has_alg(TLSEXT_comp_cert_brotli))
+ ret->cert_comp_prefs[i++] = TLSEXT_comp_cert_brotli;
+ if (ossl_comp_has_alg(TLSEXT_comp_cert_zlib))
+ ret->cert_comp_prefs[i++] = TLSEXT_comp_cert_zlib;
+ if (ossl_comp_has_alg(TLSEXT_comp_cert_zstd))
+ ret->cert_comp_prefs[i++] = TLSEXT_comp_cert_zstd;
#endif
/*
* Disable compression by default to prevent CRIME. Applications can
sc->shutdown = 0;
ossl_statem_clear(sc);
sc->handshake_func = s->method->ssl_accept;
- clear_ciphers(sc);
+ /* Ignore return value. Its a void public API function */
+ clear_record_layer(sc);
}
void SSL_set_connect_state(SSL *s)
sc->shutdown = 0;
ossl_statem_clear(sc);
sc->handshake_func = s->method->ssl_connect;
- clear_ciphers(sc);
+ /* Ignore return value. Its a void public API function */
+ clear_record_layer(sc);
}
int ssl_undefined_function(SSL *s)
return NULL;
}
-void ssl_clear_cipher_ctx(SSL_CONNECTION *s)
-{
- if (s->enc_read_ctx != NULL) {
- EVP_CIPHER_CTX_free(s->enc_read_ctx);
- s->enc_read_ctx = NULL;
- }
- if (s->enc_write_ctx != NULL) {
- EVP_CIPHER_CTX_free(s->enc_write_ctx);
- s->enc_write_ctx = NULL;
- }
-#ifndef OPENSSL_NO_COMP
- COMP_CTX_free(s->expand);
- s->expand = NULL;
- COMP_CTX_free(s->compress);
- s->compress = NULL;
-#endif
-}
-
X509 *SSL_get_certificate(const SSL *s)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
if (sc == NULL)
return NULL;
- /* TODO(RECLAYER): Remove me once SSLv3/DTLS moved to write record layer */
- if (SSL_CONNECTION_IS_DTLS(sc) || sc->version == SSL3_VERSION)
- return sc->compress ? COMP_CTX_get_method(sc->compress) : NULL;
-
return sc->rlayer.wrlmethod->get_compression(sc->rlayer.wrl);
#else
return NULL;
return ctx->num_tickets;
}
-/*
- * Allocates new EVP_MD_CTX and sets pointer to it into given pointer
- * variable, freeing EVP_MD_CTX previously stored in that variable, if any.
- * If EVP_MD pointer is passed, initializes ctx with this |md|.
- * Returns the newly allocated ctx;
- */
-
-EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md)
-{
- ssl_clear_hash_ctx(hash);
- *hash = EVP_MD_CTX_new();
- if (*hash == NULL || (md && EVP_DigestInit_ex(*hash, md, NULL) <= 0)) {
- EVP_MD_CTX_free(*hash);
- *hash = NULL;
- return NULL;
- }
- return *hash;
-}
-
-void ssl_clear_hash_ctx(EVP_MD_CTX **hash)
-{
-
- EVP_MD_CTX_free(*hash);
- *hash = NULL;
-}
-
/* Retrieve handshake hashes */
int ssl_handshake_hash(SSL_CONNECTION *s,
unsigned char *out, size_t outlen,
}
}
- while (sk_SCT_num(src) > 0) {
- sct = sk_SCT_pop(src);
+ while ((sct = sk_SCT_pop(src)) != NULL) {
if (SCT_set_source(sct, origin) != 1)
goto err;
rl = &sc->rlayer;
- if (RECORD_LAYER_read_pending(rl) || RECORD_LAYER_write_pending(rl))
- return 0;
-
- RECORD_LAYER_release(rl);
- return 1;
+ return rl->rrlmethod->free_buffers(rl->rrl)
+ && rl->wrlmethod->free_buffers(rl->wrl);
}
int SSL_alloc_buffers(SSL *ssl)
{
+ RECORD_LAYER *rl;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
if (sc == NULL)
return 0;
- return ssl3_setup_buffers(sc);
+ rl = &sc->rlayer;
+
+ return rl->rrlmethod->alloc_buffers(rl->rrl)
+ && rl->wrlmethod->alloc_buffers(rl->wrl);
}
void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb)