X509::cert_fields

Description

When given a valid certificate, returns a TCL list of field names and values which can be added to the HTTP headers in order to emulate ModSSL behavior. The output can be passed to ‘HTTP::header insert $list’ as a list for insertion in the HTTP request or response.

Syntax

X509::cert_fields <X509 certificate> <verify error code> <options list>

X509::cert_fields <X509 certificate> <verify error code> {options}

  • Returns a list of fields to be added to the HTTP headers in order to emulate ModSSL behavior. The return type is a Tcl list that the system then interprets as a header-name/header-value pair.

Options can be a list of one or more of the following fields:
  • hash | issuer | serial | sigalg | subject | subpubkey | validity | versionnum | whole

Examples

when RULE_INIT {

   # Session timeout. Length of time (in seconds) to store the client cert in the session table.
   set ::session_timeout 3600

   # SSL::sessionid returns 64 0's if the session ID doesn't exist, so set a to check for this
   set ::null_sessionid [string repeat 0 64]
}
when CLIENTSSL_CLIENTCERT {

   #################################################
   # Need to first check if there is a cert and that it's valid
   # ...
   #################################################

   # Save the first cert in the client request
   set cert [SSL::cert 0]

   # Save the cert fields to a list
   set fields [X509::cert_fields $cert [SSL::verify_result] hash issuer serial sigalg subject subpubkey validity versionnum whole]
   log local0. "Client certificate fields - $fields"

   # Add the cert to the session table for use in subsequent HTTP requests.  Use the SSL session ID as the key.
   session add ssl [SSL::sessionid] [list $cert $fields] $::session_timeout
}
when HTTP_REQUEST {

   # Check if there is an existing SSL session ID and if the cert is in the session table
   if {[SSL::sessionid] ne $::null_sessionid && [session lookup ssl [SSL::sessionid]] ne ""}{

      # Insert SSL cert details in the HTTP headers
      HTTP::header insert [lindex [session lookup ssl [SSL::sessionid]] 1]

   } else {

      # Send a response back to the client indicating they didn't present a valid cert.
      HTTP::respond 200 content [subst {<html>Invalid request with SSL session ID [SSL::sessionid]</html>}]
   }
}

when CLIENTSSL_CLIENTCERT {
    if { [SSL::cert count] > 0 } {
        session add ssl [SSL::sessionid] [X509::cert_fields [SSL::cert 0] [SSL::verify_result] whole] $timeout
    }
}