Authenticating and signing using Austrias citizen card

25 May 2019 - tsp

The following article provides a short summary (since documentation is hard to find and because of the XML-heavy nature and complexity of the specification) on how to use the citizen card issed in Austria to sign actions triggered by users and how to use that for authenticating users. Note that not all features of the card are available to all users of the service. For example the identity binding cannot be queried by any instance of the service that’s not using a server side SSL certificate for a domain under the .gv.at domain or has an additional government agency usage attribute set inside their X.509 server certificate.

Rationale: Why would one want to use the card for authentication? Because smartcards provide way better security than passwords or client certificates that are not stored inside an HSM - and of course they provide security lightyears better than using SMS or applications on mobile phones as second factors (see the comparison of TAN mechanisms)

Only the Null operation as well as the basic signing operation will be discussed in this short summary. The API is capable of doing much more but none of these services is required for basic signing and authentication.

The basic infrastructure that’s used is an application running on the users system that is interfacing the local smartcard reader (or other HSMs) to be capable of signing requests and providing identity information. I’ve also tried to use the smartcard via the usual well established PKCS#11 interface supported by many browsers for SSL client authentication - but unfortunately wasn’t able to use it that way. The application is interfaced with other web applications by providing an local webbrowser listening on 127.0.0.1:3495 with a single http-security-layer-request endpoint. Since the webserver runs locally it is accessed via http (i.e. http://127.0.0.1:3495/http-security-layer-request). Requests are sent as POST requests either via form submission or using an XMLHttpRpcRqeuest (Ajax).

After a user has issued an request the browser gets issued an redirect to an additionally supplied RedirectURL. Note that this happens immediately - even before the requested operation has finished. This redirection is done by means of HTTP 302 (Found, moved temporarily). The URI supplied by the application on the request is copied without any modification so it may contain some session information.

Data responses (for example decrypted information, identity information, signatures, etc.) of the application are not delivered by redirection but by a separate http or https request (many operations require SSL with an verifyable certificate to be used - and it’s a good idea anyway for sensitive information from an AAA process) made by the local application to the application server. The address is specified as dataURL and can contain additional session information. Note that since the request is not made by the users browser the session information from URI parameters is the only way to correlate data requests with the original HTTP request whenever one doesn’t have request information embedded for example in the signed content which is available too.

The following operations are commonly used:

There are additional operations that are supported but not commonly used. These are:

All applications are performed by requesting the operating via a well formed XML - responses are contained in XML documents too. The client side security application can perform XSLT transformations on data shown to users as well as data that should be signed - the following article only describes the most basic usage to introduce the way these mechanisms work without getting too XML loaded (which is one of the reasons these mechanisms are not implemented very often).

Operations

The following operations are the operations that are interesting to authenticating users

Null operation

The null operation is simply a no-operation operation that can be used to verify the presence of the client side security application.

It is triggered by sending an POST request to the http://127.0.0.1:3495/http-security-layer-request endpoint. This operation requires at least one parameter but is normally called with 3 parameters:

The XML request is an XML document containing just the NullOperationRequest:

<?xml version'1.0' encoding='UTF-8'?>
<NullOperationRequest xmlns='http://www.buergerkarte.at/namespaces/securitylayer/1.2#'/>

If one wants to trigger a null operation by an HTML form one could use the following document:

<!DOCTYPE HTML>
<html>
	<head>
		<title> Do a NULL request </title>
	</head>
	<body>
		<form action="http://127.0.0.1:3495/http-security-layer-request" method="POST">
			<input type="hidden" name="XMLRequest" value="<?xml version'1.0' encoding='UTF-8'?> <NullOperationRequest xmlns='http://www.buergerkarte.at/namespaces/securitylayer/1.2#'/>">
			<input type="hidden" name="DataURL" value="https://example.com/index?action=null_dataurl">
			<input type="hidden" name="RedirectURL" value="https://example.com/index?action=null_redirurl">
			<input type="submit" value="NULL request">
		</form>
	</body>
</html>

One would see that the user gets redirected with an GET request to the redirection URL receives an POST request with URL-encoded payload. This payload contains two fields:

<?xml version='1.0' encoding='UTF-8'?>
<sl:NullOperationResponse xmlns:sl='http://www.buergerkarte.at/namespaces/securitylayer/1.2#' />

One can use URL parameters to correlate the data request with any user sessions.

Signing

Signing requests support signing of full XML documents according to the XML Signature Syntax and Processing Version 1.1 recommendation. This is not required for most simple applications (for example because they want to sign a simple base64 encoded string, a simple unique number or timestamp, etc.). The signature request also supports transforming the signature data via an XSLT request (if the client application supports that) to display them in a rich formatted display. As a more extended method the client also supports a subset of XHTML which is way out of scope for this article. These features are also not presented in the following section.

