Belgium is not only known for its excellent beers and Belgian Fries, but also because it is one of a few countries with a public PKI implementation used by every citizen. Several government instances and private organizations make use of the Belgian Electronic Identity Card (eID) and the Belgian PKI on day to day bases. Applications range from Tax-on-Web (electronic tax reports) to the National Registry up until eID based Chat sites.

In this post we will describe how to utilize Netscaler to work with the Belgium Electronic Identity (Smard)Card with SSL Offloading. Using this, Netscaler is not only handling SSL connections but also offloading authentication of the eID certificates.

Each eID has an SSL certificate which can be used to uniquely authenticate the citizen in a web application based context. Belgium has its own Certificate Authorities (Belgium Root CA’s) and Intermediate Certificate Authorities for government institutions (GovernmentCA’s) and for all its citizens (CitizenCA’s). This CA structure is an absolute must for a PKI desgined to cope with over 11 million inhabitants.

The Belgium Certificate Authority Structure (CitizenCA)Goal

The goal is to automatically have the connecting users authenticate using their eID with SSL. Netscaler will verify the user’s certificate has not expired and is not revoked. After successful connection establishment, it will forward the users certificate information (Client Certificate Subject) in a standard HTTP header towards the internal Web Application. The web application can completely rely on the provided subject information because the certificate subject contains a unique national registry number for each citizen.

Authenticatino flow through Netscaler

Configuration

The full code is attached (Full Configuration.txt). The below simply explains the basic configuration.

First make sure all Citizen CA certificates are uploaded to Netscaler. You can manually download all CRT files in the Belgian CA repository or make use of the attached curl get_ca.sh script which will do this you.

  • Download the script get_ca.sh
  • Rename script get_ca.sh.txt to get_ca.sh
  • Copy it to /nsconfig/ssl (using an SFTP/SCP client like WinSCP)
  • Open up a shell prompt (type “shell” in the Netscaler CLI)
  • root@ns-demo# cd /nsconfig/ssl
    root@ns-demo# chmod 755 get_ca.sh
  • You’ll see a lot of downloads happen and removal of the 404’ed pages. At the end all certificates are downloaded to the Netscaler.

We also need the rest of the certificate chain. Download the Root signed CA’s at the Belgian Root CA repository page and the Globalsign Root CA here. Copy them to /nsconfig/ssl as well.

Now the certificates have to be imported in the Netscaler configuration (see attached ns.conf.txt for all commands), enter the commands in the Netscaler CLI.

add ssl certKey be-root-CA2 -cert belgiumrs2.crt -inform DER
add ssl certKey be-root-CA -cert belgiumrs.crt -inform DER
add ssl certKey globalsign-root-CA -cert globalsign-root-ca.crt.cer
 -inform PEM
add ssl certKey be-citizen-CA-200601
 -cert "/nsconfig/ssl/citizen200601.crt" -inform DER
...

Then we have to associate the links between the certificates (link the Globalsign CA to the Root CA, Root CA to Citizen CA’s):
link ssl certKey be-root-CA2 globalsign-root-CA
link ssl certKey be-root-CA globalsign-root-CA
link ssl certKey be-citizen-CA-200601 be-root-CA
link ssl certKey be-citizen-CA-200602 be-root-CA
...

Create the OCSP Responder, so that we can verify if the eID’s certificate hasn’t expired yet. Luckily all CA’s use the same responder. You may choose to implement batching and caching OCSP requests as well to gain some extra performance, please review the NS-TrafficMgmt-Guide.pdf in the Netscaler documentation about this.
add ssl ocspResponder eid-OCSP -url "http://ocsp.eid.belgium.be:80/"
 -batchingDelay 0 -trustResponder

Obviously we need some resources and a vserver to actually serve the requests:
add server debian-70 192.168.2.70
add server debian-71 192.168.2.71
add service svc_http_debian-70 debian-70 HTTP 80 -gslb NONE
 -maxClient 0 -maxReq 0 -cip DISABLED -usip NO -useproxyport YES -sp OFF
 -cltTimeout 180 -svrTimeout 360 -CKA NO -TCPB NO -CMP YES
add service svc_http_debian-71 debian-71 HTTP 80 -gslb NONE
 -maxClient 0 -maxReq 0 -cip DISABLED -usip NO -useproxyport YES -sp OFF
 -cltTimeout 180 -svrTimeout 360 -CKA NO -TCPB NO -CMP YES
