diff --git a/src/validator/AuthTokenSignatureValidator.php b/src/validator/AuthTokenSignatureValidator.php index b3fa1ba..0d0b1aa 100644 --- a/src/validator/AuthTokenSignatureValidator.php +++ b/src/validator/AuthTokenSignatureValidator.php @@ -27,6 +27,7 @@ namespace web_eid\web_eid_authtoken_validation_php\validator; use GuzzleHttp\Psr7\Uri; +use phpseclib3\Crypt\RSA; use web_eid\web_eid_authtoken_validation_php\exceptions\AuthTokenParseException; use web_eid\web_eid_authtoken_validation_php\exceptions\ChallengeNullOrEmptyException; use InvalidArgumentException; @@ -36,6 +37,10 @@ class AuthTokenSignatureValidator { + private const ECDSA_ALGORITHMS = ['ES256', 'ES384', 'ES512']; + + private const RSASSA_PSS_ALGORITHMS = ['PS256', 'PS384', 'PS512']; + /** Supported subset of JSON Web Signature algorithms as defined in RFC 7518, sections 3.3, 3.4, 3.5. * See https://github.com/web-eid/libelectronic-id/blob/main/include/electronic-id/enums.hpp#L176. */ @@ -72,10 +77,17 @@ public function validate(string $algorithm, string $signature, $publicKey, strin $decodedSignature = base64_decode($signature); // Note that in case of ECDSA, some eID cards output raw R||S, so we need to trascode it to DER - if (in_array($algorithm, ["ES256", "ES384", "ES512"]) && !AsnUtil::isSignatureInAsn1Format($decodedSignature)) { + if (in_array($algorithm, self::ECDSA_ALGORITHMS) && !AsnUtil::isSignatureInAsn1Format($decodedSignature)) { $decodedSignature = AsnUtil::transcodeSignatureToDER($decodedSignature); } + if (in_array($algorithm, self::RSASSA_PSS_ALGORITHMS)) { + $publicKey = openssl_get_publickey($publicKey->withPadding(RSA::SIGNATURE_PSS)->toString('PSS')); + if (!$publicKey) { + throw new AuthTokenParseException('Could not use PSS padding for RSASSA-PSS algorithm'); + } + } + $hashAlgorithm = $this->hashAlgorithmForName($algorithm); $originHash = openssl_digest($this->siteOrigin->jsonSerialize(), $hashAlgorithm, true); diff --git a/src/validator/certvalidators/SubjectCertificatePurposeValidator.php b/src/validator/certvalidators/SubjectCertificatePurposeValidator.php index 14ce96b..9a94364 100644 --- a/src/validator/certvalidators/SubjectCertificatePurposeValidator.php +++ b/src/validator/certvalidators/SubjectCertificatePurposeValidator.php @@ -32,6 +32,9 @@ final class SubjectCertificatePurposeValidator implements SubjectCertificateValidator { + private const KEY_USAGE = 'id-ce-keyUsage'; + private const KEY_USAGE_DIGITAL_SIGNATURE = 0; + private const EXTENDED_KEY_USAGE = 'id-ce-extKeyUsage'; // oid 1.3.6.1.5.5.7.3.2 private const EXTENDED_KEY_USAGE_CLIENT_AUTHENTICATION = "id-kp-clientAuth"; private $logger; @@ -44,17 +47,28 @@ public function __construct(LoggerInterface $logger = null) /** * Validates that the purpose of the user certificate from the authentication token contains client authentication. * - * @copyright 2022 Petr Muzikant pmuzikant@email.cz - * - * @param subjectCertificate user certificate to be validated + * @param X509 $subjectCertificate user certificate to be validated * @throws UserCertificateMissingPurposeException + * @throws UserCertificateWrongPurposeException + * @copyright 2022 Petr Muzikant pmuzikant@email.cz + * */ public function validate(X509 $subjectCertificate): void { - $usages = $subjectCertificate->getExtension('id-ce-extKeyUsage'); - if (!$usages || empty($usages)) { + $keyUsage = $subjectCertificate->getExtension(self::KEY_USAGE); + if (!$keyUsage || empty($keyUsage)) { throw new UserCertificateMissingPurposeException(); } + if (!$keyUsage[self::KEY_USAGE_DIGITAL_SIGNATURE]) { + throw new UserCertificateWrongPurposeException(); + } + $usages = $subjectCertificate->getExtension(self::EXTENDED_KEY_USAGE); + if (!$usages || empty($usages)) { + // Digital Signature extension present, but Extended Key Usage extension not present, + // assume it is an authentication certificate (e.g. Luxembourg eID). + $this->logger?->debug("User certificate has Digital Signature key usage and no Extended Key Usage extension, this means that it can be used for client authentication."); + return; + } // Extended usages must contain TLS Web Client Authentication if (!in_array(self::EXTENDED_KEY_USAGE_CLIENT_AUTHENTICATION, $usages)) { throw new UserCertificateWrongPurposeException(); @@ -62,4 +76,5 @@ public function validate(X509 $subjectCertificate): void $this->logger?->debug("User certificate can be used for client authentication."); } + } diff --git a/tests/_resources/DVV TEST Certificates - G5E.crt b/tests/_resources/DVV TEST Certificates - G5E.crt new file mode 100644 index 0000000..a01b659 Binary files /dev/null and b/tests/_resources/DVV TEST Certificates - G5E.crt differ diff --git a/tests/_resources/VRK TEST CA for Test Purposes - G4.crt b/tests/_resources/VRK TEST CA for Test Purposes - G4.crt new file mode 100644 index 0000000..3159602 Binary files /dev/null and b/tests/_resources/VRK TEST CA for Test Purposes - G4.crt differ diff --git a/tests/_resources/eID TEST EC Citizen CA.cer b/tests/_resources/eID TEST EC Citizen CA.cer new file mode 100644 index 0000000..06456b7 --- /dev/null +++ b/tests/_resources/eID TEST EC Citizen CA.cer @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDKTCCAq+gAwIBAgIIcND8I1qptLUwCgYIKoZIzj0EAwMwKzELMAkGA1UEBhMC +QkUxHDAaBgNVBAMME2VJRCBURVNUIEVDIFJvb3QgQ0EwIBcNMDcwNDMwMjIwMDIw +WhgPMjA4NzA0MTAyMjAwMjBaMC4xCzAJBgNVBAYTAkJFMR8wHQYDVQQDDBZlSUQg +VEVTVCBFQyBDaXRpemVuIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEJAiNoOQf +Y0r8N6JVPMLedXyRZ7MwppGwQ9ZxFzLjVsbeKuUvqEFR0yKKyEidXc875m4UF5lR +pf/FSWagg2IXGWrypnRZkgnNVP6s5W2LzKdV09hd6v7O8j/8knfHOj+No4IBmTCC +AZUwHQYDVR0OBBYEFN2zf+OaGY5ZyRFWAi31+p1v3oRLMB8GA1UdIwQYMBaAFCHA +clfKHAQEGR3ZjH4+tYPrrBwCMA4GA1UdDwEB/wQEAwIBBjBIBgNVHSAEQTA/MD0G +BmA4DAEBAjAzMDEGCCsGAQUFBwIBFiVodHRwOi8vZWlkZGV2Y2FyZHMuemV0ZXNj +YXJkcy5iZS9jZXJ0MB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDBCBgNV +HR8EOzA5MDegNaAzhjFodHRwOi8vZWlkZGV2Y2FyZHMuemV0ZXNjYXJkcy5iZS9j +cmwvcm9vdGNhRUMuY3JsMIGBBggrBgEFBQcBAQR1MHMwPgYIKwYBBQUHMAKGMmh0 +dHA6Ly9laWRkZXZjYXJkcy56ZXRlc2NhcmRzLmJlL2NlcnQvcm9vdGNhRUMuY3J0 +MDEGCCsGAQUFBzABhiVodHRwOi8vZWlkZGV2Y2FyZHMuemV0ZXNjYXJkcy5iZTo4 +ODg4MBIGA1UdEwEB/wQIMAYBAf8CAQAwCgYIKoZIzj0EAwMDaAAwZQIxAOMiiByF +0aLEA6zUrobMw7aSH5o2u1hGVMe0AL4ezYztRdfxvXVU+m1JosBVBDDjeAIwYJJN +7bLWw8BVi/lkxRjKL/+zAJP6djGywXI1pVh4HKb0D+tipq5StO+QnM8cnPmg +-----END CERTIFICATE----- diff --git a/tests/testutil/AuthTokenValidators.php b/tests/testutil/AuthTokenValidators.php index 1bcd0b2..893ab88 100644 --- a/tests/testutil/AuthTokenValidators.php +++ b/tests/testutil/AuthTokenValidators.php @@ -89,6 +89,27 @@ public static function getAuthTokenValidatorWithDisallowedESTEIDPolicy(): AuthTo ->build(); } + public static function getAuthTokenValidatorForBelgianIdCard(): AuthTokenValidator + { + return self::getAuthTokenValidator( + "https://47f0-46-131-86-189.ngrok-free.app", + ...CertificateLoader::loadCertificatesFromResources( + __DIR__ . "/../_resources/eID TEST EC Citizen CA.cer" + ) + ); + } + + public static function getAuthTokenValidatorForFinnishIdCard(): AuthTokenValidator + { + return self::getAuthTokenValidator( + "https://47f0-46-131-86-189.ngrok-free.app", + ...CertificateLoader::loadCertificatesFromResources( + __DIR__ . "/../_resources/DVV TEST Certificates - G5E.crt", + __DIR__ . "/../_resources/VRK TEST CA for Test Purposes - G4.crt" + ) + ); + } + public static function getAuthTokenValidatorWithWrongTrustedCertificate(): AuthTokenValidator { return self::getAuthTokenValidator( diff --git a/tests/validator/AuthTokenCertificateBelgianIdCardTest.php b/tests/validator/AuthTokenCertificateBelgianIdCardTest.php new file mode 100644 index 0000000..ec00940 --- /dev/null +++ b/tests/validator/AuthTokenCertificateBelgianIdCardTest.php @@ -0,0 +1,102 @@ +mockDate("2024-12-24"); + } + + protected function tearDown(): void + { + Dates::resetMockedCertificateValidatorDate(); + } + + public function testWhenIdCardWithECCSignatureCertificateIsValidatedThenValidationSucceeds(): void + { + $this->expectNotToPerformAssertions(); + $validator = AuthTokenValidators::getAuthTokenValidatorForBelgianIdCard(); + $token = $validator->parse(self::BELGIAN_TEST_ID_CARD_AUTH_TOKEN_ECC); + + $validator->validate($token, 'iMeEwP2cgUINY2XoO/lqEpOUn7z/ysHRqGXkGKC4VXE='); + } + + public function testWhenIdCardWithRSASignatureCertificateIsValidatedThenValidationSucceeds(): void + { + $this->expectNotToPerformAssertions(); + $validator = AuthTokenValidators::getAuthTokenValidatorForBelgianIdCard(); + $token = $validator->parse(self::BELGIAN_TEST_ID_CARD_AUTH_TOKEN_RSA); + + $validator->validate($token, 'YPVgYc7Qds0qmK/RilPLffnsIg7IIovM4BAWqGZWwiY='); + } + + private function mockDate(string $date) + { + Dates::setMockedCertificateValidatorDate(new DateTime($date)); + } + +} diff --git a/tests/validator/AuthTokenCertificateFinnishIdCardTest.php b/tests/validator/AuthTokenCertificateFinnishIdCardTest.php new file mode 100644 index 0000000..8465755 --- /dev/null +++ b/tests/validator/AuthTokenCertificateFinnishIdCardTest.php @@ -0,0 +1,92 @@ +mockDate("2024-12-24"); + } + + protected function tearDown(): void + { + Dates::resetMockedCertificateValidatorDate(); + } + + public function testWhenIdCardSignatureCertificateWithG5ERootCertificateIsValidatedThenValidationSucceeds(): void + { + $this->expectNotToPerformAssertions(); + $validator = AuthTokenValidators::getAuthTokenValidatorForFinnishIdCard(); + $token = $validator->parse(self::FINNISH_TEST_ID_CARD_BACKMAN_JUHANI_AUTH_TOKEN); + + $validator->validate($token, 'x9qZDRO/ao2zprt3Z0bkW4CvvE/gALFtUIf3tcC0XxY='); + } + + public function testWhenIdCardSignatureCertificateWithG4RootCertificateIsValidatedThenValidationSucceeds(): void + { + $this->expectNotToPerformAssertions(); + $validator = AuthTokenValidators::getAuthTokenValidatorForFinnishIdCard(); + $token = $validator->parse(self::FINNISH_TEST_ID_CARD_BABAFO_VELI_AUTH_TOKEN); + + $validator->validate($token, 'ZqlDATkQRqh7LkqEbspBc2qDjot29oiNLlITdLgiVIo='); + } + + private function mockDate(string $date) + { + Dates::setMockedCertificateValidatorDate(new DateTime($date)); + } + +} diff --git a/tests/validator/AuthTokenCertificateTest.php b/tests/validator/AuthTokenCertificateTest.php index 4ae445e..2750390 100644 --- a/tests/validator/AuthTokenCertificateTest.php +++ b/tests/validator/AuthTokenCertificateTest.php @@ -49,7 +49,7 @@ class AuthTokenCertificateTest extends AbstractTestWithValidator '"signature":"arx164xRiwhIQDINe0J+ZxJWZFOQTx0PBtOaWaxAe7gofEIHRIbV1w0sOCYBJnvmvMem9hU4nc2+iJx2x8poYck4Z6eI3GwtiksIec3XQ9ZIk1n/XchXnmPn3GYV+HzJ",' . '"format":"web-eid:1"}'; - private const MISSING_PURPOSE_CERT = 'MIICxjCCAa6gAwIBAgIJANTbd26vS6fmMA0GCSqGSIb3DQEBBQUAMBUxEzARBgNVBAMTCndlYi1laWQuZXUwHhcNMjAwOTI0MTIyNDMzWhcNMzAwOTIyMTIyNDMzWjAVMRMwEQYDVQQDEwp3ZWItZWlkLmV1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAza5qBFu5fvs47rx3o9yzBVfIxHjMotID8ppkwWVen/uFxlqsRVi+XnWkggW+K8X45inAnBAVi1rIw7GQNdacSHglyvQfwM64AallmD0+K+QgbqxcO9fvRvlAeISENBc2bGgqTIytPEON5ZmazzbOZjqY3M1QcPlPZOeUm6M9ZcZFhsxpiB4gwZUic9tnCz9eujd6k6DzNVfSRaJcpGA5hJ9aKH4vXS3x7anewna+USEXkRb4Il5zSlZR0i1yrVA1YNOxCG/+GgWvXfvXwdQ0z9BpGwNEyc0mRDNx+umaTukz9t+7/qTcB2JLTuiwM9Gqg5sDDnzPlcZSa7GnIU0MLQIDAQABoxkwFzAVBgNVHREEDjAMggp3ZWItZWlkLmV1MA0GCSqGSIb3DQEBBQUAA4IBAQAYGkBhTlet47uw3JYunYo6dj4nGWSGV4x6LYjCp5QlAmGd28HpC1RFB3ba+inwW8SP69kEOcB0sJQAZ/tV90oCATNsy/Whg/TtiHISL2pr1dyBoKDRWbgTp8jjzcp2Bj9nL14aqpj1t4K1lcoYETX41yVmyyJu6VFs80M5T3yikm2giAhszjChnjyoT2kaEKoua9EUK9SS27pVltgbbvtmeTp3ZPHtBfiDOATL6E03RZ5WfMLRefI796a+RcznnudzQHhMSwcjLpMDgIWpUU4OU7RiwrU+S3MrvgzCjkWh2MGu/OGLB+d3JZoW+eCvigoshmAsbJCMLbh4N78BCPqk'; + private const MISSING_KEY_USAGE_CERT = 'MIICxjCCAa6gAwIBAgIJANTbd26vS6fmMA0GCSqGSIb3DQEBBQUAMBUxEzARBgNVBAMTCndlYi1laWQuZXUwHhcNMjAwOTI0MTIyNDMzWhcNMzAwOTIyMTIyNDMzWjAVMRMwEQYDVQQDEwp3ZWItZWlkLmV1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAza5qBFu5fvs47rx3o9yzBVfIxHjMotID8ppkwWVen/uFxlqsRVi+XnWkggW+K8X45inAnBAVi1rIw7GQNdacSHglyvQfwM64AallmD0+K+QgbqxcO9fvRvlAeISENBc2bGgqTIytPEON5ZmazzbOZjqY3M1QcPlPZOeUm6M9ZcZFhsxpiB4gwZUic9tnCz9eujd6k6DzNVfSRaJcpGA5hJ9aKH4vXS3x7anewna+USEXkRb4Il5zSlZR0i1yrVA1YNOxCG/+GgWvXfvXwdQ0z9BpGwNEyc0mRDNx+umaTukz9t+7/qTcB2JLTuiwM9Gqg5sDDnzPlcZSa7GnIU0MLQIDAQABoxkwFzAVBgNVHREEDjAMggp3ZWItZWlkLmV1MA0GCSqGSIb3DQEBBQUAA4IBAQAYGkBhTlet47uw3JYunYo6dj4nGWSGV4x6LYjCp5QlAmGd28HpC1RFB3ba+inwW8SP69kEOcB0sJQAZ/tV90oCATNsy/Whg/TtiHISL2pr1dyBoKDRWbgTp8jjzcp2Bj9nL14aqpj1t4K1lcoYETX41yVmyyJu6VFs80M5T3yikm2giAhszjChnjyoT2kaEKoua9EUK9SS27pVltgbbvtmeTp3ZPHtBfiDOATL6E03RZ5WfMLRefI796a+RcznnudzQHhMSwcjLpMDgIWpUU4OU7RiwrU+S3MrvgzCjkWh2MGu/OGLB+d3JZoW+eCvigoshmAsbJCMLbh4N78BCPqk'; private const WRONG_PURPOSE_CERT = 'MIIEBDCCA2WgAwIBAgIQGIgoZxFL7VZbyFH7MAVEkTAKBggqhkjOPQQDBDBgMQswCQYDVQQGEwJFRTEbMBkGA1UECgwSU0sgSUQgU29sdXRpb25zIEFTMRcwFQYDVQRhDA5OVFJFRS0xMDc0NzAxMzEbMBkGA1UEAwwSVEVTVCBvZiBFU1RFSUQyMDE4MB4XDTE4MTAxODA5MjcyM1oXDTIzMTAxNzIxNTk1OVowfzELMAkGA1UEBhMCRUUxKjAoBgNVBAMMIUrDlUVPUkcsSkFBSy1LUklTVEpBTiwzODAwMTA4NTcxODEQMA4GA1UEBAwHSsOVRU9SRzEWMBQGA1UEKgwNSkFBSy1LUklTVEpBTjEaMBgGA1UEBRMRUE5PRUUtMzgwMDEwODU3MTgwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT3SZB34CUGYhQyLsLd9b2ihv35q7NT47Id9ugLIdgg3NSFDccH6rV16D2m8DKfuD2mn3V6QdaaZnbWF4YdDK1W0C9kLNsB70ob//y39pugMftepmQpJcBGPqug81tf5jujggHDMIIBvzAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIDiDBHBgNVHSAEQDA+MDIGCysGAQQBg5EhAQIBMCMwIQYIKwYBBQUHAgEWFWh0dHBzOi8vd3d3LnNrLmVlL0NQUzAIBgYEAI96AQIwHwYDVR0RBBgwFoEUMzgwMDEwODU3MThAZWVzdGkuZWUwHQYDVR0OBBYEFPhJx7ro54+N8r2ByiZXzZyWBbjFMGEGCCsGAQUFBwEDBFUwUzBRBgYEAI5GAQUwRzBFFj9odHRwczovL3NrLmVlL2VuL3JlcG9zaXRvcnkvY29uZGl0aW9ucy1mb3ItdXNlLW9mLWNlcnRpZmljYXRlcy8TAkVOMCAGA1UdJQEB/wQWMBQGCCsG/wUFBwMCBggrBgEFBQcDBDAfBgNVHSMEGDAWgBTAhJkpxE6fOwI09pnhClYACCk+ezBzBggrBgEFBQcBAQRnMGUwLAYIKwYBBQUHMAGGIGh0dHA6Ly9haWEuZGVtby5zay5lZS9lc3RlaWQyMDE4MDUGCCsGAQUFBzAChilodHRwOi8vYy5zay5lZS9UZXN0X29mX0VTVEVJRDIwMTguZGVyLmNydDAKBggqhkjOPQQDBAOBjAAwgYgCQgFi5XSCFGgsc8SKLWwMBWS0nu/20FjEqh6OGvsI4iPctNDkinsxcYgARdfqPsNnDX+KjALKPEKZCLKRixGL2kPLMgJCAQFXP9gstThxlj/1Q5YFb7KWhPWFiKgQEi9JdvxJQNXLkWV9onEh96mRFgv4IJJpGazuoSMZtzNpyBxmM0dwnxOf'; private const WRONG_POLICY_CERT = 'MIIEATCCA2OgAwIBAgIQOWkBWXNDJm1byFd3XsWkvjAKBggqhkjOPQQDBDBgMQswCQYDVQQGEwJFRTEbMBkGA1UECgwSU0sgSUQgU29sdXRpb25zIEFTMRcwFQYDVQRhDA5OVFJFRS0xMDc0NzAxMzEbMBkGA1UEAwwSVEVTVCBvZiBFU1RFSUQyMDE4MB4XDTE4MTAxODA5NTA0N1oXDTIzMTAxNzIxNTk1OVowfzELMAkGA1UEBhMCRUUxKjAoBgNVBAMMIUrDlUVPUkcsSkFBSy1LUklTVEpBTiwzODAwMTA4NTcxODEQMA4GA1UEBAwHSsOVRU9SRzEWMBQGA1UEKgwNSkFBSy1LUklTVEpBTjEaMBgGA1UEBRMRUE5PRUUtMzgwMDEwODU3MTgwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAR5k1lXzvSeI9O/1s1pZvjhEW8nItJoG0EBFxmLEY6S7ki1vF2Q3TEDx6dNztI1Xtx96cs8r4zYTwdiQoDg7k3diUuR9nTWGxQEMO1FDo4Y9fAmiPGWT++GuOVoZQY3XxijggHBMIIBvTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIDiDBFBgNVHSAEPjA8MDAGCSsGAQQBzh8BAzAjMCEGCCsGAQUFBwIBFhVodHRwczovL3d3dy5zay5lZS9DUFMwCAYGBACPegECMB8GA1UdEQQYMBaBFDM4MDAxMDg1NzE4QGVlc3RpLmVlMB0GA1UdDgQWBBTkLL00CRAVTDEpocmV+W4m2CbmwDBhBggrBgEFBQcBAwRVMFMwUQYGBACORgEFMEcwRRY/aHR0cHM6Ly9zay5lZS9lbi9yZXBvc2l0b3J5L2NvbmRpdGlvbnMtZm9yLXVzZS1vZi1jZXJ0aWZpY2F0ZXMvEwJFTjAgBgNVHSUBAf8EFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwHwYDVR0jBBgwFoAUwISZKcROnzsCNPaZ4QpWAAgpPnswcwYIKwYBBQUHAQEEZzBlMCwGCCsGAQUFBzABhiBodHRwOi8vYWlhLmRlbW8uc2suZWUvZXN0ZWlkMjAxODA1BggrBgEFBQcwAoYpaHR0cDovL2Muc2suZWUvVGVzdF9vZl9FU1RFSUQyMDE4LmRlci5jcnQwCgYIKoZIzj0EAwQDgYsAMIGHAkIB9VLJjHbS2bYudRatkEeMFJAMKbJ4bAVdh0KlFxWASexF5ywpGl43WSpB6QAXzNEBMe1FIWiOIud44iexNWO1jgACQQ1+M+taZ4hyWqSNW5DCIiUP7Yu4WvH3SUjEqQHbOQshyMh5EM1pVcvOn/ZgOxLt6ETv9avnhVMw2zTd1b8u4EFk'; @@ -125,9 +125,9 @@ public function testWhenCertificateFieldIsNotCertificateThenParsingFails(): void $this->validator->validate($token, self::VALID_CHALLENGE_NONCE); } - public function testWhenCertificatePurposeIsMissingThenValidationFails(): void + public function testWhenCertificateKeyUsageIsMissingThenValidationFails(): void { - $token = $this->replaceTokenField(self::AUTH_TOKEN, "unverifiedCertificate", self::MISSING_PURPOSE_CERT); + $token = $this->replaceTokenField(self::AUTH_TOKEN, "unverifiedCertificate", self::MISSING_KEY_USAGE_CERT); $this->expectException(UserCertificateMissingPurposeException::class); $this->validator->validate($token, self::VALID_CHALLENGE_NONCE); @@ -171,7 +171,7 @@ public function testWhenUsingNewMobileIdCertificateThenValidationFails(): void { $token = $this->replaceTokenField(self::AUTH_TOKEN, "unverifiedCertificate", self::NEW_MOBILE_ID_CERT); - $this->expectException(UserCertificateMissingPurposeException::class); + $this->expectException(UserCertificateDisallowedPolicyException::class); $this->validator->validate($token, self::VALID_CHALLENGE_NONCE); }