To request the signature of some data a POST request is done again to the http://127.0.0.1:3495/http-security-layer-request endpoint. The same three parameters (XMLRequest, DataURL, RedirectURL) as before are used.

The most basic XML request to sign text/plain data object contains an CreateXMLSignatureRequest object selecting the SecureSignatureKeypair keypair and supplying the data inside an DataObjectInfo as the DataObject inside it’s XMLContent element. The TransformInfo is not used for anything else than supplying the MIME type of the content.

<?xml version="1.0" encoding="UTF-8"?>
<sl:CreateXMLSignatureRequest  xmlns:sl="http://www.buergerkarte.at/namespaces/securitylayer/1.2#">
	<sl:KeyboxIdentifier>SecureSignatureKeypair</sl:KeyboxIdentifier>
	<sl:DataObjectInfo Structure="enveloping">
		<sl:DataObject>
			<sl:XMLContent>Sample text</sl:XMLContent>
		</sl:DataObject>
		<sl:TransformsInfo>
			<sl:FinalDataMetaInfo>
				<sl:MimeType>text/plain</sl:MimeType>
			</sl:FinalDataMetaInfo>
		</sl:TransformsInfo>
	</sl:DataObjectInfo>
</sl:CreateXMLSignatureRequest>

The redirection URI gets set to the landing page that the user gets redirected to (this is the same page in case of successful signature as well as in case of a failed signature - for example when the user aborts the process). The data URI is the URI that receives the signature data (asynchronously).

The signature output (in case of successful signature) contains the signed data (see the dsig:Object Id="signed-data-1-1" element), the X509Certificate certificate used to sign the data (this may be used to identify the user later on in an sign on system) as well as some certificate information. The digests of all objects are included too - note that a variety of signature algorithms may be used - at the time of writing SHA256 was the standard algorithm. All hashes as well as the certificate data are base64 encoded. The base64 encoded hashes are raw binary data, encoded certificates are base64 encoded DER encoded X.509 certificates.

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<sl:CreateXMLSignatureResponse xmlns:sl="http://www.buergerkarte.at/namespaces/securitylayer/1.2#">
        <dsig:Signature xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"  Id="signature-1-1">
                <dsig:SignedInfo>
                        <dsig:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
                        <dsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"/>
                        <dsig:Reference Id="reference-1-1" URI="#signed-data-1-1">
                                <dsig:Transforms>
                                        <dsig:Transform Algorithm="http://www.w3.org/2002/06/xmldsig-filter2">
                                                <xpf:XPath xmlns:xpf="http://www.w3.org/2002/06/xmldsig-filter2" Filter="intersect">id('signed-data-1-1')/node()</xpf:XPath>
                                        </dsig:Transform>
                                </dsig:Transforms>
                                <dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                                <dsig:DigestValue>...=</dsig:DigestValue>
                        </dsig:Reference>
                        <dsig:Reference Id="etsi-data-reference-1-1" Type="http://uri.etsi.org/01903#SignedProperties" URI="#etsi-signedproperties-1-1">
                                <dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                                <dsig:DigestValue>I...=</dsig:DigestValue>
                        </dsig:Reference>
                </dsig:SignedInfo>
                <dsig:SignatureValue Id="signaturevalue-1-1">P4NKWG8G7w6fMbDrdH1Kyc9oB0gdT3Iw9XtIeKOKqu+cZqlOIMyc1rJ3GhYz2WCN35mCTKQzObZ+DFcKUH7xPQ==</dsig:SignatureValue>
                <dsig:KeyInfo>
                        <dsig:X509Data>
                                <dsig:X509Certificate>MII....==</dsig:X509Certificate>
                        </dsig:X509Data>
                </dsig:KeyInfo>
                <dsig:Object Id="signed-data-1-1">Sample text</dsig:Object>
                <dsig:Object Id="etsi-signed-1-1">
                        <etsi:QualifyingProperties xmlns:etsi="http://uri.etsi.org/01903/v1.3.2#" Target="#signature-1-1">
                                <etsi:SignedProperties Id="etsi-signedproperties-1-1">
                                        <etsi:SignedSignatureProperties>
                                                <etsi:SigningTime>2019-05-24T23:42:14Z</etsi:SigningTime>
                                                <etsi:SigningCertificate>
                                                        <etsi:Cert>
                                                                <etsi:CertDigest>
                                                                        <dsig:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
                                                                        <dsig:DigestValue>....=</dsig:DigestValue>
                                                                </etsi:CertDigest>
                                                                <etsi:IssuerSerial>
                                                                        <dsig:X509IssuerName>CN=a-sign-Premium-Sig-05,OU=a-sign-Premium-Sig-05,O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,C=AT</dsig:X509IssuerName>
                                                                        <dsig:X509SerialNumber>XXXXXXXXXXXXXX</dsig:X509SerialNumber>
                                                                </etsi:IssuerSerial>
                                                        </etsi:Cert>
                                                </etsi:SigningCertificate>
                                                <etsi:SignaturePolicyIdentifier>
                                                        <etsi:SignaturePolicyImplied/>
                                                </etsi:SignaturePolicyIdentifier>
                                        </etsi:SignedSignatureProperties>
                                        <etsi:SignedDataObjectProperties>
                                                <etsi:DataObjectFormat ObjectReference="#reference-1-1">
                                                        <etsi:MimeType>text/plain</etsi:MimeType>
                                                </etsi:DataObjectFormat>
                                        </etsi:SignedDataObjectProperties>
                                </etsi:SignedProperties>
                        </etsi:QualifyingProperties>
                </dsig:Object>
        </dsig:Signature>
