[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/web-auth/webauthn-lib/src/ -> PublicKeyCredentialLoader.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 Base64Url\Base64Url;
  18  use CBOR\Decoder;
  19  use CBOR\MapObject;
  20  use CBOR\OtherObject\OtherObjectManager;
  21  use CBOR\Tag\TagObjectManager;
  22  use InvalidArgumentException;
  23  use Ramsey\Uuid\Uuid;
  24  use Webauthn\AttestationStatement\AttestationObjectLoader;
  25  use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientOutputsLoader;
  26  
  27  class PublicKeyCredentialLoader
  28  {
  29      private const FLAG_AT = 0b01000000;
  30      private const FLAG_ED = 0b10000000;
  31  
  32      /**
  33       * @var AttestationObjectLoader
  34       */
  35      private $attestationObjectLoader;
  36  
  37      /**
  38       * @var Decoder
  39       */
  40      private $decoder;
  41  
  42      public function __construct(AttestationObjectLoader $attestationObjectLoader, ?Decoder $decoder = null)
  43      {
  44          if (null !== $decoder) {
  45              @trigger_error('The argument "$decoder" is deprecated since 2.1 and will be removed in v3.0. Set null instead', E_USER_DEPRECATED);
  46          }
  47          $this->decoder = $decoder ?? new Decoder(new TagObjectManager(), new OtherObjectManager());
  48          $this->attestationObjectLoader = $attestationObjectLoader;
  49      }
  50  
  51      public function loadArray(array $json): PublicKeyCredential
  52      {
  53          foreach (['id', 'rawId', 'type'] as $key) {
  54              Assertion::keyExists($json, $key, sprintf('The parameter "%s" is missing', $key));
  55              Assertion::string($json[$key], sprintf('The parameter "%s" shall be a string', $key));
  56          }
  57          Assertion::keyExists($json, 'response', 'The parameter "response" is missing');
  58          Assertion::isArray($json['response'], 'The parameter "response" shall be an array');
  59          Assertion::eq($json['type'], 'public-key', sprintf('Unsupported type "%s"', $json['type']));
  60  
  61          $id = Base64Url::decode($json['id']);
  62          $rawId = Base64Url::decode($json['rawId']);
  63          Assertion::true(hash_equals($id, $rawId));
  64  
  65          $publicKeyCredential = new PublicKeyCredential(
  66              $json['id'],
  67              $json['type'],
  68              $rawId,
  69              $this->createResponse($json['response'])
  70          );
  71  
  72          return $publicKeyCredential;
  73      }
  74  
  75      public function load(string $data): PublicKeyCredential
  76      {
  77          $json = json_decode($data, true);
  78          Assertion::eq(JSON_ERROR_NONE, json_last_error(), 'Invalid data');
  79  
  80          return $this->loadArray($json);
  81      }
  82  
  83      private function createResponse(array $response): AuthenticatorResponse
  84      {
  85          Assertion::keyExists($response, 'clientDataJSON');
  86          switch (true) {
  87              case \array_key_exists('attestationObject', $response):
  88                  $attestationObject = $this->attestationObjectLoader->load($response['attestationObject']);
  89  
  90                  return new AuthenticatorAttestationResponse(CollectedClientData::createFormJson($response['clientDataJSON']), $attestationObject);
  91              case \array_key_exists('authenticatorData', $response) && \array_key_exists('signature', $response):
  92                  $authData = Base64Url::decode($response['authenticatorData']);
  93  
  94                  $authDataStream = new StringStream($authData);
  95                  $rp_id_hash = $authDataStream->read(32);
  96                  $flags = $authDataStream->read(1);
  97                  $signCount = $authDataStream->read(4);
  98                  $signCount = unpack('N', $signCount)[1];
  99  
 100                  $attestedCredentialData = null;
 101                  if (0 !== (\ord($flags) & self::FLAG_AT)) {
 102                      $aaguid = Uuid::fromBytes($authDataStream->read(16));
 103                      $credentialLength = $authDataStream->read(2);
 104                      $credentialLength = unpack('n', $credentialLength)[1];
 105                      $credentialId = $authDataStream->read($credentialLength);
 106                      $credentialPublicKey = $this->decoder->decode($authDataStream);
 107                      Assertion::isInstanceOf($credentialPublicKey, MapObject::class, 'The data does not contain a valid credential public key.');
 108                      $attestedCredentialData = new AttestedCredentialData($aaguid, $credentialId, (string) $credentialPublicKey);
 109                  }
 110  
 111                  $extension = null;
 112                  if (0 !== (\ord($flags) & self::FLAG_ED)) {
 113                      $extension = $this->decoder->decode($authDataStream);
 114                      $extension = AuthenticationExtensionsClientOutputsLoader::load($extension);
 115                  }
 116                  Assertion::true($authDataStream->isEOF(), 'Invalid authentication data. Presence of extra bytes.');
 117                  $authDataStream->close();
 118                  $authenticatorData = new AuthenticatorData($authData, $rp_id_hash, $flags, $signCount, $attestedCredentialData, $extension);
 119  
 120                  return new AuthenticatorAssertionResponse(
 121                      CollectedClientData::createFormJson($response['clientDataJSON']),
 122                      $authenticatorData,
 123                      Base64Url::decode($response['signature']),
 124                      $response['userHandle'] ?? null
 125                  );
 126              default:
 127                  throw new InvalidArgumentException('Unable to create the response object');
 128          }
 129      }
 130  }


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