/*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. All rights reserved.
*
return ssl_undefined_function(SSL_CONNECTION_GET_SSL(sc));
}
-SSL3_ENC_METHOD ssl3_undef_enc_method = {
+const SSL3_ENC_METHOD ssl3_undef_enc_method = {
ssl_undefined_function_8,
ssl_undefined_function_3,
ssl_undefined_function_4,
int ilen = (int)dlen;
int i;
int num;
+ int mdsize;
if (dane->trecs == NULL) {
ERR_raise(ERR_LIB_SSL, SSL_R_DANE_NOT_ENABLED);
}
}
- if (md != NULL && dlen != (size_t)EVP_MD_get_size(md)) {
- ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH);
- return 0;
+ if (md != NULL) {
+ mdsize = EVP_MD_get_size(md);
+ if (mdsize <= 0 || dlen != (size_t)mdsize) {
+ ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH);
+ return 0;
+ }
}
if (!data) {
ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_NULL_DATA);
case DANETLS_SELECTOR_CERT:
if (!d2i_X509(&cert, &p, ilen) || p < data ||
dlen != (size_t)(p - data)) {
+ X509_free(cert);
tlsa_free(t);
ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE);
return 0;
}
if (X509_get0_pubkey(cert) == NULL) {
+ X509_free(cert);
tlsa_free(t);
ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE);
return 0;
}
if ((DANETLS_USAGE_BIT(usage) & DANETLS_TA_MASK) == 0) {
+ /*
+ * The Full(0) certificate decodes to a seemingly valid X.509
+ * object with a plausible key, so the TLSA record is well
+ * formed. However, we don't actually need the certificate for
+ * usages PKIX-EE(1) or DANE-EE(3), because at least the EE
+ * certificate is always presented by the peer. We discard the
+ * certificate, and just use the TLSA data as an opaque blob
+ * for matching the raw presented DER octets.
+ *
+ * DO NOT FREE `t` here, it will be added to the TLSA record
+ * list below!
+ */
X509_free(cert);
break;
}
case DANETLS_SELECTOR_SPKI:
if (!d2i_PUBKEY(&pkey, &p, ilen) || p < data ||
dlen != (size_t)(p - data)) {
+ EVP_PKEY_free(pkey);
tlsa_free(t);
ERR_raise(ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_PUBLIC_KEY);
return 0;
void OPENSSL_VPROC_FUNC(void) {}
#endif
-static int clear_record_layer(SSL_CONNECTION *s)
-{
- 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)
{
if (s->method == NULL) {
OPENSSL_free(sc->psksession_id);
sc->psksession_id = NULL;
sc->psksession_id_len = 0;
- sc->hello_retry_request = 0;
+ sc->hello_retry_request = SSL_HRR_NONE;
sc->sent_tickets = 0;
sc->error = 0;
ossl_statem_clear(sc);
- /* TODO(QUIC): Version handling not yet clear */
sc->version = s->method->version;
sc->client_version = sc->version;
sc->rwstate = SSL_NOTHING;
* 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 {
return 0;
}
- RECORD_LAYER_clear(&sc->rlayer);
- BIO_free(sc->rlayer.rrlnext);
- sc->rlayer.rrlnext = NULL;
-
- if (!clear_record_layer(sc))
+ if (!RECORD_LAYER_reset(&sc->rlayer))
return 0;
return 1;
{
STACK_OF(SSL_CIPHER) *sk;
+ if (IS_QUIC_CTX(ctx)) {
+ ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
+ return 0;
+ }
+
ctx->method = meth;
if (!SSL_CTX_set_ciphersuites(ctx, OSSL_default_ciphersuites())) {
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;
- ssl->references = 1;
ssl->lock = CRYPTO_THREAD_lock_new();
if (ssl->lock == NULL)
return 0;
+ if (!CRYPTO_NEW_REF(&ssl->references, 1)) {
+ CRYPTO_THREAD_lock_free(ssl->lock);
+ return 0;
+ }
+
+ if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, ssl, &ssl->ex_data)) {
+ CRYPTO_THREAD_lock_free(ssl->lock);
+ CRYPTO_FREE_REF(&ssl->references);
+ ssl->lock = NULL;
+ return 0;
+ }
+
SSL_CTX_up_ref(ctx);
ssl->ctx = ctx;
- ssl->method = ctx->method;
-
- if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, ssl, &ssl->ex_data))
- return 0;
+ ssl->defltmeth = ssl->method = method;
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;
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;
+ ssl = NULL;
goto sslerr;
}
-#ifndef OPENSSL_NO_QUIC
- /* set the parent (user visible) ssl to self */
- s->user_ssl = ssl;
-#endif
-
RECORD_LAYER_init(&s->rlayer, s);
s->options = ctx->options;
+
s->dane.flags = ctx->dane.flags;
- s->min_proto_version = ctx->min_proto_version;
- s->max_proto_version = ctx->max_proto_version;
+ if (method->version == ctx->method->version) {
+ s->min_proto_version = ctx->min_proto_version;
+ s->max_proto_version = ctx->max_proto_version;
+ }
+
s->mode = ctx->mode;
s->max_cert_list = ctx->max_cert_list;
s->max_early_data = ctx->max_early_data;
s->recv_max_early_data = ctx->recv_max_early_data;
+
s->num_tickets = ctx->num_tickets;
s->pha_enabled = ctx->pha_enabled;
if (s->param == NULL)
goto asn1err;
X509_VERIFY_PARAM_inherit(s->param, ctx->param);
- s->quiet_shutdown = ctx->quiet_shutdown;
+ s->quiet_shutdown = IS_QUIC_CTX(ctx) ? 0 : ctx->quiet_shutdown;
+
+ if (!IS_QUIC_CTX(ctx))
+ s->ext.max_fragment_len_mode = ctx->ext.max_fragment_len_mode;
- s->ext.max_fragment_len_mode = ctx->ext.max_fragment_len_mode;
s->max_send_fragment = ctx->max_send_fragment;
s->split_send_fragment = ctx->split_send_fragment;
s->max_pipelines = ctx->max_pipelines;
s->key_update = SSL_KEY_UPDATE_NONE;
- s->allow_early_data_cb = ctx->allow_early_data_cb;
- s->allow_early_data_cb_data = ctx->allow_early_data_cb_data;
+ if (!IS_QUIC_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
#ifndef OPENSSL_NO_COMP_ALG
memcpy(s->cert_comp_prefs, ctx->cert_comp_prefs, sizeof(s->cert_comp_prefs));
#endif
+ if (ctx->client_cert_type != NULL) {
+ s->client_cert_type = OPENSSL_memdup(ctx->client_cert_type,
+ ctx->client_cert_type_len);
+ if (s->client_cert_type == NULL)
+ goto sslerr;
+ s->client_cert_type_len = ctx->client_cert_type_len;
+ }
+ if (ctx->server_cert_type != NULL) {
+ s->server_cert_type = OPENSSL_memdup(ctx->server_cert_type,
+ ctx->server_cert_type_len);
+ if (s->server_cert_type == NULL)
+ goto sslerr;
+ s->server_cert_type_len = ctx->server_cert_type_len;
+ }
#ifndef OPENSSL_NO_CT
if (!SSL_set_ct_validation_callback(ssl, ctx->ct_validation_callback,
goto sslerr;
#endif
+ s->ssl_pkey_num = SSL_PKEY_NUM + ctx->sigalg_list_len;
return ssl;
cerr:
ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
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);
+#ifndef OPENSSL_NO_QUIC
+ if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
+ return 0;
+#endif
+
if (sc == NULL)
return 0;
return SSL_CONNECTION_IS_DTLS(sc) ? 1 : 0;
}
+int SSL_is_tls(const SSL *s)
+{
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+#ifndef OPENSSL_NO_QUIC
+ if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
+ return 0;
+#endif
+
+ if (sc == NULL)
+ return 0;
+
+ return SSL_CONNECTION_IS_DTLS(sc) ? 0 : 1;
+}
+
+int SSL_is_quic(const SSL *s)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
+ return 1;
+#endif
+ return 0;
+}
+
int SSL_up_ref(SSL *s)
{
int i;
- if (CRYPTO_UP_REF(&s->references, &i, s->lock) <= 0)
+ if (CRYPTO_UP_REF(&s->references, &i) <= 0)
return 0;
REF_PRINT_COUNT("SSL", s);
if (s == NULL)
return;
- CRYPTO_DOWN_REF(&s->references, &i, s->lock);
+ CRYPTO_DOWN_REF(&s->references, &i);
REF_PRINT_COUNT("SSL", s);
if (i > 0)
return;
SSL_CTX_free(s->ctx);
CRYPTO_THREAD_lock_free(s->lock);
+ CRYPTO_FREE_REF(&s->references);
OPENSSL_free(s);
}
/* Ignore return value */
ssl_free_wbio_buffer(s);
+ /* Ignore return value */
RECORD_LAYER_clear(&s->rlayer);
BUF_MEM_free(s->init_buf);
sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free);
sk_X509_NAME_pop_free(s->client_ca_names, X509_NAME_free);
+ OPENSSL_free(s->client_cert_type);
+ OPENSSL_free(s->server_cert_type);
+
OSSL_STACK_OF_X509_free(s->verified_chain);
if (ssl->method != NULL)
s->wbio = NULL;
BIO_free_all(s->rbio);
s->rbio = NULL;
+ OPENSSL_free(s->s3.tmp.valid_flags);
}
void SSL_set0_rbio(SSL *s, BIO *rbio)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
-#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
- if (qc != NULL) {
- ossl_quic_conn_set0_net_rbio(qc, rbio);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s)) {
+ ossl_quic_conn_set0_net_rbio(s, rbio);
return;
}
#endif
void SSL_set0_wbio(SSL *s, BIO *wbio)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
-#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
- if (qc != NULL) {
- ossl_quic_conn_set0_net_wbio(qc, wbio);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s)) {
+ ossl_quic_conn_set0_net_wbio(s, wbio);
return;
}
#endif
BIO *SSL_get_rbio(const SSL *s)
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
-#ifndef OPENSSL_NO_QUIC
- const QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_CONST_SSL(s);
- if (qc != NULL)
- return ossl_quic_conn_get_net_rbio(qc);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_conn_get_net_rbio(s);
#endif
if (sc == NULL)
BIO *SSL_get_wbio(const SSL *s)
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
-#ifndef OPENSSL_NO_QUIC
- const QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_CONST_SSL(s);
- if (qc != NULL)
- return ossl_quic_conn_get_net_rbio(qc);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_conn_get_net_wbio(s);
#endif
if (sc == NULL)
}
#ifndef OPENSSL_NO_SOCK
+static const BIO_METHOD *fd_method(SSL *s)
+{
+#ifndef OPENSSL_NO_DGRAM
+ if (IS_QUIC(s))
+ return BIO_s_datagram();
+#endif
+
+ return BIO_s_socket();
+}
+
int SSL_set_fd(SSL *s, int fd)
{
int ret = 0;
BIO *bio = NULL;
- bio = BIO_new(BIO_s_socket());
+ if (s->type == SSL_TYPE_QUIC_XSO) {
+ ERR_raise(ERR_LIB_SSL, SSL_R_CONN_USE_ONLY);
+ goto err;
+ }
+
+ bio = BIO_new(fd_method(s));
if (bio == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
int SSL_set_wfd(SSL *s, int fd)
{
BIO *rbio = SSL_get_rbio(s);
+ int desired_type = IS_QUIC(s) ? BIO_TYPE_DGRAM : BIO_TYPE_SOCKET;
- if (rbio == NULL || BIO_method_type(rbio) != BIO_TYPE_SOCKET
+ if (s->type == SSL_TYPE_QUIC_XSO) {
+ ERR_raise(ERR_LIB_SSL, SSL_R_CONN_USE_ONLY);
+ return 0;
+ }
+
+ if (rbio == NULL || BIO_method_type(rbio) != desired_type
|| (int)BIO_get_fd(rbio, NULL) != fd) {
- BIO *bio = BIO_new(BIO_s_socket());
+ BIO *bio = BIO_new(fd_method(s));
if (bio == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
int SSL_set_rfd(SSL *s, int fd)
{
BIO *wbio = SSL_get_wbio(s);
+ int desired_type = IS_QUIC(s) ? BIO_TYPE_DGRAM : BIO_TYPE_SOCKET;
+
+ if (s->type == SSL_TYPE_QUIC_XSO) {
+ ERR_raise(ERR_LIB_SSL, SSL_R_CONN_USE_ONLY);
+ return 0;
+ }
- if (wbio == NULL || BIO_method_type(wbio) != BIO_TYPE_SOCKET
+ if (wbio == NULL || BIO_method_type(wbio) != desired_type
|| ((int)BIO_get_fd(wbio, NULL) != fd)) {
- BIO *bio = BIO_new(BIO_s_socket());
+ BIO *bio = BIO_new(fd_method(s));
if (bio == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_BUF_LIB);
void SSL_set_read_ahead(SSL *s, int yes)
{
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
OSSL_PARAM options[2], *opts = options;
if (sc == NULL)
int SSL_get_read_ahead(const SSL *s)
{
- const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
+ const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);
if (sc == NULL)
return 0;
* That data may not result in any application data, or we may fail to parse
* the records for some reason.
*/
- const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
+ const SSL_CONNECTION *sc;
+
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_has_pending(s);
+#endif
+
+ sc = SSL_CONNECTION_FROM_CONST_SSL(s);
/* Check buffered app data if any first */
if (SSL_CONNECTION_IS_DTLS(sc)) {
TLS_RECORD *rdata;
pitem *item, *iter;
- iter = pqueue_iterator(sc->rlayer.d->buffered_app_data.q);
+ iter = pqueue_iterator(sc->rlayer.d->buffered_app_data);
while ((item = pqueue_next(&iter)) != NULL) {
rdata = item->data;
if (rdata->length > 0)
int SSL_copy_session_id(SSL *t, const SSL *f)
{
int i;
- /* TODO(QUIC): Do we want to support this for QUIC connections? */
+ /* TODO(QUIC FUTURE): Not allowed for QUIC currently. */
SSL_CONNECTION *tsc = SSL_CONNECTION_FROM_SSL_ONLY(t);
const SSL_CONNECTION *fsc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(f);
return 0;
}
- CRYPTO_UP_REF(&fsc->cert->references, &i, fsc->cert->lock);
+ CRYPTO_UP_REF(&fsc->cert->references, &i);
ssl_cert_free(tsc->cert);
tsc->cert = fsc->cert;
if (!SSL_set_session_id_context(t, fsc->sid_ctx, (int)fsc->sid_ctx_length)) {
int SSL_accept(SSL *s)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
- if (qc != NULL)
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
return s->method->ssl_accept(s);
+#endif
if (sc == NULL)
return 0;
int SSL_connect(SSL *s)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
- if (qc != NULL)
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
return s->method->ssl_connect(s);
+#endif
if (sc == NULL)
return 0;
int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
- if (qc != NULL)
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
return s->method->ssl_read(s, buf, num, readbytes);
+#endif
if (sc == NULL)
return -1;
int ret;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
- /* TODO(QUIC): This will need special handling for QUIC */
- if (sc == NULL)
- return 0;
-
- if (!sc->server) {
+ /* TODO(QUIC 0RTT): 0-RTT support */
+ if (sc == NULL || !sc->server) {
ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return SSL_READ_EARLY_DATA_ERROR;
}
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);
- /* TODO(QUIC): This will need special handling for QUIC */
+ /* TODO(QUIC 0RTT): 0-RTT support */
if (sc == NULL)
return 0;
static int ssl_peek_internal(SSL *s, void *buf, size_t num, size_t *readbytes)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
- if (qc != NULL)
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
return s->method->ssl_peek(s, buf, num, readbytes);
+#endif
if (sc == NULL)
return 0;
return ret;
}
-int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written)
+int ssl_write_internal(SSL *s, const void *buf, size_t num,
+ uint64_t flags, size_t *written)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
- if (qc != NULL)
- return s->method->ssl_write(s, buf, num, written);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_write_flags(s, buf, num, flags, written);
+#endif
if (sc == NULL)
return 0;
return -1;
}
+ if (flags != 0) {
+ ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_WRITE_FLAG);
+ return -1;
+ }
+
if (sc->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY
|| sc->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY
|| sc->early_data_state == SSL_EARLY_DATA_READ_RETRY) {
BIO_set_retry_write(sc->wbio);
else
#endif
- ERR_raise(ERR_LIB_SSL, SSL_R_UNINITIALIZED);
+ ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(),
+ "ktls_sendfile failure");
return ret;
}
sc->rwstate = SSL_NOTHING;
return -1;
}
- ret = ssl_write_internal(s, buf, (size_t)num, &written);
+ ret = ssl_write_internal(s, buf, (size_t)num, 0, &written);
/*
* The cast is safe here because ret should be <= INT_MAX because num is
int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written)
{
- int ret = ssl_write_internal(s, buf, num, written);
+ return SSL_write_ex2(s, buf, num, 0, written);
+}
+
+int SSL_write_ex2(SSL *s, const void *buf, size_t num, uint64_t flags,
+ size_t *written)
+{
+ int ret = ssl_write_internal(s, buf, num, flags, written);
if (ret < 0)
ret = 0;
uint32_t partialwrite;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
- /* TODO(QUIC): This will need special handling for QUIC */
+ /* TODO(QUIC 0RTT): This will need special handling for QUIC */
if (sc == NULL)
return 0;
*/
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_conn_shutdown(s, 0, NULL, 0);
+#endif
+
if (sc == NULL)
return -1;
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_key_update(s, updatetype);
+#endif
+
if (sc == NULL)
return 0;
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_get_key_update_type(s);
+#endif
+
if (sc == NULL)
return 0;
}
long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
+{
+ return ossl_ctrl_internal(s, cmd, larg, parg, /*no_quic=*/0);
+}
+
+long ossl_ctrl_internal(SSL *s, int cmd, long larg, void *parg, int no_quic)
{
long l;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
- /* TODO(QUIC): Special handling for some ctrls will be needed */
+ /*
+ * Routing of ctrl calls for QUIC is a little counterintuitive:
+ *
+ * - Firstly (no_quic=0), we pass the ctrl directly to our QUIC
+ * implementation in case it wants to handle the ctrl specially.
+ *
+ * - If our QUIC implementation does not care about the ctrl, it
+ * will reenter this function with no_quic=1 and we will try to handle
+ * it directly using the QCSO SSL object stub (not the handshake layer
+ * SSL object). This is important for e.g. the version configuration
+ * ctrls below, which must use s->defltmeth (and not sc->defltmeth).
+ *
+ * - If we don't handle a ctrl here specially, then processing is
+ * redirected to the handshake layer SSL object.
+ */
+ if (!no_quic && IS_QUIC(s))
+ return s->method->ssl_ctrl(s, cmd, larg, parg);
+
if (sc == NULL)
return 0;
RECORD_LAYER_set_read_ahead(&sc->rlayer, larg);
return l;
- case SSL_CTRL_SET_MSG_CALLBACK_ARG:
- sc->msg_callback_arg = parg;
- return 1;
-
case SSL_CTRL_MODE:
{
OSSL_PARAM options[2], *opts = options;
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;
default:
- return s->method->ssl_ctrl(s, cmd, larg, parg);
+ if (IS_QUIC(s))
+ return SSL_ctrl((SSL *)sc, cmd, larg, parg);
+ else
+ return s->method->ssl_ctrl(s, cmd, larg, parg);
}
}
long SSL_callback_ctrl(SSL *s, int cmd, void (*fp) (void))
{
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
-
- if (sc == NULL)
- return 0;
-
- switch (cmd) {
- case SSL_CTRL_SET_MSG_CALLBACK:
- sc->msg_callback = (void (*)
- (int write_p, int version, int content_type,
- const void *buf, size_t len, SSL *ssl,
- void *arg))(fp);
- return 1;
-
- default:
- return s->method->ssl_callback_ctrl(s, cmd, fp);
- }
+ return s->method->ssl_callback_ctrl(s, cmd, fp);
}
LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx)
return tls1_set_groups_list(ctx, NULL, NULL, parg);
case SSL_CTRL_SET_SIGALGS_LIST:
case SSL_CTRL_SET_CLIENT_SIGALGS_LIST:
- return tls1_set_sigalgs_list(NULL, parg, 0);
+ return tls1_set_sigalgs_list(ctx, NULL, parg, 0);
default:
return 0;
}
if (sk_SSL_CIPHER_find(srvrsk, c) < 0)
continue;
- n = strlen(c->name);
- if (n + 1 > size) {
+ n = OPENSSL_strnlen(c->name, size);
+ if (n >= size) {
if (p != buf)
--p;
*p = '\0';
return buf;
}
- strcpy(p, c->name);
+ memcpy(p, c->name, n);
p += n;
*(p++) = ':';
size -= n + 1;
SSL_CTX_npn_advertised_cb_func cb,
void *arg)
{
+ if (IS_QUIC_CTX(ctx))
+ /* NPN not allowed for QUIC */
+ return;
+
ctx->ext.npn_advertised_cb = cb;
ctx->ext.npn_advertised_cb_arg = arg;
}
SSL_CTX_npn_select_cb_func cb,
void *arg)
{
+ if (IS_QUIC_CTX(ctx))
+ /* NPN not allowed for QUIC */
+ return;
+
ctx->ext.npn_select_cb = cb;
ctx->ext.npn_select_cb_arg = arg;
}
|| (sc->version < TLS1_VERSION && sc->version != DTLS1_BAD_VER))
return -1;
- return s->method->ssl3_enc->export_keying_material(sc, out, olen, label,
- llen, context,
- contextlen, use_context);
+ return sc->ssl.method->ssl3_enc->export_keying_material(sc, out, olen, label,
+ llen, context,
+ contextlen,
+ use_context);
}
int SSL_export_keying_material_early(SSL *s, unsigned char *out, size_t olen,
if (!OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL))
return NULL;
+ /* Doing this for the run once effect */
if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) {
ERR_raise(ERR_LIB_SSL, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
goto err;
}
+
ret = OPENSSL_zalloc(sizeof(*ret));
if (ret == NULL)
- goto err;
+ return NULL;
/* Init the reference counting before any call to SSL_CTX_free */
- ret->references = 1;
+ if (!CRYPTO_NEW_REF(&ret->references, 1)) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB);
ret->session_timeout = meth->get_timeout();
ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
ret->verify_mode = SSL_VERIFY_NONE;
- if ((ret->cert = ssl_cert_new()) == NULL) {
- ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
- goto err;
- }
ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
if (ret->sessions == NULL) {
#endif
/* initialize cipher/digest methods table */
- if (!ssl_load_ciphers(ret))
+ if (!ssl_load_ciphers(ret)) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
goto err;
- /* initialise sig algs */
- if (!ssl_setup_sig_algs(ret))
+ }
+
+ if (!ssl_load_groups(ret)) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
+ goto err;
+ }
+
+ /* load provider sigalgs */
+ if (!ssl_load_sigalgs(ret)) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
goto err;
+ }
- if (!ssl_load_groups(ret))
+ /* initialise sig algs */
+ if (!ssl_setup_sigalgs(ret)) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
goto err;
+ }
if (!SSL_CTX_set_ciphersuites(ret, OSSL_default_ciphersuites())) {
ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
goto err;
}
+ if ((ret->cert = ssl_cert_new(SSL_PKEY_NUM + ret->sigalg_list_len)) == NULL) {
+ ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB);
+ goto err;
+ }
+
if (!ssl_create_cipher_list(ret,
ret->tls13_ciphersuites,
&ret->cipher_list, &ret->cipher_list_by_id,
/* By default we send two session tickets automatically in TLSv1.3 */
ret->num_tickets = 2;
- ssl_ctx_system_config(ret);
+ if (!ssl_ctx_system_config(ret)) {
+ ERR_raise(ERR_LIB_SSL, SSL_R_ERROR_IN_SYSTEM_DEFAULT_CONFIG);
+ goto err;
+ }
return ret;
err:
{
int i;
- if (CRYPTO_UP_REF(&ctx->references, &i, ctx->lock) <= 0)
+ if (CRYPTO_UP_REF(&ctx->references, &i) <= 0)
return 0;
REF_PRINT_COUNT("SSL_CTX", ctx);
if (a == NULL)
return;
- CRYPTO_DOWN_REF(&a->references, &i, a->lock);
+ CRYPTO_DOWN_REF(&a->references, &i);
REF_PRINT_COUNT("SSL_CTX", a);
if (i > 0)
return;
OPENSSL_free(a->group_list[j].algorithm);
}
OPENSSL_free(a->group_list);
+ for (j = 0; j < a->sigalg_list_len; j++) {
+ OPENSSL_free(a->sigalg_list[j].name);
+ OPENSSL_free(a->sigalg_list[j].sigalg_name);
+ OPENSSL_free(a->sigalg_list[j].sigalg_oid);
+ OPENSSL_free(a->sigalg_list[j].sig_name);
+ OPENSSL_free(a->sigalg_list[j].sig_oid);
+ OPENSSL_free(a->sigalg_list[j].hash_name);
+ OPENSSL_free(a->sigalg_list[j].hash_oid);
+ OPENSSL_free(a->sigalg_list[j].keytype);
+ OPENSSL_free(a->sigalg_list[j].keytype_oid);
+ }
+ OPENSSL_free(a->sigalg_list);
+ OPENSSL_free(a->ssl_cert_info);
OPENSSL_free(a->sigalg_lookup_cache);
+ OPENSSL_free(a->tls12_sigalgs);
+
+ OPENSSL_free(a->client_cert_type);
+ OPENSSL_free(a->server_cert_type);
CRYPTO_THREAD_lock_free(a->lock);
+ CRYPTO_FREE_REF(&a->references);
#ifdef TSAN_REQUIRES_LOCKING
CRYPTO_THREAD_lock_free(a->tsan_lock);
#endif
OPENSSL_free(a->propq);
+#ifndef OPENSSL_NO_QLOG
+ OPENSSL_free(a->qlog_title);
+#endif
OPENSSL_free(a);
}
mask_a |= SSL_aNULL;
+ /*
+ * You can do anything with an RPK key, since there's no cert to restrict it
+ * But we need to check for private keys
+ */
+ if (pvalid[SSL_PKEY_RSA] & CERT_PKEY_RPK) {
+ mask_a |= SSL_aRSA;
+ mask_k |= SSL_kRSA;
+ }
+ if (pvalid[SSL_PKEY_ECC] & CERT_PKEY_RPK)
+ mask_a |= SSL_aECDSA;
+ if (TLS1_get_version(&s->ssl) == TLS1_2_VERSION) {
+ if (pvalid[SSL_PKEY_RSA_PSS_SIGN] & CERT_PKEY_RPK)
+ mask_a |= SSL_aRSA;
+ if (pvalid[SSL_PKEY_ED25519] & CERT_PKEY_RPK
+ || pvalid[SSL_PKEY_ED448] & CERT_PKEY_RPK)
+ mask_a |= SSL_aECDSA;
+ }
+
/*
* An ECC certificate may be usable for ECDH and/or ECDSA cipher suites
* depending on the key usage extension.
/*
* If the session_id_length is 0, we are not supposed to cache it, and it
- * would be rather hard to do anyway :-)
+ * would be rather hard to do anyway :-). Also if the session has already
+ * been marked as not_resumable we should not cache it for later reuse.
*/
- if (s->session->session_id_length == 0)
+ if (s->session->session_id_length == 0 || s->session->not_resumable)
return;
/*
int ret = 1;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
- /* TODO(QUIC): Do we want this for QUIC? */
+ /* Not allowed for QUIC */
if (sc == NULL
- || (s->type != SSL_TYPE_SSL_CONNECTION && s->method != meth))
+ || (s->type != SSL_TYPE_SSL_CONNECTION && s->method != meth)
+ || (s->type == SSL_TYPE_SSL_CONNECTION && IS_QUIC_METHOD(meth)))
return 0;
if (s->method != meth) {
}
int SSL_get_error(const SSL *s, int i)
+{
+ return ossl_ssl_get_error(s, i, /*check_err=*/1);
+}
+
+int ossl_ssl_get_error(const SSL *s, int i, int check_err)
{
int reason;
unsigned long l;
BIO *bio;
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
-#ifndef OPENSSL_NO_QUIC
- const QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_CONST_SSL(s);
-#endif
if (i > 0)
return SSL_ERROR_NONE;
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s)) {
+ reason = ossl_quic_get_error(s, i);
+ if (reason != SSL_ERROR_NONE)
+ return reason;
+ }
+#endif
+
if (sc == NULL)
return SSL_ERROR_SSL;
* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
* where we do encode the error
*/
- if ((l = ERR_peek_error()) != 0) {
+ if (check_err && (l = ERR_peek_error()) != 0) {
if (ERR_GET_LIB(l) == ERR_LIB_SYS)
return SSL_ERROR_SYSCALL;
else
}
#ifndef OPENSSL_NO_QUIC
- if (qc != NULL) {
- reason = ossl_quic_get_error(qc, i);
- if (reason != SSL_ERROR_NONE)
- return reason;
- }
-#endif
-
-#ifndef OPENSSL_NO_QUIC
- if (qc == NULL)
+ if (!IS_QUIC(s))
#endif
{
if (SSL_want_read(s)) {
{
int ret = 1;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
-#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
- if (qc != NULL)
- return ossl_quic_do_handshake(qc);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_do_handshake(s);
#endif
if (sc->handshake_func == NULL) {
void SSL_set_accept_state(SSL *s)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
-#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
- if (qc != NULL) {
- ossl_quic_set_accept_state(qc);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s)) {
+ ossl_quic_set_accept_state(s);
return;
}
#endif
ossl_statem_clear(sc);
sc->handshake_func = s->method->ssl_accept;
/* Ignore return value. Its a void public API function */
- clear_record_layer(sc);
+ RECORD_LAYER_reset(&sc->rlayer);
}
void SSL_set_connect_state(SSL *s)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
-#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
- if (qc != NULL) {
- ossl_quic_set_connect_state(qc);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s)) {
+ ossl_quic_set_connect_state(s);
return;
}
#endif
ossl_statem_clear(sc);
sc->handshake_func = s->method->ssl_connect;
/* Ignore return value. Its a void public API function */
- clear_record_layer(sc);
+ RECORD_LAYER_reset(&sc->rlayer);
}
int ssl_undefined_function(SSL *s)
return 0;
}
-const SSL_METHOD *ssl_bad_method(int ver)
-{
- ERR_raise(ERR_LIB_SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
- return NULL;
-}
-
const char *ssl_protocol_to_string(int version)
{
switch (version)
const char *SSL_get_version(const SSL *s)
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
- const QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_CONST_SSL(s);
- if (qc != NULL)
- return "QUIC";
+#ifndef OPENSSL_NO_QUIC
+ /* We only support QUICv1 - so if its QUIC its QUICv1 */
+ if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
+ return "QUICv1";
+#endif
if (sc == NULL)
return NULL;
return ssl_protocol_to_string(sc->version);
}
+__owur int SSL_get_handshake_rtt(const SSL *s, uint64_t *rtt)
+{
+ const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
+
+ if (sc == NULL)
+ return -1;
+ if (sc->ts_msg_write.t <= 0 || sc->ts_msg_read.t <= 0)
+ return 0; /* data not (yet) available */
+ if (sc->ts_msg_read.t < sc->ts_msg_write.t)
+ return -1;
+
+ *rtt = ossl_time2us(ossl_time_subtract(sc->ts_msg_read, sc->ts_msg_write));
+ return 1;
+}
+
static int dup_ca_names(STACK_OF(X509_NAME) **dst, STACK_OF(X509_NAME) *src)
{
STACK_OF(X509_NAME) *sk;
{
SSL *ret;
int i;
- /* TODO(QUIC): Add a SSL_METHOD function for duplication */
+ /* TODO(QUIC FUTURE): Add a SSL_METHOD function for duplication */
SSL_CONNECTION *retsc;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
/* If we're not quiescent, just up_ref! */
if (!SSL_in_init(s) || !SSL_in_before(s)) {
- CRYPTO_UP_REF(&s->references, &i, s->lock);
+ CRYPTO_UP_REF(&s->references, &i);
return s;
}
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
- /* TODO(QUIC): Do we want this for QUIC? */
+ /* Not supported with QUIC */
if (sc == NULL)
return;
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);
- /* TODO(QUIC): Do we want this for QUIC? */
+ /* Not supported with QUIC */
if (sc == NULL)
return 0;
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
- /* TODO(QUIC): Do we want this for QUIC? */
+ /* Not supported with QUIC */
if (sc == NULL)
return;
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s);
- /* TODO(QUIC): Do we want this for QUIC? */
+#ifndef OPENSSL_NO_QUIC
+ /* QUIC: Just indicate whether the connection was shutdown cleanly. */
+ if (IS_QUIC(s))
+ return ossl_quic_get_shutdown(s);
+#endif
+
if (sc == NULL)
return 0;
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
- /* TODO(QUIC): Do we want to report QUIC version this way instead? */
+#ifndef OPENSSL_NO_QUIC
+ /* We only support QUICv1 - so if its QUIC its QUICv1 */
+ if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
+ return OSSL_QUIC1_VERSION;
+#endif
if (sc == NULL)
return 0;
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
- /* TODO(QUIC): Do we want to report QUIC version this way instead? */
+#ifndef OPENSSL_NO_QUIC
+ /* We only support QUICv1 - so if its QUIC its QUICv1 */
+ if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO)
+ return OSSL_QUIC1_VERSION;
+#endif
if (sc == NULL)
return 0;
CERT *new_cert;
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
- /* TODO(QUIC): Do we need this for QUIC support? */
+ /* TODO(QUIC FUTURE): Add support for QUIC */
if (sc == NULL)
return NULL;
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_want(s);
+#endif
+
if (sc == NULL)
return SSL_NOTHING;
int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size)
{
+ if (IS_QUIC_CTX(ctx) && block_size > 1)
+ return 0;
+
/* block size of 0 or 1 is basically no padding */
if (block_size == 1)
ctx->block_padding = 0;
size_t len, void *arg))
{
BIO *b;
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
if (sc == NULL)
return 0;
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
- if (sc == NULL)
+ if (sc == NULL || (IS_QUIC(ssl) && block_size > 1))
return 0;
/* block size of 0 or 1 is basically no padding */
{
const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_get_options(s);
+#endif
+
if (sc == NULL)
return 0;
uint64_t SSL_set_options(SSL *s, uint64_t op)
{
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ SSL_CONNECTION *sc;
OSSL_PARAM options[2], *opts = options;
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_set_options(s, op);
+#endif
+
+ sc = SSL_CONNECTION_FROM_SSL(s);
if (sc == NULL)
return 0;
/* Ignore return value */
sc->rlayer.rrlmethod->set_options(sc->rlayer.rrl, options);
+ sc->rlayer.wrlmethod->set_options(sc->rlayer.wrl, options);
return sc->options;
}
uint64_t SSL_clear_options(SSL *s, uint64_t op)
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ OSSL_PARAM options[2], *opts = options;
+
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_clear_options(s, op);
+#endif
if (sc == NULL)
return 0;
- return sc->options &= ~op;
+ sc->options &= ~op;
+
+ *opts++ = OSSL_PARAM_construct_uint64(OSSL_LIBSSL_RECORD_LAYER_PARAM_OPTIONS,
+ &sc->options);
+ *opts = OSSL_PARAM_construct_end();
+
+ /* Ignore return value */
+ sc->rlayer.rrlmethod->set_options(sc->rlayer.rrl, options);
+ sc->rlayer.wrlmethod->set_options(sc->rlayer.wrl, options);
+
+ return sc->options;
}
STACK_OF(X509) *SSL_get0_verified_chain(const SSL *s)
* If |dst| points to a NULL pointer, a new stack will be created and owned by
* the caller.
* Returns the number of SCTs moved, or a negative integer if an error occurs.
+ * The |dst| stack is created and possibly partially populated even in case
+ * of error, likewise the |src| stack may be left in an intermediate state.
*/
static int ct_move_scts(STACK_OF(SCT) **dst, STACK_OF(SCT) *src,
sct_source_t origin)
if (SCT_set_source(sct, origin) != 1)
goto err;
- if (sk_SCT_push(*dst, sct) <= 0)
+ if (!sk_SCT_push(*dst, sct))
goto err;
scts_moved += 1;
}
return scts_moved;
err:
- if (sct != NULL)
- sk_SCT_push(src, sct); /* Put the SCT back */
+ SCT_free(sct);
return -1;
}
return NULL;
}
-static int ct_permissive(const CT_POLICY_EVAL_CTX * ctx,
+static int ct_permissive(const CT_POLICY_EVAL_CTX *ctx,
const STACK_OF(SCT) *scts, void *unused_arg)
{
return 1;
}
-static int ct_strict(const CT_POLICY_EVAL_CTX * ctx,
+static int ct_strict(const CT_POLICY_EVAL_CTX *ctx,
const STACK_OF(SCT) *scts, void *unused_arg)
{
int count = scts != NULL ? sk_SCT_num(scts) : 0;
return CTLOG_STORE_load_file(ctx->ctlog_store, path);
}
-void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE * logs)
+void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE *logs)
{
CTLOG_STORE_free(ctx->ctlog_store);
ctx->ctlog_store = logs;
int SSL_free_buffers(SSL *ssl)
{
RECORD_LAYER *rl;
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
if (sc == NULL)
return 0;
if (sc == NULL)
return 0;
+ /* QUIC always has buffers allocated. */
+ if (IS_QUIC(ssl))
+ return 1;
+
rl = &sc->rlayer;
return rl->rrlmethod->alloc_buffers(rl->rrl)
int SSL_set_max_early_data(SSL *s, uint32_t max_early_data)
{
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
if (sc == NULL)
return 0;
int SSL_set_recv_max_early_data(SSL *s, uint32_t recv_max_early_data)
{
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
if (sc == NULL)
return 0;
int SSL_stateless(SSL *s)
{
int ret;
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
- /* TODO(QUIC): This will need further work. */
if (sc == NULL)
return 0;
void SSL_set_post_handshake_auth(SSL *ssl, int val)
{
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl);
if (sc == NULL)
return;
{
SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(ssl)) {
+ ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION);
+ return 0;
+ }
+#endif
+
if (sc == NULL)
return 0;
SSL_allow_early_data_cb_fn cb,
void *arg)
{
- SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
if (sc == NULL)
return;
}
/* QUIC-specific methods which are supported on QUIC connections only. */
-int SSL_tick(SSL *s)
+int SSL_handle_events(SSL *s)
{
SSL_CONNECTION *sc;
-#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
- if (qc != NULL)
- return ossl_quic_tick(qc);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_handle_events(s);
#endif
sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
if (sc != NULL && SSL_CONNECTION_IS_DTLS(sc))
- return DTLSv1_handle_timeout(s);
+ /*
+ * DTLSv1_handle_timeout returns 0 if the timer wasn't expired yet,
+ * which we consider a success case. Theoretically DTLSv1_handle_timeout
+ * can also return 0 if s is NULL or not a DTLS object, but we've
+ * already ruled out those possibilities above, so this is not possible
+ * here. Thus the only failure cases are where DTLSv1_handle_timeout
+ * returns -1.
+ */
+ return DTLSv1_handle_timeout(s) >= 0;
- return 0;
+ return 1;
}
-int SSL_get_tick_timeout(SSL *s, struct timeval *tv)
+int SSL_get_event_timeout(SSL *s, struct timeval *tv, int *is_infinite)
{
SSL_CONNECTION *sc;
-#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc;
- qc = QUIC_CONNECTION_FROM_SSL(s);
- if (qc != NULL)
- return ossl_quic_get_tick_timeout(qc, tv);
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_get_event_timeout(s, tv, is_infinite);
#endif
sc = SSL_CONNECTION_FROM_SSL_ONLY(s);
- if (sc != NULL && SSL_CONNECTION_IS_DTLS(sc)) {
- if (!DTLSv1_get_timeout(s, tv)) {
- tv->tv_sec = -1;
- tv->tv_usec = 0;
- }
+ if (sc != NULL && SSL_CONNECTION_IS_DTLS(sc)
+ && DTLSv1_get_timeout(s, tv)) {
+ *is_infinite = 0;
return 1;
}
- return 0;
+ tv->tv_sec = 1000000;
+ tv->tv_usec = 0;
+ *is_infinite = 1;
+ return 1;
}
int SSL_get_rpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc)
{
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
+ if (IS_QUIC(s))
+ return ossl_quic_get_rpoll_descriptor(s, desc);
+#endif
+
+ if (sc == NULL || sc->rbio == NULL)
+ return 0;
- if (qc == NULL)
+ return BIO_get_rpoll_descriptor(sc->rbio, desc);
+}
+
+int SSL_get_wpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc)
+{
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_get_wpoll_descriptor(s, desc);
+#endif
+
+ if (sc == NULL || sc->wbio == NULL)
+ return 0;
+
+ return BIO_get_wpoll_descriptor(sc->wbio, desc);
+}
+
+int SSL_net_read_desired(SSL *s)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
+ return SSL_want_read(s);
+
+ return ossl_quic_get_net_read_desired(s);
+#else
+ return SSL_want_read(s);
+#endif
+}
+
+int SSL_net_write_desired(SSL *s)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
+ return SSL_want_write(s);
+
+ return ossl_quic_get_net_write_desired(s);
+#else
+ return SSL_want_write(s);
+#endif
+}
+
+int SSL_set_blocking_mode(SSL *s, int blocking)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
+ return 0;
+
+ return ossl_quic_conn_set_blocking_mode(s, blocking);
+#else
+ return 0;
+#endif
+}
+
+int SSL_get_blocking_mode(SSL *s)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
return -1;
- return ossl_quic_get_rpoll_descriptor(qc, desc);
+ return ossl_quic_conn_get_blocking_mode(s);
#else
return -1;
#endif
}
-int SSL_get_wpoll_descriptor(SSL *s, BIO_POLL_DESCRIPTOR *desc)
+int SSL_set1_initial_peer_addr(SSL *s, const BIO_ADDR *peer_addr)
{
#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
+ if (!IS_QUIC(s))
+ return 0;
+
+ return ossl_quic_conn_set_initial_peer_addr(s, peer_addr);
+#else
+ return 0;
+#endif
+}
+
+int SSL_shutdown_ex(SSL *ssl, uint64_t flags,
+ const SSL_SHUTDOWN_EX_ARGS *args,
+ size_t args_len)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(ssl))
+ return SSL_shutdown(ssl);
+
+ return ossl_quic_conn_shutdown(ssl, flags, args, args_len);
+#else
+ return SSL_shutdown(ssl);
+#endif
+}
+
+int SSL_stream_conclude(SSL *ssl, uint64_t flags)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(ssl))
+ return 0;
+
+ return ossl_quic_conn_stream_conclude(ssl);
+#else
+ return 0;
+#endif
+}
- if (qc == NULL)
+SSL *SSL_new_stream(SSL *s, uint64_t flags)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
+ return NULL;
+
+ return ossl_quic_conn_stream_new(s, flags);
+#else
+ return NULL;
+#endif
+}
+
+SSL *SSL_get0_connection(SSL *s)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
+ return s;
+
+ return ossl_quic_get0_connection(s);
+#else
+ return s;
+#endif
+}
+
+int SSL_is_connection(SSL *s)
+{
+ return SSL_get0_connection(s) == s;
+}
+
+int SSL_get_stream_type(SSL *s)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
+ return SSL_STREAM_TYPE_BIDI;
+
+ return ossl_quic_get_stream_type(s);
+#else
+ return SSL_STREAM_TYPE_BIDI;
+#endif
+}
+
+uint64_t SSL_get_stream_id(SSL *s)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
+ return UINT64_MAX;
+
+ return ossl_quic_get_stream_id(s);
+#else
+ return UINT64_MAX;
+#endif
+}
+
+int SSL_is_stream_local(SSL *s)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
return -1;
- return ossl_quic_get_wpoll_descriptor(qc, desc);
+ return ossl_quic_is_stream_local(s);
#else
return -1;
#endif
}
-int SSL_want_net_read(SSL *s)
+int SSL_set_default_stream_mode(SSL *s, uint32_t mode)
{
#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
+ if (!IS_QUIC(s))
+ return 0;
+
+ return ossl_quic_set_default_stream_mode(s, mode);
+#else
+ return 0;
+#endif
+}
- if (qc == NULL)
+int SSL_set_incoming_stream_policy(SSL *s, int policy, uint64_t aec)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
return 0;
- return ossl_quic_get_want_net_read(qc);
+ return ossl_quic_set_incoming_stream_policy(s, policy, aec);
#else
return 0;
#endif
}
-int SSL_want_net_write(SSL *s)
+SSL *SSL_accept_stream(SSL *s, uint64_t flags)
{
#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
+ if (!IS_QUIC(s))
+ return NULL;
+
+ return ossl_quic_accept_stream(s, flags);
+#else
+ return NULL;
+#endif
+}
- if (qc == NULL)
+size_t SSL_get_accept_stream_queue_len(SSL *s)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
return 0;
- return ossl_quic_get_want_net_write(qc);
+ return ossl_quic_get_accept_stream_queue_len(s);
#else
return 0;
#endif
}
-int SSL_set_blocking_mode(SSL *s, int blocking)
+int SSL_stream_reset(SSL *s,
+ const SSL_STREAM_RESET_ARGS *args,
+ size_t args_len)
{
#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
-
- if (qc == NULL)
+ if (!IS_QUIC(s))
return 0;
- return ossl_quic_conn_set_blocking_mode(qc, blocking);
+ return ossl_quic_stream_reset(s, args, args_len);
#else
return 0;
#endif
}
-int SSL_get_blocking_mode(SSL *s)
+int SSL_get_stream_read_state(SSL *s)
{
#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
+ if (!IS_QUIC(s))
+ return SSL_STREAM_STATE_NONE;
- if (qc == NULL)
+ return ossl_quic_get_stream_read_state(s);
+#else
+ return SSL_STREAM_STATE_NONE;
+#endif
+}
+
+int SSL_get_stream_write_state(SSL *s)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
+ return SSL_STREAM_STATE_NONE;
+
+ return ossl_quic_get_stream_write_state(s);
+#else
+ return SSL_STREAM_STATE_NONE;
+#endif
+}
+
+int SSL_get_stream_read_error_code(SSL *s, uint64_t *app_error_code)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
return -1;
- return ossl_quic_conn_get_blocking_mode(qc);
+ return ossl_quic_get_stream_read_error_code(s, app_error_code);
#else
return -1;
#endif
}
-int SSL_set_initial_peer_addr(SSL *s, const BIO_ADDR *peer_addr)
+int SSL_get_stream_write_error_code(SSL *s, uint64_t *app_error_code)
{
#ifndef OPENSSL_NO_QUIC
- QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
+ if (!IS_QUIC(s))
+ return -1;
- if (qc == NULL)
+ return ossl_quic_get_stream_write_error_code(s, app_error_code);
+#else
+ return -1;
+#endif
+}
+
+int SSL_get_conn_close_info(SSL *s, SSL_CONN_CLOSE_INFO *info,
+ size_t info_len)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (!IS_QUIC(s))
return -1;
- return ossl_quic_conn_set_initial_peer_addr(qc, peer_addr);
+ return ossl_quic_get_conn_close_info(s, info, info_len);
#else
return -1;
#endif
}
+
+int SSL_get_value_uint(SSL *s, uint32_t class_, uint32_t id,
+ uint64_t *value)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_get_value_uint(s, class_, id, value);
+#endif
+
+ ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_PROTOCOL);
+ return 0;
+}
+
+int SSL_set_value_uint(SSL *s, uint32_t class_, uint32_t id,
+ uint64_t value)
+{
+#ifndef OPENSSL_NO_QUIC
+ if (IS_QUIC(s))
+ return ossl_quic_set_value_uint(s, class_, id, value);
+#endif
+
+ ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_PROTOCOL);
+ return 0;
+}
+
+int SSL_add_expected_rpk(SSL *s, EVP_PKEY *rpk)
+{
+ unsigned char *data = NULL;
+ SSL_DANE *dane = SSL_get0_dane(s);
+ int ret;
+
+ if (dane == NULL || dane->dctx == NULL)
+ return 0;
+ if ((ret = i2d_PUBKEY(rpk, &data)) <= 0)
+ return 0;
+
+ ret = SSL_dane_tlsa_add(s, DANETLS_USAGE_DANE_EE,
+ DANETLS_SELECTOR_SPKI,
+ DANETLS_MATCHING_FULL,
+ data, (size_t)ret) > 0;
+ OPENSSL_free(data);
+ return ret;
+}
+
+EVP_PKEY *SSL_get0_peer_rpk(const SSL *s)
+{
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+ if (sc == NULL || sc->session == NULL)
+ return NULL;
+ return sc->session->peer_rpk;
+}
+
+int SSL_get_negotiated_client_cert_type(const SSL *s)
+{
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+ if (sc == NULL)
+ return 0;
+
+ return sc->ext.client_cert_type;
+}
+
+int SSL_get_negotiated_server_cert_type(const SSL *s)
+{
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+ if (sc == NULL)
+ return 0;
+
+ return sc->ext.server_cert_type;
+}
+
+static int validate_cert_type(const unsigned char *val, size_t len)
+{
+ size_t i;
+ int saw_rpk = 0;
+ int saw_x509 = 0;
+
+ if (val == NULL && len == 0)
+ return 1;
+
+ if (val == NULL || len == 0)
+ return 0;
+
+ for (i = 0; i < len; i++) {
+ switch (val[i]) {
+ case TLSEXT_cert_type_rpk:
+ if (saw_rpk)
+ return 0;
+ saw_rpk = 1;
+ break;
+ case TLSEXT_cert_type_x509:
+ if (saw_x509)
+ return 0;
+ saw_x509 = 1;
+ break;
+ case TLSEXT_cert_type_pgp:
+ case TLSEXT_cert_type_1609dot2:
+ default:
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int set_cert_type(unsigned char **cert_type,
+ size_t *cert_type_len,
+ const unsigned char *val,
+ size_t len)
+{
+ unsigned char *tmp = NULL;
+
+ if (!validate_cert_type(val, len))
+ return 0;
+
+ if (val != NULL && (tmp = OPENSSL_memdup(val, len)) == NULL)
+ return 0;
+
+ OPENSSL_free(*cert_type);
+ *cert_type = tmp;
+ *cert_type_len = len;
+ return 1;
+}
+
+int SSL_set1_client_cert_type(SSL *s, const unsigned char *val, size_t len)
+{
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+ return set_cert_type(&sc->client_cert_type, &sc->client_cert_type_len,
+ val, len);
+}
+
+int SSL_set1_server_cert_type(SSL *s, const unsigned char *val, size_t len)
+{
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s);
+
+ return set_cert_type(&sc->server_cert_type, &sc->server_cert_type_len,
+ val, len);
+}
+
+int SSL_CTX_set1_client_cert_type(SSL_CTX *ctx, const unsigned char *val, size_t len)
+{
+ return set_cert_type(&ctx->client_cert_type, &ctx->client_cert_type_len,
+ val, len);
+}
+
+int SSL_CTX_set1_server_cert_type(SSL_CTX *ctx, const unsigned char *val, size_t len)
+{
+ return set_cert_type(&ctx->server_cert_type, &ctx->server_cert_type_len,
+ val, len);
+}
+
+int SSL_get0_client_cert_type(const SSL *s, unsigned char **t, size_t *len)
+{
+ const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
+
+ if (t == NULL || len == NULL)
+ return 0;
+
+ *t = sc->client_cert_type;
+ *len = sc->client_cert_type_len;
+ return 1;
+}
+
+int SSL_get0_server_cert_type(const SSL *s, unsigned char **t, size_t *len)
+{
+ const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
+
+ if (t == NULL || len == NULL)
+ return 0;
+
+ *t = sc->server_cert_type;
+ *len = sc->server_cert_type_len;
+ return 1;
+}
+
+int SSL_CTX_get0_client_cert_type(const SSL_CTX *ctx, unsigned char **t, size_t *len)
+{
+ if (t == NULL || len == NULL)
+ return 0;
+
+ *t = ctx->client_cert_type;
+ *len = ctx->client_cert_type_len;
+ return 1;
+}
+
+int SSL_CTX_get0_server_cert_type(const SSL_CTX *ctx, unsigned char **t, size_t *len)
+{
+ if (t == NULL || len == NULL)
+ return 0;
+
+ *t = ctx->server_cert_type;
+ *len = ctx->server_cert_type_len;
+ return 1;
+}