cancel
Showing results for 
Search instead for 
Did you mean: 

Passing PKI Certificate as "base64encode"

bcarreker
Cirrus
Cirrus

I am trying to create an iRule for an app service, so that it authenticates traffic on the context path and passes the PKI certificate as "base64encode" in the "sslclientcert64" header sent to the app service.

 

(Please see attachment) I've taken the base64 script found on Devcentral, and added an "when HTTP_REQUEST" line, so that when "/tsmats_tools" is added to the URL, the iRule goes into effect. Unfortunately, this results in a 403 FORBIDDEN.

 

Is there anything else I can do on my end?

1 REPLY 1

bcarreker
Cirrus
Cirrus

Here's the iRule I'm using:

 

# client_cert_header_insert_rule

 

when CLIENTSSL_CLIENTCERT {

 

  # Check if client presented at least one cert

  if {[SSL::cert count] > 0}{

 

     # Insert the following fields in the session table with a timeout of 7200 seconds:

     #  Do the processing now as opposed to in HTTP_REQUEST as there

     #  can be many HTTP requests using the same SSL session ID

     #

     #  Index - item

     #  0 - base64 encoding of the client SSL cert

     #  1 - serial number of the cert

     #  2 - the verification status text for the client cert against the client SSL profile's root CA cert

     session add ssl [SSL::sessionid] [list \

        [SSL::verify_result] \

        [b64encode [SSL::cert 0]] \

        [X509::serial_number [SSL::cert 0]] \

     ] 7200

 

     log local0. "[IP::client_addr]:[TCP::client_port]: Added session data for cert. Status:\

        [X509::verify_cert_error_string [lindex [session lookup ssl [SSL::sessionid]] 0]] with key [SSL::sessionid]"

  }

}

 

when HTTP_REQUEST {

 

  if {[string tolower [HTTP::host]] equals "URL goes here" and [string tolower [HTTP::uri]] equals "URI goes here" } {

 

   HTTP::header replace Host "Back end service goes here"

  # Check if SSL session ID is in the cache (SSL::sessionid returns 64 zeroes if it's not in v9 and a null string in v10)

  if {[SSL::sessionid] ne "0000000000000000000000000000000000000000000000000000000000000000" && [SSL::sessionid] ne ""}{

 

     # Get the session table entry (a TCL list) for this session ID

     set session_data [session lookup ssl [SSL::sessionid]]

 

     # Check if the first element of the session table entry for this session ID is 0 (status for successful cert validation)

     if {[lindex $session_data 0] == 0}{

 

        log local0. "[IP::client_addr]:[TCP::client_port]: Valid cert per session table entry. Inserting cert details in HTTP headers."

 

        # Insert cert details in the HTTP headers

        HTTP::header insert SSLClientCertStatus "ok"

        HTTP::header insert SSLClientCertb64 [lindex $session_data 1]

        HTTP::header insert SSLClientCertSN [lindex $session_data 2]

 

        # Exit this event in this rule

        return

     }

  }

  # If we're still in this rule, cert wasn't valid

  #  so send HTTP 302 redirect to an error page

  HTTP::respond 302 Location "http://[HTTP::host]/cert_error.html"

 

  log local0. "[IP::client_addr]:[TCP::client_port]: No or invalid cert from client."

}

}