From: Joe Orton Date: Tue, 15 Feb 2005 12:39:45 +0000 (+0000) Subject: * modules/ssl/mod_ssl.h: Add ssl_ext_lookup optional hook declaration. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d48e90850031681840c9271445dacc4359f4fe5;p=thirdparty%2Fapache%2Fhttpd.git * modules/ssl/mod_ssl.h: Add ssl_ext_lookup optional hook declaration. * modules/ssl/ssl_engine_vars.c (ssl_ext_lookup): New function. (ssl_var_register): Register optional function. * modules/ssl/ssl_private.h (ssl_ext_lookup): Add prototype. Submitted by: David Reid, Joe Orton git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk/modules/ssl@153933 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/mod_ssl.h b/mod_ssl.h index 67761c78136..fdde6411965 100644 --- a/mod_ssl.h +++ b/mod_ssl.h @@ -27,6 +27,16 @@ APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup, conn_rec *, request_rec *, char *)); +/* The ssl_ext_lookup() optional function retrieves the value of a SSL + * certificate X.509 extension. The client certificate is used if + * peer is non-zero; the server certificate is used otherwise. The + * oidnum parameter specifies the numeric OID (e.g. "1.2.3.4") of the + * desired extension. The string value of the extension is returned, + * or NULL on error. */ +APR_DECLARE_OPTIONAL_FN(const char *, ssl_ext_lookup, + (apr_pool_t *p, conn_rec *c, int peer, + const char *oidnum)); + /* An optional function which returns non-zero if the given connection * is using SSL/TLS. */ APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *)); diff --git a/ssl_engine_vars.c b/ssl_engine_vars.c index 568ebb20b01..58a974e53cf 100644 --- a/ssl_engine_vars.c +++ b/ssl_engine_vars.c @@ -61,6 +61,7 @@ void ssl_var_register(void) { APR_REGISTER_OPTIONAL_FN(ssl_is_https); APR_REGISTER_OPTIONAL_FN(ssl_var_lookup); + APR_REGISTER_OPTIONAL_FN(ssl_ext_lookup); return; } @@ -655,6 +656,61 @@ static char *ssl_var_lookup_ssl_version(apr_pool_t *p, char *var) return result; } +const char *ssl_ext_lookup(apr_pool_t *p, conn_rec *c, int peer, + const char *oidnum) +{ + SSLConnRec *sslconn = myConnConfig(c); + SSL *ssl; + X509 *xs = NULL; + ASN1_OBJECT *oid; + int count = 0, j; + char *result = NULL; + + if (!sslconn || !sslconn->ssl) { + return NULL; + } + ssl = sslconn->ssl; + + oid = OBJ_txt2obj(oidnum, 1); + if (!oid) { + ERR_clear_error(); + return NULL; + } + + xs = peer ? SSL_get_peer_certificate(ssl) : SSL_get_certificate(ssl); + if (xs == NULL) { + return NULL; + } + + count = X509_get_ext_count(xs); + + for (j = 0; j < count; j++) { + X509_EXTENSION *ext = X509_get_ext(xs, j); + + if (OBJ_cmp(ext->object, oid) == 0) { + BIO *bio = BIO_new(BIO_s_mem()); + + if (X509V3_EXT_print(bio, ext, 0, 0) == 1) { + BUF_MEM *buf; + + BIO_get_mem_ptr(bio, &buf); + result = apr_pstrmemdup(p, buf->data, buf->length); + } + + BIO_vfree(bio); + break; + } + } + + if (peer) { + /* only SSL_get_peer_certificate raises the refcount */ + X509_free(xs); + } + + ERR_clear_error(); + return result; +} + /* _________________________________________________________________ ** ** SSL Extension to mod_log_config diff --git a/ssl_private.h b/ssl_private.h index de8c376ccdc..38fde078078 100644 --- a/ssl_private.h +++ b/ssl_private.h @@ -641,6 +641,8 @@ void ssl_log_ssl_error(const char *, int, int, server_rec *); /* Variables */ void ssl_var_register(void); char *ssl_var_lookup(apr_pool_t *, server_rec *, conn_rec *, request_rec *, char *); +const char *ssl_ext_lookup(apr_pool_t *p, conn_rec *c, int peer, const char *oid); + void ssl_var_log_config_register(apr_pool_t *p); #define APR_SHM_MAXSIZE (64 * 1024 * 1024)