提交 b1f79e7c 编写于 作者: J John Baldwin 提交者: Tomas Mraz

Support KTLS on connections using BIO_TYPE_CONNECT.

This requires duplicating the KTLS changes from bss_sock.c in
bss_conn.c.  One difference from BIO_TYPE_SOCKET is that the call to
ktls_enable is performed after the socket is created in BIO_socket
rather than BIO_new_connect.

Some applications such as 'openssl s_time' use connect BIOs instead of
socket BIOs.  Note that the new connections created for accept BIOs
use BIO_TYPE_SOCKET via BIO_new_socket, so bss_acpt.c does not require
changes.
Reviewed-by: NMatt Caswell <matt@openssl.org>
Reviewed-by: NTomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/10489)
上级 fda127be
......@@ -12,6 +12,7 @@
#include <errno.h>
#include "bio_local.h"
#include "internal/ktls.h"
#include <openssl/err.h>
......@@ -51,6 +52,17 @@ int BIO_socket(int domain, int socktype, int protocol, int options)
BIOerr(BIO_F_BIO_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
return INVALID_SOCKET;
}
# 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(sock);
}
# endif
return sock;
}
......
......@@ -11,6 +11,7 @@
#include <errno.h>
#include "bio_local.h"
#include "internal/ktls.h"
#ifndef OPENSSL_NO_SOCK
......@@ -20,6 +21,9 @@ typedef struct bio_connect_st {
char *param_hostname;
char *param_service;
int connect_mode;
# ifndef OPENSSL_NO_KTLS
unsigned char record_type;
# endif
BIO_ADDRINFO *addr_first;
const BIO_ADDRINFO *addr_iter;
......@@ -308,7 +312,12 @@ static int conn_read(BIO *b, char *out, int outl)
if (out != NULL) {
clear_socket_error();
ret = readsocket(b->num, out, outl);
# ifndef OPENSSL_NO_KTLS
if (BIO_get_ktls_recv(b))
ret = ktls_read_record(b->num, out, outl);
else
# endif
ret = readsocket(b->num, out, outl);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (BIO_sock_should_retry(ret))
......@@ -333,7 +342,16 @@ static int conn_write(BIO *b, const char *in, int inl)
}
clear_socket_error();
ret = writesocket(b->num, in, inl);
# ifndef OPENSSL_NO_KTLS
if (BIO_should_ktls_ctrl_msg_flag(b)) {
ret = ktls_send_ctrl_message(b->num, data->record_type, in, inl);
if (ret >= 0) {
ret = inl;
BIO_clear_ktls_ctrl_msg_flag(b);
}
} else
# endif
ret = writesocket(b->num, in, inl);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (BIO_sock_should_retry(ret))
......@@ -349,6 +367,13 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
const char **pptr = NULL;
long ret = 1;
BIO_CONNECT *data;
# ifndef OPENSSL_NO_KTLS
# ifdef __FreeBSD__
struct tls_enable *crypto_info;
# else
struct tls12_crypto_info_aes_gcm_128 *crypto_info;
# endif
# endif
data = (BIO_CONNECT *)b->ptr;
......@@ -497,6 +522,31 @@ static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_CTRL_EOF:
ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
break;
# ifndef OPENSSL_NO_KTLS
case BIO_CTRL_SET_KTLS:
# ifdef __FreeBSD__
crypto_info = (struct tls_enable *)ptr;
# else
crypto_info = (struct tls12_crypto_info_aes_gcm_128 *)ptr;
# endif
ret = ktls_start(b->num, crypto_info, sizeof(*crypto_info), num);
if (ret)
BIO_set_ktls_flag(b, num);
break;
case BIO_CTRL_GET_KTLS_SEND:
return BIO_should_ktls_flag(b, 1);
case BIO_CTRL_GET_KTLS_RECV:
return BIO_should_ktls_flag(b, 0);
case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG:
BIO_set_ktls_ctrl_msg_flag(b);
data->record_type = num;
ret = 0;
break;
case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG:
BIO_clear_ktls_ctrl_msg_flag(b);
ret = 0;
break;
# endif
default:
ret = 0;
break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册