web-base/Core/Objects/TwoFactor/AuthenticationData.class.php

95 lines
2.7 KiB
PHP
Raw Normal View History

2022-02-20 16:53:26 +01:00
<?php
2022-11-18 18:06:46 +01:00
namespace Core\Objects\TwoFactor;
2022-02-20 16:53:26 +01:00
2022-11-18 18:06:46 +01:00
use Core\Objects\ApiObject;
2022-02-20 16:53:26 +01:00
class AuthenticationData extends ApiObject {
2024-04-07 18:29:33 +02:00
use CBORDecoder;
const FLAG_USER_PRESENT = 1;
const FLAG_USER_VERIFIED = 4;
const FLAG_ATTESTED_DATA_INCLUDED = 64;
const FLAG_EXTENSION_DATA_INCLUDED = 128;
2022-02-20 16:53:26 +01:00
private string $rpIDHash;
private int $flags;
2024-04-07 18:29:33 +02:00
private int $signCount;
2022-02-20 16:53:26 +01:00
private string $aaguid;
private string $credentialID;
2024-04-07 18:29:33 +02:00
private array $extensions;
2022-02-20 16:53:26 +01:00
private PublicKey $publicKey;
public function __construct(string $buffer) {
2024-04-07 18:29:33 +02:00
$bufferLength = strlen($buffer);
if ($bufferLength < 32 + 1 + 4) {
2022-02-20 16:53:26 +01:00
throw new \Exception("Invalid authentication data buffer size");
}
$offset = 0;
$this->rpIDHash = substr($buffer, $offset, 32); $offset += 32;
2024-04-07 18:29:33 +02:00
$this->flags = ord(substr($buffer, $offset, 1)); $offset += 1;
$this->signCount = unpack("N", substr($buffer, $offset, 4))[1]; $offset += 4;
2022-02-20 16:53:26 +01:00
2024-04-07 18:29:33 +02:00
if ($this->attestedCredentialData()) {
2022-02-20 16:53:26 +01:00
$this->aaguid = substr($buffer, $offset, 16); $offset += 16;
2024-04-07 18:29:33 +02:00
$credentialIdLength = unpack("n", substr($buffer, $offset, 4))[1]; $offset += 2;
2022-02-20 16:53:26 +01:00
$this->credentialID = substr($buffer, $offset, $credentialIdLength); $offset += $credentialIdLength;
2024-04-07 18:29:33 +02:00
if ($offset < $bufferLength) {
$publicKeyData = $this->decode(substr($buffer, $offset));
$this->publicKey = new PublicKey($publicKeyData);
// TODO: we should add $publicKeyData->length to $offset, but it's not implemented yet?;
}
}
if ($this->hasExtensionData()) {
// not supported yet
2022-02-20 16:53:26 +01:00
}
}
public function jsonSerialize(): array {
return [
"rpIDHash" => base64_encode($this->rpIDHash),
"flags" => $this->flags,
2024-04-07 18:29:33 +02:00
"signCount" => $this->signCount,
2022-02-20 16:53:26 +01:00
"aaguid" => base64_encode($this->aaguid),
"credentialID" => base64_encode($this->credentialID),
"publicKey" => $this->publicKey->jsonSerialize()
];
}
public function getHash(): string {
return $this->rpIDHash;
}
public function verifyIntegrity(string $rp): bool {
return $this->rpIDHash === hash("sha256", $rp, true);
}
public function isUserPresent(): bool {
2024-04-07 18:29:33 +02:00
return boolval($this->flags & self::FLAG_USER_PRESENT);
2022-02-20 16:53:26 +01:00
}
public function isUserVerified(): bool {
2024-04-07 18:29:33 +02:00
return boolval($this->flags & self::FLAG_USER_VERIFIED);
2022-02-20 16:53:26 +01:00
}
public function attestedCredentialData(): bool {
2024-04-07 18:29:33 +02:00
return boolval($this->flags & self::FLAG_ATTESTED_DATA_INCLUDED);
2022-02-20 16:53:26 +01:00
}
public function hasExtensionData(): bool {
2024-04-07 18:29:33 +02:00
return boolval($this->flags & self::FLAG_EXTENSION_DATA_INCLUDED);
2022-02-20 16:53:26 +01:00
}
public function getPublicKey(): PublicKey {
return $this->publicKey;
}
2024-04-07 18:29:33 +02:00
public function getCredentialID(): string {
2022-02-20 16:53:26 +01:00
return $this->credentialID;
}
}