You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ma...@apache.org on 2005/07/20 18:42:59 UTC

svn commit: r219940 - in /httpd/httpd/trunk: docs/manual/mod/mod_ssl.xml modules/ssl/ssl_expr.h modules/ssl/ssl_expr_eval.c modules/ssl/ssl_expr_parse.y modules/ssl/ssl_expr_scan.l

Author: martin
Date: Wed Jul 20 09:42:58 2005
New Revision: 219940

URL: http://svn.apache.org/viewcvs?rev=219940&view=rev
Log:
Collaborative work: (Thanks, dreid!)
Implement OID checking for mod_ssl. This code allows for checking of arbitrary client
certificate extensions by OID, in a syntax like:
   SSLRequire "BaDCA Generated Certificate" in Oid("2.16.840.1.113730.1.13") \
          || "committers"                   in Oid("1.3.6.1.4.1.18060.1")
Note the following:
* A given OID can occur multiple times in one cert, with different values. Therefore
  the OID function compares the left-hand string against each of the OID values,
  until a complete match is found. If none patches, the result is FALSE
* The left hand side can be another expression, so can be a reference to a variable
  or an file() invocation etc.
* The OID is also just a reference to a string, or function, or whatever.
* My manual description is very short. Someone else please help improve the description


Modified:
    httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml
    httpd/httpd/trunk/modules/ssl/ssl_expr.h
    httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c
    httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y
    httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l

Modified: httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml?rev=219940&r1=219939&r2=219940&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/mod_ssl.xml Wed Jul 20 09:42:58 2005
@@ -1188,7 +1188,7 @@
 <usage>
 <p>
 This directive specifies a general access requirement which has to be
-fulfilled in order to allow access. It's a very powerful directive because the
+fulfilled in order to allow access. It is a very powerful directive because the
 requirement specification is an arbitrarily complex boolean expression
 containing any number of access checks.</p>
 <note type="warning">
@@ -1216,6 +1216,7 @@
            | word "<strong>&gt;</strong>"  word | word "<strong>gt</strong>" word
            | word "<strong>&gt;=</strong>" word | word "<strong>ge</strong>" word
            | word "<strong>in</strong>" "<strong>{</strong>" wordlist "<strong>}</strong>"
+           | word "<strong>in</strong>" "<strong>OID(</strong>" word "<strong>)</strong>"
            | word "<strong>=~</strong>" regex
            | word "<strong>!~</strong>" regex
 
@@ -1258,6 +1259,11 @@
             and %{TIME_HOUR} &gt;= 8 and %{TIME_HOUR} &lt;= 20       ) \<br />
            or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
 </example>
+<p>The <code>OID()</code> function expects to find zero or more instances
+of the given OID in the client certificate, and compares the left-hand side
+string against the value of matching OID attributes. Every matching OID is
+checked, until a match is found.
+</p>
 
 <p><em>Standard CGI/1.0 and Apache variables:</em></p>
 <pre>

