You are hereeID

eID


Belgian eID to login on Mac OS X

This short howto explains how to use the Belgian eID to login on your Mac OS X machine. In this document I assume your cardreader is detected/installed and you are administrator of your machine. I am using Mac OS X 10.4.11.

Enable SmartCard authentication (only Mac OS X 10.4)

The happy owners of Leopard, Mac OS X 10.5, shouldn't change anything in their configuration file. Just jump to the part about access permissions.

Probably for performance reasons Apple didn't activate SmartCard login by default. So we will need to change a few configuration files to enable it. This procedure is explained on this page. Here's my own documentation with the examples for the Belgian eID.

The instructions in this part should be exactly the same on your system.

$ sudo -s
Password:
$ cd /etc/
$ cp authorization authorization.20080707.orig
$ cp authorization /tmp/authorization.mod

Now edit the temporary file using your favorite editor or by using the graphical editor if you prefer.

$ vi /tmp/authorization.mod
$ open -a "Property List Editor" /tmp/authorization.mod

Make the following changes to the mechanisms Array inside the system.login.console rights (Line 452):
After the string <string>builtin:auto-login,privileged</string> add the string <string>builtin:smartcard-sniffer,privileged</string>.
After the string <string>builtin:reset-password,privileged</string> remove the string <string>authinternal</string> then add string <string>builtin:authenticate,privileged</string>

Make the following changes to the "mechanisms" Array inside the "authenticate" rules (Line 649):
Add the following string to the beginning of the array <string>builtin:smartcard-sniffer,privileged</string>
After the string <string>builtin:authenticate</string> remove the string <string>authinternal</string> then add the string <string>builtin:authenticate,privileged</string>

Now copy the file to the right place on your system:

$ cp /tmp/authorization.mod /etc/authorization

You can check the differences here or download the original and modified file (Mac OS X 10.4.11)

$ diff -uN /etc/authorization /tmp/authorization.mod 
--- /etc/authorization  2008-03-23 17:53:36.000000000 +0100
+++ /tmp/authorization.mod      2008-07-07 11:19:05.000000000 +0200
@@ -449,9 +449,10 @@
                        <key>mechanisms</key>
                        <array>
                                <string>builtin:auto-login,privileged</string>
+                               <string>builtin:smartcard-sniffer,privileged</string>
                                <string>loginwindow_builtin:login</string>
                                <string>builtin:reset-password,privileged</string>
-                               <string>authinternal</string>
+                               <string>builtin:authenticate,privileged</string>
                                <string>builtin:getuserinfo,privileged</string>
                                <string>builtin:sso,privileged</string>
                                <string>HomeDirMechanism:login,privileged</string>
@@ -645,8 +646,9 @@
                        <string>evaluate-mechanisms</string>
                        <key>mechanisms</key>
                        <array>
+                               <string>builtin:smartcard-sniffer,privileged</string>
                                <string>builtin:authenticate</string>
-                               <string>authinternal</string>
+                               <string>builtin:authenticate,privileged</string>
                        </array>
                </dict>
                <key>authenticate-admin</key>

Access permissions (everyone)

We now enabled SmartCard authentication. The question that remains open is: Who owns what SmartCard?

On the eID card there are two private keys present. One for signing purposes and one for authentication. We will use the authentication key of course.
Go back to your Terminal that was logged in as root and type the following command. This will list the hashes of the keys.

$ sc_auth hash
3F5C816C10AB60926E2E8A3CD9096C1F8AF34C9C PrK#2 (authentication)
35BDB8600FA219204D28FAD856380F6E06123B62 PrK#3 (signature)

$ sc_auth accept -u chri -h 3F5C816C10AB60926E2E8A3CD9096C1F8AF34C9C

If desired, more than one smart card can be associated with a single user account by running the script again with the hash from the additional card(s).
We can check if it's OK:

$ dscl . -read /Users/chri
...
AuthenticationAuthority: ;ShadowHash;HASHLIST:<SALTED-SHA1,SMB-NT,SMB-LAN-MANAGER>
  ;pubkeyhash;3F5C816C10AB60926E2E8A3CD9096C1F8AF34C9C
...

