Skip to content

Commit 457a0ba

Browse files
Guido Gröönmrts
authored andcommitted
WE2-729 Updated readme
WE2-729 Added copyright information to some functions Code unification
1 parent 502df76 commit 457a0ba

14 files changed

+80
-25
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
web-eid-authtoken-validation-php is 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.
66

7+
The logic of this repository is based on the [Java library](https://github.com/web-eid/web-eid-authtoken-validation-java). We also draw inspiration from the [PHP library](https://github.com/Muzosh/web-eid-authtoken-validation-php) created by Petr Muzikant and used some of his code.
8+
79
More information about the Web eID project is available on the project [website](https://web-eid.eu/).
810

911
# Quickstart

src/certificate/CertificateValidator.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ public function __construct()
4242
throw new BadFunctionCallException("Utility class");
4343
}
4444

45+
/**
46+
* @copyright 2022 Petr Muzikant [email protected]
47+
*/
4548
public static function certificateIsValidOnDate(X509 $subjectCertificate, DateTime $date, string $subject): void
4649
{
4750
if (!$subjectCertificate->validateDate($date)) {
@@ -63,6 +66,9 @@ public static function trustedCACertificatesAreValidOnDate(TrustedCertificates $
6366
}
6467
}
6568

69+
/**
70+
* @copyright 2022 Petr Muzikant [email protected]
71+
*/
6672
public static function validateIsSignedByTrustedCA(X509 $certificate, TrustedCertificates $trustedCertificates): X509
6773
{
6874
foreach ($trustedCertificates->getCertificates() as $trustedCertificate) {

src/challenge/ChallengeNonceGeneratorBuilder.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ class ChallengeNonceGeneratorBuilder
4444
*/
4545
private $secureRandom;
4646

47+
/**
48+
* @copyright 2022 Petr Muzikant [email protected]
49+
*/
4750
public function __construct()
4851
{
4952
// 5 minutes
@@ -57,6 +60,8 @@ public function __construct()
5760
* Override default nonce time-to-live duration.
5861
* <p>
5962
* When the time-to-live passes, the nonce is considered to be expired.
63+
*
64+
* @copyright 2022 Petr Muzikant [email protected]
6065
*
6166
* @param int $seconds - challenge nonce time-to-live duration in seconds
6267
* @return ChallengeNonceGeneratorBuilder builder instance
@@ -92,6 +97,11 @@ public function withSecureRandom(callable $secureRandom): ChallengeNonceGenerato
9297
return $this;
9398
}
9499

100+
/**
101+
* Validates the configuration and builds the {@link ChallengeNonceGenerator} instance.
102+
*
103+
* @return new challenge nonce generator instance
104+
*/
95105
public function build(): ChallengeNonceGenerator
96106
{
97107
// Force to use PHP session based nounce store when store is not set
@@ -102,7 +112,7 @@ public function build(): ChallengeNonceGenerator
102112
return new ChallengeNonceGeneratorImpl($this->challengeNonceStore, $this->secureRandom, $this->ttl);
103113
}
104114

105-
private function validateParameters(): void
115+
private function validateParameters(): void
106116
{
107117
if (is_null($this->challengeNonceStore)) {
108118
throw new InvalidArgumentException("Challenge nonce store must not be null");

src/challenge/ChallengeNonceGeneratorImpl.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,19 @@ final class ChallengeNonceGeneratorImpl implements ChallengeNonceGenerator
3030
{
3131
private ChallengeNonceStore $challengeNonceStore;
3232
private $secureRandom;
33-
private int $ttlSeconds;
33+
private int $ttl;
3434

35-
public function __construct(ChallengeNonceStore $challengeNonceStore, callable $secureRandom, int $ttlSeconds)
35+
public function __construct(ChallengeNonceStore $challengeNonceStore, callable $secureRandom, int $ttl)
3636
{
3737
$this->challengeNonceStore = $challengeNonceStore;
3838
$this->secureRandom = $secureRandom;
39-
$this->ttlSeconds = $ttlSeconds;
39+
$this->ttl = $ttl;
4040
}
4141

4242
public function generateAndStoreNonce(): ChallengeNonce
4343
{
4444
$nonceString = call_user_func($this->secureRandom, self::NONCE_LENGTH);
45-
$expirationTime = DateAndTime::utcNow()->modify("+{$this->ttlSeconds} seconds");
45+
$expirationTime = DateAndTime::utcNow()->modify("+{$this->ttl} seconds");
4646
$base64Nonce = base64_encode($nonceString);
4747
$challengeNonce = new ChallengeNonce($base64Nonce, $expirationTime);
4848
$this->challengeNonceStore->put($challengeNonce);

src/util/CollectionsUtil.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
use TypeError;
1313
use web_eid\web_eid_authtoken_validation_php\validator\certvalidators\SubjectCertificateValidator;
1414

15+
/**
16+
* @copyright 2022 Petr Muzikant [email protected]
17+
*/
1518
abstract class Collection implements Countable, IteratorAggregate, ArrayAccess
1619
{
1720
protected array $array;

src/util/DateAndTime.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ public static function requirePositiveDuration(int $duration, string $fieldName)
6767
}
6868
}
6969

70+
/**
71+
* @copyright 2022 Petr Muzikant [email protected]
72+
*/
7073
public static function toUtcString(?DateTime $date): string
7174
{
7275
if (is_null($date)) {
@@ -76,9 +79,13 @@ public static function toUtcString(?DateTime $date): string
7679
}
7780
}
7881

82+
/**
83+
* @copyright 2022 Petr Muzikant [email protected]
84+
*/
7985
final class DefaultClock
8086
{
8187
private static DefaultClock $instance;
88+
private DateTime $mockedClock;
8289

8390
public static function getInstance()
8491
{

src/validator/AuthTokenValidationConfiguration.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ final class AuthTokenValidationConfiguration
4545
private UriCollection $nonceDisabledOcspUrls;
4646
private ?DesignatedOcspServiceConfiguration $designatedOcspServiceConfiguration = null;
4747

48+
/**
49+
* @copyright 2022 Petr Muzikant [email protected]
50+
*/
4851
public function __construct()
4952
{
5053
// Don't allow Estonian Mobile-ID policy by default.
@@ -120,13 +123,13 @@ public function getNonceDisabledOcspUrls(): UriCollection
120123
public function validate(): void
121124
{
122125
if (is_null($this->siteOrigin)) {
123-
throw new InvalidArgumentException('Origin URI must not be null');
126+
throw new InvalidArgumentException("Origin URI must not be null");
124127
}
125128

126129
self::validateIsOriginURL($this->siteOrigin);
127130

128131
if (count($this->trustedCACertificates) == 0) {
129-
throw new InvalidArgumentException('At least one trusted certificate authority must be provided');
132+
throw new InvalidArgumentException("At least one trusted certificate authority must be provided");
130133
}
131134

132135
DateAndTime::requirePositiveDuration($this->ocspRequestTimeout, "OCSP request timeout");
@@ -143,7 +146,7 @@ public function validateIsOriginURL(Uri $uri): void
143146
{
144147
// 1. Verify that the URI can be converted to absolute URL.
145148
if (!$uri->isAbsolute()) {
146-
throw new InvalidArgumentException('Provided URI is not a valid URL');
149+
throw new InvalidArgumentException("Provided URI is not a valid URL");
147150
}
148151

149152
$reference = $uri->createFromArray([
@@ -154,7 +157,7 @@ public function validateIsOriginURL(Uri $uri): void
154157

155158
// 2. Verify that the URI contains only HTTPS scheme, host and optional port components.
156159
if ($uri->getUrl() !== $reference->getUrl()) {
157-
throw new InvalidArgumentException('Origin URI must only contain the HTTPS scheme, host and optional port component');
160+
throw new InvalidArgumentException("Origin URI must only contain the HTTPS scheme, host and optional port component");
158161
}
159162
}
160163
}

src/validator/AuthTokenValidatorBuilder.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ public function withSiteOrigin(Uri $origin): AuthTokenValidatorBuilder
6767
* <p>
6868
* At least one trusted intermediate Certificate Authority must be provided as a mandatory configuration parameter.
6969
*
70+
* @copyright 2022 Petr Muzikant [email protected]
71+
*
7072
* @param X509 $certificates trusted intermediate Certificate Authority certificates
7173
* @return the builder instance for method chaining
7274
*/
@@ -83,6 +85,8 @@ public function withTrustedCertificateAuthorities(X509 ...$certificates): AuthTo
8385
* Adds the given policies to the list of disallowed user certificate policies.
8486
* In order for the user certificate to be considered valid, it must not contain any policies
8587
* present in this list.
88+
*
89+
* @copyright 2022 Petr Muzikant [email protected]
8690
*
8791
* @param string $policies disallowed user certificate policies as string array
8892
* @return the builder instance for method chaining
@@ -133,6 +137,8 @@ public function withOcspRequestTimeout(int $ocspRequestTimeout): AuthTokenValida
133137
* Adds the given URLs to the list of OCSP URLs for which the nonce protocol extension will be disabled.
134138
* The OCSP URL is extracted from the user certificate and some OCSP services don't support the nonce extension.
135139
*
140+
* @copyright 2022 Petr Muzikant [email protected]
141+
*
136142
* @param URI $urls OCSP URLs for which the nonce protocol extension will be disabled
137143
* @return the builder instance for method chaining
138144
*/

src/validator/AuthTokenValidatorImpl.php

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
use web_eid\web_eid_authtoken_validation_php\validator\ocsp\OcspClientImpl;
4545
use web_eid\web_eid_authtoken_validation_php\validator\ocsp\OcspServiceProvider;
4646
use web_eid\web_eid_authtoken_validation_php\validator\ocsp\service\AiaOcspServiceConfiguration;
47+
use web_eid\web_eid_authtoken_validation_php\util\TrustedCertificates;
4748

4849
final class AuthTokenValidatorImpl implements AuthTokenValidator
4950
{
@@ -54,11 +55,15 @@ final class AuthTokenValidatorImpl implements AuthTokenValidator
5455
private AuthTokenValidationConfiguration $configuration;
5556
private SubjectCertificateValidatorBatch $simpleSubjectCertificateValidators;
5657
private AuthTokenSignatureValidator $authTokenSignatureValidator;
58+
private TrustedCertificates $trustedCACertificates;
5759
private Log $logger;
5860

5961
private OcspClient $ocspClient;
6062
private OcspServiceProvider $ocspServiceProvider;
6163

64+
/**
65+
* @copyright 2022 Petr Muzikant [email protected]
66+
*/
6267
public function __construct(AuthTokenValidationConfiguration $configuration)
6368
{
6469
$this->logger = Log::getLogger(self::class);
@@ -67,9 +72,10 @@ public function __construct(AuthTokenValidationConfiguration $configuration)
6772
$this->configuration = clone $configuration;
6873

6974
// Create and cache trusted CA certificate JCA objects for SubjectCertificateTrustedValidator and AiaOcspService.
70-
$this->trustedCertificates = CertificateValidator::buildTrustFromCertificates($configuration->getTrustedCACertificates());
75+
$this->trustedCACertificates = CertificateValidator::buildTrustFromCertificates($configuration->getTrustedCACertificates());
76+
7177
$this->simpleSubjectCertificateValidators = new SubjectCertificateValidatorBatch(
72-
new SubjectCertificateExpiryValidator($this->trustedCertificates),
78+
new SubjectCertificateExpiryValidator($this->trustedCACertificates),
7379
new SubjectCertificatePurposeValidator(),
7480
new SubjectCertificatePolicyValidator($configuration->getDisallowedSubjectCertificatePolicies())
7581
);
@@ -80,7 +86,7 @@ public function __construct(AuthTokenValidationConfiguration $configuration)
8086
$configuration->getDesignatedOcspServiceConfiguration(),
8187
new AiaOcspServiceConfiguration(
8288
$configuration->getNonceDisabledOcspUrls(),
83-
$this->trustedCertificates
89+
$this->trustedCACertificates
8490
)
8591
);
8692
}
@@ -91,10 +97,10 @@ public function __construct(AuthTokenValidationConfiguration $configuration)
9197
private function validateTokenLength(string $authToken): void
9298
{
9399
if (is_null($authToken) || strlen($authToken) < self::TOKEN_MIN_LENGTH) {
94-
throw new AuthTokenParseException('Auth token is null or too short');
100+
throw new AuthTokenParseException("Auth token is null or too short");
95101
}
96102
if (strlen($authToken) > self::TOKEN_MAX_LENGTH) {
97-
throw new AuthTokenParseException('Auth token is too long');
103+
throw new AuthTokenParseException("Auth token is too long");
98104
}
99105
}
100106

@@ -136,16 +142,16 @@ public function validate(WebEidAuthToken $authToken, string $currentChallengeNon
136142
}
137143
}
138144

139-
private function validateToken(WebEidAuthToken $authToken, string $currentChallengeNonce): X509
145+
private function validateToken(WebEidAuthToken $token, string $currentChallengeNonce): X509
140146
{
141-
if (is_null($authToken->getFormat()) || substr($authToken->getFormat(), 0, strlen(self::CURRENT_TOKEN_FORMAT_VERSION)) != self::CURRENT_TOKEN_FORMAT_VERSION) {
147+
if (is_null($token->getFormat()) || substr($token->getFormat(), 0, strlen(self::CURRENT_TOKEN_FORMAT_VERSION)) != self::CURRENT_TOKEN_FORMAT_VERSION) {
142148
throw new AuthTokenParseException("Only token format version '" . self::CURRENT_TOKEN_FORMAT_VERSION . "' is currently supported");
143149
}
144-
if (is_null($authToken->getUnverifiedCertificate()) || empty($authToken->getUnverifiedCertificate())) {
150+
if (is_null($token->getUnverifiedCertificate()) || empty($token->getUnverifiedCertificate())) {
145151
throw new AuthTokenParseException("'unverifiedCertificate' field is missing, null or empty");
146152
}
147153
$subjectCertificate = new X509();
148-
if (!$subjectCertificate->loadX509($authToken->getUnverifiedCertificate())) {
154+
if (!$subjectCertificate->loadX509($token->getUnverifiedCertificate())) {
149155
throw new CertificateDecodingException("'unverifiedCertificate' decode failed");
150156
}
151157

@@ -156,8 +162,8 @@ private function validateToken(WebEidAuthToken $authToken, string $currentChalle
156162
// have been implicitly and correctly verified without the need to implement any additional checks.
157163

158164
$this->authTokenSignatureValidator->validate(
159-
$authToken->getAlgorithm(),
160-
$authToken->getSignature(),
165+
$token->getAlgorithm(),
166+
$token->getSignature(),
161167
$subjectCertificate->getPublicKey(),
162168
$currentChallengeNonce
163169
);
@@ -168,7 +174,7 @@ private function validateToken(WebEidAuthToken $authToken, string $currentChalle
168174
private function getCertTrustValidators(): SubjectCertificateValidatorBatch
169175
{
170176

171-
$certTrustedValidator = new SubjectCertificateTrustedValidator($this->trustedCertificates);
177+
$certTrustedValidator = new SubjectCertificateTrustedValidator($this->trustedCACertificates);
172178

173179
$validatorBatch = new SubjectCertificateValidatorBatch(
174180
$certTrustedValidator

src/validator/certvalidators/SubjectCertificatePurposeValidator.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public function __construct()
4444
/**
4545
* Validates that the purpose of the user certificate from the authentication token contains client authentication.
4646
*
47+
* @copyright 2022 Petr Muzikant [email protected]
48+
*
4749
* @param subjectCertificate user certificate to be validated
4850
* @throws UserCertificateMissingPurposeException
4951
*/

0 commit comments

Comments
 (0)