httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Reid <da...@jetnet.co.uk>
Subject [PATCH] ssl_ext_lookup #2
Date Mon, 12 Sep 2005 15:02:02 GMT
Following the comments from Joe, here is a revised patch that should
work better :-) I've tried to add a sensible comment about why we have
both functions listed.

It removes the nastiness of the len pointer and also converts the
extlist fucntion to simply call into ssl_ext_lookup.

I've changed the log level down to INFO.

david

Index: modules/ssl/ssl_private.h
===================================================================
--- modules/ssl/ssl_private.h   (revision 279892)
+++ modules/ssl/ssl_private.h   (working copy)
@@ -646,7 +646,7 @@
 /**  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);
+const char  *ssl_ext_lookup(apr_pool_t *p, conn_rec *c, int peer, const
char *extension, int index);

 extern apr_array_header_t *ssl_extlist_by_oid(request_rec *r, const
char *oidstr);

Index: modules/ssl/ssl_expr_eval.c
===================================================================
--- modules/ssl/ssl_expr_eval.c (revision 279892)
+++ modules/ssl/ssl_expr_eval.c (working copy)
@@ -200,55 +200,24 @@

 #define NUM_OID_ELTS 8 /* start with 8 oid slots, resize when needed */

-apr_array_header_t *ssl_extlist_by_oid(request_rec *r, const char *oidstr)
+apr_array_header_t *ssl_extlist_by_oid(request_rec *r, const char *extname)
 {
-    int count = 0, j;
-    X509 *xs = NULL;
-    ASN1_OBJECT *oid;
+    int count = 0, j, n = 0;
     apr_array_header_t *val_array;
-    SSLConnRec *sslconn = myConnConfig(r->connection);
+    const char *val = NULL;

     /* trivia */
-    if (oidstr == NULL || sslconn == NULL || sslconn->ssl == NULL)
+    if (extname == NULL)
         return NULL;

-    /* Determine the oid we are looking for */
-    if ((oid = OBJ_txt2obj(oidstr, 1)) == NULL) {
-        ERR_clear_error();
-        return NULL;
-    }
-
-    /* are there any extensions in the cert? */
-    if ((xs = SSL_get_peer_certificate(sslconn->ssl)) == NULL ||
-        (count = X509_get_ext_count(xs)) == 0) {
-        return NULL;
-    }
-
     val_array = apr_array_make(r->pool, NUM_OID_ELTS, sizeof(char *));

-    /* Loop over all extensions, extract the desired oids */
-    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;
-                char **new = apr_array_push(val_array);
-
-                BIO_get_mem_ptr(bio, &buf);
-
-                *new = apr_pstrdup(r->pool, buf->data);
-            }
-
-            BIO_vfree(bio);
-        }
+    while ((val = ssl_ext_lookup(r->pool, r->connection, 1,
+                                 extname, n++))) {
+        char **newentry =apr_array_push(val_array);
+        *newentry = (char *)val;
     }

-    X509_free(xs);
-    ERR_clear_error();
-
     if (val_array->nelts == 0)
         return NULL;
     else
Index: modules/ssl/ssl_engine_vars.c
===================================================================
--- modules/ssl/ssl_engine_vars.c       (revision 279892)
+++ modules/ssl/ssl_engine_vars.c       (working copy)
@@ -661,7 +661,7 @@
 }

 const char *ssl_ext_lookup(apr_pool_t *p, conn_rec *c, int peer,
-                           const char *oidnum)
+                           const char *extension, int index)
 {
     SSLConnRec *sslconn = myConnConfig(c);
     SSL *ssl;
@@ -669,14 +669,21 @@
     ASN1_OBJECT *oid;
     int count = 0, j;
     char *result = NULL;
-
+
     if (!sslconn || !sslconn->ssl) {
         return NULL;
     }
     ssl = sslconn->ssl;

-    oid = OBJ_txt2obj(oidnum, 1);
+    /* We accept the "extension" string to be converted as
+     * a long name (nsComment), short name (DN) or
+     * numeric OID (1.2.3.4).
+     */
+    oid = OBJ_txt2obj(extension, 0);
     if (!oid) {
+        ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
+                      "Failed to create an object for extension '%s'",
+                      extension);
         ERR_clear_error();
         return NULL;
     }
@@ -692,13 +699,31 @@
         X509_EXTENSION *ext = X509_get_ext(xs, j);

         if (OBJ_cmp(ext->object, oid) == 0) {
-            BIO *bio = BIO_new(BIO_s_mem());
+            BIO *bio = NULL;

-            if (X509V3_EXT_print(bio, ext, 0, 0) == 1) {
+            if (index != -1 && --index > 0)
+                continue;
+
+            bio = BIO_new(BIO_s_mem());
+
+            /* As Joe keeps pointing out, the object of this function
+             * is to return a string. Sadly the function that openssl
+             * provides (X509V3_EXT_print) isn't up to much and often fails
+             * to provide a string. Thankfully what we want is contained
+             * in ext->value, which is an ASN1_OCTET_STRING. The function
+             * ASN1_STRING_print is able to handle these, so we fallback to
+             * this fucntion.
+             */
+            if (X509V3_EXT_print(bio, ext, 0, 0) == 1 ||
+                ASN1_STRING_print(bio, ext->value) == 1) {
                 BUF_MEM *buf;

                 BIO_get_mem_ptr(bio, &buf);
                 result = apr_pstrmemdup(p, buf->data, buf->length);
+            } else {
+                ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
+                              "Found an extension '%s', but failed to "
+                              "create a string from it", extension);
             }

             BIO_vfree(bio);
Index: modules/ssl/mod_ssl.h
===================================================================
--- modules/ssl/mod_ssl.h       (revision 279892)
+++ modules/ssl/mod_ssl.h       (working copy)
@@ -37,14 +37,20 @@
                          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. */
+ * certificate X.509 extension.
+ * The client certificate is used if peer is non-zero; the server
+ * certificate is used otherwise.
+ * Extension specifies the extensions to use as a string. This can be
+ * one of the "known" long or short names, or a numeric OID,
+ * e.g. "1.2.3.4", 'nsComment' and 'DN' are all valid.
+ * The index parameter allows for multiple values to be retrieved by
+ * repeated calls with the index incremented. Using an index of 0 will
+ * provide the first matching result.
+ * 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));
+                         const char *extension, int index));

 /** An optional function which returns non-zero if the given connection
  * is using SSL/TLS. */

Mime
View raw message