[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/web-auth/webauthn-lib/src/ -> AuthenticatorAttestationResponseValidator.php (source)

   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  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer