* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. All rights reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
#include <openssl/ct.h>
#include "internal/cryptlib.h"
#include "internal/refcount.h"
+#include "internal/ktls.h"
static int ssl_undefined_function_1(SSL *ssl, SSL3_RECORD *r, size_t s, int t)
{
s->psk_find_session_cb = ctx->psk_find_session_cb;
s->psk_use_session_cb = ctx->psk_use_session_cb;
+ s->async_cb = ctx->async_cb;
+ s->async_cb_arg = ctx->async_cb_arg;
+
s->job = NULL;
#ifndef OPENSSL_NO_CT
dane_final(&s->dane);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
+ RECORD_LAYER_release(&s->rlayer);
+
/* Ignore return value */
ssl_free_wbio_buffer(s);
BIO_free_all(s->wbio);
+ s->wbio = NULL;
BIO_free_all(s->rbio);
+ s->rbio = NULL;
BUF_MEM_free(s->init_buf);
EVP_MD_CTX_free(s->pha_dgst);
sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free);
+ sk_X509_NAME_pop_free(s->client_ca_names, X509_NAME_free);
sk_X509_pop_free(s->verified_chain, X509_free);
if (s->method != NULL)
s->method->ssl_free(s);
- RECORD_LAYER_release(&s->rlayer);
-
SSL_CTX_free(s->ctx);
ASYNC_WAIT_CTX_free(s->waitctx);
}
BIO_set_fd(bio, fd, BIO_NOCLOSE);
SSL_set_bio(s, bio, bio);
+#ifndef OPENSSL_NO_KTLS
+ /*
+ * The new socket is created successfully regardless of ktls_enable.
+ * ktls_enable doesn't change any functionality of the socket, except
+ * changing the setsockopt to enable the processing of ktls_start.
+ * Thus, it is not a problem to call it for non-TLS sockets.
+ */
+ ktls_enable(fd);
+#endif /* OPENSSL_NO_KTLS */
ret = 1;
err:
return ret;
}
BIO_set_fd(bio, fd, BIO_NOCLOSE);
SSL_set0_wbio(s, bio);
+#ifndef OPENSSL_NO_KTLS
+ /*
+ * The new socket is created successfully regardless of ktls_enable.
+ * ktls_enable doesn't change any functionality of the socket, except
+ * changing the setsockopt to enable the processing of ktls_start.
+ * Thus, it is not a problem to call it for non-TLS sockets.
+ */
+ ktls_enable(fd);
+#endif /* OPENSSL_NO_KTLS */
} else {
BIO_up_ref(rbio);
SSL_set0_wbio(s, rbio);
numdelfds);
}
+int SSL_CTX_set_async_callback(SSL_CTX *ctx, SSL_async_callback_fn callback)
+{
+ ctx->async_cb = callback;
+ return 1;
+}
+
+int SSL_CTX_set_async_callback_arg(SSL_CTX *ctx, void *arg)
+{
+ ctx->async_cb_arg = arg;
+ return 1;
+}
+
+int SSL_set_async_callback(SSL *s, SSL_async_callback_fn callback)
+{
+ s->async_cb = callback;
+ return 1;
+}
+
+int SSL_set_async_callback_arg(SSL *s, void *arg)
+{
+ s->async_cb_arg = arg;
+ return 1;
+}
+
+int SSL_get_async_status(SSL *s, int *status)
+{
+ ASYNC_WAIT_CTX *ctx = s->waitctx;
+
+ if (ctx == NULL)
+ return 0;
+ *status = ASYNC_WAIT_CTX_get_status(ctx);
+ return 1;
+}
+
int SSL_accept(SSL *s)
{
if (s->handshake_func == NULL) {
return s->method->get_timeout();
}
+static int ssl_async_wait_ctx_cb(void *arg)
+{
+ SSL *s = (SSL *)arg;
+
+ return s->async_cb(s, s->async_cb_arg);
+}
+
static int ssl_start_async_job(SSL *s, struct ssl_async_args *args,
int (*func) (void *))
{
s->waitctx = ASYNC_WAIT_CTX_new();
if (s->waitctx == NULL)
return -1;
+ if (s->async_cb != NULL
+ && !ASYNC_WAIT_CTX_set_callback
+ (s->waitctx, ssl_async_wait_ctx_cb, s))
+ return -1;
}
switch (ASYNC_start_job(&s->job, s->waitctx, &ret, func, args,
sizeof(struct ssl_async_args))) {
return 1;
}
-int SSL_get_key_update_type(SSL *s)
+int SSL_get_key_update_type(const SSL *s)
{
return s->key_update;
}
return s->method->ssl_renegotiate(s);
}
-int SSL_renegotiate_pending(SSL *s)
+int SSL_renegotiate_pending(const SSL *s)
{
/*
* becomes true when negotiation is requested; false again once a
case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
return 0;
+#ifndef OPENSSL_NO_KTLS
+ if (s->wbio != NULL && BIO_get_ktls_send(s->wbio))
+ return 0;
+#endif /* OPENSSL_NO_KTLS */
s->max_send_fragment = larg;
if (s->max_send_fragment < s->split_send_fragment)
s->split_send_fragment = s->max_send_fragment;
return NULL;
}
+/*
+ * Distinguish between ciphers controlled by set_ciphersuite() and
+ * set_cipher_list() when counting.
+ */
+static int cipher_list_tls12_num(STACK_OF(SSL_CIPHER) *sk)
+{
+ int i, num = 0;
+ const SSL_CIPHER *c;
+
+ if (sk == NULL)
+ return 0;
+ for (i = 0; i < sk_SSL_CIPHER_num(sk); ++i) {
+ c = sk_SSL_CIPHER_value(sk, i);
+ if (c->min_tls >= TLS1_3_VERSION)
+ continue;
+ num++;
+ }
+ return num;
+}
+
/** specify the ciphers to be used by default by the SSL_CTX */
int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
{
*/
if (sk == NULL)
return 0;
- else if (sk_SSL_CIPHER_num(sk) == 0) {
+ else if (cipher_list_tls12_num(sk) == 0) {
SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);
return 0;
}
/* see comment in SSL_CTX_set_cipher_list */
if (sk == NULL)
return 0;
- else if (sk_SSL_CIPHER_num(sk) == 0) {
+ else if (cipher_list_tls12_num(sk) == 0) {
SSLerr(SSL_F_SSL_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);
return 0;
}
if ((ret->ca_names = sk_X509_NAME_new_null()) == NULL)
goto err;
+ if ((ret->client_ca_names = sk_X509_NAME_new_null()) == NULL)
+ goto err;
+
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data))
goto err;
sk_SSL_CIPHER_free(a->tls13_ciphersuites);
ssl_cert_free(a->cert);
sk_X509_NAME_pop_free(a->ca_names, X509_NAME_free);
+ sk_X509_NAME_pop_free(a->client_ca_names, X509_NAME_free);
sk_X509_pop_free(a->extra_certs, X509_free);
a->comp_methods = NULL;
#ifndef OPENSSL_NO_SRTP
}
}
-const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx)
+const SSL_METHOD *SSL_CTX_get_ssl_method(const SSL_CTX *ctx)
{
return ctx->method;
}
-const SSL_METHOD *SSL_get_ssl_method(SSL *s)
+const SSL_METHOD *SSL_get_ssl_method(const SSL *s)
{
return s->method;
}
return ssl_protocol_to_string(s->version);
}
-SSL *SSL_dup(SSL *s)
+static int dup_ca_names(STACK_OF(X509_NAME) **dst, STACK_OF(X509_NAME) *src)
{
STACK_OF(X509_NAME) *sk;
X509_NAME *xn;
+ int i;
+
+ if (src == NULL) {
+ *dst = NULL;
+ return 1;
+ }
+
+ if ((sk = sk_X509_NAME_new_null()) == NULL)
+ return 0;
+ for (i = 0; i < sk_X509_NAME_num(src); i++) {
+ xn = X509_NAME_dup(sk_X509_NAME_value(src, i));
+ if (xn == NULL) {
+ sk_X509_NAME_pop_free(sk, X509_NAME_free);
+ return 0;
+ }
+ if (sk_X509_NAME_insert(sk, xn, i) == 0) {
+ X509_NAME_free(xn);
+ sk_X509_NAME_pop_free(sk, X509_NAME_free);
+ return 0;
+ }
+ }
+ *dst = sk;
+
+ return 1;
+}
+
+SSL *SSL_dup(SSL *s)
+{
SSL *ret;
int i;
goto err;
/* Dup the client_CA list */
- if (s->ca_names != NULL) {
- if ((sk = sk_X509_NAME_dup(s->ca_names)) == NULL)
- goto err;
- ret->ca_names = sk;
- for (i = 0; i < sk_X509_NAME_num(sk); i++) {
- xn = sk_X509_NAME_value(sk, i);
- if (sk_X509_NAME_set(sk, i, X509_NAME_dup(xn)) == NULL) {
- X509_NAME_free(xn);
- goto err;
- }
- }
- }
+ if (!dup_ca_names(&ret->ca_names, s->ca_names)
+ || !dup_ca_names(&ret->client_ca_names, s->client_ca_names))
+ goto err;
+
return ret;
err:
return s->s3->tmp.new_cipher;
}
-const COMP_METHOD *SSL_get_current_compression(SSL *s)
+const COMP_METHOD *SSL_get_current_compression(const SSL *s)
{
#ifndef OPENSSL_NO_COMP
return s->compress ? COMP_CTX_get_method(s->compress) : NULL;
#endif
}
-const COMP_METHOD *SSL_get_current_expansion(SSL *s)
+const COMP_METHOD *SSL_get_current_expansion(const SSL *s)
{
#ifndef OPENSSL_NO_COMP
return s->expand ? COMP_CTX_get_method(s->expand) : NULL;
ctx->record_padding_arg = arg;
}
-void *SSL_CTX_get_record_padding_callback_arg(SSL_CTX *ctx)
+void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx)
{
return ctx->record_padding_arg;
}
ssl->record_padding_arg = arg;
}
-void *SSL_get_record_padding_callback_arg(SSL *ssl)
+void *SSL_get_record_padding_callback_arg(const SSL *ssl)
{
return ssl->record_padding_arg;
}
return 1;
}
-size_t SSL_get_num_tickets(SSL *s)
+size_t SSL_get_num_tickets(const SSL *s)
{
return s->num_tickets;
}
return 1;
}
-size_t SSL_CTX_get_num_tickets(SSL_CTX *ctx)
+size_t SSL_CTX_get_num_tickets(const SSL_CTX *ctx)
{
return ctx->num_tickets;
}
return s->server;
}
-#if OPENSSL_API_COMPAT < 0x10100000L
+#if !OPENSSL_API_1_1_0
void SSL_set_debug(SSL *s, int debug)
{
/* Old function was do-nothing anyway... */
size_t i;
size_t prefix_len;
- if (ssl->ctx->keylog_callback == NULL) return 1;
+ if (ssl->ctx->keylog_callback == NULL)
+ return 1;
/*
* Our output buffer will contain the following strings, rendered with