SSL::cert


Description

Returns data about an X509 SSL certificate, or sets the certificate mode.

Syntax

SSL::cert <index>
SSL::cert issuer <index>
SSL::cert count
SSL::cert mode [<"request" | "require" | "ignore">]

SSL::cert <index>

  • Returns the X509 SSL certificate at the specified index in the peer certificate chain, where index is a value greater than or equal to zero. A value of zero denotes the first certificate in the chain, a value of one denotes the next, and so on. This command is currently applicable only under a client-side context and returns an error within a server-side contextNote2.

SSL::cert issuer <index>

  • Returns the issuer certificate of the index of the X509 SSL certificate in the peer certificate chain, where index is a value greater than or equal to zero. A value of zero denotes the first certificate in the chain, a value of one denotes the next, and so on. This command is currently applicable only under a client-side context and returns an error within a server-side contextNote2.

SSL::cert count

  • Returns the total number of certificates that the peer has offered.

SSL::cert mode

  • This command has different results depending on whether the system evaluates the command under a client-side or server-side context. When the system evaluates the command under a client-side context, the command returns or overrides the client-side SSL connection’s current setting regarding client certificates. When the system evaluates the command under a server-side context, the command returns or overrides the server-side SSL connection’s current setting regarding server certificates. Only the require and ignore arguments are valid in a server-side context.

Note: As of 10.1.0, as described in CR116806, the following iRule commands now apply to the lifetime of the SSL session, and not only for the connection in which the system receives the client certificate:
  • SSL::cert
  • SSL::cert issuer
  • SSL::cert count

The system stores the received peer certificate in the SSL session table, so the certificate is available to the specified iRule commands as long as the SSL session is valid. From 11.4.0, this behavior is controlled by Retain Certificate setting in SSL profile. Default setting of this parameter is set to enabled, which maintains the certificate storage as described previously and permits certificate retrieval from HTTP_REQUEST event (in addition to CLIENTSSL_CLIENTCERT event). If Retain Certificate is set to disabled, it will not be possible to retrieve the certificate from HTTP_REQUEST.
Note1: when Retain Certificate is enabled, it can create memory pressure when lots of certificates are stored. Refer to https://support.f5.com/csp/article/K19802202 for more details.”
Note2: As tested in version 11.6.0 HF5, the following iRule commands are applicable under a server-side context and not only within a client-side context:
  • SSL::cert
  • SSL::cert issuer
  • SSL::cert count

Examples

# v10.1 or higher
# Redirect any client HTTP request with no client certificate or with a cert which is not correctly
#   validated against the trusted root certificate specified in the client SSL profile.
when HTTP_REQUEST {

    # Check if there is more than one client cert
    if {[SSL::cert count] > 0}{

        # Check if there was no error in validating the client cert against LTM's server cert
        if { [SSL::verify_result] == 0 }{

            # Exit this event in this iRule
            return
        } else {
            # Use the SSL status code in the HTTP response (defined here: http://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS)
            set error_string [X509::verify_cert_error_string [SSL::verify_result]]
        }
    } else {
        set error_string "No client certificate provided"
    }
    # If we are still executing this iRule, the client did not present a cert or did not present a valid cert
    HTTP::respond 403 content "<html>Invalid client certificate: $error_string</html>"
}

when RULE_INIT {
  set ::key [AES::key 128]
}
when CLIENTSSL_CLIENTCERT {
  session add ssl [SSL::sessionid] [SSL::cert 0] 180
}
when HTTP_REQUEST {
  if {! [HTTP::cookie exists EncClientCert]} {
    if { [SSL::cert count] < 1 } {
      HTTP::redirect "http://errorpage.example.com/"
      return
    }
    set id [SSL::sessionid]
    if { $id eq "" } {
      reject
      return
    } else {
      set cert [session lookup ssl $id]
    }
    if { $cert eq "" } {
      reject
      return
    }
    session delete ssl $id
    set enccert [b64encode [AES::encrypt $::key $cert]]
  } else {
    set cert [AES::decrypt $::key [b64decode [HTTP::cookie EncClientCert]]]
  }
  HTTP::header insert ClientCert [b64encode $cert]
}
when HTTP_RESPONSE {
  if { [info exists enccert ]} {
    HTTP::header insert "Set-Cookie EncClientCert=$enccert"
  }
}