Complex PHP example

Redaktsioon seisuga 13. mai 2014, kell 16:59 kasutajalt Ivomehide (arutelu | kaastöö) (→‎DigiDocService)
Jump to navigation Jump to search

Complex PHP example for creating and processing digitally signed claims


Use case participants

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

Detailed description:

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 [1] 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[3]. 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[4]. 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 [7]. The server response is the same, but this time it is also decrypted[8] and the signature is verified within the application[8], not the DigiDoc client.

Therefore, the use case demonstrates

  1. personal identification on the Web,
  2. usage of DigiDocService
    1. for creating containers,
    2. signing and
    3. signature verification,
  3. encrypting a file with the sender's certificate,
  4. personal identification in an application,
  5. creating a container in an application,
  6. signing in an application,
  7. reading the personal data file of an ID card,
  8. decrypting a file and
  9. 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

Web form sequence diagram

This is web-based component for filling out the claim form and for signing it with the help of ID-card.

  1. The web server carries out a personal identification in the course of the SSL/TLS handshake.
  2. 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.
  3. 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.
  4. 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).
  5. A text file is created from the data inserted into the form and it is saved in a temporary folder.
  6. 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.
  7. 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.
  8. The next page is displayed to the user, with the signing certificate's serial number and the hash to be signed.
  9. The user clicks the button "Sign", upon which the process is handed over to the JavaScript library that obtains the signature to the hash from the user.
  10. 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).
  11. 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.
  12. 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

Mobile ID's web form sequence diagram. The parts in the blue boxes are repeated until a query result is obtained. The communication between the mobile operator and the user is missing from the scheme, because it is not important from the point of view of development.

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

Claims application sequence diagram

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.

  1. 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).
  2. 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.
  3. 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.
  4. 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.
  5. It is checked whether the container verifies and it is written on the disk.
  6. 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.
  7. 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.
  8. The signed response is saved on the disk and then its signature is verified.
  9. 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

Claims handling service sequence diagram

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.

  1. 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-*.
  2. 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.
  3. The contained data files are read from within the claim and written on the disk.
  4. If the signature is valid, a response is generated. Its contents are not important to us, so it is a constant string.
  5. The libdigidoc library is reset and a signing container created (in the SWIG wrapper, the corresponding methods are initialize and new_signature_container).
  6. 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).
  7. 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).
  8. The service creates a new encryption container (new_encryption_container) and encrypts the freshly generated response (encrypt_ddoc).
  9. 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).
  10. 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:

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:

  • openjdk-7-jdk
  • 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

General information

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 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
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, but for Apache server they should be converted to PEM format:

mkdir /etc/ssl/crl
cd /etc/ssl/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

Applying Apache configuration changes

For activating the configuration changes there is needed to to restart for Apache service:

/etc/init.d/apache2 restart


For signing and signature verification in PHP, DigiDocService can be used. To enable communication with the service over HTTPS, the cURL extension has to be added to PHP.

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[1], 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 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 The same logic applies alto for Mobile-ID / you should upload your Mobile-ID certificate using the URL

For more specific instructions please see