*/ private $statusReports = []; /** * @var string[] */ private $rootCertificates = []; public static function createFromString(string $statement): self { $data = json_decode($statement, true); Assertion::isArray($data, 'Invalid Metadata Statement'); return self::createFromArray($data); } public function getLegalHeader(): ?string { return $this->legalHeader; } public function getAaid(): ?string { return $this->aaid; } public function getAaguid(): ?string { return $this->aaguid; } /** * @return string[] */ public function getAttestationCertificateKeyIdentifiers(): array { return $this->attestationCertificateKeyIdentifiers; } public function getDescription(): string { return $this->description; } /** * @return string[] */ public function getAlternativeDescriptions(): array { return $this->alternativeDescriptions; } public function getAuthenticatorVersion(): int { return $this->authenticatorVersion; } public function getProtocolFamily(): string { return $this->protocolFamily; } /** * @return Version[] */ public function getUpv(): array { return $this->upv; } public function getAssertionScheme(): ?string { return $this->assertionScheme; } public function getAuthenticationAlgorithm(): ?int { return $this->authenticationAlgorithm; } /** * @return int[] */ public function getAuthenticationAlgorithms(): array { return $this->authenticationAlgorithms; } public function getPublicKeyAlgAndEncoding(): ?int { return $this->publicKeyAlgAndEncoding; } /** * @return int[] */ public function getPublicKeyAlgAndEncodings(): array { return $this->publicKeyAlgAndEncodings; } /** * @return int[] */ public function getAttestationTypes(): array { return $this->attestationTypes; } /** * @return VerificationMethodANDCombinations[] */ public function getUserVerificationDetails(): array { return $this->userVerificationDetails; } public function getKeyProtection(): int { return $this->keyProtection; } public function isKeyRestricted(): ?bool { return (bool) $this->isKeyRestricted; } public function isFreshUserVerificationRequired(): ?bool { return (bool) $this->isFreshUserVerificationRequired; } public function getMatcherProtection(): int { return $this->matcherProtection; } public function getCryptoStrength(): ?int { return $this->cryptoStrength; } public function getOperatingEnv(): ?string { return $this->operatingEnv; } public function getAttachmentHint(): int { return $this->attachmentHint; } public function isSecondFactorOnly(): ?bool { return (bool) $this->isSecondFactorOnly; } public function getTcDisplay(): int { return $this->tcDisplay; } public function getTcDisplayContentType(): ?string { return $this->tcDisplayContentType; } /** * @return DisplayPNGCharacteristicsDescriptor[] */ public function getTcDisplayPNGCharacteristics(): array { return $this->tcDisplayPNGCharacteristics; } /** * @return string[] */ public function getAttestationRootCertificates(): array { return $this->attestationRootCertificates; } /** * @return EcdaaTrustAnchor[] */ public function getEcdaaTrustAnchors(): array { return $this->ecdaaTrustAnchors; } public function getIcon(): ?string { return $this->icon; } /** * @return ExtensionDescriptor[] */ public function getSupportedExtensions(): array { return $this->supportedExtensions; } public static function createFromArray(array $data): self { $object = new self(); foreach (['description', 'protocolFamily'] as $key) { if (!isset($data[$key])) { throw new InvalidArgumentException(sprintf('The parameter "%s" is missing', $key)); } } $object->legalHeader = $data['legalHeader'] ?? null; $object->aaid = $data['aaid'] ?? null; $object->aaguid = $data['aaguid'] ?? null; $object->attestationCertificateKeyIdentifiers = $data['attestationCertificateKeyIdentifiers'] ?? []; $object->description = $data['description']; $object->alternativeDescriptions = $data['alternativeDescriptions'] ?? []; $object->authenticatorVersion = $data['authenticatorVersion'] ?? 0; $object->protocolFamily = $data['protocolFamily']; if (isset($data['upv'])) { $upv = $data['upv']; Assertion::isArray($upv, 'Invalid Metadata Statement'); foreach ($upv as $value) { Assertion::isArray($value, 'Invalid Metadata Statement'); $object->upv[] = Version::createFromArray($value); } } $object->assertionScheme = $data['assertionScheme'] ?? null; $object->authenticationAlgorithm = $data['authenticationAlgorithm'] ?? null; $object->authenticationAlgorithms = $data['authenticationAlgorithms'] ?? []; $object->publicKeyAlgAndEncoding = $data['publicKeyAlgAndEncoding'] ?? null; $object->publicKeyAlgAndEncodings = $data['publicKeyAlgAndEncodings'] ?? []; $object->attestationTypes = $data['attestationTypes'] ?? []; if (isset($data['userVerificationDetails'])) { $userVerificationDetails = $data['userVerificationDetails']; Assertion::isArray($userVerificationDetails, 'Invalid Metadata Statement'); foreach ($userVerificationDetails as $value) { Assertion::isArray($value, 'Invalid Metadata Statement'); $object->userVerificationDetails[] = VerificationMethodANDCombinations::createFromArray($value); } } $object->keyProtection = $data['keyProtection'] ?? 0; $object->isKeyRestricted = $data['isKeyRestricted'] ?? null; $object->isFreshUserVerificationRequired = $data['isFreshUserVerificationRequired'] ?? null; $object->matcherProtection = $data['matcherProtection'] ?? 0; $object->cryptoStrength = $data['cryptoStrength'] ?? null; $object->operatingEnv = $data['operatingEnv'] ?? null; $object->attachmentHint = $data['attachmentHint'] ?? 0; $object->isSecondFactorOnly = $data['isSecondFactorOnly'] ?? null; $object->tcDisplay = $data['tcDisplay'] ?? 0; $object->tcDisplayContentType = $data['tcDisplayContentType'] ?? null; if (isset($data['tcDisplayPNGCharacteristics'])) { $tcDisplayPNGCharacteristics = $data['tcDisplayPNGCharacteristics']; Assertion::isArray($tcDisplayPNGCharacteristics, 'Invalid Metadata Statement'); foreach ($tcDisplayPNGCharacteristics as $tcDisplayPNGCharacteristic) { Assertion::isArray($tcDisplayPNGCharacteristic, 'Invalid Metadata Statement'); $object->tcDisplayPNGCharacteristics[] = DisplayPNGCharacteristicsDescriptor::createFromArray($tcDisplayPNGCharacteristic); } } $object->attestationRootCertificates = $data['attestationRootCertificates'] ?? []; $object->ecdaaTrustAnchors = $data['ecdaaTrustAnchors'] ?? []; $object->icon = $data['icon'] ?? null; if (isset($data['supportedExtensions'])) { $supportedExtensions = $data['supportedExtensions']; Assertion::isArray($supportedExtensions, 'Invalid Metadata Statement'); foreach ($supportedExtensions as $supportedExtension) { Assertion::isArray($supportedExtension, 'Invalid Metadata Statement'); $object->supportedExtensions[] = ExtensionDescriptor::createFromArray($supportedExtension); } } $object->rootCertificates = $data['rootCertificates'] ?? []; if (isset($data['statusReports'])) { $reports = $data['statusReports']; Assertion::isArray($reports, 'Invalid Metadata Statement'); foreach ($reports as $report) { Assertion::isArray($report, 'Invalid Metadata Statement'); $object->statusReports[] = StatusReport::createFromArray($report); } } return $object; } public function jsonSerialize(): array { $data = [ 'legalHeader' => $this->legalHeader, 'aaid' => $this->aaid, 'aaguid' => $this->aaguid, 'attestationCertificateKeyIdentifiers' => $this->attestationCertificateKeyIdentifiers, 'description' => $this->description, 'alternativeDescriptions' => $this->alternativeDescriptions, 'authenticatorVersion' => $this->authenticatorVersion, 'protocolFamily' => $this->protocolFamily, 'upv' => $this->upv, 'assertionScheme' => $this->assertionScheme, 'authenticationAlgorithm' => $this->authenticationAlgorithm, 'authenticationAlgorithms' => $this->authenticationAlgorithms, 'publicKeyAlgAndEncoding' => $this->publicKeyAlgAndEncoding, 'publicKeyAlgAndEncodings' => $this->publicKeyAlgAndEncodings, 'attestationTypes' => $this->attestationTypes, 'userVerificationDetails' => $this->userVerificationDetails, 'keyProtection' => $this->keyProtection, 'isKeyRestricted' => $this->isKeyRestricted, 'isFreshUserVerificationRequired' => $this->isFreshUserVerificationRequired, 'matcherProtection' => $this->matcherProtection, 'cryptoStrength' => $this->cryptoStrength, 'operatingEnv' => $this->operatingEnv, 'attachmentHint' => $this->attachmentHint, 'isSecondFactorOnly' => $this->isSecondFactorOnly, 'tcDisplay' => $this->tcDisplay, 'tcDisplayContentType' => $this->tcDisplayContentType, 'tcDisplayPNGCharacteristics' => array_map(static function (DisplayPNGCharacteristicsDescriptor $object): array { return $object->jsonSerialize(); }, $this->tcDisplayPNGCharacteristics), 'attestationRootCertificates' => $this->attestationRootCertificates, 'ecdaaTrustAnchors' => array_map(static function (EcdaaTrustAnchor $object): array { return $object->jsonSerialize(); }, $this->ecdaaTrustAnchors), 'icon' => $this->icon, 'supportedExtensions' => array_map(static function (ExtensionDescriptor $object): array { return $object->jsonSerialize(); }, $this->supportedExtensions), 'rootCertificates' => $this->rootCertificates, 'statusReports' => $this->statusReports, ]; return Utils::filterNullValues($data); } /** * @return StatusReport[] */ public function getStatusReports(): array { return $this->statusReports; } /** * @param StatusReport[] $statusReports */ public function setStatusReports(array $statusReports): self { $this->statusReports = $statusReports; return $this; } /** * @return string[] */ public function getRootCertificates(): array { return $this->rootCertificates; } /** * @param string[] $rootCertificates */ public function setRootCertificates(array $rootCertificates): self { $this->rootCertificates = $rootCertificates; return $this; } }