Modified: httpd/httpd/trunk/modules/ssl/ssl_expr.h
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/ssl/ssl_expr.h?rev=219940&r1=219939&r2=219940&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_expr.h (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_expr.h Wed Jul 20 09:42:58 2005
@@ -61,7 +61,7 @@
 #endif
 
 typedef enum {
-    op_NOP, op_ListElement,
+    op_NOP, op_ListElement, op_OidListElement,
     op_True, op_False, op_Not, op_Or, op_And, op_Comp,
     op_EQ, op_NE, op_LT, op_LE, op_GT, op_GE, op_IN, op_REG, op_NRE,
     op_Digit, op_String, op_Regex, op_Var, op_Func

Modified: httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c?rev=219940&r1=219939&r2=219940&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_expr_eval.c Wed Jul 20 09:42:58 2005
@@ -36,6 +36,7 @@
 
 static BOOL  ssl_expr_eval_comp(request_rec *, ssl_expr *);
 static char *ssl_expr_eval_word(request_rec *, ssl_expr *);
+static BOOL  ssl_expr_eval_oid(const char *w, request_rec *r, const char *oidstr);
 static char *ssl_expr_eval_func_file(request_rec *, char *);
 static int   ssl_expr_eval_strcmplex(char *, char *);
 
@@ -113,8 +114,19 @@
             char *w1 = ssl_expr_eval_word(r, e1);
             BOOL found = FALSE;
             do {
+                ssl_expr_node_op op = e2->node_op;
                 e3 = (ssl_expr *)e2->node_arg1;
                 e2 = (ssl_expr *)e2->node_arg2;
+
+                if (op == op_OidListElement) {
+                    char *w3 = ssl_expr_eval_word(r, e3);
+
+                    found = ssl_expr_eval_oid(w1, r, w3);
+
+                    /* There will be no more nodes on the list, so the result is authoritative */
+                    break;
+                }
+
                 if (strcmp(w1, ssl_expr_eval_word(r, e3)) == 0) {
                     found = TRUE;
                     break;
@@ -185,6 +197,60 @@
         }
     }
 }
+
+static BOOL ssl_expr_eval_oid(const char *word, request_rec *r, const char *oidstr)
+{
+    SSLConnRec *sslconn = myConnConfig(r->connection);
+    SSL *ssl;
+    X509 *xs = NULL;
+    ASN1_OBJECT *oid;
+    int count = 0, j;
+    BOOL result = FALSE;
+
+    if (!oidstr || !sslconn || !sslconn->ssl)
+        return FALSE;
+
+    ssl = sslconn->ssl;
+
+    oid = OBJ_txt2obj(oidstr, 1);
+    if (!oid) {
+        ERR_clear_error();
+        return FALSE;
+    }
+
+    xs = SSL_get_peer_certificate(ssl);
+    if (xs == NULL) {
+        return FALSE;
+    }
+
+    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);
+
+                if (strcmp(word, buf->data) == 0)
+                    result = TRUE;
+            }
+
+            BIO_vfree(bio);
+            if (result != FALSE)
+                break;
+        }
+    }
+
+    X509_free(xs);
+    ERR_clear_error();
+    return result;
+}
+
 
 static char *ssl_expr_eval_func_file(request_rec *r, char *filename)
 {

Modified: httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y?rev=219940&r1=219939&r2=219940&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_expr_parse.y Wed Jul 20 09:42:58 2005
@@ -61,6 +61,7 @@
 %token  T_OP_REG
 %token  T_OP_NRE
 %token  T_OP_IN
+%token  T_OP_OID
 
 %token  T_OP_OR
 %token  T_OP_AND
@@ -75,6 +76,7 @@
 %type   <exVal>   funccall
 %type   <exVal>   regex
 %type   <exVal>   words
+%type   <exVal>   wordlist
 %type   <exVal>   word
 
 %%
@@ -97,10 +99,14 @@
           | word T_OP_LE word            { $$ = ssl_expr_make(op_LE,  $1, $3); }
           | word T_OP_GT word            { $$ = ssl_expr_make(op_GT,  $1, $3); }
           | word T_OP_GE word            { $$ = ssl_expr_make(op_GE,  $1, $3); }
-          | word T_OP_IN '{' words '}'   { $$ = ssl_expr_make(op_IN,  $1, $4); }
+          | word T_OP_IN wordlist        { $$ = ssl_expr_make(op_IN,  $1, $3); }
           | word T_OP_REG regex          { $$ = ssl_expr_make(op_REG, $1, $3); }
           | word T_OP_NRE regex          { $$ = ssl_expr_make(op_NRE, $1, $3); }
           ;
+
+wordlist  : T_OP_OID '(' word ')'	 { $$ = ssl_expr_make(op_OidListElement, $3, NULL); }
+          | '{' words '}'                { $$ = $2 ; }
+	  ;
 
 words     : word                         { $$ = ssl_expr_make(op_ListElement, $1, NULL); }
           | words ',' word               { $$ = ssl_expr_make(op_ListElement, $3, $1);   }

Modified: httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l
URL: http://svn.apache.org/viewcvs/httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l?rev=219940&r1=219939&r2=219940&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l (original)
+++ httpd/httpd/trunk/modules/ssl/ssl_expr_scan.l Wed Jul 20 09:42:58 2005
@@ -173,6 +173,7 @@
 "not" { return T_OP_NOT; }
 "!"   { return T_OP_NOT; }
 "in"  { return T_OP_IN; }
+[Oo][Ii][Dd] { return T_OP_OID; }
 
  /*
   * Functions



Re: svn commit: r219940 - in /httpd/httpd/trunk: docs/manual/mod/mod_ssl.xml modules/ssl/ssl_expr.h modules/ssl/ssl_expr_eval.c modules/ssl/ssl_expr_parse.y modules/ssl/ssl_expr_scan.l

Posted by Justin Erenkrantz <ju...@erenkrantz.com>.
On Fri, Jul 22, 2005 at 12:02:29PM +0100, Joe Orton wrote:
> and since I can't update to fix (2) myself, here's another...

Try again.  All should be operational again.  -- justin

Re: svn commit: r219940 - in /httpd/httpd/trunk: docs/manual/mod/mod_ssl.xml modules/ssl/ssl_expr.h modules/ssl/ssl_expr_eval.c modules/ssl/ssl_expr_parse.y modules/ssl/ssl_expr_scan.l

Posted by Joe Orton <jo...@redhat.com>.
On Fri, Jul 22, 2005 at 11:12:07AM +0100, Joe Orton wrote:
> On Wed, Jul 20, 2005 at 04:42:59PM -0000, Martin Kraemer wrote:
> > Author: martin
> > Date: Wed Jul 20 09:42:58 2005
> > New Revision: 219940
> > 
> > URL: http://svn.apache.org/viewcvs?rev=219940&view=rev
> > Log:
> > Collaborative work: (Thanks, dreid!)
> > Implement OID checking for mod_ssl. This code allows for checking of arbitrary client
> > certificate extensions by OID, in a syntax like:
> >    SSLRequire "BaDCA Generated Certificate" in Oid("2.16.840.1.113730.1.13") \
> >           || "committers"                   in Oid("1.3.6.1.4.1.18060.1")
> > Note the following:
> > * A given OID can occur multiple times in one cert, with different values. Therefore
> >   the OID function compares the left-hand string against each of the OID values,
> >   until a complete match is found. If none patches, the result is FALSE
> > * The left hand side can be another expression, so can be a reference to a variable
> >   or an file() invocation etc.
> > * The OID is also just a reference to a string, or function, or whatever.
> > * My manual description is very short. Someone else please help improve the description

and since I can't update to fix (2) myself, here's another...

3) oid() is a terrible name for this; it's simply the type of the 
parameter.  It would be like calling malloc() "size()".  The function 
expands (conceptually) to the values of an extension in the peer's 
certificate, identified by OID; so call it peerext() or something 
meaningful like that.

Re: svn commit: r219940 - in /httpd/httpd/trunk: docs/manual/mod/mod_ssl.xml modules/ssl/ssl_expr.h modules/ssl/ssl_expr_eval.c modules/ssl/ssl_expr_parse.y modules/ssl/ssl_expr_scan.l

Posted by Joe Orton <jo...@redhat.com>.
On Wed, Jul 20, 2005 at 04:42:59PM -0000, Martin Kraemer wrote:
> Author: martin
> Date: Wed Jul 20 09:42:58 2005
> New Revision: 219940
> 
> URL: http://svn.apache.org/viewcvs?rev=219940&view=rev
> Log:
> Collaborative work: (Thanks, dreid!)
> Implement OID checking for mod_ssl. This code allows for checking of arbitrary client
> certificate extensions by OID, in a syntax like:
>    SSLRequire "BaDCA Generated Certificate" in Oid("2.16.840.1.113730.1.13") \
>           || "committers"                   in Oid("1.3.6.1.4.1.18060.1")
> Note the following:
> * A given OID can occur multiple times in one cert, with different values. Therefore
>   the OID function compares the left-hand string against each of the OID values,
>   until a complete match is found. If none patches, the result is FALSE
> * The left hand side can be another expression, so can be a reference to a variable
>   or an file() invocation etc.
> * The OID is also just a reference to a string, or function, or whatever.
> * My manual description is very short. Someone else please help improve the description

1) this is a pretty specific to way to code it.  Is there no way to make 
it more general so that OID() is just a function like file() and can be 
used e.g. in regex matches too?

2) you must always check in the regenerated generated scanner source 
along with changes to the lex file.

Regards,

joe