Skip to content

Commit 926b2c8

Browse files
Guido Gröönmrts
authored andcommitted
Removed log location configuration
Updated readme Correct .htaccess file to examples Added CSRF validation to example Format code
1 parent 0e249c9 commit 926b2c8

File tree

92 files changed

+582
-494
lines changed

Some content is hidden

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

92 files changed

+582
-494
lines changed

README.md

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,14 @@ Add the following lines to `composer.json` to include the Web eID authentication
3535

3636
### Configure the log file location
3737

38-
Define the constant `LOGFILE` for log file location.
38+
By default, log entries are written to the server log. If there is a need to collect log entries in a separate file, define the constant `LOGFILE` for the log file location.
3939

40+
Example:
4041
```php
4142
define("LOGFILE", dirname(__FILE__) . "/../log/web-eid-authtoken-validation-php.log");
4243
```
4344

44-
In case, when you don't want to collect log at all, define this constant like so:
45-
46-
```php
47-
define("LOGFILE", false);
48-
```
45+
It is essential, that your log file directory has write access.
4946

5047
## 2. Configure the challenge nonce store
5148

@@ -231,44 +228,6 @@ The Web eID authentication token validation library for PHP contains the impleme
231228

232229
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).
233230

234-
# Authentication token format
235-
236-
In the following,
237-
238-
- **origin** is defined as the website origin, the URL serving the web application,
239-
- **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.
240-
241-
The Web eID authentication token is a JSON data structure that looks like the following example:
242-
243-
```json
244-
{
245-
"unverifiedCertificate": "MIIFozCCA4ugAwIBAgIQHFpdK-zCQsFW4...",
246-
"algorithm": "RS256",
247-
"signature": "HBjNXIaUskXbfhzYQHvwjKDUWfNu4yxXZha...",
248-
"format": "web-eid:1.0",
249-
"appVersion": "https://web-eid.eu/web-eid-app/releases/v2.0.0"
250-
}
251-
```
252-
253-
It contains the following fields:
254-
255-
- `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,
256-
257-
- `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:
258-
259-
```
260-
"ES256", "ES384", "ES512", // ECDSA
261-
"PS256", "PS384", "PS512", // RSASSA-PSS
262-
"RS256", "RS384", "RS512" // RSASSA-PKCS1-v1_5
263-
```
264-
265-
- `signature`: the base64-encoded signature of the token (see the description below),
266-
267-
- `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,
268-
269-
- `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.
270-
271-
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.
272231

273232
# Authentication token validation
274233

composer.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
"psr-4": {
1717
"web_eid\\web_eid_authtoken_validation_php\\": ["src"]
1818
},
19-
"files": [
20-
"config/configuration.php"
21-
],
2219
"classmap": [
2320
"src/util/CollectionsUtil.php"
2421
]

config/configuration.php

Lines changed: 0 additions & 6 deletions
This file was deleted.

examples/public/.htaccess

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
RewriteEngine on
22
RewriteCond %{REQUEST_FILENAME} !-f
3-
RewriteCond %{REQUEST_FILENAME}/ !-f
3+
RewriteCond %{REQUEST_FILENAME} !.(ico,css,js,jpg,gif,png)$
4+
RewriteCond %{REQUEST_FILENAME} !-d
45
RewriteRule . index.php [L]

examples/public/index.php

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,35 @@
11
<?php
22

3+
/*
4+
* Copyright (c) 2020-2021 Estonian Information System Authority
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
325
header('Content-type: text/html; charset=UTF-8');
426

527
session_start();
628

7-
// Define the log location
8-
define("LOGFILE", dirname(__FILE__) . "/../log/web-eid-authtoken-validation-php.log");
29+
// Uncomment following line to define the custom log location (by default the server log is used)
30+
//define("LOGFILE", dirname(__FILE__) . "/../log/web-eid-authtoken-validation-php.log");
931

1032
require __DIR__ . '/../vendor/autoload.php';
1133

1234
$router = new Router();
13-
$router->init();
35+
$router->init();

examples/src/Auth.php

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
11
<?php
22

3+
/*
4+
* Copyright (c) 2020-2021 Estonian Information System Authority
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
325
use web_eid\web_eid_authtoken_validation_php\authtoken\WebEidAuthToken;
426
use web_eid\web_eid_authtoken_validation_php\certificate\CertificateData;
527
use web_eid\web_eid_authtoken_validation_php\certificate\CertificateLoader;
@@ -17,7 +39,8 @@ class Auth
1739
public function trustedIntermediateCACertificates(): array
1840
{
1941
return CertificateLoader::loadCertificatesFromResources(
20-
__DIR__ . "/../certificates/esteid2018.der.crt", __DIR__ . "/../certificates/ESTEID-SK_2015.der.crt"
42+
__DIR__ . "/../certificates/esteid2018.der.crt",
43+
__DIR__ . "/../certificates/ESTEID-SK_2015.der.crt"
2144
);
2245
}
2346

@@ -40,29 +63,35 @@ public function tokenValidator(): AuthTokenValidator
4063
* Get challenge nonce
4164
*
4265
* @return string
43-
*/
66+
*/
4467
public function getNonce()
4568
{
4669
try {
4770
header('Content-Type: application/json; charset=utf-8');
48-
$generator = $this->generator();
49-
$challengeNonce = $generator->generateAndStoreNonce();
71+
$challengeNonce = $this->generator()->generateAndStoreNonce();
5072
$responseArr = [];
51-
$responseArr["nonce"] = $challengeNonce->getBase64EncodedNonce();
73+
$responseArr = ["nonce" => $challengeNonce->getBase64EncodedNonce()];
5274
echo json_encode($responseArr);
5375
} catch (Exception $e) {
5476
header("HTTP/1.0 400 Bad Request");
55-
echo $e->getMessage();
77+
echo "Nonce generation failed";
5678
}
5779
}
5880

