Forum Discussion

am_gli_287451's avatar
am_gli_287451
Icon for Nimbostratus rankNimbostratus
Feb 28, 2018

Writing Client-Cert info into Header - irule with strange behavior

Hi,

I have an inherited a BIG-IP and I'm facing a problem with an irule that is implemented there.

The important part is this:

   when HTTP_REQUEST priority 200 {
    ...
     create HTTP headers with ssl cert infos
    set dn [ X509::issuer $cert ]
     Split DN into Parts
    set parts [ split $dn {,} ]
     Fill array with the different parts (O=, OU=, ...)
    foreach part $parts {
      set thispart [ split $part {=} ]

      if { [ llength $thispart ] == 2 } {
        set dnparts([lindex $thispart 0 ]) [ lindex $thispart 1 ]
      }
   }
    Insert the neccessary headers from the DN
   HTTP::header insert "SSL_CLIENT_I_DN"           $dn
   foreach {part myvar} {
     {C}       {SSL_CLIENT_I_DN_C}
     {CN}      {SSL_CLIENT_I_DN_CN}
     {O}       {SSL_CLIENT_I_DN_O}
     {OU}      {SSL_CLIENT_I_DN_OU}
   } {
     if { [info exists dnparts($part) ] } {
       HTTP::header insert "$myvar" "$dnparts($part)"
     }
  }

So - the irule should read the issuer information and put it in such a format into HTTP headers:

SSL_CLIENT_I_DN: C=DE, O=Test-Organisation, OU=Test-OU, CN=Test-CN

SSL_CLIENT_I_DN_C: DE

SSL_CLIENT_I_DN_CN: Test-CN

SSL_CLIENT_I_DN_O: Test-Organisation

SSL_CLIENT_I_DN_OU: Test-OU

Now the application admin reported, that these headers are not sent properly. I activated a logging irule and I can see that for some requests (it seems the initial ones) the format is OK. But for the requests later, the behavior changes. In the log I can only see the first 2 lines repeating constantly:

SSL_CLIENT_I_DN: C=DE, O=Test-Organisation, OU=Test-OU, CN=Test-CN

SSL_CLIENT_I_DN_C: DE

SSL_CLIENT_I_DN: C=DE, O=Test-Organisation, OU=Test-OU, CN=Test-CN

SSL_CLIENT_I_DN_C: DE

SSL_CLIENT_I_DN: C=DE, O=Test-Organisation, OU=Test-OU, CN=Test-CN

SSL_CLIENT_I_DN_C: DE

As mentioned, I've inherited this irule from the prior admin and I'm not that deep into TCL. For me, the rule is performed on every HTTP-Request from scratch, so there shouldn't be any difference in the behavior.

Any ideas? 🙂

6 Replies

  • Anesh's avatar
    Anesh
    Icon for Cirrostratus rankCirrostratus

    Try the below code:

     

    set parts [ split $dn {,} ]
    
    set country [lindex $parts 0]
    set x [string range $country 2 end]
    HTTP::header insert "SSL_CLIENT_I_DN_C" $x
    
    set org  [lindex $parts 1]
    set y [string range $org 2 end]
    HTTP::header insert "SSL_CLIENT_I_DN_O" $y
    
    set unit [lindex $parts 2]
    set z [string range $unit 3 end]
    HTTP::header insert "SSL_CLIENT_I_DN_OU" $z
    
    set cname [lindex $parts 3]
    set a [string range $cname 3 end]
    HTTP::header insert "SSL_CLIENT_I_DN_CN" $a
    
    HTTP::header insert "SSL_CLIENT_I_DN" $dn
  • nathe's avatar
    nathe
    Icon for Cirrocumulus rankCirrocumulus

    I would certainly test this, perhaps using the 255.255.255 255 mask.

     

  • Figured it out - it was an issue with the space behind the comma.

    So "SSL_CLIENT_I_DN: C=DE, O=Test-Organisation, OU=Test-OU, CN=Test-CN" was split to an array but, with leading spaces:

    "C|AT"  
    " O|Test...."  
    " OU|Test..."  
    etc.
    

    So in this part:

    foreach {part myvar} {
         {C}       {SSL_CLIENT_I_DN_C}
         {CN}      {SSL_CLIENT_I_DN_CN}
         {O}       {SSL_CLIENT_I_DN_O}
         {OU}      {SSL_CLIENT_I_DN_OU}
    

    the only line that was readable from the array was C, all other didn't match because of the space.

  • I already had such issue. there might be another issue, if CN contains a comma (with backslash before), split command may cause an issue. I used following code to convert comma to | except if comma is backslashed:

     

    array set dnparts [split [string map [list "\\," "," " , " "|" " ," "|" ", " "|"] $dn] "|="]

    this command already create the array.

     

    your code become:

     

    when HTTP_REQUEST priority 200 {
        ...
         create HTTP headers with ssl cert infos
        set dn [ X509::issuer $cert ]
         Split DN into Parts
        array set dnparts [split [string map [list "\\," "," " , " "|" " ," "|" ", " "|"] $dn] "|="]
    
         Insert the neccessary headers from the DN
        HTTP::header insert "SSL_CLIENT_I_DN"           "\"$dn\""
        foreach field [array names dnparts] {
            HTTP::header insert "SSL_CLIENT_I_DN_$field" "\"$dnparts($field)\""
        }
    }