mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
1.12.0: [FEATURE, API Change] Certificate verification
This commit is contained in:
parent
de1c35ddaf
commit
7f2bd84c85
11 changed files with 285 additions and 17 deletions
|
@ -36,7 +36,7 @@ SOFTWARE.
|
|||
#if LS_HPACK_EMIT_TEST_CODE
|
||||
#include "lshpack-test.h"
|
||||
#endif
|
||||
#include "lsquic_xxhash.h"
|
||||
#include XXH_HEADER_NAME
|
||||
|
||||
#define HPACK_STATIC_TABLE_SIZE 61
|
||||
#define INITIAL_DYNAMIC_TABLE_SIZE 4096
|
||||
|
|
|
@ -609,14 +609,6 @@ int gen_prof(const uint8_t *chlo_data, size_t chlo_data_len,
|
|||
}
|
||||
|
||||
|
||||
int verify_cert(const char *buf, int len)
|
||||
{
|
||||
//X509_verify_cert();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int verify_prof(const uint8_t *chlo_data, size_t chlo_data_len, lsquic_str_t * scfg,
|
||||
const EVP_PKEY *pub_key, const uint8_t *buf, size_t len)
|
||||
{
|
||||
|
|
|
@ -335,6 +335,8 @@ lsquic_engine_new (unsigned flags,
|
|||
engine->pub.enp_pmi = &stock_pmi;
|
||||
engine->pub.enp_pmi_ctx = NULL;
|
||||
}
|
||||
engine->pub.enp_verify_cert = api->ea_verify_cert;
|
||||
engine->pub.enp_verify_ctx = api->ea_verify_ctx;
|
||||
engine->pub.enp_engine = engine;
|
||||
conn_hash_init(&engine->conns_hash,
|
||||
hash_conns_by_addr(engine) ? CHF_USE_ADDR : 0);
|
||||
|
|
|
@ -9,10 +9,14 @@
|
|||
|
||||
struct lsquic_conn;
|
||||
struct lsquic_engine;
|
||||
struct stack_st_X509;
|
||||
|
||||
struct lsquic_engine_public {
|
||||
struct lsquic_mm enp_mm;
|
||||
struct lsquic_engine_settings enp_settings;
|
||||
int (*enp_verify_cert)(void *verify_ctx,
|
||||
struct stack_st_X509 *chain);
|
||||
void *enp_verify_ctx;
|
||||
const struct lsquic_packout_mem_if
|
||||
*enp_pmi;
|
||||
void *enp_pmi_ctx;
|
||||
|
|
|
@ -2677,7 +2677,7 @@ immediate_close (struct full_conn *conn)
|
|||
return TICK_CLOSE;
|
||||
}
|
||||
|
||||
assert(conn->fc_flags & (FC_ERROR|FC_ABORTED|FC_TIMED_OUT));
|
||||
assert(conn->fc_flags & (FC_ERROR|FC_ABORTED|FC_TIMED_OUT|FC_HSK_FAILED));
|
||||
if (conn->fc_flags & FC_ERROR)
|
||||
{
|
||||
error_code = 0x01; /* QUIC_INTERNAL_ERROR */
|
||||
|
@ -2693,6 +2693,11 @@ immediate_close (struct full_conn *conn)
|
|||
error_code = 0x19; /* QUIC_NETWORK_IDLE_TIMEOUT */
|
||||
error_reason = "connection timed out";
|
||||
}
|
||||
else if (conn->fc_flags & FC_HSK_FAILED)
|
||||
{
|
||||
error_code = 0x2A; /* QUIC_PROOF_INVALID */
|
||||
error_reason = "handshake failed";
|
||||
}
|
||||
else
|
||||
{
|
||||
error_code = 0x10; /* QUIC_PEER_GOING_AWAY */
|
||||
|
|
|
@ -1108,15 +1108,17 @@ static int handle_chlo_reply_verify_prof(lsquic_enc_session_t *enc_session,
|
|||
in + lsquic_str_len(&enc_session->hs_ctx.crt);
|
||||
EVP_PKEY *pub_key;
|
||||
int ret;
|
||||
X509 *cert;
|
||||
size_t i;
|
||||
X509 *cert, *server_cert;
|
||||
STACK_OF(X509) *chain = NULL;
|
||||
ret = decompress_certs(in, in_end,cached_certs, cached_certs_count,
|
||||
out_certs, out_certs_count);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
cert = bio_to_crt((const char *)lsquic_str_cstr(out_certs[0]),
|
||||
server_cert = bio_to_crt((const char *)lsquic_str_cstr(out_certs[0]),
|
||||
lsquic_str_len(out_certs[0]), 0);
|
||||
pub_key = X509_get_pubkey(cert);
|
||||
pub_key = X509_get_pubkey(server_cert);
|
||||
ret = verify_prof((const uint8_t *)lsquic_str_cstr(&enc_session->chlo),
|
||||
(size_t)lsquic_str_len(&enc_session->chlo),
|
||||
&enc_session->info->scfg,
|
||||
|
@ -1124,7 +1126,36 @@ static int handle_chlo_reply_verify_prof(lsquic_enc_session_t *enc_session,
|
|||
(const uint8_t *)lsquic_str_cstr(&enc_session->hs_ctx.prof),
|
||||
lsquic_str_len(&enc_session->hs_ctx.prof));
|
||||
EVP_PKEY_free(pub_key);
|
||||
X509_free(cert);
|
||||
if (ret != 0)
|
||||
goto cleanup;
|
||||
|
||||
if (enc_session->enpub->enp_verify_cert)
|
||||
{
|
||||
chain = sk_X509_new_null();
|
||||
sk_X509_push(chain, server_cert);
|
||||
for (i = 1; i < *out_certs_count; ++i)
|
||||
{
|
||||
cert = bio_to_crt((const char *)lsquic_str_cstr(out_certs[i]),
|
||||
lsquic_str_len(out_certs[i]), 0);
|
||||
if (cert)
|
||||
sk_X509_push(chain, cert);
|
||||
else
|
||||
{
|
||||
LSQ_WARN("cannot push certificate to stack");
|
||||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
ret = enc_session->enpub->enp_verify_cert(
|
||||
enc_session->enpub->enp_verify_ctx, chain);
|
||||
LSQ_INFO("server certificate verification %ssuccessful",
|
||||
ret == 0 ? "" : "not ");
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (chain)
|
||||
sk_X509_free(chain);
|
||||
X509_free(server_cert);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1837,6 +1868,41 @@ lsquic_enc_session_verify_reset_token (lsquic_enc_session_t *enc_session,
|
|||
}
|
||||
|
||||
|
||||
static STACK_OF(X509) *
|
||||
lsquic_enc_session_get_server_cert_chain (lsquic_enc_session_t *enc_session)
|
||||
{
|
||||
const struct cert_hash_item_st *item;
|
||||
STACK_OF(X509) *chain;
|
||||
X509 *cert;
|
||||
int i;
|
||||
|
||||
item = c_find_certs(&enc_session->hs_ctx.sni);
|
||||
if (!item)
|
||||
{
|
||||
LSQ_WARN("could not find certificates for `%.*s'",
|
||||
(int) lsquic_str_len(&enc_session->hs_ctx.sni),
|
||||
lsquic_str_cstr(&enc_session->hs_ctx.sni));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
chain = sk_X509_new_null();
|
||||
for (i = 0; i < item->count; ++i)
|
||||
{
|
||||
cert = bio_to_crt(lsquic_str_cstr(&item->crts[i]),
|
||||
lsquic_str_len(&item->crts[i]), 0);
|
||||
if (cert)
|
||||
sk_X509_push(chain, cert);
|
||||
else
|
||||
{
|
||||
sk_X509_free(chain);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return chain;
|
||||
}
|
||||
|
||||
|
||||
#ifdef NDEBUG
|
||||
const
|
||||
#endif
|
||||
|
@ -1859,6 +1925,7 @@ struct enc_session_funcs lsquic_enc_session_gquic_1 =
|
|||
.esf_handle_chlo_reply = lsquic_enc_session_handle_chlo_reply,
|
||||
.esf_mem_used = lsquic_enc_session_mem_used,
|
||||
.esf_verify_reset_token = lsquic_enc_session_verify_reset_token,
|
||||
.esf_get_server_cert_chain = lsquic_enc_session_get_server_cert_chain,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
struct lsquic_engine_public;
|
||||
struct lsquic_enc_session;
|
||||
struct stack_st_X509;
|
||||
|
||||
typedef struct lsquic_enc_session lsquic_enc_session_t;
|
||||
|
||||
|
@ -139,6 +140,9 @@ struct enc_session_funcs
|
|||
int
|
||||
(*esf_verify_reset_token) (lsquic_enc_session_t *, const unsigned char *,
|
||||
size_t);
|
||||
|
||||
struct stack_st_X509 *
|
||||
(*esf_get_server_cert_chain) (lsquic_enc_session_t *);
|
||||
};
|
||||
|
||||
extern
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue