Hi,

I have started to add SSL support to mod_webapp. I have prepared a test patch
for client certificates, it works.

I will now add the missing part and improve it a little:
Storing the ssl_cert and other in a substructure of wa_request instead directly
in wa_request.
Something like:
+++
 typedef struct wa_ssldata wa_ssldata;
 struct wa_ssldata {
   char     *ssl_cert;
   char     *ssl_cipher;
   char     *ssl_session;
   int       ssl_key_size;
 }
 struct wa_request {
  ...
  wa_ssldata *ssld;
 }
+++
 
Changing the protocol elements:
TYPE_CBK_READ to TYPE_ASK_READ
TYPE_CBK_DATA to TYPE_REP_DATA
TYPE_CBK_DOME to TYPE_REP_DONE
To see more easly was it from web server (REP: Reponse) and to web server (ASK:
Ask).

I will (from the patch) remove (TYPE_REP_SSL_SESSION, TYPE_REP_SSL_CIPHER,
TYPE_REP_SSL_KEYSIZ and replace them by TYPE_REP_SSL that will carry
SSL_SESSION, SSL_CIPHER and KEYSIZ in its payload.

The things like "SSL_CLIENT_CERT", that are extracted from mod_ssl I will put
them in an include file I think that they have fixed values in a webserver
implementation.
req->ssl_cert = (char *)ap_table_get(r->subprocess_env,"SSL_CLIENT_CERT");

Any comments?

Cheers

Jean-frederic
Index: apache-1.3/mod_webapp.c
===================================================================
RCS file: /home/cvs/mirror/jakarta-tomcat-connectors/webapp/apache-1.3/mod_webapp.c,v
retrieving revision 1.24
diff -u -r1.24 mod_webapp.c
--- apache-1.3/mod_webapp.c     2001/10/09 10:41:25     1.24
+++ apache-1.3/mod_webapp.c     2001/10/18 15:15:59
@@ -462,6 +462,7 @@
     req->clen=0;
     req->ctyp="\0";
     req->rlen=0;
+    req->ssl_cert = (char *)ap_table_get(r->subprocess_env,"SSL_CLIENT_CERT");
 
     /* Copy headers into webapp request structure */
     if (r->headers_in!=NULL) {
Index: include/wa_request.h
===================================================================
RCS file: /home/cvs/mirror/jakarta-tomcat-connectors/webapp/include/wa_request.h,v
retrieving revision 1.6
diff -u -r1.6 wa_request.h
--- include/wa_request.h        2001/07/19 23:47:31     1.6
+++ include/wa_request.h        2001/10/18 15:16:02
@@ -128,6 +128,8 @@
     long rlen;
     /** The current headers table. */
     apr_table_t *hdrs;
+    /** The client certificate string */
+    char *ssl_cert;
 };
 
 /**
Index: java/Constants.java.in
===================================================================
RCS file: /home/cvs/mirror/jakarta-tomcat-connectors/webapp/java/Constants.java.in,v
retrieving revision 1.11
diff -u -r1.11 Constants.java.in
--- java/Constants.java.in      2001/08/09 20:02:15     1.11
+++ java/Constants.java.in      2001/10/18 15:16:03
@@ -363,4 +363,62 @@
      * No payload.<br>
      */
     public static final int TYPE_CBK_DONE=0x42;
+
+    /**
+     * ASK_SSL: The WARP client (HTTP server) asks the WARP server to
+     * transfer the basic SSL information (cypher, keysize and session).
+     * <br>
+     * No payload.<br>
+     */
+    public static final int TYPE_ASK_SSL=0x43;
+
+    /**
+     * ASK_SSL_CLIENT: The WARP client (HTTP server) asks the WARP server to
+     * transfer the client certificate.
+     * (just the first element of the chain and the webserver should request
+     * for it to the browser if possible).
+     * <br>
+     * No payload.<br>
+     */
+    public static final int TYPE_ASK_SSL_CLIENT=0x44;
+
+    /**
+     * REP_SSL_CERT: The client certificate (remote peer).
+     * <br>
+     * Payload description:<br>
+     * [string] The client certificate.
+     */
+    public static final int TYPE_REP_SSL_CERT=0x52;
+ 
+    /**
+     * REP_SSL_CIPHER: The cipher used between client and server.
+     * <br>
+     * Payload description:<br>
+     * [string] The cipher_suite.
+     */
+    public static final int TYPE_REP_SSL_CIPHER=0x53;
+ 
+    /**
+     * REP_SSL_SESSION: The ssl session.
+     * <br>
+     * Payload description:<br>
+     * [string] The ssl session. (That is not in the spec's).
+     */
+    public static final int TYPE_REP_SSL_SESSION=0x54;
+ 
+    /**
+     * REP_SSL_KEYSIZ: size of the used algorithm.
+     * <br>
+     * Payload description:<br>
+     * [ushort] size of the algorithm (56-128).
+     */
+    public static final int TYPE_REP_SSL_KEYSIZ=0x55;
+ 
+    /**
+     * REP_SSL_NO: Request SSL information is not available.
+     * <br>
+     * No payload.<br>
+     */
+    public static final int TYPE_REP_SSL_NO=0x5F;
 }
