Forum Discussion

TIm_Maestas's avatar
TIm_Maestas
Icon for Nimbostratus rankNimbostratus
Apr 06, 2005

SSL cert verify TCL error?

I have the following iRule:

 

 

when CLIENTSSL_HANDSHAKE {

 

set cert [SSL::cert 0 ]

 

}

 

when HTTP_REQUEST {

 

set stuff [X509::subject $cert ]

 

if { [matchclass $stuff contains $::merlin] } {

 

use pool test-sun }

 

else { reject }

 

}

 

 

The merlin class contains things like CN=validhost.company.com. When a host comes in presenting a client certificate with a valid CN everything works fine. When a host comes in without a matching CN in the merlin class, they get a page cannot be displayed error in IE, which is also fine. However, when a client comes in by typing the IP in their browser, which results in a pop-up window because the IP doesn't match the common name of the certificate, I get the following error logged to /var/log/ltm:

 

 

tmm tmm[5569]: 01220001:3: TCL error: Rule test - while executing "X509::subject $cert "

 

 

While this isn't necessarily a bad thing (because they should be coming in via the correct URL and not get any pop-up errors) it makes me think I've writte my rule incorrectly or should have done this differently. Is there a better way to do what I'm doing?

5 Replies

  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    You may want to try adding this:

     
     when HTTP_REQUEST { 
        if { [info exists cert] } { 
           ... your existing rule stuff... 
        } else { 
           log "No Cert presented" 
           reject 
        } 
     } 
     

    Basically, you have to remember there is no guarantee the client presented a certificate before sending an HTTP request.

    The "info exists" command is Tcl's way of determining whether a variable has been previously set.
  • That didn't seem to work. My rule now looks like

     

     

    when CLIENTSSL_HANDSHAKE {

     

    set cert [SSL::cert 0 ]

     

    }

     

    when HTTP_REQUEST {

     

     

    if { [ info exists cert ] } {

     

    log local0. "cert variable is $cert"

     

    set stuff [X509::subject $cert ]

     

    if { [matchclass $stuff contains $::merlin] } {

     

    use pool test-sun }

     

    else {

     

    log local0. "Invalid Cert from [IP::client_addr]"

     

    reject

     

    }

     

     

    } else {

     

    log local0. "No Cert Presented from [IP::client_addr]"

     

    reject

     

    }

     

    }

     

     

    But I'm still getting the error when a client comes in via IP address (or any other way that requires them to click yes to the SSL warning pop-up dialogue). The log message seems to indicate that indeed the $cert variable is not being populated, but if that is the case why is that block of the rule getting executed at all?

     

     

     

    Apr 5 21:19:25 tmm tmm[5569]: Rule test : cert variable is

     

    Apr 5 21:19:25 tmm tmm[5569]: 01220001:3: TCL error: Rule test - while executing "X509::subject $cert "

     

     

    Thanks.

     

  • bl0ndie_127134's avatar
    bl0ndie_127134
    Historic F5 Account
    How about something like this ...
    when HTTP_REQUEST {   
           if {[SSL::cert count] == 0} {       
               reject   
           } else {   
               set subject [X509::subject [SSL::cert 0 ]]   
               if { [matchclass $subject contains $::merlin] } {   
                  use pool test-sun    
               }   
           }   
       }

    Alternatively you could modify your CLIENTSSL_HANDSHAKE to look like this ...

    when CLIENTSSL_HANDSHAKE {    
           if {[SSL::cert count] > 0} {       
               set cert [SSL::cert 0 ]   
           }    
       }
    I am still a little baffled as to why "info exists" failed. I will do some testing tomorrow to try and find out why.
  • Ok so I realized my plan was flawed in that, as was pointed out to me above, a client will not present a cert on each and every http request. So, I began going down the road of tracking whether we have validated a cert using the session table. However, I seem to be doing something wrong just adding the session entry. The rule:

     
     when CLIENTSSL_CLIENTCERT { 
       set id [SSL::sessionid] 
       session add ssl $id [X509::verify_cert_error_string [SSL::verify_result]] 180 
     } 
     when HTTP_REQUEST {  
          if {[SSL::cert count] == 0} {      
              reject 
          } else { 
              set subject [X509::subject [SSL::cert 0 ]]  
              if { [matchclass $subject contains $::merlin] } {  
                 use pool test-sun   
              }  
          }  
      } 
     

    ..Generates the error:

    Apr 6 12:01:39 tmm tmm[5569]: 01220001:3: TCL error: Rule test - Prerequisite operation not in progress (line 1) invoked from within "session add ssl $id [X509::verify_cert_error_string [SSL::verify_result]] 180"

    ..what is the prerequisite operation that is not in progress?

  • efftee_26336's avatar
    efftee_26336
    Historic F5 Account
    Hi there,

     

     

    does anybody has a solution for this. I have the same problem.