mirror of
https://github.com/libretro/RetroArch
synced 2025-03-24 13:43:32 +00:00
Add BearSSL support
This commit is contained in:
parent
3849278b50
commit
18f46e65ea
115
Makefile.common
115
Makefile.common
@ -536,7 +536,114 @@ ifeq ($(HAVE_LIBRETRODB), 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_BUILTINMBEDTLS), 1)
|
||||
HAVE_BEARSSL := 0
|
||||
ifeq ($(HAVE_BEARSSL), 1)
|
||||
HAVE_SSL = 1
|
||||
DEFINES += -DHAVE_SSL -DHAVE_BEARSSL
|
||||
|
||||
# these -Is are only needed for BearSSL itself
|
||||
INCLUDE_DIRS += -Ideps/bearssl-0.6/src -Ideps/bearssl-0.6/inc
|
||||
OBJS_BEAR = deps/bearssl-0.6/src/aead/ccm.o \
|
||||
deps/bearssl-0.6/src/codec/ccopy.o \
|
||||
deps/bearssl-0.6/src/codec/dec32be.o \
|
||||
deps/bearssl-0.6/src/codec/dec32le.o \
|
||||
deps/bearssl-0.6/src/codec/dec64be.o \
|
||||
deps/bearssl-0.6/src/codec/enc32be.o \
|
||||
deps/bearssl-0.6/src/codec/enc32le.o \
|
||||
deps/bearssl-0.6/src/codec/enc64be.o \
|
||||
deps/bearssl-0.6/src/ec/ec_all_m31.o \
|
||||
deps/bearssl-0.6/src/ec/ec_c25519_m31.o \
|
||||
deps/bearssl-0.6/src/ec/ecdsa_atr.o \
|
||||
deps/bearssl-0.6/src/ec/ecdsa_i31_bits.o \
|
||||
deps/bearssl-0.6/src/ec/ecdsa_i31_vrfy_asn1.o \
|
||||
deps/bearssl-0.6/src/ec/ecdsa_i31_vrfy_raw.o \
|
||||
deps/bearssl-0.6/src/ec/ec_p256_m31.o \
|
||||
deps/bearssl-0.6/src/ec/ec_prime_i31.o \
|
||||
deps/bearssl-0.6/src/ec/ec_secp256r1.o \
|
||||
deps/bearssl-0.6/src/ec/ec_secp384r1.o \
|
||||
deps/bearssl-0.6/src/ec/ec_secp521r1.o \
|
||||
deps/bearssl-0.6/src/hash/ghash_ctmul64.o \
|
||||
deps/bearssl-0.6/src/hash/ghash_pclmul.o \
|
||||
deps/bearssl-0.6/src/hash/md5.o \
|
||||
deps/bearssl-0.6/src/hash/multihash.o \
|
||||
deps/bearssl-0.6/src/hash/sha1.o \
|
||||
deps/bearssl-0.6/src/hash/sha2big.o \
|
||||
deps/bearssl-0.6/src/hash/sha2small.o \
|
||||
deps/bearssl-0.6/src/int/i31_add.o \
|
||||
deps/bearssl-0.6/src/int/i31_bitlen.o \
|
||||
deps/bearssl-0.6/src/int/i31_decmod.o \
|
||||
deps/bearssl-0.6/src/int/i31_decode.o \
|
||||
deps/bearssl-0.6/src/int/i31_decred.o \
|
||||
deps/bearssl-0.6/src/int/i31_encode.o \
|
||||
deps/bearssl-0.6/src/int/i31_fmont.o \
|
||||
deps/bearssl-0.6/src/int/i31_iszero.o \
|
||||
deps/bearssl-0.6/src/int/i31_modpow2.o \
|
||||
deps/bearssl-0.6/src/int/i31_modpow.o \
|
||||
deps/bearssl-0.6/src/int/i31_montmul.o \
|
||||
deps/bearssl-0.6/src/int/i31_muladd.o \
|
||||
deps/bearssl-0.6/src/int/i31_ninv31.o \
|
||||
deps/bearssl-0.6/src/int/i31_rshift.o \
|
||||
deps/bearssl-0.6/src/int/i31_sub.o \
|
||||
deps/bearssl-0.6/src/int/i31_tmont.o \
|
||||
deps/bearssl-0.6/src/int/i32_div32.o \
|
||||
deps/bearssl-0.6/src/int/i62_modpow2.o \
|
||||
deps/bearssl-0.6/src/mac/hmac_ct.o \
|
||||
deps/bearssl-0.6/src/mac/hmac.o \
|
||||
deps/bearssl-0.6/src/rand/hmac_drbg.o \
|
||||
deps/bearssl-0.6/src/rand/sysrng.o \
|
||||
deps/bearssl-0.6/src/rsa/rsa_default_pkcs1_vrfy.o \
|
||||
deps/bearssl-0.6/src/rsa/rsa_default_pub.o \
|
||||
deps/bearssl-0.6/src/rsa/rsa_i31_pkcs1_vrfy.o \
|
||||
deps/bearssl-0.6/src/rsa/rsa_i31_pub.o \
|
||||
deps/bearssl-0.6/src/rsa/rsa_i62_pkcs1_vrfy.o \
|
||||
deps/bearssl-0.6/src/rsa/rsa_i62_pub.o \
|
||||
deps/bearssl-0.6/src/rsa/rsa_pkcs1_sig_unpad.o \
|
||||
deps/bearssl-0.6/src/ssl/prf_md5sha1.o \
|
||||
deps/bearssl-0.6/src/ssl/prf.o \
|
||||
deps/bearssl-0.6/src/ssl/prf_sha256.o \
|
||||
deps/bearssl-0.6/src/ssl/prf_sha384.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_client_default_rsapub.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_client_full.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_client.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_engine_default_aescbc.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_engine_default_aesccm.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_engine_default_aesgcm.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_engine_default_chapol.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_engine_default_descbc.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_engine_default_ecdsa.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_engine_default_rsavrfy.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_engine.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_hs_client.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_rec_cbc.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_rec_ccm.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_rec_chapol.o \
|
||||
deps/bearssl-0.6/src/ssl/ssl_rec_gcm.o \
|
||||
deps/bearssl-0.6/src/symcipher/aes_ct64_cbcdec.o \
|
||||
deps/bearssl-0.6/src/symcipher/aes_ct64_cbcenc.o \
|
||||
deps/bearssl-0.6/src/symcipher/aes_ct64_ctrcbc.o \
|
||||
deps/bearssl-0.6/src/symcipher/aes_ct64_ctr.o \
|
||||
deps/bearssl-0.6/src/symcipher/aes_ct64_dec.o \
|
||||
deps/bearssl-0.6/src/symcipher/aes_ct64_enc.o \
|
||||
deps/bearssl-0.6/src/symcipher/aes_ct64.o \
|
||||
deps/bearssl-0.6/src/symcipher/aes_x86ni_cbcdec.o \
|
||||
deps/bearssl-0.6/src/symcipher/aes_x86ni_cbcenc.o \
|
||||
deps/bearssl-0.6/src/symcipher/aes_x86ni_ctrcbc.o \
|
||||
deps/bearssl-0.6/src/symcipher/aes_x86ni_ctr.o \
|
||||
deps/bearssl-0.6/src/symcipher/aes_x86ni.o \
|
||||
deps/bearssl-0.6/src/symcipher/chacha20_ct.o \
|
||||
deps/bearssl-0.6/src/symcipher/chacha20_sse2.o \
|
||||
deps/bearssl-0.6/src/symcipher/des_ct_cbcdec.o \
|
||||
deps/bearssl-0.6/src/symcipher/des_ct_cbcenc.o \
|
||||
deps/bearssl-0.6/src/symcipher/des_ct.o \
|
||||
deps/bearssl-0.6/src/symcipher/des_support.o \
|
||||
deps/bearssl-0.6/src/symcipher/poly1305_ctmul.o \
|
||||
deps/bearssl-0.6/src/symcipher/poly1305_ctmulq.o \
|
||||
deps/bearssl-0.6/src/x509/x509_decoder.o \
|
||||
deps/bearssl-0.6/src/x509/x509_minimal_full.o \
|
||||
deps/bearssl-0.6/src/x509/x509_minimal.o \
|
||||
|
||||
OBJ += $(OBJS_BEAR)
|
||||
else ifeq ($(HAVE_BUILTINMBEDTLS), 1)
|
||||
HAVE_SSL = 1
|
||||
DEFINES += -DHAVE_SSL
|
||||
|
||||
@ -1910,8 +2017,10 @@ ifeq ($(HAVE_NETWORKING), 1)
|
||||
OBJ += tasks/task_core_updater.o
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SSL), 1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/net/net_socket_ssl.o
|
||||
ifeq ($(HAVE_BEARSSL), 1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/net/net_socket_ssl_bear.o
|
||||
else ifeq ($(HAVE_SSL), 1)
|
||||
OBJ += $(LIBRETRO_COMM_DIR)/net/net_socket_ssl_mbed.o
|
||||
endif
|
||||
|
||||
ifneq ($(HAVE_SOCKET_LEGACY),1)
|
||||
|
@ -64,6 +64,9 @@ int socket_next(void **address);
|
||||
|
||||
int socket_close(int fd);
|
||||
|
||||
bool socket_set_block(int fd, bool block);
|
||||
|
||||
/* TODO: all callers should be converted to socket_set_block() */
|
||||
bool socket_nonblock(int fd);
|
||||
|
||||
int socket_select(int nfds, fd_set *readfs, fd_set *writefds,
|
||||
|
@ -123,20 +123,25 @@ int socket_receive_all_blocking(int fd, void *data_, size_t size)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool socket_nonblock(int fd)
|
||||
bool socket_set_block(int fd, bool block)
|
||||
{
|
||||
#if defined(__CELLOS_LV2__) || defined(VITA) || defined(WIIU)
|
||||
int i = 1;
|
||||
int i = block;
|
||||
setsockopt(fd, SOL_SOCKET, SO_NBIO, &i, sizeof(int));
|
||||
return true;
|
||||
#elif defined(_WIN32)
|
||||
u_long mode = 1;
|
||||
u_long mode = block;
|
||||
return ioctlsocket(fd, FIONBIO, &mode) == 0;
|
||||
#else
|
||||
return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK) == 0;
|
||||
return fcntl(fd, F_SETFL, (fcntl(fd, F_GETFL) & ~O_NONBLOCK) | (block ? 0 : O_NONBLOCK)) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool socket_nonblock(int fd)
|
||||
{
|
||||
return socket_set_block(fd, false);
|
||||
}
|
||||
|
||||
int socket_close(int fd)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(_XBOX360)
|
||||
|
340
libretro-common/net/net_socket_ssl_bear.c
Normal file
340
libretro-common/net/net_socket_ssl_bear.c
Normal file
@ -0,0 +1,340 @@
|
||||
/* Copyright (C) 2010-2020 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (net_socket.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <net/net_socket_ssl.h>
|
||||
#include <net/net_socket.h>
|
||||
#include <encodings/base64.h>
|
||||
#include <streams/file_stream.h>
|
||||
#include "../../deps/bearssl-0.6/inc/bearssl.h"
|
||||
|
||||
static br_x509_trust_anchor TAs[500] = {};
|
||||
static size_t TAs_NUM = 0;
|
||||
|
||||
static uint8_t* current_vdn;
|
||||
static size_t current_vdn_size;
|
||||
|
||||
static uint8_t* blobdup(const void * src, size_t len)
|
||||
{
|
||||
uint8_t * ret = malloc(len);
|
||||
memcpy(ret, src, len);
|
||||
return ret;
|
||||
}
|
||||
static void vdn_append(void* dest_ctx, const void * src, size_t len)
|
||||
{
|
||||
current_vdn = realloc(current_vdn, current_vdn_size + len);
|
||||
memcpy(current_vdn+current_vdn_size, src, len);
|
||||
current_vdn_size += len;
|
||||
}
|
||||
static bool append_cert_x509(void* x509, size_t len)
|
||||
{
|
||||
br_x509_trust_anchor* ta = &TAs[TAs_NUM];
|
||||
br_x509_decoder_context dc;
|
||||
br_x509_pkey* pk;
|
||||
|
||||
current_vdn = NULL;
|
||||
current_vdn_size = 0;
|
||||
|
||||
br_x509_decoder_init(&dc, vdn_append, NULL);
|
||||
br_x509_decoder_push(&dc, x509, len);
|
||||
pk = br_x509_decoder_get_pkey(&dc);
|
||||
if (pk == NULL || !br_x509_decoder_isCA(&dc)) return false;
|
||||
|
||||
ta->dn.len = current_vdn_size;
|
||||
ta->dn.data = current_vdn;
|
||||
ta->flags = BR_X509_TA_CA;
|
||||
|
||||
switch (pk->key_type)
|
||||
{
|
||||
case BR_KEYTYPE_RSA:
|
||||
ta->pkey.key_type = BR_KEYTYPE_RSA;
|
||||
ta->pkey.key.rsa.nlen = pk->key.rsa.nlen;
|
||||
ta->pkey.key.rsa.n = blobdup(pk->key.rsa.n, pk->key.rsa.nlen);
|
||||
ta->pkey.key.rsa.elen = pk->key.rsa.elen;
|
||||
ta->pkey.key.rsa.e = blobdup(pk->key.rsa.e, pk->key.rsa.elen);
|
||||
break;
|
||||
case BR_KEYTYPE_EC:
|
||||
ta->pkey.key_type = BR_KEYTYPE_EC;
|
||||
ta->pkey.key.ec.curve = pk->key.ec.curve;
|
||||
ta->pkey.key.ec.qlen = pk->key.ec.qlen;
|
||||
ta->pkey.key.ec.q = blobdup(pk->key.ec.q, pk->key.ec.qlen);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
TAs_NUM++;
|
||||
return true;
|
||||
}
|
||||
|
||||
static char* delete_linebreaks(char* in)
|
||||
{
|
||||
char* iter_in;
|
||||
char* iter_out;
|
||||
while (*in == '\n') in++;
|
||||
|
||||
iter_in = in;
|
||||
|
||||
while (*iter_in != '\n' && *iter_in != '\0') iter_in++;
|
||||
iter_out = iter_in;
|
||||
while (*iter_in != '\0')
|
||||
{
|
||||
while (*iter_in == '\n') iter_in++;
|
||||
*iter_out++ = *iter_in++;
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
/* this rearranges its input, it's easier to implement that way and caller doesn't need it anymore anyways */
|
||||
static void append_certs_pem_x509(char * certs_pem)
|
||||
{
|
||||
char * cert = certs_pem;
|
||||
char * cert_end = certs_pem;
|
||||
|
||||
void * cert_bin;
|
||||
int cert_bin_len;
|
||||
|
||||
while (true)
|
||||
{
|
||||
cert = strstr(cert_end, "-----BEGIN CERTIFICATE-----");
|
||||
if (!cert) break;
|
||||
cert += strlen("-----BEGIN CERTIFICATE-----");
|
||||
cert_end = strstr(cert, "-----END CERTIFICATE-----");
|
||||
|
||||
*cert_end = '\0';
|
||||
cert = delete_linebreaks(cert);
|
||||
|
||||
cert_bin = unbase64(cert, cert_end-cert, &cert_bin_len);
|
||||
append_cert_x509(cert_bin, cert_bin_len);
|
||||
free(cert_bin);
|
||||
|
||||
cert_end++; /* skip the NUL we just added */
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: not thread safe, rthreads doesn't provide any statically allocatable mutex/etc */
|
||||
static void initialize()
|
||||
{
|
||||
void* certs_pem;
|
||||
if (TAs_NUM) return;
|
||||
/* filestream_read_file appends a NUL */
|
||||
filestream_read_file("/etc/ssl/certs/ca-certificates.crt", &certs_pem, NULL);
|
||||
append_certs_pem_x509((char*)certs_pem);
|
||||
free(certs_pem);
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct ssl_state
|
||||
{
|
||||
int fd;
|
||||
br_ssl_client_context sc;
|
||||
br_x509_minimal_context xc;
|
||||
uint8_t iobuf[BR_SSL_BUFSIZE_BIDI];
|
||||
};
|
||||
|
||||
void* ssl_socket_init(int fd, const char *domain)
|
||||
{
|
||||
struct ssl_state *state = (struct ssl_state*)calloc(1, sizeof(*state));
|
||||
|
||||
initialize();
|
||||
|
||||
br_ssl_client_init_full(&state->sc, &state->xc, TAs, TAs_NUM);
|
||||
br_ssl_engine_set_buffer(&state->sc.eng, state->iobuf, sizeof(state->iobuf), true);
|
||||
br_ssl_client_reset(&state->sc, domain, false);
|
||||
|
||||
state->fd = fd;
|
||||
return state;
|
||||
}
|
||||
|
||||
static bool process_inner(struct ssl_state *state, bool blocking)
|
||||
{
|
||||
size_t buflen;
|
||||
uint8_t * buf;
|
||||
ssize_t bytes;
|
||||
bool dummy;
|
||||
|
||||
buf = br_ssl_engine_sendrec_buf(&state->sc.eng, &buflen);
|
||||
if (buflen)
|
||||
{
|
||||
if (blocking) bytes = (socket_send_all_blocking(state->fd, buf, buflen, true) ? buflen : -1);
|
||||
else bytes = socket_send_all_nonblocking(state->fd, buf, buflen, true);
|
||||
|
||||
if (bytes > 0) br_ssl_engine_sendrec_ack(&state->sc.eng, bytes);
|
||||
if (bytes < 0) return false;
|
||||
|
||||
return true; /* if we did something, return immediately so we don't try to read if Bear still wants to send */
|
||||
}
|
||||
|
||||
buf = br_ssl_engine_recvrec_buf(&state->sc.eng, &buflen);
|
||||
if (buflen)
|
||||
{
|
||||
/* if the socket is blocking, socket_receive_all_nonblocking blocks,
|
||||
* but only to read at least 1 byte which is exactly what we want */
|
||||
bytes = socket_receive_all_nonblocking(state->fd, &dummy, buf, buflen);
|
||||
if (bytes > 0) br_ssl_engine_recvrec_ack(&state->sc.eng, bytes);
|
||||
if (bytes < 0) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int ssl_socket_connect(void *state_data,
|
||||
void *data, bool timeout_enable, bool nonblock)
|
||||
{
|
||||
struct ssl_state *state = (struct ssl_state*)state_data;
|
||||
unsigned bearstate;
|
||||
|
||||
if (socket_connect(state->fd, data, timeout_enable))
|
||||
return -1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!process_inner(state, true))
|
||||
return -1;
|
||||
|
||||
bearstate = br_ssl_engine_current_state(&state->sc.eng);
|
||||
if (bearstate & BR_SSL_SENDAPP) break; /* handshake done */
|
||||
if (bearstate & BR_SSL_CLOSED) return -1; /* failed */
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
ssize_t ssl_socket_receive_all_nonblocking(void *state_data,
|
||||
bool *error, void *data_, size_t size)
|
||||
{
|
||||
struct ssl_state *state = (struct ssl_state*)state_data;
|
||||
uint8_t * bear_data;
|
||||
size_t bear_data_size;
|
||||
|
||||
socket_set_block(state->fd, false);
|
||||
|
||||
if (!process_inner(state, false))
|
||||
{
|
||||
*error = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
bear_data = br_ssl_engine_recvapp_buf(&state->sc.eng, &bear_data_size);
|
||||
if (bear_data_size > size) bear_data_size = size;
|
||||
memcpy(data_, bear_data, bear_data_size);
|
||||
if (bear_data_size)
|
||||
br_ssl_engine_recvapp_ack(&state->sc.eng, bear_data_size);
|
||||
|
||||
return bear_data_size;
|
||||
}
|
||||
|
||||
int ssl_socket_receive_all_blocking(void *state_data,
|
||||
void *data_, size_t size)
|
||||
{
|
||||
struct ssl_state *state = (struct ssl_state*)state_data;
|
||||
uint8_t *data = (uint8_t*)data_;
|
||||
uint8_t * bear_data;
|
||||
size_t bear_data_size;
|
||||
|
||||
socket_set_block(state->fd, true);
|
||||
|
||||
while (true)
|
||||
{
|
||||
bear_data = br_ssl_engine_recvapp_buf(&state->sc.eng, &bear_data_size);
|
||||
if (bear_data_size > size) bear_data_size = size;
|
||||
memcpy(data, bear_data, bear_data_size);
|
||||
if (bear_data_size)
|
||||
br_ssl_engine_recvapp_ack(&state->sc.eng, bear_data_size);
|
||||
data += bear_data_size;
|
||||
size -= bear_data_size;
|
||||
|
||||
if (size) process_inner(state, true);
|
||||
else break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ssl_socket_send_all_blocking(void *state_data,
|
||||
const void *data_, size_t size, bool no_signal)
|
||||
{
|
||||
struct ssl_state *state = (struct ssl_state*)state_data;
|
||||
const uint8_t *data = (const uint8_t*)data_;
|
||||
uint8_t * bear_data;
|
||||
size_t bear_data_size;
|
||||
|
||||
socket_set_block(state->fd, true);
|
||||
|
||||
while (true)
|
||||
{
|
||||
bear_data = br_ssl_engine_sendapp_buf(&state->sc.eng, &bear_data_size);
|
||||
if (bear_data_size > size) bear_data_size = size;
|
||||
memcpy(bear_data, data_, bear_data_size);
|
||||
if (bear_data_size)
|
||||
br_ssl_engine_sendapp_ack(&state->sc.eng, bear_data_size);
|
||||
data += bear_data_size;
|
||||
size -= bear_data_size;
|
||||
|
||||
if (size) process_inner(state, true);
|
||||
else break;
|
||||
}
|
||||
|
||||
br_ssl_engine_flush(&state->sc.eng, false);
|
||||
process_inner(state, false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ssize_t ssl_socket_send_all_nonblocking(void *state_data,
|
||||
const void *data_, size_t size, bool no_signal)
|
||||
{
|
||||
struct ssl_state *state = (struct ssl_state*)state_data;
|
||||
uint8_t * bear_data;
|
||||
size_t bear_data_size;
|
||||
|
||||
socket_set_block(state->fd, false);
|
||||
|
||||
bear_data = br_ssl_engine_sendapp_buf(&state->sc.eng, &bear_data_size);
|
||||
if (bear_data_size > size) bear_data_size = size;
|
||||
memcpy(bear_data, data_, bear_data_size);
|
||||
if (bear_data_size)
|
||||
{
|
||||
br_ssl_engine_sendapp_ack(&state->sc.eng, bear_data_size);
|
||||
br_ssl_engine_flush(&state->sc.eng, false);
|
||||
}
|
||||
|
||||
if (!process_inner(state, false))
|
||||
return -1;
|
||||
|
||||
return bear_data_size;
|
||||
}
|
||||
|
||||
void ssl_socket_close(void *state_data)
|
||||
{
|
||||
struct ssl_state *state = (struct ssl_state*)state_data;
|
||||
|
||||
br_ssl_engine_close(&state->sc.eng);
|
||||
process_inner(state, false); /* send close notification */
|
||||
socket_close(state->fd); /* but immediately close socket and don't worry about recipient getting our message */
|
||||
}
|
||||
|
||||
void ssl_socket_free(void *state_data)
|
||||
{
|
||||
struct ssl_state *state = (struct ssl_state*)state_data;
|
||||
/* BearSSL does zero allocations of its own, so other than this struct, there is nothing to free */
|
||||
free(state);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user