+
Index: java/Makefile.in
===================================================================
RCS file: /home/cvs/mirror/jakarta-tomcat-connectors/webapp/java/Makefile.in,v
retrieving revision 1.3
diff -u -r1.3 Makefile.in
--- java/Makefile.in    2001/09/17 05:04:02     1.3
+++ java/Makefile.in    2001/10/18 15:16:04
@@ -70,6 +70,7 @@
        WarpRequest.java \
        WarpRequestHandler.java \
        WarpResponse.java \
+       WarpCertificates.java
 
 ARCHIVE = warp.jar
 
Index: java/WarpConnector.java
===================================================================
RCS file: /home/cvs/mirror/jakarta-tomcat-connectors/webapp/java/WarpConnector.java,v
retrieving revision 1.21
diff -u -r1.21 WarpConnector.java
--- java/WarpConnector.java     2001/10/13 01:33:00     1.21
+++ java/WarpConnector.java     2001/10/18 15:16:06
@@ -481,6 +481,8 @@
             }
         } catch (IOException e) {
             throw new LifecycleException("Error creating server socket",e);
+        } catch (java.security.GeneralSecurityException e) {
+            throw new LifecycleException("Error creating SSL server socket",e);
         }
     }
 
Index: java/WarpRequest.java
===================================================================
RCS file: /home/cvs/mirror/jakarta-tomcat-connectors/webapp/java/WarpRequest.java,v
retrieving revision 1.9
diff -u -r1.9 WarpRequest.java
--- java/WarpRequest.java       2001/07/25 22:32:05     1.9
+++ java/WarpRequest.java       2001/10/18 15:16:06
@@ -77,6 +77,20 @@
         this.setStream(this.localstream);
     }
 
+    /** Process the SSL attributes */
+    public Object getAttribute(String name) {
+        if (name.equals("javax.servlet.request.X509Certificate")) {
+            WarpCertificates cert = null;
+            try {
+                cert = new WarpCertificates(localstream.getX509Certificates());
+            } catch (IOException e) {
+                return null;
+            }
+            return(cert.getCertificates());
+        }
+        return(super.getAttribute(name));
+    }
+
     public void setHost(Host host) {
         this.host=host;
     }
@@ -150,6 +164,22 @@
             this.request.getConnection().recv(packet);
             return(this.read());
         }
+        public String getX509Certificates()
+        throws IOException {
+            if (closed) throw new IOException("Stream closed");
+            this.packet.reset();
+            this.packet.setType(Constants.TYPE_ASK_SSL_CLIENT);
+            this.request.getConnection().send(packet);
+            packet.reset();
+
+            this.request.getConnection().recv(packet);
+            if (closed) throw new IOException("Stream closed");
+            if (packet.getType()==Constants.TYPE_REP_SSL_NO) return(null);
+            if (packet.getType()!=Constants.TYPE_REP_SSL_CERT)
+               throw new IOException("Invalid WARP packet type for CC");
+            return(this.packet.readString());
+        }
+
         
         public void close()
         throws IOException {
Index: lib/pr_warp.c
===================================================================
RCS file: /home/cvs/mirror/jakarta-tomcat-connectors/webapp/lib/pr_warp.c,v
retrieving revision 1.16
diff -u -r1.16 pr_warp.c
--- lib/pr_warp.c       2001/10/09 10:41:25     1.16
+++ lib/pr_warp.c       2001/10/18 15:16:08
@@ -428,6 +428,22 @@
                 }
                 break;
             }
+            case TYPE_ASK_SSL_CLIENT: {
+                /* Request for client certificate */
+                if (r->ssl_cert==NULL) {
+                    pack->type=TYPE_REP_SSL_NO;
+                    pack->size=0;
+                } else {
+                    pack->type=TYPE_REP_SSL_CERT;
+                    p_write_string(pack,r->ssl_cert);
+                }
+                wa_debug(WA_MARK,"CC bytes: (Sent=%d)",pack->size);
+                if (n_send(conf->sock,pack)!=wa_true) {
+                    n_disconnect(conn);
+                    return(wa_rerror(WA_MARK,r,500,"Communitcation interrupted"));
+                }
+                break;
+            }
             case TYPE_ERROR: {
                 char *mesg=NULL;
                 p_read_string(pack,&mesg);
package org.apache.catalina.connector.warp;

import java.security.cert.X509Certificate;
import java.security.cert.CertificateFactory;

import java.io.ByteArrayInputStream;

/*
 * Certificates handling.
 */

public class WarpCertificates {
    X509Certificate jsseCerts[] = null;
    /**
     * Create the certificate using the String.
     */
    public WarpCertificates(String certString) {
        byte[] certData = certString.getBytes();
        ByteArrayInputStream bais = new ByteArrayInputStream(certData);
 
        // Fill the first element.
        try {
            CertificateFactory cf =
                    CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate)
                    cf.generateCertificate(bais);
            jsseCerts =  new X509Certificate[1];
            jsseCerts[0] = cert;
        } catch(java.security.cert.CertificateException e) {
            // Certificate convertion failed.
            return;
        }
    }
    public X509Certificate [] getCertificates() {
        return jsseCerts;
    }
}

Reply via email to