</sl:CreateXMLSignatureResponse>

To display certificate data for debugging purposes one can use the

openssl x509 -noout -text -inform der -in BINARYDATA.DER

command (in the following output the fields CN (Common Name - the full name of the user), SN (Sure name) and GN have been anonymized as wel as the serial number. Note that this would not really have been required since this certificate only contains publically available data.

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: XXXXXXXXXXXXXX (0xXXXXXXXXXXXXXX)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=AT, O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH, OU=a-sign-Premium-Sig-05, CN=a-sign-Premium-Sig-05
        Validity
            Not Before: Jan 11 11:58:14 2017 GMT
            Not After : Jan 11 10:58:14 2022 GMT
        Subject: C=AT, CN=XXXXXXXXXXXXXX, SN=XXXXXXXXXXXXXX, GN=XXXXXXXXXXXXXX/serialNumber=XXXXXXXXXXXXXX
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:6a:c8:33:21:f6:13:67:65:26:42:eb:a4:87:38:
                    ...
                    b7:6d:fa:ec:fc
                ASN1 OID: prime256v1
        X509v3 extensions:
            Authority Information Access:
                CA Issuers - URI:http://www.a-trust.at/certs/a-sign-Premium-Sig-05.crt
                OCSP - URI:http://ocsp.a-trust.at/ocsp

            X509v3 Key Usage: critical
                Digital Signature, Non Repudiation
            qcStatements: critical
                0.0......F..0
..+.......
            X509v3 CRL Distribution Points:

                Full Name:
                  URI:http://crl.a-trust.at/crl/a-sign-premium-sig-05

            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Certificate Policies:
                Policy: 0.4.0.1456.1.1
                Policy: 1.2.40.0.17.1.11
                  CPS: http://www.a-trust.at/docs/cp/a-sign-Premium

            X509v3 Authority Key Identifier:
                keyid:41:F8:08:39:1B:01:E8:24

            X509v3 Subject Key Identifier:
                4D:...:11
    Signature Algorithm: sha256WithRSAEncryption
         84:93:f8:48:08:ad:6d:b4:7e:2c:3d:7b:24:29:b0:e2:37:16:
         ...
         f5:06:d5:48:21:a4:c3:0b

One can use the certificate hash or the certificate itself as an identifier for the user for an authentication system. Note that this certificate of course changes whenever the user exchanges his signature card. One can also just check the subject (which also changes since it includes the serial) if one trust the signature of the issuer.

How to use these operations for authentication of users

The basic idea is simple. One can perform a binding between a user and his certificate by issuing a simple signature request against some arbitrary random (guaranteed to be used only once) bunch of data. The response contains a signature as well as the certificate data one can store the certificate data or it’s hash inside an database or directory and link it to the internal user id. The signature has to be verified to prevent spoofed requests. Note that this is not easily preventable during the first registration - one can protect the user against that attacks by attaching an nonce to the data URI that can only be used for a really short time interval for exactly one operation - of by displaying the Subject contained inside the request. This of course does not protect against malware on the users computer during the registration process that might intercept the request and insert it’s own certificate.

After registration a user can log in by simply signing a random only-used-once nonce again. The certificate received with the signature request can be used to identify the user, the signature has to be verified to check that the request really originated from the user and is not replayed from a previous time. One should also include additional information from the session to prevent replaying or intercepting the requests.

This article is tagged: Internet, Security, Web


Dipl.-Ing. Thomas Spielauer, Wien (webcomplains389t48957@tspi.at)

This webpage is also available via TOR at http://jugujbrirx3irwyx.onion/

Valid HTML 4.01 Strict Powered by FreeBSD IPv6 support