Files
f7cloud_client/3rdparty/web-auth/webauthn-lib/src/CeremonyStep/CheckRelyingPartyIdIdHash.php
T

64 lines
2.7 KiB
PHP

<?php
declare(strict_types=1);
namespace Webauthn\CeremonyStep;
use Webauthn\AuthenticationExtensions\AuthenticationExtensions;
use Webauthn\AuthenticatorAssertionResponse;
use Webauthn\AuthenticatorAttestationResponse;
use Webauthn\Exception\AuthenticatorResponseVerificationException;
use Webauthn\PublicKeyCredentialCreationOptions;
use Webauthn\PublicKeyCredentialRequestOptions;
use Webauthn\PublicKeyCredentialSource;
use Webauthn\U2FPublicKey;
use function is_string;
final class CheckRelyingPartyIdIdHash implements CeremonyStep
{
public function process(
PublicKeyCredentialSource $publicKeyCredentialSource,
AuthenticatorAssertionResponse|AuthenticatorAttestationResponse $authenticatorResponse,
PublicKeyCredentialRequestOptions|PublicKeyCredentialCreationOptions $publicKeyCredentialOptions,
?string $userHandle,
string $host
): void {
$authData = $authenticatorResponse instanceof AuthenticatorAssertionResponse ? $authenticatorResponse->authenticatorData : $authenticatorResponse->attestationObject->authData;
$C = $authenticatorResponse->clientDataJSON;
$attestedCredentialData = $publicKeyCredentialSource->getAttestedCredentialData();
$credentialPublicKey = $attestedCredentialData->credentialPublicKey;
$credentialPublicKey !== null || throw AuthenticatorResponseVerificationException::create(
'No public key available.'
);
$isU2F = U2FPublicKey::isU2FKey($credentialPublicKey);
$rpId = $publicKeyCredentialOptions->rpId ?? $publicKeyCredentialOptions->rp->id ?? $host;
$facetId = $this->getFacetId($rpId, $publicKeyCredentialOptions->extensions, $authData ->extensions);
$rpIdHash = hash('sha256', $isU2F ? $C->origin : $facetId, true);
hash_equals(
$rpIdHash,
$authData
->rpIdHash
) || throw AuthenticatorResponseVerificationException::create('rpId hash mismatch.');
}
private function getFacetId(
string $rpId,
AuthenticationExtensions $authenticationExtensionsClientInputs,
null|AuthenticationExtensions $authenticationExtensionsClientOutputs
): string {
if ($authenticationExtensionsClientOutputs === null || ! $authenticationExtensionsClientInputs->has(
'appid'
) || ! $authenticationExtensionsClientOutputs->has('appid')) {
return $rpId;
}
$appId = $authenticationExtensionsClientInputs->get('appid')
->value;
$wasUsed = $authenticationExtensionsClientOutputs->get('appid')
->value;
if (! is_string($appId) || $wasUsed !== true) {
return $rpId;
}
return $appId;
}
}