Test your configuration

That's it. Save all your open files, log out of the system and connect your SmartCard. You should see the Enter PIN when your card is connected:
No card is connected or detected. Enter your normal password to login. The card is connected. See the 'PIN' box.

Debug info

When entering the cardreader in /var/log/secure.log (open using Console). If you don't see these messages check that your cardreader is configured correctly on the system.

com.apple.SecurityServer: Token reader CCID Smart Card Reader 0 0 inserted into system
com.apple.SecurityServer: token inserted into reader CCID Smart Card Reader 0 0
com.apple.SecurityServer: reader CCID Smart Card Reader 0 0 inserted token
  "BELPIC-534C494E336600296CFF2491AB111E14" (BELPIC-534C494E336600296CFF2491AB111E14) 
  subservice 2 using driver com.apple.tokend.belpic

After a successfull login see these messages:

SecurityAgent[1994]: Showing Login Window
SecurityAgent[1994]: User Authenticated: continue login process
com.apple.SecurityServer: Succeeded authorizing right system.login.console 
  by process /System/Library/CoreServices/loginwindow.app for authorization 
  created by /System/Library/CoreServices/loginwindow.app.
com.apple.SecurityServer: Succeeded authorizing right system.login.done 
  by process /System/Library/CoreServices/loginwindow.app for authorization 
  created by /System/Library/CoreServices/loginwindow.app.

Links

Apple Smart Card Setup Guide
Mac OS X 10.4: Enabling smart card login

eID things

Some output from some commands:

Welke slots zijn er ?

$ ./pkcs11-tool --list-slots
Available slots:
Slot 0           CCID Smart Card Reader 0 0
 token label:   BELPIC (Basic PIN)
 token manuf:   (unknown)
 token model:   PKCS #15 SCard
 token flags:   rng, login required, PIN initialized, token initialized
 serial num  :  6CFF2491AB111E14
Slot 1           (empty)
Slot 2           (empty)
Slot 3           (empty)
Slot 4           (empty)
Slot 5           (empty)
Slot 6           (empty)
Slot 7           (empty)

Hier zijn dus nog 7 vrije slots die we kunnen gebruiken voor alles en nog
wat. Sommigen gebruiken het voor SSL certificaten, anderen voor kun
private PGP/GPG keys

Wat kan de kaart zoal:

 ./pkcs11-tool --list-mechanisms
Supported mechanisms:
 SHA-1, digest
 SHA256, digest
 SHA384, digest
 SHA512, digest
 MD5, digest
 RIPEMD160, digest
 RSA-PKCS, sign, verify, unwrap, decrypt
 SHA1-RSA-PKCS, sign, verify
 MD5-RSA-PKCS, sign, verify
 RIPEMD160-RSA-PKCS, sign, verify
 RSA-PKCS-KEY-PAIR-GEN, keypairgen

De objecten die op de kaart staan (certificaten dus):

$ ./pkcs11-tool --login --list-objects
Please enter User PIN:
Private Key Object; RSA
 label:      Authentication
 ID:         02
 Usage:      sign
.... enzovoort.

Welke certs staan er op :

$ ./pkcs15-tool --list-certificates
X.509 Certificate [Authentication]
       Flags    : 3
       Authority: no
       Path     : 3f00df005038
       ID       : 02

X.509 Certificate [Signature]
       Flags    : 3
       Authority: no
       Path     : 3f00df005039
       ID       : 03

X.509 Certificate [CA]
       Flags    : 3
       Authority: yes
       Path     : 3f00df00503a
       ID       : 04

X.509 Certificate [Root]
       Flags    : 3
       Authority: yes
       Path     : 3f00df00503b
       ID       : 06

En natuurlijk ook expliciet de details over de private keys. We zien dat
de private keys niet extractable zijn:

$ ./pkcs15-tool --list-keys
Private RSA Key [Authentication]
       Com. Flags  : 3
       Usage       : [0x4], sign
       Access Flags: [0x1D], sensitive, alwaysSensitive, neverExtract,
local
       ModLength   : 1024
       Key ref     : 130
       Native      : yes
       Path        : 3f00df00
       Auth ID     : 01
       ID          : 02

