Forum Discussion

eric_haupt1's avatar
eric_haupt1
Icon for Nimbostratus rankNimbostratus
Sep 06, 2017

Client Certificate - Regex to parse numbers from cert subject

I've been using an irule from Devcentral for quite some time to parse the othername:UPN x509 field from our client certificates for APM use. However, our clients are provided two certs and one of these certs does not have this .x509 extension field. We typically tell the clients which cert to use, but I'm trying to build logic to pull the UPN identifier from the cert subject field on the second cert. This identifier will be a set of either 10 numbers or 16 numbers. I'm having a bit of difficulty with the regex on this one. The lines of interest are in the "else" section. Basically I'd like to take the cert subject - extract the 10 or 16 numbers from it - add the site ID - then query LDAP for this user.

Thanks!

when ACCESS_POLICY_AGENT_EVENT {
     switch [ACCESS::policy agent_id] {
          "CACPROCESSING" {
                if { [ACCESS::session data get session.ssl.cert.x509extension] contains "othername:UPN<" } {
                     set tempupn [findstr [ACCESS::session data get session.ssl.cert.x509extension] "othername:UPN<" 14 ">"]
                     ACCESS::session data set session.custom.certupn $tempupn }
              else { set temppiv [regxp ([0-9]{16}|[0-9]{10}) [ACCESS::session data get session.ssl.cert.subject] ]
                     set tempupn $temppiv + "@company"
                     ACCESS::session data set session.custom.certupn $tempupn }
                   }
}

5 Replies

  • Stanislas, Here is an example of the subject:

    CN=SMITH.SAM.S.2345678011,OU=ADMINISTRATOR,OU=PKI,OU=CMR,O=COMPANY,C=US

  • And as a further addendum, regexp does not return a string, it takes a variable name to set to the match:

    when ACCESS_POLICY_AGENT_EVENT {
         switch [ACCESS::policy agent_id] {
              "CACPROCESSING" {
                    if { [ACCESS::session data get session.ssl.cert.x509extension] contains "othername:UPN<" } {
                         set tempupn [findstr [ACCESS::session data get session.ssl.cert.x509extension] "othername:UPN<" 14 ">"]
                         ACCESS::session data set session.custom.certupn $tempupn }
                    else { if { [regexp {([0-9]{16}|[0-9]{10})} [ACCESS::session data get session.ssl.cert.subject] temppiv ] == 1 } {
                              set tempupn "$temppiv@company"
                              ACCESS::session data set session.custom.certupn $tempupn }
                         }
                }
            }
    }
    

    Add some logging and do some testing. I hope this helps.

  • Hi,

    you can do it without an irule event (what is not optimal usage or APM) but with the following expression in

    variable assign

    set extension [mcget {session.ssl.cert.x509extension}];
    if {[set tempupn [string range $extension [expr {[string first "othername:UPN<" $extension] +14}] [expr {[string last ">" $extension] -1}] ]] != ""} {
        return $tempupn;
    } elseif {[regexp {\d{10,16}} [mcget {session.ssl.cert.subject}] tempiv]} {
        return "$tempiv@company";
    }