bind lb monitor http svc_http_debian-70
bind lb monitor http svc_http_debian-71
add lb vserver vs_demo_eid SSL 192.168.1.90 443 -persistenceType NONE
 -cltTimeout 180
bind lb vserver vs_demo_eid svc_http_debian-70
bind lb vserver vs_demo_eid svc_http_debian-71

Then we associate the SSL server certificate to this SSL vserver. I used one from my own CA, in production environments you’d use one signed by a public CA. Or in this special case: every Belgian government institution can have their Certificate Signing Requests signed free of charge by the Government CA by contacting the FedICT Registration Authority.
add ssl certKey ca-citrix-local -cert "/nsconfig/ssl/citrix.local.crt"
add ssl certKey protected-citrix-local
 -cert "/nsconfig/ssl/protected.citrix.local.crt"
 -key "/nsconfig/ssl/protected.citrix.local.key" -passcrypt somekey
link ssl certKey protected-citrix-local ca-citrix-local
bind ssl vserver vs_demo_eid -certkeyName protected-citrix-local

Last step to get authentication working is to have to enable Client Certificate Authentication for vserver vs_demo_eid and add all CA’s involved in the process.
set ssl vserver vs_demo_eid -clientAuth ENABLED -clientCert Mandatory
bind ssl vserver vs_deb_eid -certkeyName be-root-CA -CA -ocspCheck Mandatory
bind ssl vserver vs_deb_eid -certkeyName be-root-CA2 -CA -ocspCheck Mandatory
bind ssl vserver vs_demo_eid -certkeyName be-citizen-CA-200601
 -CA -ocspCheck Mandatory
bind ssl vserver vs_demo_eid -certkeyName be-citizen-CA-200602
 -CA -ocspCheck Mandatory
bind ssl vserver vs_demo_eid -certkeyName be-citizen-CA-200603
 -CA -ocspCheck Mandatory
...
bind ssl vserver vs_demo_eid -certkeyName be-citizen-CA-201206
 -CA -ocspCheck Mandatory
bind ssl vserver vs_demo_eid -certkeyName be-citizen-CA-201207
 -CA -ocspCheck Mandatory
bind ssl vserver vs_demo_eid -certkeyName be-citizen-CA-201208
 -CA -ocspCheck Mandatory

Now we’re ready to test the authentication by accessing our vs_demo_eid vserver in a browser with eID software installed (see here if you don’t have eID software yet). We should now be asked to select our citizen’s certificate and enter the PIN code.

Select Client Certificate to utilize for authenticatingEnter Certificate PIN codeAfter authentication we should see the default webpage:

Succesful authentication with eID

But now to top it all, we also want our backend webapplication to know who logged in so we can use this to display his personal information, associate him with the correct records in our database and so forth.

To do this, we add a rewrite policy to inject the custom HTTP header X-eID-Subject. So each request from this authenticated user will have this header.

add rewrite action rw_ins_http_eidheader insert_http_header
 X-eID-Subject CLIENT.SSL.CLIENT_CERT.SUBJECT
add rewrite policy pol_rw_insert_eid_header_to_server
 true rw_ins_http_eidheader
bind lb vserver vs_demo_eid -policyName pol_rw_insert_eid_header_to_server
 -priority 100 -gotoPriorityExpression END -type REQUEST

And if we then have a web application (or CGI script such as the attached eid_head.pl script) that reads information from the header we have a following result:

Perl CGI Script displaying eID informationIn which serialNumber is the National Registry number uniquely assigned to each Belgian citizen.

This shows once again how Netscaler Rocks in offloading SSL traffic and authentication.

Update 20th of January 2014:

Thanks to Lieven Van de Walle here’s an update on the latest certificate chains (applicable 2014). The new Root-CA’s are now signed by CyberTrust Root CA and no longer the GlobalSign Root CA. Which means you’ll need to import more CA’s and link some CA’s differently:

link ssl certKey be-root-CA4 cybertrust-root-CA
link ssl certKey be-root-CA3 cybertrust-root-CA
link ssl certKey be-root-CA2 cybertrust-root-CA
link ssl certKey be-root-CA globalsign-root-CA

And of course adjust the vserver bindings:
bind ssl vserver vs_demo_eid -certkeyName globalsign-root-CA -CA -ocspCheck Mandatory
bind ssl vserver vs_demo_eid -certkeyName cybertrust-root-CA -CA -ocspCheck Mandatory

Be aware that this will not be the only update to Root CA’s. You’ll need to verify regularly all the CA’s and subordinates and import accordingly as over time more and more CA’s will be added (and old ones expired and invalid).