Private RSA Key [Signature]
       Com. Flags  : 3
       Usage       : [0x200], nonRepudiation
       Access Flags: [0x1D], sensitive, alwaysSensitive, neverExtract,
local
       ModLength   : 1024
       Key ref     : 131
       Native      : yes
       Path        : 3f00df00
       Auth ID     : 01
       ID          : 03

Database authorization for openVPN with eID

In my previous post I explained how to use your Belgian eID to login on your openVPN server.
I did use a simple hello-world script to check the authorization. The username (rijksregisternummer/numero du registre national) was hardcoded in a file.

This evening I finally quickly enhanced the script do perform database authorization:

Download the full script. Or see the relevant database part:
if ($x509 =~ /\/serialNumber=([^\/]+)/) {
    # Accept the connection if the X509 common name
    # string matches the passed cn argument.
    my $dbh = DBI->connect('DBI:mysql:sslvpn', 'sslvpn', 'sslvpn')
            or die "Couldn't connect to database: " . DBI->errstr;
    my $sth = $dbh->prepare("SELECT `id`, `name`, `firstname` FROM `users` WHERE id=$1")
            or die "Couldn't prepare statement: " . $dbh->errstr;
    my @data;
    $sth->execute() 
            or die "Couldn't execute statement: " . $sth->errstr;

    # Read the matching records and print them out          
    while (@data = $sth->fetchrow_array()) {
        $id = $data[0];
        $name = $data[1];
        $firstname = $data[2];
        #print "Database result: \t$id: $firstname $name\n";
    }

    # Authentication failed -- Either we could not parse
    # the X509 subject string, or the common name in the
    # subject string didn't match the passed cn argument.
    if ($sth->rows == 0) {
        print "TLS-VERIFY: EE - Unknown user: $x509\n";
        $result=1;
    } 
    # Authentication is OK
    else {
        print "TLS-VERIFY: OK - $id - '$firstname $name' logged in\n";
        $result=0;
    } 
    $sth->finish;
    $dbh->disconnect;
}

The database:

