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
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
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.
Requests are sent as
POST requests either via form submission or using an
After a user has issued an request the browser gets issued an redirect to an additionally supplied
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:
InfoboxReadRequest). This is an request that is restricted to certain government agencies and certified applications. For companies there is an additional method of requesting less information by providing the governmental issued companies register identifier.
Certificatesstore. This of course only reads public keys, private keys are as usual never exposed by the smartcard (this is of course not enforced by the application but by the smartcard)
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).
The following operations are the operations that are interesting to authenticating users
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
endpoint. This operation requires at least one parameter but is normally called with 3 parameters:
XMLRequestis the required request that gets parsed by the security layer. It’s described below
DataURLcontains an URI to which the application should send the application - application request (not using the users browser). These requests are always
RedirectURLis the URL the user gets redirected via a HTTP 302 response. This happens immediately - i.e. it has no direct timed relation to the data URL request.
The XML request is an XML document containing just the
<?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:
ResponseTypejust contains the string
XMLResponsecontains an XML document describing the response:
<?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 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
endpoint. The same three parameters (
RedirectURL) as before are used.
The most basic XML request to sign
text/plain data object contains an
SecureSignatureKeypair keypair and supplying the data inside an
DataObjectInfo as the
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),
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: 220.127.116.11.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.
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.