William A. Rowe, Jr. wrote:
At 04:17 AM 2/2/2005, David Reid wrote:

Basically this allows us to gain access to the actual cert structure.


Agreed that raw cert isn't that useful, and somewhat frightens
me in the environment table. The PEM or DER formats would be generally useful. Unpacking the extended X509 attributes
might be even more useful.


Bill


This is the patch that provides me with the functionality I need. It's generalised to a high degree and provides an easy way to get access to extension data. It keeps the details hidden within mod_ssl where they belong.

david


Index: ssl_private.h
===================================================================
--- ssl_private.h (revision 123890)
+++ ssl_private.h (working copy)
@@ -633,6 +633,7 @@
/* Variables */
void ssl_var_register(void);
char *ssl_var_lookup(apr_pool_t *, server_rec *, conn_rec *, request_rec *, char *);
+char *ssl_ext_lookup(apr_pool_t *, conn_rec *, char *, char *);
void ssl_var_log_config_register(apr_pool_t *p);


 #define APR_SHM_MAXSIZE (64 * 1024 * 1024)
Index: ssl_engine_vars.c
===================================================================
--- ssl_engine_vars.c   (revision 123890)
+++ ssl_engine_vars.c   (working copy)
@@ -60,6 +60,7 @@
 {
     APR_REGISTER_OPTIONAL_FN(ssl_is_https);
     APR_REGISTER_OPTIONAL_FN(ssl_var_lookup);
+    APR_REGISTER_OPTIONAL_FN(ssl_ext_lookup);
     return;
 }

@@ -654,6 +655,68 @@
     return result;
 }


+/* This function must remain safe to use for a non-SSL connection.
+ * This function is essentially the same as ssl_var_lookup but it looks ONLY
+ * in the X509_EXTENSION structures. It looks for a matching OID and (optionally)
+ * a value to match.
+ */
+char *ssl_ext_lookup(apr_pool_t *p, conn_rec *c, char *oid, char *var)
+{
+ SSLConnRec *sslconn = myConnConfig(c);
+ char *result = NULL;
+ SSL *ssl = sslconn->ssl;
+ X509 *xs = NULL;
+ int count = 0, j;
+ size_t oidlen, varlen = 0;
+
+ if (!oid)
+ return result;
+
+ oidlen = strlen(oid);
+ if (var)
+ varlen = strlen(var);
+
+ /*
+ * When no pool is given try to find one
+ */
+ if (p == NULL) {
+ if (c != NULL)
+ p = c->pool;
+ }
+ if (!p)


+ return result;
+
+ /* We ONLY operate on peer certificates */
+ if (! (xs = SSL_get_peer_certificate(ssl)))
+ return result;
+
+ if ((count = X509_get_ext_count(xs)) == 0)
+ return result;
+
+ for (j = 0; j < count; j++) {
+ X509_EXTENSION *ext = X509_get_ext(xs, j);
+ char *this_oid = alloca(oidlen + 1);
+ if (OBJ_obj2txt(this_oid, oidlen + 1, ext->object, 1) == oidlen &&
+ strncmp(this_oid, oid, oidlen) == 0) {
+ /* We have found a matching OID.
+ * If we have been asked to match a value, then we check it here,
+ * if we've just been asked to find an instance of the OID
+ * then we simply return the value.
+ */
+ char *str = ASN1_STRING_data((ASN1_STRING *)ext->value);
+ if (var) {
+ if (strncmp(str, var, varlen) == 0)
+ result = apr_pstrdup(p, str);
+ } else
+ result = apr_pstrdup(p, str);
+
+ if (result)
+ break;
+ }
+ }
+ return result;
+}
+
/* _________________________________________________________________
**
** SSL Extension to mod_log_config


Index: mod_ssl.h
===================================================================
--- mod_ssl.h   (revision 123890)
+++ mod_ssl.h   (working copy)
@@ -26,6 +26,11 @@
                          conn_rec *, request_rec *,
                          char *));

+/* The ssl_ext_lookup() optional function retrieves SSL environment
+ * variables. */
+APR_DECLARE_OPTIONAL_FN(char *, ssl_ext_lookup,
+                        (apr_pool_t *, conn_rec *, char *, char *));
+
 /* 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 *));



Reply via email to