Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions bin/http_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <event2/event.h>

#include <openssl/md5.h>
#include <openssl/x509.h>

#include "lsquic.h"
#include "../src/liblsquic/lsquic_hash.h"
Expand Down Expand Up @@ -361,6 +362,38 @@ http_server_on_goaway (lsquic_conn_t *conn)
}


static void
http_server_on_hsk_done (lsquic_conn_t *conn, enum lsquic_hsk_status status)
{
STACK_OF(X509) *chain;
X509_NAME *name;
X509 *cert;
unsigned i;
char buf[100];

if (status != LSQ_HSK_OK && status != LSQ_HSK_RESUMED_OK)
return;

chain = lsquic_conn_get_full_cert_chain(conn);
if (!chain)
{
LSQ_DEBUG("peer did not provide full certificate chain");
return;
}

for (i = 0; i < sk_X509_num(chain); ++i)
{
cert = sk_X509_value(chain, i);
name = X509_get_subject_name(cert);
LSQ_INFO("full cert #%u: name: %s", i,
X509_NAME_oneline(name, buf, sizeof(buf)));
X509_free(cert);
}

sk_X509_free(chain);
}


static void
http_server_on_conn_closed (lsquic_conn_t *conn)
{
Expand Down Expand Up @@ -1086,6 +1119,7 @@ const struct lsquic_stream_if http_server_if = {
.on_write = http_server_on_write,
.on_close = http_server_on_close,
.on_goaway_received = http_server_on_goaway,
.on_hsk_done = http_server_on_hsk_done,
};


Expand Down Expand Up @@ -1202,6 +1236,7 @@ const struct lsquic_stream_if hq_server_if = {
.on_read = hq_server_on_read,
.on_write = hq_server_on_write,
.on_close = http_server_on_close,
.on_hsk_done = http_server_on_hsk_done,
};
#endif

Expand Down Expand Up @@ -1771,6 +1806,7 @@ const struct lsquic_stream_if interop_http_server_if = {
.on_read = http_server_interop_on_read,
.on_write = http_server_interop_on_write,
.on_close = http_server_on_close,
.on_hsk_done = http_server_on_hsk_done,
};
#endif /* HAVE_REGEX */

Expand Down
7 changes: 7 additions & 0 deletions docs/apiref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2039,6 +2039,13 @@ Miscellaneous Connection Functions

The caller releases the stack using sk_X509_free().

.. function:: struct stack_st_X509 * lsquic_conn_get_full_cert_chain (lsquic_conn_t *conn)

Get full certificate chain returned by the server/client. This can be used for
server/client certificate verification.

The caller releases the stack using sk_X509_free().

.. function:: lsquic_conn_ctx_t * lsquic_conn_get_ctx (const lsquic_conn_t *conn)

Get user-supplied context associated with the connection.
Expand Down
10 changes: 10 additions & 0 deletions include/lsquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1808,6 +1808,16 @@ lsquic_stream_has_unacked_data (lsquic_stream_t *s);
struct stack_st_X509 *
lsquic_conn_get_server_cert_chain (lsquic_conn_t *);

/**
* Get the full certificate chain returned by the server/lient.
* This can be used for server/client certificate verification.
*
* The caller releases the stack using sk_X509_free().
*/
struct stack_st_X509 *
lsquic_conn_get_full_cert_chain (lsquic_conn_t *);


/** Returns ID of the stream */
lsquic_stream_id_t
lsquic_stream_id (const lsquic_stream_t *s);
Expand Down
10 changes: 10 additions & 0 deletions src/liblsquic/lsquic_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@ lsquic_conn_get_server_cert_chain (struct lsquic_conn *lconn)
}


struct stack_st_X509 *
lsquic_conn_get_full_cert_chain (struct lsquic_conn *lconn)
{
if (lconn->cn_enc_session)
return lconn->cn_esf_c->esf_get_full_cert_chain(lconn->cn_enc_session);
else
return NULL;
}


void
lsquic_conn_make_stream (struct lsquic_conn *lconn)
{
Expand Down
3 changes: 3 additions & 0 deletions src/liblsquic/lsquic_enc_sess.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ struct enc_session_funcs_common
struct stack_st_X509 *
(*esf_get_server_cert_chain) (enc_session_t *);

struct stack_st_X509 *
(*esf_get_full_cert_chain) (enc_session_t *);

int
(*esf_verify_reset_token) (enc_session_t *, const unsigned char *, size_t);

Expand Down
23 changes: 23 additions & 0 deletions src/liblsquic/lsquic_enc_sess_ietf.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ free_handshake_keys (struct enc_sess_iquic *);
static struct stack_st_X509 *
iquic_esf_get_server_cert_chain (enc_session_t *);

static struct stack_st_X509 *
iquic_esf_get_full_cert_chain (enc_session_t *);

static void
maybe_drop_SSL (struct enc_sess_iquic *);

Expand Down Expand Up @@ -2612,6 +2615,22 @@ iquic_esf_get_server_cert_chain (enc_session_t *enc_session_p)
}


static struct stack_st_X509 *
iquic_esf_get_full_cert_chain (enc_session_t *enc_session_p)
{
struct enc_sess_iquic *const enc_sess = enc_session_p;
STACK_OF(X509) *chain;

if (enc_sess->esi_ssl)
{
chain = SSL_get_peer_full_cert_chain(enc_sess->esi_ssl);
return X509_chain_up_ref(chain);
}
else
return NULL;
}


static const char *
iquic_esf_cipher (enc_session_t *enc_session_p)
{
Expand Down Expand Up @@ -2864,6 +2883,8 @@ const struct enc_session_funcs_common lsquic_enc_session_common_ietf_v1 =
.esf_tag_len = IQUIC_TAG_LEN,
.esf_get_server_cert_chain
= iquic_esf_get_server_cert_chain,
.esf_get_full_cert_chain
= iquic_esf_get_full_cert_chain,
.esf_get_sni = iquic_esf_get_sni,
.esf_cipher = iquic_esf_cipher,
.esf_keysize = iquic_esf_keysize,
Expand All @@ -2883,6 +2904,8 @@ const struct enc_session_funcs_common lsquic_enc_session_common_ietf_v1_no_flush
.esf_tag_len = IQUIC_TAG_LEN,
.esf_get_server_cert_chain
= iquic_esf_get_server_cert_chain,
.esf_get_full_cert_chain
= iquic_esf_get_full_cert_chain,
.esf_get_sni = iquic_esf_get_sni,
.esf_cipher = iquic_esf_cipher,
.esf_keysize = iquic_esf_keysize,
Expand Down