src/tls/boringssl/xqc_ssl_if_impl.c (93 lines of code) (raw):
/**
* @copyright Copyright (c) 2022, Alibaba Group Holding Limited
*/
#include <openssl/base.h>
#include <openssl/ssl.h>
#include "src/tls/xqc_ssl_if.h"
#include "src/tls/xqc_tls_common.h"
#include "src/transport/xqc_conn.h"
void
xqc_ssl_ctx_set_timeout(SSL_CTX *ctx, uint32_t timeout)
{
timeout = (timeout == 0 ? XQC_SESSION_DEFAULT_TIMEOUT : timeout);
SSL_CTX_set_timeout(ctx, timeout);
SSL_CTX_set_session_psk_dhe_timeout(ctx, timeout);
}
void
xqc_ssl_ctx_enable_max_early_data(SSL_CTX *ctx)
{
/* for encapsulation, BoringSSL has no interface to enable max_early_data on SSL_CTX */
}
xqc_int_t
xqc_ssl_ctx_set_cipher_suites(SSL_CTX *ctx, const char *ciphers)
{
/* BoringSSL have a built-in preference order and do not support setting TLS 1.3 cipher */
return XQC_OK;
}
xqc_bool_t
xqc_ssl_session_is_early_data_enabled(SSL_SESSION *session)
{
return SSL_SESSION_early_data_capable(session);
}
void
xqc_ssl_enable_max_early_data(SSL *ssl)
{
SSL_set_early_data_enabled(ssl, 1);
}
xqc_int_t
xqc_ssl_get_certs_array(SSL *ssl, X509_STORE_CTX *store_ctx, unsigned char **certs_array,
size_t array_cap, size_t *certs_array_len, size_t *certs_len)
{
const STACK_OF(CRYPTO_BUFFER) *chain = SSL_get0_peer_certificates(ssl);
*certs_array_len = sk_CRYPTO_BUFFER_num(chain);
if (*certs_array_len > XQC_MAX_VERIFY_DEPTH) {
X509_STORE_CTX_set_error(store_ctx, X509_V_ERR_CERT_CHAIN_TOO_LONG);
return -XQC_TLS_INTERNAL;
}
for (int i = 0; i < *certs_array_len; i++) {
CRYPTO_BUFFER * buffer = sk_CRYPTO_BUFFER_value(chain, i);
certs_array[i] = (unsigned char *)CRYPTO_BUFFER_data(buffer);
certs_len[i] = (size_t)CRYPTO_BUFFER_len(buffer);
}
return XQC_OK;
}
void
xqc_ssl_free_certs_array(unsigned char **certs_array, size_t certs_array_len)
{
}
xqc_bool_t
xqc_ssl_is_early_data_accepted(SSL *ssl)
{
return SSL_early_data_accepted(ssl) ? XQC_TRUE : XQC_FALSE;
}
xqc_ssl_handshake_res_t
xqc_ssl_do_handshake(SSL *ssl, xqc_connection_t *conn, xqc_log_t *log)
{
int ret;
again:
ERR_clear_error();
ret = SSL_do_handshake(ssl);
/* check if client hello is received completely */
if (SSL_quic_read_level(ssl) > 0
&& conn != NULL
&& !(conn->conn_flag & XQC_CONN_FLAG_TLS_CH_RECVD))
{
conn->conn_flag |= XQC_CONN_FLAG_TLS_CH_RECVD;
}
xqc_log(log, XQC_LOG_DEBUG, "|ssl_do_handshake|SSL_quic_read_level:%d|SSL_quic_write_level:%d|rv:%d|",
(int) SSL_quic_read_level(ssl),
(int) SSL_quic_write_level(ssl),
ret);
if (ret <= 0) {
switch (SSL_get_error(ssl, ret)) {
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
return XQC_SSL_HSK_RES_WAIT;
case SSL_ERROR_EARLY_DATA_REJECTED: {
/* reset the state */
SSL_reset_early_data_reject(ssl);
/* resume handshake */
goto again;
}
case SSL_ERROR_SSL:
default:
return XQC_SSL_HSK_RES_FAIL;
}
}
/* early return */
if (SSL_in_early_data(ssl)) {
return XQC_SSL_HSK_RES_WAIT;
}
return XQC_SSL_HSK_RES_FIN;
}