5981
/**
6082
* Authenticate
6183
*
6284
* @return string
63-
*/
85+
*/
6486
public function validate()
6587
{
88+
$headers = getallheaders();
89+
if (!isset($headers["X-CSRF-TOKEN"]) || ($headers["X-CSRF-TOKEN"] != $_SESSION["csrf-token"])) {
90+
header("HTTP/1.0 405 Method Not Allowed");
91+
echo "Unable to process your request";
92+
return;
93+
}
94+
6695
$authToken = file_get_contents('php://input');
6796

6897
try {
@@ -72,11 +101,8 @@ public function validate()
72101

73102
try {
74103

75-
// Build token validator
76-
$tokenValidator = $this->tokenValidator();
77-
78104
// Validate token
79-
$cert = $tokenValidator->validate(new WebEidAuthToken($authToken), $challengeNonce->getBase64EncodedNonce());
105+
$cert = $this->tokenValidator()->validate(new WebEidAuthToken($authToken), $challengeNonce->getBase64EncodedNonce());
80106

81107
session_regenerate_id();
82108

@@ -88,15 +114,13 @@ public function validate()
88114
$_SESSION["auth-user"] = $subjectName;
89115

90116
echo json_encode($result);
91-
92117
} catch (Exception $e) {
93118
header("HTTP/1.0 400 Bad Request");
94-
echo $e->getMessage();
119+
echo "Validation failed";
95120
}
96-
97121
} catch (ChallengeNonceExpiredException $e) {
98122
header("HTTP/1.0 400 Bad Request");
99-
echo $e->getMessage();
123+
echo "Challenge nonce not found or expired";
100124
}
101125
}
102126

@@ -111,5 +135,4 @@ public function logout()
111135
// Redirect to login
112136
header("location:/");
113137
}
114-
115-
}
138+
}

examples/src/Pages.php

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,27 @@
11
<?php
22

3+
/*
4+
* Copyright (c) 2020-2021 Estonian Information System Authority
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
325
class Pages
426
{
527
var $template;
@@ -10,21 +32,32 @@ public function __construct()
1032
$this->template = new Template();
1133
}
1234

35+
private function _generateToken()
36+
{
37+
// Store token to session
38+
$_SESSION["csrf-token"] = bin2hex(random_bytes(32));
39+
return $_SESSION["csrf-token"];
40+
}
41+
1342
public function login()
1443
{
15-
$this->data['content'] = $this->template->getHtml(__DIR__ . '/../tpl/login.phtml');
44+
$this->data = [
45+
"content" => $this->template->getHtml(__DIR__ . '/../tpl/login.phtml')
46+
];
1647
}
1748

1849
public function welcome()
1950
{
2051
$data = [];
21-
$data["auth_user"] = $_SESSION["auth-user"];
22-
$this->data['content'] = $this->template->getHtml(__DIR__ . '/../tpl/welcome.phtml', $data);
52+
$data = ["auth_user" => $_SESSION["auth-user"]];
53+
$this->data = [
54+
"content" => $this->template->getHtml(__DIR__ . '/../tpl/welcome.phtml', $data)
55+
];
2356
}
2457

2558
public function __destruct()
2659
{
60+
$this->data["token"] = $this->_generateToken();;
2761
echo $this->template->getHtml(__DIR__ . '/../tpl/site.phtml', $this->data);
2862
}
29-
30-
}
63+
}

examples/src/Router.php

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,27 @@
11
<?php
2+
3+
/*
4+
* Copyright (c) 2020-2021 Estonian Information System Authority
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
225
/* App router */
326

427
class Router
@@ -10,19 +33,19 @@ public function init()
1033
$router->setBasePath('');
1134

1235
// Page routes
13-
$router->map('GET', '', ['controller' => 'Pages', 'method' => 'login']);
36+
//$router->map('GET', '', ['controller' => 'Pages', 'method' => 'login']);
1437
$router->map('GET', '/', ['controller' => 'Pages', 'method' => 'login']);
1538
$router->map('GET', '/logout', ['controller' => 'Auth', 'method' => 'logout']);
1639

40+
// Web eID routes
41+
$router->map('GET', '/nonce', ['controller' => 'Auth', 'method' => 'getNonce']);
42+
$router->map('POST', '/validate', ['controller' => 'Auth', 'method' => 'validate']);
43+
1744
// Allow route only for authenticated users
1845
if (isset($_SESSION["auth-user"])) {
1946
$router->map('GET', '/welcome', ['controller' => 'Pages', 'method' => 'welcome']);
2047
}
2148

22-
// Web eID routes
23-
$router->map('GET', '/nonce', ['controller' => 'Auth', 'method' => 'getNonce']);
24-
$router->map('POST', '/validate', ['controller' => 'Auth', 'method' => 'validate']);
25-
2649
$match = $router->match();
2750

2851
if (!$match) {
@@ -35,7 +58,6 @@ public function init()
3558
$controller = new $match['target']['controller'];
3659
$method = $match['target']['method'];
3760

38-
call_user_func([$controller, $method], $match['params'], []);
39-
61+
call_user_func([$controller, $method], $match['params'], []);
4062
}
41-
}
63+
}

examples/src/Template.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,5 @@ public function getHtml($template, $data = [])
1515
return $contents;
1616
}
1717
throw new Exception("Could not load template file " . $template);
18-
1918
}
20-
21-
}
19+
}

0 commit comments

Comments
 (0)