CREATE TABLE `users` (
  `id` varchar(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `firstname` varchar(255) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `id` (`id`),
  KEY `id_2` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `users` (`id`, `name`, `firstname`) VALUES 
('83021811535', 'Vandeplas', 'Christophe');

OpenVPN with Belgian eID

Edit: I added database authentication. Details see: here.

Some time ago Nicolas told us he played with the Belgian eID. In the past I also hacked the belpic code to compile it under Gentoo, but since I have my Mac I haven't really played with it except to use it as an online-auth for the Gov-sites.
For some weeks now I enabled SSL-VPN on my server using SSL Certificates with a self-signed authority. But just like Nicolas says :"Pretty cool stuff, if this'd work... Both VPN and SSH authentication will be done using my eID if this turns out well.".

So the plan is:

  • Make a VPN tunnel using OpenVPN
  • Identify my server using a certificate (self-signed or a CAcert one.)
  • Identify the user using certificates from the Belgian eID / Digital Identity Card
  • Authorize users based on their rijksregister-nummer/numéro de registre national
  • Check the validity of the card using CRL or OCSP

The client will need OpenVPN 2.1 (still in RC atm). The server seems to work with the latest stable release (2.0.6 on my system).

Installing eID drivers

There are plenty of manuals to do this, or if you use a distro like ubuntu/debian/openSUSE/... there should be packages for it. For MacOS X there is an installer and this manual if you want to use it to logon on your system.

Just to be sure it works. You can check what keys are on your card with the pkcs15-tool --dump command.
Notice that we have two private keys. One for Authentication and one as Signature. You are not authorized (neverExtract) to download the private key from the card.

Private RSA Key [Authentication]
        Usage       : [0x4], sign
        Access Flags: [0x1D], sensitive, alwaysSensitive, neverExtract, local
Private RSA Key [Signature]
        Usage       : [0x200], nonRepudiation
        Access Flags: [0x1D], sensitive, alwaysSensitive, neverExtract, local

Extract info from the card

With the command openvpn --show-pkcs11-ids provider you can see the DN and serial of your keys. This info will be used later.

The provider is the shared library you get when compiling the beid driver. On a linux system it's a .so file, on a mac a .dylib and probably a .dll on Windows.
If you don't know where it is, check the 'Security Devices' of your Firefox as it might already be used there.

$ openvpn --show-pkcs11-ids /usr/local/lib/beid-pkcs11.bundle/Contents/MacOS/libbeidpkcs11.2.1.0.dylib 

The following objects are available for use.
Each object shown below may be used as parameter to
--pkcs11-id option please remember to use single quote mark.

Certificate
       DN:             /C=BE/CN=Christophe Vandeplas (Authentication)/SN=Vandeplas/
                            GN=Christophe Marie-Luc/serialNumber=83021811535
       Serial:         1000000000006F3CBE8C921BC713F8FD
       Serialized id:  Axalto/Belgium\x20eID/6CFF2491AB111E14/BELPIC\x20\x28Basic\x20PIN\x29/02

Certificate
       DN:             /C=BE/CN=Christophe Vandeplas (Signature)/SN=Vandeplas/
                            GN=Christophe Marie-Luc/serialNumber=83021811535
       Serial:         1000000000005A011FBE437FC4363A3D
       Serialized id:  Axalto/Belgium\x20eID/6CFF2491AB111E14/BELPIC\x20\x28Basic\x20PIN\x29/03

Take the Serialized id from the Authentication certificate. (bold)
This ID will be used to tell OpenVPN what key he should read. But there is a small thing, you must replace all \x20 to a space the \x28 to a ( and \x29 to ).
The result is something like this: pkcs11-id "Axalto/Belgium eID/6CFF2491AB111E14/BELPIC (Basic PIN)/02"

The last things we must extract are the certificates of the Belgian government.
The command pkcs15-tool --list-certificates lists the certificates present on the smartcard. Two fields require our attention (bold):

  • X.509 Certificate [CA]: The certificate authority that signed our key
  • X.509 Certificate [Root]: The root certificate
$ pkcs15-tool --list-certificates
X.509 Certificate [Authentication]
        Flags    : 3
        Authority: no
        Path     : 3f00df005038
        ID       : 02

X.509 Certificate [Signature]
        Flags    : 3
        Authority: no
        Path     : 3f00df005039
        ID       : 03

X.509 Certificate [CA]
        Flags    : 3
        Authority: yes
        Path     : 3f00df00503a
        ID       : 04

X.509 Certificate [Root]
        Flags    : 3
        Authority: yes
        Path     : 3f00df00503b
        ID       : 06

We write down the IDs of both certificates: 04 and 05. These numbers are used to export the certificates to a pem file.

$ pkcs15-tool --read-certificate 04 > belgium.crt
$ pkcs15-tool --read-certificate 06 >> belgium.crt

Current client/server configuration

Complete configurations with comments at the end of this article.
client
dev tun
proto udp
remote myserver.org 1194
resolv-retry infinite
nobind
user nobody
group nobody
persist-key
persist-tun
pkcs11-providers /usr/local/lib/beid-pkcs11.bundle/Contents/MacOS/libbeidpkcs11.2.1.0.dylib
pkcs11-id "Axalto/Belgium eID/6CFF2491AB111E14/BELPIC (Basic PIN)/02"
ca ca.crt
ns-cert-type server
comp-lzo
verb 3

The ca.crt file contains the certificate of the Certificate Authority that signed the key of my server.
The server configuration:

port 1194
proto udp
dev tun
cert server.crt
key server.key
ca belgium.crt
#tls-verify /etc/openvpn/auth-eid-check  # TODO uncomment this later
dh dh1024.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "redirect-gateway"
keepalive 10 120
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
log         openvpn.log
verb 4
mute 20

Establishing the connection:

Server: /etc/init.d/openvpn start and client: openvpn --config openvpn.conf

I first didn't export both certificates in the same file (belgium.crt) and got the following error in my server logs:

Sun Feb  3 12:34:26 2008 us=556133 62.235.210.17:50545 VERIFY ERROR: depth=0, error=unable to get 
  local issuer certificate: /C=BE/CN=Christophe_Vandeplas__Authentication_/SN=Vandeplas/GN=Christophe_
  Marie-Luc/serialNumber=83021811535
Sun Feb  3 12:34:26 2008 us=556290 62.235.210.17:50545 TLS_ERROR: BIO read tls_read_plaintext 
  error: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned

A working situation should show:

Sun Feb  3 12:45:31 2008 us=101863 62.235.210.17:50609 VERIFY OK: depth=2, /C=BE/CN=Belgium_Root_CA
Sun Feb  3 12:45:31 2008 us=102526 62.235.210.17:50609 VERIFY OK: depth=1, /C=BE/CN=Citizen_CA
Sun Feb  3 12:45:31 2008 us=103299 62.235.210.17:50609 VERIFY OK: depth=0, /C=BE/CN=Christophe_
  Vandeplas__Authentication_/SN=Vandeplas/GN=Christophe_Marie-Luc/serialNumber=83021811535
  ...
Sun Feb  3 12:45:33 2008 us=834295 62.235.210.17:50609 [Christophe_Vandeplas__Authentication_] 
  Peer Connection Initiated with 62.235.210.17:50609
Sun Feb  3 12:45:33 2008 us=834410 Christophe_Vandeplas__Authentication_/62.235.210.17:50609 
  MULTI: Learn: 10.8.0.10 -> Christophe_Vandeplas__Authentication_/62.235.210.17:50609
Sun Feb  3 12:45:33 2008 us=834445 Christophe_Vandeplas__Authentication_/62.235.210.17:50609 
  MULTI: primary virtual IP for Christophe_Vandeplas__Authentication_/62.235.210.17:50609: 10.8.0.10

This works ! Yess.. This means everyone with an eID can login on the VPN.. hmm.. probably not something I/you want.

Authorization

The authentication part works fine. We are fully certain that the certificate is valid but everyone with an eID can login. Time to implement a little authorization. Isn't it?

Remember this line? tls-verify /etc/openvpn/auth-eid-check. Uncomment it.
When the authentication has been performed (but before the CRL check) the authorization is done by running the following script. This script gets 2 parameters and should exit 0 if OK and exit 1 if unauthorized.
You should probably do some database-checking or put keys in an or secure file.

  • The depth of the certificate-chain: 0 -> X
  • The CommonName : /C=BE/CN=Christophe Vandeplas (Authentication)/SN=Vandeplas/GN=Christophe Marie-Luc/serialNumber=83021811535
Complete script with comments at the end of this article.
#!/usr/bin/perl
die "usage: auth-eid-check certificate_depth X509_NAME_oneline" if (@ARGV != 2);
($depth, $x509) = @ARGV;
$cn="83021811535";  # the key that is allowed
if ($depth == 0) {  # only check the final/client certificate
    if ($x509 =~ /\/serialNumber=([^\/]+)/) {
        # check here the validity of the serialNumber, or something else
        if ($cn eq $1) { 
            exit 0;
        }
    }
    exit 1;  # invalid user, should not be able to login
}
exit 0;

Validity of the certificate - CRL & OCSP

It looks like OCSP is not supported in OpenVPN. Even in 2005 people were asking for it, but I can't find a thing in the manuals or the internet.
You can try to use the CRL of Belgium. But the problem is this database is soooo big it's almost unusable. I didn't try it but it should work by adding the following lines in your server.conf configuration file.

crl-verify http://crl.eid.belgium.be/belgium.crl

Docs I used

http://openvpn.net/howto.html#pkcs11
http://openvpn.net/man-beta.html
http://michele.pupazzo.org/docs/smart-cards-openvpn.html
http://christophe.vandeplas.com/2008/02/08/database-authorization-openvpn-eid


Full configfiles

I Love Belgium... and you?

About Me
GnuPG Public Key Still More LinkedIn profile
Photos
Projects
WeIDS 2.0 Linux Lessons WiFi Auth Project
Documentation
Acer Aspire 2012 WLMi Acer TM 4002 WLMi IR-receiver (Win)(NL)
Links
Ubuntu Belgium Planet Grep

FOSDEM BruCON Profoss hacker emblem www.cacert.org Get OpenOffice Get Firefox Get Thunderbird