Forum Discussion

Robert_Decker_2's avatar
Robert_Decker_2
Icon for Nimbostratus rankNimbostratus
Jun 18, 2007

ssl ocsp Irule help needed

I have a virtual server that serves pages to clients with and without client certificates. Those users with a client certificate will need to be verified against an ocsp server and have an http header inserted that says "cert auth = pass". That part seems to work fine. Those without a certificate would need to be forwarded to the pool members with an http header inserted that says "cert auth = failed".

 

 

The users without a certificate go to auth_wantcredential and then fail. I see “CLIENTSSL_CLIENTCERT: application verification failure” in the log.

 

 

How would I write an Irule that allows a client without a cert to skip the ocsp verification, but verifies those that do have a certificate? I am currently working with version 9.3.

 

 

Thank you for your help,

 

rob

 

  • Below is my Irule:

     

     

    when CLIENT_ACCEPTED {

     

    set tmm_auth_ssl_ocsp_sid [AUTH::start pam default_ssl_ocsp]

     

    use the following logging line for troubleshooting only

     

    log local0. "Client Address: [IP::client_addr]"

     

    }

     

     

    when CLIENTSSL_CLIENTCERT {

     

    Check certificate validity

     

    set ssl_cert [SSL::cert 0]

     

    set ssl_errstr [X509::verify_cert_error_string [SSL::verify_result]]

     

     

    Set results in the session so they are available to other events

     

    0=The certificate, 1=The validation error, 2=Revocation status

     

    set ssl_stuff [list anything1 anything2 anything3]

     

    lset ssl_stuff 0 $ssl_cert

     

    lset ssl_stuff 1 $ssl_errstr

     

    lset ssl_stuff 2 ""

     

    session add ssl [SSL::sessionid] $ssl_stuff 180

     

     

    Check revocation status of the certificate with the OCSP servers

     

    AUTH::cert_credential $tmm_auth_ssl_ocsp_sid [SSL::cert 0]

     

    AUTH::cert_issuer_credential $tmm_auth_ssl_ocsp_sid [SSL::cert issuer 0]

     

    AUTH::authenticate $tmm_auth_ssl_ocsp_sid

     

    set id [SSL::sessionid]

     

    SSL::handshake hold

     

     

    Log results

     

    log local0. "Client IP: [IP::remote_addr]"

     

    }

     

     

     

     

    when AUTH_SUCCESS {

     

    if {$tmm_auth_ssl_ocsp_sid eq [AUTH::last_event_session_id]} {

     

    OCSP servers say the certificate is good

     

    SSL::handshake resume

     

    lset ssl_stuff 2 "success"

     

    session add ssl $id $ssl_stuff

     

    }

     

    }

     

     

    when AUTH_FAILURE {

     

    if {$tmm_auth_ssl_ocsp_sid eq [AUTH::last_event_session_id]} {

     

    OCSP servers say the certificate was revoked

     

    SSL::handshake resume

     

    lset ssl_stuff 2 "failure"

     

    session add ssl $id $ssl_stuff

     

    }

     

    }

     

     

    when AUTH_ERROR {

     

    if {$tmm_auth_ssl_ocsp_sid eq [AUTH::last_event_session_id]} {

     

    An error occurred communicating with the OCSP servers

     

    SSL::handshake resume

     

    lset ssl_stuff 2 "error"

     

    session add ssl $id $ssl_stuff

     

    }

     

    }

     

     

    when AUTH_WANTCREDENTIAL {

     

    if {$tmm_auth_ssl_ocsp_sid eq [AUTH::last_event_session_id]} {

     

    OCSP servers want more info?

     

    reject

     

    }

     

    }

     

     

    when HTTP_REQUEST {

     

    Retrieve certificate information from the session

     

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

     

     

    log statements below are to allow admin to view cert results through logs

     

    log local0. "Client IP: [IP::remote_addr], requesting: [HTTP::method]/[HTTP::host][HTTP::uri], browser: [HTTP::header User-Agent], Referer: [HTTP::header exists Referer], HTTP version [HTTP::version], Persitance Cookie: [HTTP::cookie exists JSESSIONID], SSL: [SSL::cipher name]/[SSL::cipher version]/[SSL::cipher bits]"

     

     

     

    if { $ssl_stuff2 == "" } {

     

    No certificate was supplied, set CertAuth to "Fail" so the

     

    webservers know the user was not authenticated via OCSP

     

    log local0. "Cert Auth = Failed"

     

    HTTP::header insert CertAuth "Fail"

     

    } else {

     

    A certificate was supplied

     

    set ssl_cert2 [lindex $ssl_stuff2 0]

     

    set ssl_errstr2 [lindex $ssl_stuff2 1]

     

    set ssl_revoke2 [lindex $ssl_stuff2 2]

     

    log local0. "Certificate Information, Trusted Certificate Validation: $ssl_errstr2, OCSP Revocation Statue: $ssl_revoke2"

     

     

    if { $ssl_errstr2 eq "ok" } {

     

    The certificate has passed Trusted Certificate Validation

     

    Below are the OCSP states

     

    switch $ssl_revoke2 {

     

    "error" {

     

    An error occurred communicating with the OCSP servers

     

    HTTP::redirect "http://10.1.1.1/errorcert.html"

     

    log local0. "OCSP error was redirected"

     

    }

     

    "failure" {

     

    version of verisign cert is not in OCSP server--must allow without verifying revocation status

     

    if { [X509::issuer $ssl_cert2] contains "OU=verisign" } {

     

    log local0. "Cert is from verisign, Cert issuer - [X509::issuer $ssl_cert2]"

     

    HTTP::header insert CertAuth "Pass"

     

    HTTP::header insert SSLClientCertSubject [X509::subject $ssl_cert2]

     

    } else {

     

    The cert was actually in OCSP server as a revoked cert

     

    HTTP::redirect "http://10.1.1.1/revokedcert.html"

     

    log local0. "Revoked certificate was redirected"

     

    }

     

    }

     

    "success" {

     

    The certificate is valid, the user is authenticated.

     

    Add the certificate subject so the web servers can lookup the

     

    the user's account and priviledges

     

    HTTP::header insert CertAuth "Pass"

     

    HTTP::header insert SSLClientCertSubject [X509::subject $ssl_cert2]

     

    }

     

    default {

     

    We should not get here, I don't know what happened

     

    log local0.error "Invalid revocation status = $ssl_revoke2"

     

    reject

     

    }

     

    }

     

    } else {

     

    The certificate was invalid.

     

    we should not get here

     

    HTTP::redirect "http://10.1.1.1/invalidcert.html"

     

    log local0. "Invalid certificate was redirected"

     

    }

     

    }

     

    }

     

     

     

     

    Thanks again for any help!

     

    rob