Skip to content

Instantly share code, notes, and snippets.

@skroll
Created March 24, 2016 18:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skroll/64c8bfdca89d9cd286df to your computer and use it in GitHub Desktop.
Save skroll/64c8bfdca89d9cd286df to your computer and use it in GitHub Desktop.
Example module of getting the SSL Subject/Issuer DN is RFC 2253 format
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
typedef ngx_int_t (*ngx_x509rfc2253_variable_handler_pt)(ngx_connection_t *c,
ngx_pool_t *pool, ngx_str_t *s);
static ngx_int_t ngx_x509rfc2253_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_x509rfc2253_add_variables(ngx_conf_t *cf);
static ngx_int_t ngx_x509rfc2253_get_subject_dn(ngx_connection_t *c,
ngx_pool_t *pool, ngx_str_t *s);
static ngx_int_t ngx_x509rfc2253_get_issuer_dn(ngx_connection_t *c,
ngx_pool_t *pool, ngx_str_t *s);
static ngx_http_module_t ngx_x509rfc2253_module_ctx = {
ngx_x509rfc2253_add_variables, /* preconfiguration */
NULL, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
NULL, /* merge server configuration */
NULL, /* create location configuration */
NULL /* merge location configuration */
};
ngx_module_t ngx_x509rfc2253_module = {
NGX_MODULE_V1,
&ngx_x509rfc2253_module_ctx, /* module context */
NULL, /* module directives */
NGX_HTTP_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
static ngx_http_variable_t ngx_x509rfc2253_vars[] = {
{ ngx_string("ssl_client_s_dn_rfc2253"), NULL, ngx_x509rfc2253_variable,
(uintptr_t) ngx_x509rfc2253_get_subject_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
{ ngx_string("ssl_client_i_dn_rfc2253"), NULL, ngx_x509rfc2253_variable,
(uintptr_t) ngx_x509rfc2253_get_issuer_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
};
static ngx_int_t
ngx_x509rfc2253_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
uintptr_t data)
{
ngx_x509rfc2253_variable_handler_pt handler = (ngx_x509rfc2253_variable_handler_pt) data;
ngx_str_t s;
if (r->connection->ssl) {
if (handler(r->connection, r->pool, &s) != NGX_OK) {
return NGX_ERROR;
}
v->len = s.len;
v->data = s.data;
if (v->len) {
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
return NGX_OK;
}
}
v->not_found = 1;
return NGX_OK;
}
static ngx_int_t
ngx_x509rfc2253_add_variables(ngx_conf_t *cf) {
ngx_http_variable_t *var, *v;
for (v = ngx_x509rfc2253_vars; v->name.len; v++) {
var = ngx_http_add_variable(cf, &v->name, v->flags);
if (var == NULL) {
return NGX_ERROR;
}
var->get_handler = v->get_handler;
var->data = v->data;
}
return NGX_OK;
}
static ngx_int_t
ngx_x509rfc2253_get_subject_dn(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s)
{
BIO *bio;
size_t len;
X509 *cert;
X509_NAME *name;
s->len = 0;
cert = SSL_get_peer_certificate(c->ssl->connection);
if (cert == NULL) {
return NGX_OK;
}
name = X509_get_subject_name(cert);
if (name == NULL) {
X509_free(cert);
return NGX_ERROR;
}
bio = BIO_new(BIO_s_mem());
if (bio == NULL) {
X509_free(cert);
return NGX_ERROR;
}
if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) {
goto failed;
}
len = BIO_pending(bio);
s->len = len;
s->data = ngx_pnalloc(pool, len);
if (s->data == NULL) {
goto failed;
}
BIO_read(bio, s->data, len);
BIO_free(bio);
X509_free(cert);
return NGX_OK;
failed:
BIO_free(bio);
X509_free(cert);
return NGX_ERROR;
}
static ngx_int_t
ngx_x509rfc2253_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s)
{
BIO *bio;
size_t len;
X509 *cert;
X509_NAME *name;
s->len = 0;
cert = SSL_get_peer_certificate(c->ssl->connection);
if (cert == NULL) {
return NGX_OK;
}
name = X509_get_issuer_name(cert);
if (name == NULL) {
X509_free(cert);
return NGX_ERROR;
}
bio = BIO_new(BIO_s_mem());
if (bio == NULL) {
X509_free(cert);
return NGX_ERROR;
}
if (X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253) < 0) {
goto failed;
}
len = BIO_pending(bio);
s->len = len;
s->data = ngx_pnalloc(pool, len);
if (s->data == NULL) {
goto failed;
}
BIO_read(bio, s->data, len);
BIO_free(bio);
X509_free(cert);
return NGX_OK;
failed:
BIO_free(bio);
X509_free(cert);
return NGX_ERROR;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment