[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 declare(strict_types=1); 4 5 /* 6 * The MIT License (MIT) 7 * 8 * Copyright (c) 2014-2019 Spomky-Labs 9 * 10 * This software may be modified and distributed under the terms 11 * of the MIT license. See the LICENSE file for details. 12 */ 13 14 namespace Webauthn; 15 16 use Assert\Assertion; 17 use Psr\Http\Message\ServerRequestInterface; 18 use Webauthn\AttestationStatement\AttestationObject; 19 use Webauthn\AttestationStatement\AttestationStatementSupportManager; 20 use Webauthn\AuthenticationExtensions\ExtensionOutputCheckerHandler; 21 use Webauthn\TokenBinding\TokenBindingHandler; 22 23 class AuthenticatorAttestationResponseValidator 24 { 25 /** 26 * @var AttestationStatementSupportManager 27 */ 28 private $attestationStatementSupportManager; 29 30 /** 31 * @var PublicKeyCredentialSourceRepository 32 */ 33 private $publicKeyCredentialSource; 34 35 /** 36 * @var TokenBindingHandler 37 */ 38 private $tokenBindingHandler; 39 40 /** 41 * @var ExtensionOutputCheckerHandler 42 */ 43 private $extensionOutputCheckerHandler; 44 45 public function __construct(AttestationStatementSupportManager $attestationStatementSupportManager, PublicKeyCredentialSourceRepository $publicKeyCredentialSource, TokenBindingHandler $tokenBindingHandler, ExtensionOutputCheckerHandler $extensionOutputCheckerHandler) 46 { 47 $this->attestationStatementSupportManager = $attestationStatementSupportManager; 48 $this->publicKeyCredentialSource = $publicKeyCredentialSource; 49 $this->tokenBindingHandler = $tokenBindingHandler; 50 $this->extensionOutputCheckerHandler = $extensionOutputCheckerHandler; 51 } 52 53 /** 54 * @see https://www.w3.org/TR/webauthn/#registering-a-new-credential 55 */ 56 public function check(AuthenticatorAttestationResponse $authenticatorAttestationResponse, PublicKeyCredentialCreationOptions $publicKeyCredentialCreationOptions, ServerRequestInterface $request): PublicKeyCredentialSource 57 { 58 /** @see 7.1.1 */ 59 //Nothing to do 60 61 /** @see 7.1.2 */ 62 $C = $authenticatorAttestationResponse->getClientDataJSON(); 63 64 /* @see 7.1.3 */ 65 Assertion::eq('webauthn.create', $C->getType(), 'The client data type is not "webauthn.create".'); 66 67 /* @see 7.1.4 */ 68 Assertion::true(hash_equals($publicKeyCredentialCreationOptions->getChallenge(), $C->getChallenge()), 'Invalid challenge.'); 69 70 /** @see 7.1.5 */ 71 $rpId = $publicKeyCredentialCreationOptions->getRp()->getId() ?? $request->getUri()->getHost(); 72 73 $parsedRelyingPartyId = parse_url($C->getOrigin()); 74 Assertion::isArray($parsedRelyingPartyId, sprintf('The origin URI "%s" is not valid', $C->getOrigin())); 75 Assertion::keyExists($parsedRelyingPartyId, 'scheme', 'Invalid origin rpId.'); 76 $scheme = $parsedRelyingPartyId['scheme'] ?? ''; 77 Assertion::eq('https', $scheme, 'Invalid scheme. HTTPS required.'); 78 $clientDataRpId = $parsedRelyingPartyId['host'] ?? ''; 79 Assertion::notEmpty($clientDataRpId, 'Invalid origin rpId.'); 80 $rpIdLength = mb_strlen($rpId); 81 Assertion::eq(mb_substr($clientDataRpId, -$rpIdLength), $rpId, 'rpId mismatch.'); 82 83 /* @see 7.1.6 */ 84 if (null !== $C->getTokenBinding()) { 85 $this->tokenBindingHandler->check($C->getTokenBinding(), $request); 86 } 87 88 /** @see 7.1.7 */ 89 $clientDataJSONHash = hash('sha256', $authenticatorAttestationResponse->getClientDataJSON()->getRawData(), true); 90 91 /** @see 7.1.8 */ 92 $attestationObject = $authenticatorAttestationResponse->getAttestationObject(); 93 94 /** @see 7.1.9 */ 95 $rpIdHash = hash('sha256', $rpId, true); 96 Assertion::true(hash_equals($rpIdHash, $attestationObject->getAuthData()->getRpIdHash()), 'rpId hash mismatch.'); 97 98 /* @see 7.1.10 */ 99 /* @see 7.1.11 */ 100 if (AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_REQUIRED === $publicKeyCredentialCreationOptions->getAuthenticatorSelection()->getUserVerification()) { 101 Assertion::true($attestationObject->getAuthData()->isUserPresent(), 'User was not present'); 102 Assertion::true($attestationObject->getAuthData()->isUserVerified(), 'User authentication required.'); 103 } 104 105 /* @see 7.1.12 */ 106 $extensions = $attestationObject->getAuthData()->getExtensions(); 107 if (null !== $extensions) { 108 $this->extensionOutputCheckerHandler->check($extensions); 109 } 110 111 /** @see 7.1.13 */ 112 $fmt = $attestationObject->getAttStmt()->getFmt(); 113 Assertion::true($this->attestationStatementSupportManager->has($fmt), 'Unsupported attestation statement format.'); 114 115 /** @see 7.1.14 */ 116 $attestationStatementSupport = $this->attestationStatementSupportManager->get($fmt); 117 Assertion::true($attestationStatementSupport->isValid($clientDataJSONHash, $attestationObject->getAttStmt(), $attestationObject->getAuthData()), 'Invalid attestation statement.'); 118 119 /* @see 7.1.15 */ 120 /* @see 7.1.16 */ 121 /* @see 7.1.17 */ 122 Assertion::true($attestationObject->getAuthData()->hasAttestedCredentialData(), 'There is no attested credential data.'); 123 $attestedCredentialData = $attestationObject->getAuthData()->getAttestedCredentialData(); 124 Assertion::notNull($attestedCredentialData, 'There is no attested credential data.'); 125 $credentialId = $attestedCredentialData->getCredentialId(); 126 Assertion::null($this->publicKeyCredentialSource->findOneByCredentialId($credentialId), 'The credential ID already exists.'); 127 128 /* @see 7.1.18 */ 129 /* @see 7.1.19 */ 130 return $this->createPublicKeyCredentialSource( 131 $credentialId, 132 $attestedCredentialData, 133 $attestationObject, 134 $publicKeyCredentialCreationOptions->getUser()->getId() 135 ); 136 } 137 138 private function createPublicKeyCredentialSource(string $credentialId, AttestedCredentialData $attestedCredentialData, AttestationObject $attestationObject, string $userHandle): PublicKeyCredentialSource 139 { 140 return new PublicKeyCredentialSource( 141 $credentialId, 142 PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, 143 [], 144 $attestationObject->getAttStmt()->getType(), 145 $attestationObject->getAttStmt()->getTrustPath(), 146 $attestedCredentialData->getAaguid(), 147 $attestedCredentialData->getCredentialPublicKey(), 148 $userHandle, 149 $attestationObject->getAuthData()->getSignCount() 150 ); 151 } 152 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |