Skip to content

Commit ecb24dd

Browse files
Guido Gröönmrts
authored andcommitted
WE2-680 Added session based caching
WE2-683 Added nonce generation and saving to cache WE2-684 Added AuthTokenValidator (builder, implementation, batch) WE2-685 Added simple subject certificate validators WE2-686 Added token body validators WE2-688 Implement certificate utility classes WE2-689 Updated README WE2-687 Added initial certificate trust validators and initial OCSP request Added phpseclib3/X509 class as certificate parser Added logging util Added util class Collection for objects array
1 parent e103fd4 commit ecb24dd

File tree

80 files changed

+4087
-331
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+4087
-331
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
vendor
22
composer.lock
33
.DS_Store
4-
.phpunit.result.cache
4+
.phpunit.result.cache
5+
web-eid-authtoken-validation-php.log

README.md

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,103 @@
11
# web-eid-authtoken-validation-php
2-
Web eID authentication token validation library for PHP
2+
3+
![European Regional Development Fund](https://github.com/open-eid/DigiDoc4-Client/blob/master/client/images/EL_Regionaalarengu_Fond.png)
4+
5+
Web eID authentication token validation library a PHP library for issuing challenge nonces and validating Web eID authentication tokens during secure authentication with electronic ID (eID) smart cards in web applications.
6+
7+
More information about the Web eID project is available on the project [website](https://web-eid.eu/).
8+
9+
# Quickstart
10+
11+
Complete the steps below to add support for secure authentication with eID cards to your PHP web application back end. Instructions for the front end are available [here](https://github.com/web-eid/web-eid.js).
12+
13+
A PHP web application that uses Composer to manage packages is needed for running this quickstart.
14+
15+
## 1. Add the library to your project
16+
17+
Add the following lines to `composer.json` to include the Web eID authentication token validation library in your project:
18+
19+
```json
20+
```
21+
22+
## 2. Configure the challenge nonce store
23+
24+
## 3. Add trusted certificate authority certificates
25+
26+
## 4. Configure the authentication token validator
27+
28+
## 5. Add a REST endpoint for issuing challenge nonces
29+
30+
## 6. Implement authentication
31+
32+
# Table of contents
33+
34+
- [Quickstart](#quickstart)
35+
36+
# Introduction
37+
38+
The Web eID authentication token validation library for PHP contains the implementation of the Web eID authentication token validation process in its entirety to ensure that the authentication token sent by the Web eID browser extension contains valid, consistent data that has not been modified by a third party. It also implements secure challenge nonce generation as required by the Web eID authentication protocol. It is easy to configure and integrate into your authentication service.
39+
40+
The authentication protocol, authentication token format, validation requirements and challenge nonce usage is described in more detail in the [Web eID system architecture document](https://github.com/web-eid/web-eid-system-architecture-doc#authentication-1).
41+
42+
# Authentication token format
43+
44+
In the following,
45+
46+
- **origin** is defined as the website origin, the URL serving the web application,
47+
- **challenge nonce** (or challenge) is defined as a cryptographic nonce, a large random number that can be used only once, with at least 256 bits of entropy.
48+
49+
The Web eID authentication token is a JSON data structure that looks like the following example:
50+
51+
```json
52+
{
53+
"unverifiedCertificate": "MIIFozCCA4ugAwIBAgIQHFpdK-zCQsFW4...",
54+
"algorithm": "RS256",
55+
"signature": "HBjNXIaUskXbfhzYQHvwjKDUWfNu4yxXZha...",
56+
"format": "web-eid:1.0",
57+
"appVersion": "https://web-eid.eu/web-eid-app/releases/v2.0.0"
58+
}
59+
```
60+
61+
It contains the following fields:
62+
63+
- `unverifiedCertificate`: the base64-encoded DER-encoded authentication certificate of the eID user; the public key contained in this certificate should be used to verify the signature; the certificate cannot be trusted as it is received from client side and the client can submit a malicious certificate; to establish trust, it must be verified that the certificate is signed by a trusted certificate authority,
64+
65+
- `algorithm`: the signature algorithm used to produce the signature; the allowed values are the algorithms specified in [JWA RFC](https://www.ietf.org/rfc/rfc7518.html) sections 3.3, 3.4 and 3.5:
66+
67+
```
68+
"ES256", "ES384", "ES512", // ECDSA
69+
"PS256", "PS384", "PS512", // RSASSA-PSS
70+
"RS256", "RS384", "RS512" // RSASSA-PKCS1-v1_5
71+
```
72+
73+
- `signature`: the base64-encoded signature of the token (see the description below),
74+
75+
- `format`: the type identifier and version of the token format separated by a colon character '`:`', `web-eid:1.0` as of now; the version number consists of the major and minor number separated by a dot, major version changes are incompatible with previous versions, minor version changes are backwards-compatible within the given major version,
76+
77+
- `appVersion`: the URL identifying the name and version of the application that issued the token; informative purpose, can be used to identify the affected application in case of faulty tokens.
78+
79+
The value that is signed by the user’s authentication private key and included in the `signature` field is `hash(origin)+hash(challenge)`. The hash function is used before concatenation to ensure field separation as the hash of a value is guaranteed to have a fixed length. Otherwise the origin `example.com` with challenge nonce `.eu1234` and another origin `example.com.eu` with challenge nonce `1234` would result in the same value after concatenation. The hash function `hash` is the same hash function that is used in the signature algorithm, for example SHA256 in case of RS256.
80+
81+
# Authentication token validation
82+
83+
The authentication token validation process consists of two stages:
84+
85+
- First, **user certificate validation**: the validator parses the token and extracts the user certificate from the *unverifiedCertificate* field. Then it checks the certificate expiration, purpose and policies. Next it checks that the certificate is signed by a trusted CA and checks the certificate status with OCSP.
86+
- Second, **token signature validation**: the validator validates that the token signature was created using the provided user certificate by reconstructing the signed data `hash(origin)+hash(challenge)` and using the public key from the certificate to verify the signature in the `signature` field. If the signature verification succeeds, then the origin and challenge nonce have been implicitly and correctly verified without the need to implement any additional security checks.
87+
88+
The website back end must lookup the challenge nonce from its local store using an identifier specific to the browser session, to guarantee that the authentication token was received from the same browser to which the corresponding challenge nonce was issued. The website back end must guarantee that the challenge nonce lifetime is limited and that its expiration is checked, and that it can be used only once by removing it from the store during validation.
89+
90+
## Basic usage
91+
92+
## Extended configuration
93+
94+
## Certificates' Authority Information Access (AIA) extension
95+
96+
## Possible validation errors
97+
98+
# Challenge nonce generation
99+
100+
## Basic usage
101+
102+
103+

composer.json

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,27 @@
99
"role" : "developer"
1010
}
1111
],
12-
"require": {
13-
"mlocati/ocsp": "1.0.2"
14-
},
1512
"require-dev": {
1613
"phpunit/phpunit": "^9.5"
1714
},
1815
"autoload": {
1916
"psr-4": {
2017
"web_eid\\web_eid_authtoken_validation_php\\": ["src"]
21-
}
18+
},
19+
"files": [
20+
"config/configuration.php"
21+
],
22+
"classmap": [
23+
"src/util/CollectionsUtil.php"
24+
]
2225
},
2326
"autoload-dev": {
2427
"psr-4": {
2528
"web_eid\\web_eid_authtoken_validation_php\\": ["tests"]
2629
}
27-
}
28-
29-
}
30+
},
31+
"require": {
32+
"lyquidity/requester": "^1.0",
33+
"phpseclib/phpseclib": "3.0.14"
34+
}
35+
}

examples/index.html

Whitespace-only changes.

examples/index.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
// Coming
3+
?>

examples/js/errors.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2020 The Web eID Project
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
23+
"use strict";
24+
25+
const alertUi = {
26+
alert: document.querySelector("#error-message"),
27+
alertMessage: document.querySelector("#error-message .message"),
28+
alertDetails: document.querySelector("#error-message .details")
29+
};
30+
31+
export function hideErrorMessage() {
32+
alertUi.alert.style.display = "none";
33+
}
34+
35+
export function showErrorMessage(error) {
36+
const message = "Authentication failed";
37+
const details =
38+
`[Code]\n${error.code}` +
39+
`\n\n[Message]\n${error.message}` +
40+
(error.response ? `\n\n[response]\n${JSON.stringify(error.response, null, " ")}` : "");
41+
42+
alertUi.alertMessage.innerText = message;
43+
alertUi.alertDetails.innerText = details;
44+
alertUi.alert.style.display = "block";
45+
}
46+
47+
export async function checkHttpError(response) {
48+
if (!response.ok) {
49+
let body;
50+
try {
51+
body = await response.text();
52+
} catch (error) {
53+
body = "<<unable to retrieve response body>>";
54+
}
55+
const error = new Error("Server error: " + body);
56+
error.code = response.status;
57+
throw error;
58+
}
59+
}

0 commit comments

Comments
 (0)