Hi Ralf

I'm using Andreas Müller's great ldap Authentication Module mod_authz_ldap
that is able to verify users on an ldap server by using the SSL Client
Certififace for authentication.

However, this module needs to know either the IssuerDN or the serialNumber
of the client's certificate in order to clearly identify the cert. The
following patch against 2.8.0 will expose these values to underlying
authentication modules, so they can identify a client certificate properly
(it was created by Andres Müller, not me, just for the credits).

Bye
Tim


*** ssl_engine_kernel.c-old     Wed Feb  7 14:01:53 2001
--- ssl_engine_kernel.c-new     Wed Feb  7 14:22:21 2001
***************
*** 216,221 ****
--- 216,223 ----
       * Predefine some client verification results
       */
      ap_ctx_set(fb->ctx, "ssl::client::dn", NULL);
+     ap_ctx_set(fb->ctx, "ssl::client::issuer::dn", NULL);
+     ap_ctx_set(fb->ctx, "ssl::client::serial", NULL);
      ap_ctx_set(fb->ctx, "ssl::verify::error", NULL);
      ap_ctx_set(fb->ctx, "ssl::verify::info", NULL);
      SSL_set_verify_result(ssl, X509_V_OK);
***************
*** 372,380 ****
--- 374,410 ----
           * Remember the peer certificate's DN
           */
          if ((xs = SSL_get_peer_certificate(ssl)) != NULL) {
+             ASN1_INTEGER *bs;
+ 
              cp = X509_NAME_oneline(X509_get_subject_name(xs), NULL, 0);
              ap_ctx_set(fb->ctx, "ssl::client::dn", ap_pstrdup(conn->pool, cp));
              free(cp);
+           
+             /* the following code is adapted from crypto/asn1/t_x509.c  */
+             /* from the openssl distribution                            */
+             bs = X509_get_serialNumber(xs);
+             if (bs->length <= 4) {
+                 unsigned long l = ASN1_INTEGER_get(bs);
+                 ap_ctx_set(fb->ctx, "ssl::client::serial",
+                         ap_psprintf(conn->pool, "%lu", (unsigned long)l));
+             } else {
+               /* this part untested... */
+                 char *cp1;
+                 int i;
+                 cp1 = cp = ap_palloc(conn->pool, 1 + (3 * bs->length));
+                 memset(cp, 0, 1 + (3 * bs->length));
+                 if (bs->type == V_ASN1_NEG_INTEGER) { *(cp1++) = '-'; }
+                 for (i = 0; i < bs->length; i++) {
+                         ap_snprintf(cp1, 3, "%02x", bs->data[i]); cp1 += 2;
+                         if (i+1 < bs->length) { *(cp1++) = ':'; }
+                 }
+                 ap_ctx_set(fb->ctx, "ssl::client::serial", cp);
+             }
+             cp = X509_NAME_oneline(X509_get_issuer_name(xs), NULL, 0);
+             ap_ctx_set(fb->ctx, "ssl::client::issuer::dn",
+                 ap_pstrdup(conn->pool, cp));
+             free(cp);
+           
          }
  
          /*
***************
*** 997,1006 ****
--- 1027,1065 ----
           * Remember the peer certificate's DN
           */
          if ((cert = SSL_get_peer_certificate(ssl)) != NULL) {
+           ASN1_INTEGER *bs;
+ 
              cp = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
              ap_ctx_set(r->connection->client->ctx, "ssl::client::dn", 
                         ap_pstrdup(r->connection->pool, cp));
              free(cp);
+ 
+             /* the following code is adapted from crypto/asn1/t_x509.c  */
+             /* from the openssl distribution                            */
+             bs = X509_get_serialNumber(cert);
+             if (bs->length <= 4) {
+                 unsigned long l = ASN1_INTEGER_get(bs);
+                 ap_ctx_set(r->connection->client->ctx, "ssl::client::serial",
+                         ap_psprintf(r->connection->pool, "%lu", (unsigned long)l));
+             } else {
+               /* this part untested... */
+                 char *cp1;
+                 int i;
+                 cp1 = cp = ap_palloc(r->connection->pool, 1 + (3 * bs->length));
+                 memset(cp, 0, 1 + (3 * bs->length));
+                 if (bs->type == V_ASN1_NEG_INTEGER) { *(cp1++) = '-'; }
+                 for (i = 0; i < bs->length; i++) {
+                         ap_snprintf(cp1, 3, "%02x", bs->data[i]); cp1 += 2;
+                         if (i+1 < bs->length) { *(cp1++) = ':'; }
+                 }
+                 ap_ctx_set(r->connection->client->ctx, "ssl::client::serial", cp);
+             }
+ 
+             cp = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
+             ap_ctx_set(r->connection->client->ctx, "ssl::client::issuer::dn",
+                 ap_pstrdup(r->connection->pool, cp));
+             free(cp);
+ 
          }
  
          /*

Reply via email to