From 8e1836f57e8bcdb228dd5baadc71dfbf30b544e0 Mon Sep 17 00:00:00 2001 From: Christian Fischbach Date: Thu, 9 Feb 2023 00:48:17 +0100 Subject: Get common name and subject alternative names of peer certificate (#1617) Co-authored-by: Christian Fischbach --- src/supplemental/tls/mbedtls/tls.c | 86 ++++++++++++++++++++++++++++++++++---- src/supplemental/tls/tls_common.c | 42 ++++++++++++++++++- 2 files changed, 119 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/supplemental/tls/mbedtls/tls.c b/src/supplemental/tls/mbedtls/tls.c index a216b3a6..79f3ffd4 100644 --- a/src/supplemental/tls/mbedtls/tls.c +++ b/src/supplemental/tls/mbedtls/tls.c @@ -276,6 +276,74 @@ conn_verified(nng_tls_engine_conn *ec) return (mbedtls_ssl_get_verify_result(&ec->ctx) == 0); } +static char * +conn_peer_cn(nng_tls_engine_conn *ec) +{ + const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&ec->ctx); + if (!crt) { + return (NULL); + } + + char buf[0x400]; + int len = mbedtls_x509_dn_gets(buf, sizeof(buf), &crt->subject); + if (len <= 0) { + return (NULL); + } + + const char *pos = strstr(buf, "CN="); + if (!pos) { + return (NULL); + } + + pos += 3; + len -= pos - buf - 1; + if (len <= 1) { + return (NULL); + } + + char *rv = malloc(len); + memcpy(rv, pos, len); + return (rv); +} + +static char ** +conn_peer_alt_names(nng_tls_engine_conn *ec) +{ + const mbedtls_x509_crt *crt = mbedtls_ssl_get_peer_cert(&ec->ctx); + if (!crt) { + return (NULL); + } + + const mbedtls_asn1_sequence * seq = &crt->subject_alt_names; + + // get count + int count = 0; + do { + if (seq->buf.len > 0) ++count; + seq = seq->next; + } while (seq); + if (count == 0) return NULL; + + seq = &crt->subject_alt_names; + + // copy strings + char ** rv = malloc((count + 1) * sizeof(char *)); + int i = 0; + do { + if (seq->buf.len == 0) continue; + + rv[i] = malloc(seq->buf.len + 1); + memcpy(rv[i], seq->buf.p, seq->buf.len); + rv[i][seq->buf.len] = 0; + ++i; + + seq = seq->next; + } while (seq); + rv[i] = NULL; + + return rv; +} + static void config_fini(nng_tls_engine_config *cfg) { @@ -526,14 +594,16 @@ static nng_tls_engine_config_ops config_ops = { }; static nng_tls_engine_conn_ops conn_ops = { - .size = sizeof(nng_tls_engine_conn), - .init = conn_init, - .fini = conn_fini, - .close = conn_close, - .recv = conn_recv, - .send = conn_send, - .handshake = conn_handshake, - .verified = conn_verified, + .size = sizeof(nng_tls_engine_conn), + .init = conn_init, + .fini = conn_fini, + .close = conn_close, + .recv = conn_recv, + .send = conn_send, + .handshake = conn_handshake, + .verified = conn_verified, + .peer_cn = conn_peer_cn, + .peer_alt_names = conn_peer_alt_names, }; static nng_tls_engine tls_engine_mbed = { diff --git a/src/supplemental/tls/tls_common.c b/src/supplemental/tls/tls_common.c index 357c8411..d05a289d 100644 --- a/src/supplemental/tls/tls_common.c +++ b/src/supplemental/tls/tls_common.c @@ -756,11 +756,51 @@ tls_get_verified(void *arg, void *buf, size_t *szp, nni_type t) return (nni_copyout_bool(v, buf, szp, t)); } +static int +tls_get_peer_cn(void *arg, void *buf, size_t *szp, nni_type t) +{ + NNI_ARG_UNUSED(szp); + + if (t != NNI_TYPE_STRING) { + return (NNG_EBADTYPE); + } + + tls_conn *conn = arg; + nni_mtx_lock(&conn->lock); + *(char **) buf = conn->ops.peer_cn((void *) (conn + 1)); + nni_mtx_unlock(&conn->lock); + return (0); +} + +static int +tls_get_peer_alt_names(void *arg, void *buf, size_t *szp, nni_type t) +{ + NNI_ARG_UNUSED(szp); + + if (t != NNI_TYPE_POINTER) { + return (NNG_EBADTYPE); + } + + tls_conn *conn = arg; + nni_mtx_lock(&conn->lock); + *(char ***) buf = conn->ops.peer_alt_names((void *) (conn + 1)); + nni_mtx_unlock(&conn->lock); + return (0); +} + static const nni_option tls_options[] = { { .o_name = NNG_OPT_TLS_VERIFIED, .o_get = tls_get_verified, }, + { + .o_name = NNG_OPT_TLS_PEER_CN, + .o_get = tls_get_peer_cn, + }, + { + .o_name = NNG_OPT_TLS_PEER_ALT_NAMES, + .o_get = tls_get_peer_alt_names, + }, { .o_name = NULL, }, @@ -1680,4 +1720,4 @@ nni_tls_sys_fini(void) { } -#endif // !NNG_SUPP_TLS \ No newline at end of file +#endif // !NNG_SUPP_TLS -- cgit v1.2.3-70-g09d2