Joe Orton wrote:
> On Mon, Sep 12, 2005 at 04:02:02PM +0100, David Reid wrote:
> 
>>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.
> 
> 
> "OpenSSL... isn't up to much" isn't really very helpful (or sensible).  
> If the problem is that X509_ext_print will only handle particular types 
> of extension and that you can fall back on ASN1_print for extensions 
> which are simple e.g. string types then say that and cut out the waffle.

OK. Guess spending too long figuring out what did didn't work led me to
a dark place :-)

>>It removes the nastiness of the len pointer and also converts the
>>extlist fucntion to simply call into ssl_ext_lookup.
> 
> 
> That's pretty nasty, going through all the setup overhead and iterating 
> through the extension list again for each call.  But you miss my point: 
> the overlap in functionality is a bad thing not an missed opportunity 
> for refactoring.

OK, then what about the below.

> 
>>I've changed the log level down to INFO.

> 
> 
> DEBUG is the maximum acceptable IMO.

OK. OK. OK. I give in. DEBUG.

david


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

-extern apr_array_header_t *ssl_extlist_by_oid(request_rec *r, const
char *oidstr);
-
 void         ssl_var_log_config_register(apr_pool_t *p);

 #define APR_SHM_MAXSIZE (64 * 1024 * 1024)
Index: modules/ssl/ssl_expr_eval.c
===================================================================
--- modules/ssl/ssl_expr_eval.c (revision 279892)
+++ modules/ssl/ssl_expr_eval.c (working copy)
@@ -198,63 +198,6 @@
     }
 }

-#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)
-{
-    int count = 0, j;
-    X509 *xs = NULL;
-    ASN1_OBJECT *oid;
-    apr_array_header_t *val_array;
-    SSLConnRec *sslconn = myConnConfig(r->connection);
-
-    /* trivia */
-    if (oidstr == NULL || sslconn == NULL || sslconn->ssl == 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);
-        }
-    }
-
-    X509_free(xs);
-    ERR_clear_error();
-
-    if (val_array->nelts == 0)
-        return NULL;
-    else
-        return val_array;
-}
-
 static BOOL ssl_expr_eval_oid(request_rec *r, const char *word, const
char *oidstr)
 {
     int j;
@@ -262,7 +205,7 @@
     apr_array_header_t *oid_array;
     char **oid_value;

-    if (NULL == (oid_array = ssl_extlist_by_oid(r, oidstr))) {
+    if (NULL == (oid_array = ssl_ext_list(r->pool, r->connection, 1,
oidstr))) {
         return FALSE;
     }

Index: modules/ssl/ssl_engine_vars.c
===================================================================
--- modules/ssl/ssl_engine_vars.c       (revision 279892)
+++ modules/ssl/ssl_engine_vars.c       (working copy)
@@ -62,7 +62,7 @@
 {
     APR_REGISTER_OPTIONAL_FN(ssl_is_https);
     APR_REGISTER_OPTIONAL_FN(ssl_var_lookup);
-    APR_REGISTER_OPTIONAL_FN(ssl_ext_lookup);
+    APR_REGISTER_OPTIONAL_FN(ssl_ext_list);
     return;
 }

@@ -660,23 +660,30 @@
     return result;
 }

-const char *ssl_ext_lookup(apr_pool_t *p, conn_rec *c, int peer,
-                           const char *oidnum)
+apr_array_header_t *ssl_ext_list(apr_pool_t *p, conn_rec *c, int peer,
+                                 const char *extension)
 {
     SSLConnRec *sslconn = myConnConfig(c);
-    SSL *ssl;
+    SSL *ssl = NULL;
+    apr_array_header_t *array = NULL;
     X509 *xs = NULL;
-    ASN1_OBJECT *oid;
+    ASN1_OBJECT *oid = NULL;
     int count = 0, j;
-    char *result = NULL;
-
-    if (!sslconn || !sslconn->ssl) {
+
+    if (!sslconn || !sslconn->ssl || !extension) {
         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_DEBUG, 0, c,
+                      "Failed to create an object for extension '%s'",
+                      extension);
         ERR_clear_error();
         return NULL;
     }
@@ -685,25 +692,42 @@
     if (xs == NULL) {
         return NULL;
     }
-
+
     count = X509_get_ext_count(xs);
+    /* Create an array large enough to accomodate every extension. This is
+     * likely overkill, but safe.
+     */
+    array = apr_array_make(p, count, sizeof(char *));
+    if (array) {
+        for (j = 0; j < count; j++) {
+            X509_EXTENSION *ext = X509_get_ext(xs, j);

-    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 (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);
+                /* We want to obtain a string representation of the
extensions
+                 * value and add it to the array we're building.
+                 * X509V3_EXT_print() doesn't know about all the possible
+                 * data types, but the value is stored as an
ASN1_OCTET_STRING
+                 * allowing us a fallback in case of X509V3_EXT_print
+                 * not knowing how to handle the data.
+                 */
+                if (X509V3_EXT_print(bio, ext, 0, 0) == 1 ||
+                    ASN1_STRING_print(bio, ext->value) == 1) {
+                    BUF_MEM *buf;
+                    char **ptr = apr_array_push(array);
+                    BIO_get_mem_ptr(bio, &buf);
+                    *ptr = apr_pstrmemdup(p, buf->data, buf->length);
+                } else {
+                    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+                                  "Found an extension '%s', but failed to "
+                                  "create a string from it", extension);
+                }
+                BIO_vfree(bio);
             }
-
-            BIO_vfree(bio);
-            break;
         }
+        if (array->nelts == 0)
+            array = NULL;
     }

     if (peer) {
@@ -712,7 +736,7 @@
     }

     ERR_clear_error();
-    return result;
+    return array;
 }

 static char *ssl_var_lookup_ssl_compress_meth(SSL *ssl)
Index: modules/ssl/mod_ssl.c
===================================================================
--- modules/ssl/mod_ssl.c       (revision 279892)
+++ modules/ssl/mod_ssl.c       (working copy)
@@ -504,8 +504,6 @@

     APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable);
     APR_REGISTER_OPTIONAL_FN(ssl_engine_disable);
-
-    APR_REGISTER_OPTIONAL_FN(ssl_extlist_by_oid);
 }

 module AP_MODULE_DECLARE_DATA ssl_module = {
Index: modules/ssl/mod_ssl.h
===================================================================
--- modules/ssl/mod_ssl.h       (revision 279892)
+++ modules/ssl/mod_ssl.h       (working copy)
@@ -36,15 +36,20 @@
                          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,
+/** The ssl_ext_list() optional function attempts to build an array
+ * of all the values contained in the named X.509 extension. The
+ * returned array will be created in the supplied pool.
+ * 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.
+ * A pointer to an apr_array_header_t structure is returned if at
+ * least one matching extension is found, NULL otherwise.
+ */
+APR_DECLARE_OPTIONAL_FN(apr_array_header_t *, ssl_ext_list,
                         (apr_pool_t *p, conn_rec *c, int peer,
-                         const char *oidnum));
+                         const char *extension));

 /** An optional function which returns non-zero if the given connection
  * is using SSL/TLS. */
@@ -58,7 +63,5 @@

 APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *));

-APR_DECLARE_OPTIONAL_FN(apr_array_header_t *, ssl_extlist_by_oid,
(request_rec *r, const char *oidstr));
-
 #endif /* __MOD_SSL_H__ */
 /** @} */

Reply via email to