Complex PHP example
Complex PHP example for creating and processing digitally signed claims
- 1 Overview
- 2 Working principles of the example solution
- 3 Installing the sample solution
- 3.1 Dependencies
- 3.2 Configuring the Apache web server
- 3.2.1 General information
- 3.2.2 Installing of the certificates
- 3.2.3 Enabling mod_ssl in Apache configuration
- 3.2.4 Modifying the Apache configuration files
- 3.2.5 Enabling ID-card authentication support in Apache configuration
- 3.2.6 Applying Apache configuration changes
- 3.3 DigiDocService
- 3.4 Installing the sample software
- 4 Märkused näiterakenduse kohta
- 5 References
On this chapter is presented example solution for creating the claim, signing it digitally, receiving and verifying it. Example solution consists of three parts:
- Claim creation and digial signing form on the Web server: implemented in PHP
- Service for processing, verififying and encrypting claims on the Web server: implemented in PHP
- Alternative command line utility for creating and digitally signing of claims: implemented in Java and .Net
Let's presume there is an organisation to which claims can be presented. For that, the organisation has to set up a web server with a web form. Communication with the server is carried out over the HTTPS protocol and it requires the user to identify himself (See  in the list below). In the form, the name and personal identification number fields have been pre-filled with data taken from the certificate. After that, the user writes down his claim, which the web service will place into a DigiDoc container with the name and personal identification number, using DigiDocService[2.1]. As a last step, the user is asked to sign the container in the web browser[2.2].
The created container is forwarded to another service, which checks the signature [2.3] and issues an automatic response in a container that is signed with the organisation's digital stamp and encrypted with the public key from the user's certificate. The user can save the presented claim and the received answer in his computer and then take a closer look at the answer with the DigiDoc client.
Parallel to the web form, there is also an application where the user has to identify himself. Then the signed container is created in the client's computer[5, 6] and sent as a whole to the same service as the web form. In addition to the claim, the application also includes the information found in the personal data file of the ID card . The server response is the same, but this time it is also decrypted and the signature is verified within the application, not the DigiDoc client.
Therefore, the use case demonstrates
- personal identification on the Web,
- usage of DigiDocService
- for creating containers,
- signing and
- signature verification,
- encrypting a file with the sender's certificate,
- personal identification in an application,
- creating a container in an application,
- signing in an application,
- reading the personal data file of an ID card,
- decrypting a file and
- verifying a signature in an application.
Working principles of the example solution
Web-based component for entering the claim and digitally signing it with the ID-card
This is web-based component for filling out the claim form and for signing it with the help of ID-card.
- The web server carries out a personal identification in the course of the SSL/TLS handshake.
- The application uses DigiDocService for verifying client certificate validity. See certificate validity check in an SSL/TLS session to learn why it is done like that.
- The user is presented a web form that consists of four fields. Three of them (name, surname and personal identification number) are pre-filled with the data obtained at personal identification.
- When the form is presented, contents of the fields and the user's signing certificate with its serial number is sent to the server (although the serial number could be read from the certificate, it is better to leave this work to the client's side).
- A text file is created from the data inserted into the form and it is saved in a temporary folder.
- A new session is started with DigiDocService and a container created, where the freshly created file's hash is put (StartSession). Although it is possible to send the source files to the service, it is more sensible from the point of view of privacy and data volume to send hashes.
- Preparations are made to sign the container: The user's certificate is sent to DigiDocService together with the metainformation, i.e. role and location (PrepareSignature). In sample code, constants are used for metainformation, as asking them from the user is trivial and does not require a special example. The service returns a container hash that the client has to sign.
- The next page is displayed to the user, with the signing certificate's serial number and the hash to be signed.
- The signature is sent back to the web form with the next query, and the web form finalises the signing process (FinalizeSignature), downloads the signed container (GetSignedDoc) and closes the session (CloseSession).
- In the downloaded container, the hashes are replaced with the actual files that were saved on the disk beforehand, and forwarded to the claims handling service.
- The downloaded container and the response from the organisation are saved on the disk, from where the user can in turn download them using his browser.
Web-based component for entering the claim and digitally signing it with the help of Mobile-ID
A version of the web form that uses mobile ID. In general, it is an application quite like the web form (see also installing requirements there), with two important differences.
First, the client's certificate is not requested in the course of the SSL/TLS handshake -- the certificate is on mobile ID SIM and the user's web browser has no access to it. Instead, we use the DigiDocService method MobileAuthenticate for forwarding an authentication query. As method parameters, we give the user's phone number and language preference. After that, we invoke the method GetMobileAuthenticateStatus every five seconds until it returns authentication results. The method also returns the user's certificate, the validity of which has already been verified.
Second, the document is not signed with a web browser plugin but with mobile ID. Consequently, we do not invoke the methods PrepareSignature and FinalizeSignature, but MobileSign and GetStatusInfo: the first sends a signing query and the second we check every five seconds until we have a result. The rest of the steps needed for hashing documents, creating containers and determining metainformation are the same as with the web form.
The interval of five seconds that has been chosen for both status checks is good for testing, when the test numbers answer quickly. In a product environment, users take much longer to answer mobile ID queries, so that the interval can also be increased (especially the waiting time before the first query is made).
Note: The response obtained from the claims handling service is encrypted and the only receiver is the mobile ID's personal identification certificate - but as mobile ID does not support encryption, this response cannot be read. However, the contents of the response are not important at all -- the fact that the response was returned shows that the statement was correct and its sending successful.
Java and .Net based Claims application
This is a command line application that generates a claim on the basis of information gathered from the user and the personal identity document, puts it in a container, signs and sends it to the claims handling service. In response, a new container is delivered. The application decrypts it, verifies the signature and displays the contents of the container to the user.
The application is originally written in Java, where the JDigiDoc library is used, and then ported to .NET, where a COM library is used. Some subparts of the application (signing, personal identification, signature verification and data decryption) have also been rewritten in C++, but as its usage is quite similar to Java, there was no need to re-port the whole application.
- The application performs personal identification as described in personal identification and executed in the standalone personal identification application.
- The .NET application verifies certificate validity using only CRL; for OCSP support, third party libraries must be used (e.g. Bouncy Castle).
- The user is asked for input for the claim - it is a simple, one-line text input. As libraries are only able to use files that have been saved on the disk, the input information is saved into a temporary file.
- The personal data read from the card is temporarily saved on the disk (libraries don't support reading the personal data file, which is why it has to be done manually, on the basis of the EstEID card user manual (in Estonian) -- read more about whether and how to read the personal data file from Using the personal data file.
- The data is contained in a DDOC container and signed -- in the course of the latter, the validity of the certificate for signing is also used.
- It is checked whether the container verifies and it is written on the disk.
- The container is sent to the claims handling service and an encrypted container is received in response.
- As the COM library does not support decrypting, in the case of a .NET application, the server is requested an unencrypted response. Therefore, the next step is also missed.
- The transport key in the container is decrypted with the secret key of the user's personal identification certificate and it is used for decrypting the signed response from the service.
- The signed response is saved on the disk and then its signature is verified.
- The contents of the response from the service are displayed to the user.
NB! The Java application requires Java version 1.7 or later.
By default, personal identification in the claims application works only with cards employing 2048-bit keys. In order to use older cards, the relevant hash algorithm must be changed in the source code (see The fault in pre-2011 cards).
Claims handling service
The claims handling service is written in PHP and uses DigiDocService for verifying the signature on the claim. For signing and encrypting the response, a SWIG wrapper around the libdigidoc library is used.
- A POST query is presented to the service with two mandatory fields: claim and cert.
- cert must contain the personal identification certificate of the receiver of the response in a base64 coded DER form (this is not PEM, because the lines BEGIN and END are absent),
- claim must contain the signed claim. The file's MIME type has to be either application/x-ddoc or application/vnd.bdoc-*.
- The service checks if the upload was successful and if the signature on the claim is valid. For validity check, the claim is sent to DigiDocService, using the query StartSession, where the flag bHoldSession has been put to negative so that the connection would be closed immediately. As a response, DigiDocService sends the signature's status.
- Again, not the whole claim is sent to DigiDocService but data files with their hashes.
- The contained data files are read from within the claim and written on the disk.
- If the signature is valid, a response is generated. Its contents are not important to us, so it is a constant string.
- The libdigidoc library is reset and a signing container created (in the SWIG wrapper, the corresponding methods are initialize and new_signature_container).
- The generated response is added to the container (add_data_file) and signed (sign_container). The PIN used for signing can be either an argument of the signing function or a value of the key AUTOSIGN_PIN in the configuration file of the libdigidoc library (in this case when the function is invoked, the value of the parameter pin will remain NULL).
- The signed response is written on the disk and released from memory (methods save_signed_document and free_signature_container. NB! Here it would be reasonable to retain the container in the memory, as it will be read from the disk again right away -- but this cannot be done at the moment, as the library function createSignedDocInMemory produces a faulty XML, so we have to use the version that writes on the disk).
- The service creates a new encryption container (new_encryption_container) and encrypts the freshly generated response (encrypt_ddoc).
- The used transport key is encrypted with the public key of the certificate on the field cert and is added to the container (add_recipient).
- The encrypted container is saved on the disk (method save_encrypted_container. NB! Again, it would be better not to write the container on the disk, but the conversion of the container into XML in the memory is hidden from us in the library, and the only way to generate XML is to write the file). The memory taken for the container is freed (free_encryption_container) and the response is sent to the sender of the initial query.
While installing the service, it must be made sure that it has writing rights in its own folder and the conf.php file must be tweaked, where at least the DD_RESPONSE_SERVER address must be changed (this is used by the web form and its value should be set to the address of the claims handling service).
Attention: Keep in mind that the class necessary for the communication with the DigiDoc service is generated by PHP only once, and then saved to disk. If, following that, the developer alters either the rest of the source code or conf.php, or installs the PHP cURL module, then the wsdl.class.php must be deleted so that it could be generated as new.
Installing the sample solution
Dependencies of web-based components
Sample code has been created on the platform Ubuntu 12.04 Long-Term Support a.k.a Precise Pangolin (64-bit), using the default package versions:
- apache2 2.2.22-1ubuntu1.4
- php5 5.3.10-1ubuntu3
- php5-dev 5.3.10-1ubuntu3
- php5-curl 5.3.10-1ubuntu3
- swig 2.0.4+really2.0.4-4ubuntu2
By default this platform contains out-of-the-box old DigiDoc libraries. In order to use new libraries the following script should be downloaded and executed from command line: https://installer.id.ee/media/install-scripts/install-esteid-ubuntu.sh.
Dependencies of Java command line utility
In order to be able compile of Java command line utility following packages should be installed into the computer:
- ant 1.8.2-4build1
There is also required to install the following external packages:
Deployment scripts and configuration of Java command line application are designed for installing the application into the same computer, where is claims service installed. If this is not the case then there is probably required to do suitable changes in deployment scripts and configuration files. Also on such case there is required to install DigiDoc libraries.
Configuring the Apache web server
The web server should be Apache httpd (naturally other web servers may be used, but these will not be discussed here). It is necessary to have PHP support installed and the server configured to use HTTPS. All of this is done as normal and there is no eID specifics.
For logging in with an ID-card, the server has to be additionally configured to request the user for his certificate on the relevant webpage. Guidelines for it can be found on the corresponding ID.ee page. In the present use case, an ID-card is only used on the web form so that the guide should be consulted for this application only. If all applications run on the same web server, requesting the certificate should be configured for the web form only; the certificate should definitely not be requested by the claims handling service; otherwise, other applications cannot present claims to it.
Servers configured according to these guidelines verify the validity of users' certificates against revocation lists (CRL, Certificate Revocation List) only -- adding OCSP (Online Certificate Status Protocol) requests would be a good idea. But as mentioned at certificate validity check, it is not easily done in a web server.
As noted above, the client's certificate is only used in the SSL/TLS session at the web form, where DigiDocService support already exists. Therefore, validity confirmation can also be asked through this service. In the mobile-ID web form, DigiDocService performs a validity check for us, so there is no need to do it separately.
In the following there are step by step described how the Apache web server should be configured.
Installing of the certificates
Creating the server certificate
For demonstrating purposes there is sufficient to use self-signed certificates. For real server there should real SSL server certificate obtained. Self-signed certificate can be generated with the help of the following commands:
su - cd /etc/ssl/private openssl genrsa -out server.key 1024 openssl req -new -key server.key -out server.csr openssl x509 -req -days 365 -in server.csr -signkey server.key -out ../certs/server.crt
Loading the SK certificates
There is needed to download and install suitable SK (AS Sertifitseerimiskeskus) CA certificates:
cd /etc/ssl/certs wget http://sk.ee/upload/files/JUUR-SK.PEM.cer wget http://sk.ee/upload/files/EECCRCA.pem.cer wget http://sk.ee/upload/files/ESTEID-SK%202007.PEM.cer wget http://sk.ee/upload/files/ESTEID-SK%202011.pem.cer cat JUUR-SK.PEM.cer EECCRCA.pem.cer ESTEID-SK\ 2007.PEM.cer ESTEID-SK\ 2011.pem.cer > id.crt
Loading the certificate revocation lists
Certificate revocation list (CRL) contains information about all revoked certificates. CRLs can be downloaded from www.sk.ee, but for Apache server they should be converted to PEM format:
mkdir /etc/ssl/crl cd /etc/ssl/crl wget http://www.sk.ee/crls/esteid/esteid2007.crl wget http://www.sk.ee/crls/juur/crl.crl wget http://www.sk.ee/crls/eeccrca/eeccrca.crl wget http://www.sk.ee/repository/crls/esteid2011.crl openssl crl -in esteid2007.crl -out esteid2007.crl -inform DER openssl crl -in crl.crl -out crl.crl -inform DER openssl crl -in eeccrca.crl -out eeccrca.crl -inform DER openssl crl -in esteid2011.crl -out esteid2011.crl -inform DER
Creating the certificate revocation list collection
Apache server is seraching the CRLs from the specified dierctory based by very specific hashed file name. Therefore there is needed to create suitable symbolic links with the help of the following commands:
ln -s crl.crl `openssl crl -hash -noout -in crl.crl`.r0 ln -s esteid2007.crl `openssl crl -hash -noout -in esteid2007.crl`.r0 ln -s eeccrca.crl `openssl crl -hash -noout -in eeccrca.crl`.r0 ln -s esteid2011.crl `openssl crl -hash -noout -in esteid2011.crl`.r0
Enabling mod_ssl in Apache configuration
By default the mod_ssl module is switched off. Use the following commands for switching this on:
cp /etc/apache2/sites-available/default-ssl /etc/apache2/sites-enabled/ cd /etc/apache2/mods-enabled ln -s ../available/ssl.conf ln -s ../available/ssl.load
Modifying the Apache configuration files
For enabling the use of correct certificates modify the Apache configuration file /etc/apache2/sites-enabled/default-ssl as follows (insert or modify corresponding parameters):
SSLCertificateFile /etc/ssl/certs/server.crt SSLCertificateKeyFile /etc/ssl/private/server.key SSLCACertificateFile /etc/ssl/certs/id.crt SSLCARevocationPath /etc/ssl/crl/
Enabling ID-card authentication support in Apache configuration
For activating the ID-card authentication for some particular location (on current case - for directory "webform"), insert the following lines into configuration file /etc/apache2/sites-enabled/default-ssl:
<Location /eid/avaldused/webform> SSLVerifyClient require SSLVerifyDepth 2 SSLOptions +StdEnvVars +ExportCertData </Location>
Applying Apache configuration changes
For activating the configuration changes there is needed to to restart for Apache service:
The interface of DigiDocService is defined in WSDL, upon which the PHP class for using the service is generated. Although PHP 5 comes with built-in SOAP client and the possibility to generate a class upon WSDL, sample code uses the included SOAP module from PEAR, with which the code will also work with older versions. The code should work with PHP 4.3.4 at least, but working on older versions is not excluded either. If the web application uses PHP 5, it is advisable to use built-in tools for new developments.
For reading XML files and DigiDoc containers, a shortened and slightly modified version of sample code is used, which is available at https://www.openxades.org/ddservice/. If the shortened version lacks the desired functionality, it may be present in the full version.
Using the test version of DigiDocService
In order to use the test version of DigiDocService, you should first enable this for your ID-card. Service will be enabled for your ID-card if you upload your ID-card certificate into DigiDoc Portal https://www.openxades.org/upload_cert.php The same logic applies alto for Mobile-ID / you should upload your Mobile-ID certificate using the URL https://www.openxades.org/MIDCertsReg/
For more concrete instructions please see http://www.id.ee/?lang=en&id=35755
Installing the sample software
All source code for software samples can be accessed through the GitHub environment: https://github.com/tammet/eid
For installing the sample solution, download it, execute build script and install script:
cd /var/www git clone https://github.com/tammet/eid cd eid/avaldused sh ./build.sh su -c ./inst-root.sh
NB! Install script changes the global configuration file /etc/digidoc.conf in order to enable usage of test-DigiDocService. After the change the configuration file is no more suitable for production environment. The old configuration file will be backed up to file /etc/digidoc.conf.orig.
By default the signing of the response is turned off on the sample claims processing service. If you like to test this functionality too, then you should connect the ID-card reader to the server, configure it and insert eID card into this reader. For activating the digital signing of responses modify the file eid/avaldused/conf.php and change the definition of the constant DD_SIGN_RESPONSE to 1:
Setting up the web forms
There is no specific actions needed in order to set up the web forms for sample solution. You can just open the right URL https://localhost/eid/avaldused/ in your web browser (replace "localhost" with the computer name where you installed the sample solution) and choose the suitable web form. In case you select the web form with digital signing by the help of ID-card, then immediately ID-card authentication will be required.
Installing Java command line utility
If you like to use Java command line utility then this should be separately compiled. Go to the directory eid/avaldused/client-java and execute the command:
Java command line utility can be executed with command:
Klient on häälestatud töötama avaldusi töötleva veebiteenusega üle HTTP protokolli. Kui on soov testida üle HTTPS protokolli toimimist (vajalik tingimata pärisrealisatsioonides), tuleb vastavalt modifitseerida client.sh skriptis leiduvat URLi. Lisaks tuleb hoolitseda, et serveri sertifikaadi väljaandja oleks süsteemile tuttav. Selleks peab vastav sertifikaat olema keystore'is olemas. Kui teenus kasutab enda allkirjastatud (self-signed) sertifikaate (näiteks testimisel), siis on vaja need enne Java keystore'i lisada:
By default the utility is configured to use web service over HTTP protocol. If an HTTPS connection is created with the service (very advisable), then it is needed to change the URL in client.sh file and also checked that the issuer of the server certificate is known to the system. This means that the key should be present in keystore.
If the service uses self-signed certificates (e.g. at testing), these need to be added to the Java keystore beforehand:
keytool -import -alias <certificate alias> -file <certificate location> -keystore <keystore location>
E.g. under Ubuntu:
# keytool -import -alias snakeoil -file /etc/ssl/certs/ssl-cert-snakeoil.pem -keystore /usr/lib/jvm/default-java/jre/lib/security/cacerts
Installing .Net application
The .NET application comes with Visual Studio 2010 project files that can be used for compiling the application. If there is none, a reference to the COM library has to be added to the project. After the reference has been added, under References, the Properties of DIGIDOCLIBCOMLib have to be opened and Embed Interop Types value set to False.
If an HTTPS connection is created with the service (very advisable), then it is checked that the issuer of the server certificate is known to the system. This means that he key should be installed in the Windows certificate repository. For installing a self-signed certificate in the Windows certificate repository, it is enough to double-click it and choose "Install certificate".
The application can be executed with the command:
- url - address of the claims handling service, default value https://localhost/eid/submit.php
Märkused näiterakenduse kohta
The library's interface facilitates:
- loading the best installed plugin for the operating system and the browser
- reading the user's signing certificate from the ID card and
- signing the given hash with the user's ID card.
Error messages of the library are in Estonian, English, Lithuanian and Russian. For choosing the desired language, the value of the method
loadSigningPlugin() should be set respectively to "est", "eng", "lit" or "rus".
All three are used in the claims presentation web form and the sample code is available there.
The library with documentation is available at: http://id.ee/index.php?id=30496
In addition to the library, a new universal plugin was also created that is distributed as part of the ID card base software and is recommended for use in the future, as the older Java applet is no longer updated.
Sample application in the .NET framework
Although .NET allows several operations to be performed with the smart card with the tools already included in the framework, it lacks support for the DDOC format. Therefore, for signing or verifying a container in a .NET application, a COM-library must be used or the appropriate functionality implemented.
.NET sample code can be seen in the claim application.
There is a plan to create a separate .NET library by 2013 that will replace the COM library.
Using DigiDoc Library in PHP
If there is no wish or possibility to use DigiDocService, DigiDoc libraries can be used as an alternative. None has been written for PHP; therefore, a wrapper around an existing one has to be used.
To simplify interfacing with a library and minimise wrapped surface, a simple middle layer was created in the sample code that hides the usage of libdigidoc library behind a function. The middle layer is transmission-specific, which is why it is not suitable for general use, but it will give an idea of what it could be like. After that, a SWIG wrapper was created around the middle layer, not the library. The result was a PHP extension with the help of which it is possible to use all the methods of the middle layer.
The extension is used for signing and encrypting the server-side response. The latter of these cannot be done with DigiDocService, which is more proof of the necessity of using libraries.
Compiling the SWIG extension
SWIG component resides in directory eid/avaldused/swig. Install script of sample application executes all required actions in order to install this component. Here is given some advices in case there is interest to manually install this comonent.
Because of the created middle layer, the digidoc interface in source code is very simple -- it only contains the directive for the inclusion of digidoc.h headers. From the interface, the wrapper's code can be generated by giving the command:
swig -php digidoc.i
As a result of this, three new files are created: digidoc_wrap.c, digidoc.php and php_digidoc.h.
- The first, digidoc_wrap.c, contains the code in C needed for compiling the PHP extension.
- The second, digidoc.php, can be included in PHP scripts. It attempts to load the extension dynamically and places the wrapped functions into the abstract class digidoc.
- The last, php_digidoc.h, contains necessary header information for when you wish to link the extension statically into a PHP interpreter. If you do not want to do that, this file is not needed.
After that, the middle layer code together with the generated C code of the wrapper should be compiled into one shared object. For compiling, the header locations of PHP interpreter headers must also be given, which can be done with the php-config tool, and then the libdigidoc library should be linked. E.g. using GCC, the compiling would look like this:
$ gcc `php-config --includes` -fPIC -c digidoc.c digidoc_wrap.c $ gcc -shared digidoc.o digidoc_wrap.o -ldigidoc -o digidoc.so
Loading the extension
When including digidoc.php, it is attempted to dynamically load the created extension with the command dl (if it hasn't been loaded already). As there have been problems with the dl command, it is first better to load the module manually. For that, a line has to be added to the php.ini configuration file (or the existing one changed):
extension=digidoc.so # Linux extension=digidoc.dll # Windows
As the SWIG wrapper uses the libdigidoc library, the file digidoc.conf must be changed for configuring it. Default values are mostly suitable, but there is one important line: DIGIDOC_OCSP_URL, which determines where the OCSP query will be sent. For testing purposes, the value should be http://www.openxades.org/cgi-bin/ocsp.cgi.
Attention: Do not forget to change it back when you want to send queries in a product environment using the libdigidoc library.
Configuring the digital stamp
If the service uses a digital stamp instead of an ID card for signing, libdigidoc version 3.7 or newer is needed and the digital stamp drivers must be installed. Also, some changes have to be made in the settings file of libdigidoc library.
For installing drivers, see the chapter Using the crypto-stick.
The default location of the settings file of libdigidoc library is %PROGRAMFILES%\Estonian ID card\digidoc.ini (Windows) or /etc/digidoc.conf (Linux).
The following lines should be present in the settings file (module location may differ):
DIGIDOC_DEFAULT_DRIVER=1 DIGIDOC_DRIVERS=1 DIGIDOC_DRIVER_1_NAME=OpenSC DIGIDOC_DRIVER_1_DESC=OpenSC projects PKCS#11 driver DIGIDOC_DRIVER_1_FILE=/usr/lib/opensc-pkcs11.so
Here, it is necessary to use the freshly installed SafeNet eToken module instead of the OpenSC one. For this, just replace the existing module or add a new one. The last version would look like this (again, the actual module locations may differ):
DIGIDOC_DEFAULT_DRIVER=2 DIGIDOC_DRIVERS=2 DIGIDOC_DRIVER_1_NAME=OpenSC DIGIDOC_DRIVER_1_DESC=OpenSC projects PKCS#11 driver DIGIDOC_DRIVER_1_FILE=/usr/lib/opensc-pkcs11.so DIGIDOC_DRIVER_2_NAME=eToken DIGIDOC_DRIVER_2_DESC=SafeNet eToken PKCS#11 driver DIGIDOC_DRIVER_2_FILE=/lib/libeToken.so.8In addition, the number of the slot used for digital signing must be changed:
- Signing on web applications with the ID-card and digi-ID. http://id.ee/index.php?id=35741