189 lines
5.5 KiB
PHP

<?php
declare(strict_types=1);
/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2021 Spomky-Labs
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace Webauthn\MetadataService;
use Assert\Assertion;
use Base64Url\Base64Url;
use function count;
use JsonSerializable;
use LogicException;
class MetadataTOCPayloadEntry implements JsonSerializable
{
/**
* @var string|null
*/
private $aaid;
/**
* @var string|null
*/
private $aaguid;
/**
* @var string[]
*/
private $attestationCertificateKeyIdentifiers = [];
/**
* @var string|null
*/
private $hash;
/**
* @var string|null
*/
private $url;
/**
* @var StatusReport[]
*/
private $statusReports = [];
/**
* @var string
*/
private $timeOfLastStatusChange;
/**
* @var string
*/
private $rogueListURL;
/**
* @var string
*/
private $rogueListHash;
public function __construct(?string $aaid, ?string $aaguid, array $attestationCertificateKeyIdentifiers, ?string $hash, ?string $url, string $timeOfLastStatusChange, ?string $rogueListURL, ?string $rogueListHash)
{
if (null !== $aaid && null !== $aaguid) {
throw new LogicException('Authenticators cannot support both AAID and AAGUID');
}
if (null === $aaid && null === $aaguid && 0 === count($attestationCertificateKeyIdentifiers)) {
throw new LogicException('If neither AAID nor AAGUID are set, the attestation certificate identifier list shall not be empty');
}
foreach ($attestationCertificateKeyIdentifiers as $attestationCertificateKeyIdentifier) {
Assertion::string($attestationCertificateKeyIdentifier, Utils::logicException('Invalid attestation certificate identifier. Shall be a list of strings'));
Assertion::notEmpty($attestationCertificateKeyIdentifier, Utils::logicException('Invalid attestation certificate identifier. Shall be a list of strings'));
Assertion::regex($attestationCertificateKeyIdentifier, '/^[0-9a-f]+$/', Utils::logicException('Invalid attestation certificate identifier. Shall be a list of strings'));
}
$this->aaid = $aaid;
$this->aaguid = $aaguid;
$this->attestationCertificateKeyIdentifiers = $attestationCertificateKeyIdentifiers;
$this->hash = Base64Url::decode($hash);
$this->url = $url;
$this->timeOfLastStatusChange = $timeOfLastStatusChange;
$this->rogueListURL = $rogueListURL;
$this->rogueListHash = $rogueListHash;
}
public function getAaid(): ?string
{
return $this->aaid;
}
public function getAaguid(): ?string
{
return $this->aaguid;
}
public function getAttestationCertificateKeyIdentifiers(): array
{
return $this->attestationCertificateKeyIdentifiers;
}
public function getHash(): ?string
{
return $this->hash;
}
public function getUrl(): ?string
{
return $this->url;
}
public function addStatusReports(StatusReport $statusReport): self
{
$this->statusReports[] = $statusReport;
return $this;
}
/**
* @return StatusReport[]
*/
public function getStatusReports(): array
{
return $this->statusReports;
}
public function getTimeOfLastStatusChange(): string
{
return $this->timeOfLastStatusChange;
}
public function getRogueListURL(): string
{
return $this->rogueListURL;
}
public function getRogueListHash(): string
{
return $this->rogueListHash;
}
public static function createFromArray(array $data): self
{
$data = Utils::filterNullValues($data);
Assertion::keyExists($data, 'timeOfLastStatusChange', Utils::logicException('Invalid data. The parameter "timeOfLastStatusChange" is missing'));
Assertion::keyExists($data, 'statusReports', Utils::logicException('Invalid data. The parameter "statusReports" is missing'));
Assertion::isArray($data['statusReports'], Utils::logicException('Invalid data. The parameter "statusReports" shall be an array of StatusReport objects'));
$object = new self(
$data['aaid'] ?? null,
$data['aaguid'] ?? null,
$data['attestationCertificateKeyIdentifiers'] ?? [],
$data['hash'] ?? null,
$data['url'] ?? null,
$data['timeOfLastStatusChange'],
$data['rogueListURL'] ?? null,
$data['rogueListHash'] ?? null
);
foreach ($data['statusReports'] as $statusReport) {
$object->addStatusReports(StatusReport::createFromArray($statusReport));
}
return $object;
}
public function jsonSerialize(): array
{
$data = [
'aaid' => $this->aaid,
'aaguid' => $this->aaguid,
'attestationCertificateKeyIdentifiers' => $this->attestationCertificateKeyIdentifiers,
'hash' => Base64Url::encode($this->hash),
'url' => $this->url,
'statusReports' => array_map(static function (StatusReport $object): array {
return $object->jsonSerialize();
}, $this->statusReports),
'timeOfLastStatusChange' => $this->timeOfLastStatusChange,
'rogueListURL' => $this->rogueListURL,
'rogueListHash' => $this->rogueListHash,
];
return Utils::filterNullValues($data);
}
}