Created
March 24, 2016 18:58
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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