Skip to content

Commit

Permalink
proxy: str = rctx:tls_peer_cn()
Browse files Browse the repository at this point in the history
Returns a string copy of the TLS peer CN entry. Returns nil if none
exists or unable to parse the certificate.
  • Loading branch information
dormando committed Aug 20, 2024
1 parent 41db678 commit e078242
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 0 deletions.
1 change: 1 addition & 0 deletions proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,7 @@ int mcplib_rcontext_res_any(lua_State *L);
int mcplib_rcontext_res_ok(lua_State *L);
int mcplib_rcontext_result(lua_State *L);
int mcplib_rcontext_cfd(lua_State *L);
int mcplib_rcontext_tls_peer_cn(lua_State *L);
int mcplib_rcontext_sleep(lua_State *L);
int mcplib_funcgenbare_new(lua_State *L);
int mcplib_funcgen_new(lua_State *L);
Expand Down
1 change: 1 addition & 0 deletions proxy_lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -1673,6 +1673,7 @@ int proxy_register_libs(void *ctx, LIBEVENT_THREAD *t, void *state) {
{"res_any", mcplib_rcontext_res_any},
{"result", mcplib_rcontext_result},
{"cfd", mcplib_rcontext_cfd},
{"tls_peer_cn", mcplib_rcontext_tls_peer_cn},
//{"sleep", mcplib_rcontext_sleep}, see comments on function
{NULL, NULL}
};
Expand Down
26 changes: 26 additions & 0 deletions proxy_luafgen.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */

#include "proxy.h"
#ifdef TLS
#include "tls.h"
#endif

static mcp_funcgen_t *mcp_funcgen_route(lua_State *L, mcp_funcgen_t *fgen, mcp_parser_t *pr);
static int mcp_funcgen_router_cleanup(lua_State *L, mcp_funcgen_t *fgen);
Expand Down Expand Up @@ -1405,6 +1408,29 @@ int mcplib_rcontext_cfd(lua_State *L) {
return 1;
}

// Must not call this if rctx has returned result to client already.
int mcplib_rcontext_tls_peer_cn(lua_State *L) {
mcp_rcontext_t *rctx = lua_touserdata(L, 1);
if (!rctx->c) {
lua_pushnil(L);
return 1;
}

#ifdef TLS
int len = 0;
const unsigned char *cn = ssl_get_peer_cn(rctx->c, &len);
if (cn) {
lua_pushlstring(L, (const char *)cn, len);
} else {
lua_pushnil(L);
}
#else
lua_pushnil(L);
#endif

return 1;
}

// the supplied handle must be valid.
void mcp_rcontext_push_rqu_res(lua_State *L, mcp_rcontext_t *rctx, int handle) {
struct mcp_rqueue_s *rqu = &rctx->qslots[handle];
Expand Down
35 changes: 35 additions & 0 deletions tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,41 @@ void *ssl_accept(conn *c, int sfd, bool *fail) {
* that for a future refactor.
*/

// TODO: add int offset, and find the nth NID here.
// or different function that accepts a string, then does etc?
// Caller _must immediately_ use the string and not store the pointer.
const unsigned char *ssl_get_peer_cn(conn *c, int *len) {
if (!c->ssl) {
return NULL;
}

// can't use get0 to avoid getting a reference since that requires 3.0.0+
X509 *cert = SSL_get_peer_certificate(c->ssl);
if (cert == NULL) {
return NULL;
}
X509_NAME *name = X509_get_subject_name(cert);
if (name == NULL) {
X509_free(cert);
return NULL;
}

int r = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
if (r == -1) {
X509_free(cert);
return NULL;
}
ASN1_STRING *asn1 = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, r));

if (asn1 == NULL) {
X509_free(cert);
return NULL;
}
*len = ASN1_STRING_length(asn1);
X509_free(cert);
return ASN1_STRING_get0_data(asn1);
}

/*
* Reads decrypted data from the underlying BIO read buffers,
* which reads from the socket.
Expand Down
1 change: 1 addition & 0 deletions tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#ifdef TLS
void *ssl_accept(conn *c, int sfd, bool *fail);
const unsigned char *ssl_get_peer_cn(conn *c, int *len);
int ssl_init(void);
void ssl_init_settings(void);
void ssl_init_conn(conn *c, void *ssl);
Expand Down

0 comments on commit e078242

Please sign in to comment.