[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/plugins/system/webauthn/src/ -> MetadataRepository.php (source)

   1  <?php
   2  
   3  /**
   4   * @package         Joomla.Plugin
   5   * @subpackage      System.Webauthn
   6   *
   7   * @copyright   (C) 2022 Open Source Matters, Inc. <https://www.joomla.org>
   8   * @license         GNU General Public License version 2 or later; see LICENSE.txt
   9   */
  10  
  11  namespace Joomla\Plugin\System\Webauthn;
  12  
  13  use Exception;
  14  use Joomla\CMS\Date\Date;
  15  use Joomla\CMS\Http\HttpFactory;
  16  use Lcobucci\JWT\Configuration;
  17  use Lcobucci\JWT\Token\Plain;
  18  use Webauthn\MetadataService\MetadataStatement;
  19  use Webauthn\MetadataService\MetadataStatementRepository;
  20  
  21  use function defined;
  22  
  23  // phpcs:disable PSR1.Files.SideEffects
  24  \defined('_JEXEC') or die;
  25  // phpcs:enable PSR1.Files.SideEffects
  26  
  27  /**
  28   * Authenticator metadata repository.
  29   *
  30   * This repository contains the metadata of all FIDO authenticators as published by the FIDO
  31   * Alliance in their MDS version 3.0.
  32   *
  33   * @see   https://fidoalliance.org/metadata/
  34   * @since 4.2.0
  35   */
  36  final class MetadataRepository implements MetadataStatementRepository
  37  {
  38      /**
  39       * Cache of authenticator metadata statements
  40       *
  41       * @var   MetadataStatement[]
  42       * @since 4.2.0
  43       */
  44      private $mdsCache = [];
  45  
  46      /**
  47       * Map of AAGUID to $mdsCache index
  48       *
  49       * @var   array
  50       * @since 4.2.0
  51       */
  52      private $mdsMap = [];
  53  
  54      /**
  55       * Have I already tried to load the metadata cache?
  56       *
  57       * @var   bool
  58       * @since 4.2.2
  59       */
  60      private $loaded = false;
  61  
  62      /**
  63       * Find an authenticator metadata statement given an AAGUID
  64       *
  65       * @param   string  $aaguid  The AAGUID to find
  66       *
  67       * @return  MetadataStatement|null  The metadata statement; null if the AAGUID is unknown
  68       * @since   4.2.0
  69       */
  70      public function findOneByAAGUID(string $aaguid): ?MetadataStatement
  71      {
  72          $this->load();
  73  
  74          $idx = $this->mdsMap[$aaguid] ?? null;
  75  
  76          return $idx ? $this->mdsCache[$idx] : null;
  77      }
  78  
  79      /**
  80       * Get basic information of the known FIDO authenticators by AAGUID
  81       *
  82       * @return  object[]
  83       * @since   4.2.0
  84       */
  85      public function getKnownAuthenticators(): array
  86      {
  87          $this->load();
  88  
  89          $mapKeys = function (MetadataStatement $meta) {
  90              return $meta->getAaguid();
  91          };
  92          $mapvalues = function (MetadataStatement $meta) {
  93              return $meta->getAaguid() ? (object) [
  94                  'description' => $meta->getDescription(),
  95                  'icon'        => $meta->getIcon(),
  96              ] : null;
  97          };
  98          $keys    = array_map($mapKeys, $this->mdsCache);
  99          $values  = array_map($mapvalues, $this->mdsCache);
 100          $return  = array_combine($keys, $values) ?: [];
 101  
 102          $filter = function ($x) {
 103              return !empty($x);
 104          };
 105  
 106          return array_filter($return, $filter);
 107      }
 108  
 109      /**
 110       * Load the authenticator metadata cache
 111       *
 112       * @return  void
 113       * @since   4.2.0
 114       */
 115      private function load(): void
 116      {
 117          if ($this->loaded) {
 118              return;
 119          }
 120  
 121          $this->loaded = true;
 122  
 123          $this->mdsCache = [];
 124          $this->mdsMap   = [];
 125  
 126          $jwtFilename = JPATH_PLUGINS . '/system/webauthn/fido.jwt';
 127          $rawJwt      = file_get_contents($jwtFilename);
 128  
 129          if (!is_string($rawJwt) || strlen($rawJwt) < 1024) {
 130              return;
 131          }
 132  
 133          try {
 134              $jwtConfig = Configuration::forUnsecuredSigner();
 135              $token     = $jwtConfig->parser()->parse($rawJwt);
 136          } catch (Exception $e) {
 137              return;
 138          }
 139  
 140          if (!($token instanceof Plain)) {
 141              return;
 142          }
 143  
 144          unset($rawJwt);
 145  
 146          $entriesMapper = function (object $entry) {
 147              try {
 148                  $array = json_decode(json_encode($entry->metadataStatement), true);
 149  
 150                  /**
 151                   * This prevents an error when we're asking for attestation on authenticators which
 152                   * don't allow it. We are really not interested in the attestation per se, but
 153                   * requiring an attestation is the only way we can get the AAGUID of the
 154                   * authenticator.
 155                   */
 156                  if (isset($array['attestationTypes'])) {
 157                      unset($array['attestationTypes']);
 158                  }
 159  
 160                  return MetadataStatement::createFromArray($array);
 161              } catch (Exception $e) {
 162                  return null;
 163              }
 164          };
 165          $entries = array_map($entriesMapper, $token->claims()->get('entries', []));
 166  
 167          unset($token);
 168  
 169          $entriesFilter                = function ($x) {
 170              return !empty($x);
 171          };
 172          $this->mdsCache = array_filter($entries, $entriesFilter);
 173  
 174          foreach ($this->mdsCache as $idx => $meta) {
 175              $aaguid = $meta->getAaguid();
 176  
 177              if (empty($aaguid)) {
 178                  continue;
 179              }
 180  
 181              $this->mdsMap[$aaguid] = $idx;
 182          }
 183      }
 184  }


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