[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 declare(strict_types=1); 4 5 /* 6 * The MIT License (MIT) 7 * 8 * Copyright (c) 2014-2019 Spomky-Labs 9 * 10 * This software may be modified and distributed under the terms 11 * of the MIT license. See the LICENSE file for details. 12 */ 13 14 namespace Webauthn; 15 16 use Assert\Assertion; 17 use Cose\Algorithm\Algorithm; 18 use Cose\Algorithm\ManagerFactory; 19 use Cose\Algorithm\Signature\ECDSA; 20 use Cose\Algorithm\Signature\EdDSA; 21 use Cose\Algorithm\Signature\RSA; 22 use Psr\Http\Client\ClientInterface; 23 use Psr\Http\Message\RequestFactoryInterface; 24 use Psr\Http\Message\ServerRequestInterface; 25 use Webauthn\AttestationStatement\AndroidKeyAttestationStatementSupport; 26 use Webauthn\AttestationStatement\AndroidSafetyNetAttestationStatementSupport; 27 use Webauthn\AttestationStatement\AttestationObjectLoader; 28 use Webauthn\AttestationStatement\AttestationStatementSupportManager; 29 use Webauthn\AttestationStatement\FidoU2FAttestationStatementSupport; 30 use Webauthn\AttestationStatement\NoneAttestationStatementSupport; 31 use Webauthn\AttestationStatement\PackedAttestationStatementSupport; 32 use Webauthn\AttestationStatement\TPMAttestationStatementSupport; 33 use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs; 34 use Webauthn\AuthenticationExtensions\ExtensionOutputCheckerHandler; 35 use Webauthn\MetadataService\MetadataStatementRepository; 36 use Webauthn\TokenBinding\TokenBindingNotSupportedHandler; 37 38 class Server 39 { 40 /** 41 * @var int 42 */ 43 public $timeout = 60000; 44 45 /** 46 * @var int 47 */ 48 public $challengeSize = 32; 49 50 /** 51 * @var PublicKeyCredentialRpEntity 52 */ 53 private $rpEntity; 54 55 /** 56 * @var ManagerFactory 57 */ 58 private $coseAlgorithmManagerFactory; 59 60 /** 61 * @var PublicKeyCredentialSourceRepository 62 */ 63 private $publicKeyCredentialSourceRepository; 64 65 /** 66 * @var TokenBindingNotSupportedHandler 67 */ 68 private $tokenBindingHandler; 69 70 /** 71 * @var ExtensionOutputCheckerHandler 72 */ 73 private $extensionOutputCheckerHandler; 74 75 /** 76 * @var string[] 77 */ 78 private $selectedAlgorithms; 79 80 /** 81 * @var MetadataStatementRepository|null 82 */ 83 private $metadataStatementRepository; 84 85 /** 86 * @var ClientInterface 87 */ 88 private $httpClient; 89 90 /** 91 * @var string 92 */ 93 private $googleApiKey; 94 95 /** 96 * @var RequestFactoryInterface 97 */ 98 private $requestFactory; 99 100 public function __construct(PublicKeyCredentialRpEntity $relayingParty, PublicKeyCredentialSourceRepository $publicKeyCredentialSourceRepository, ?MetadataStatementRepository $metadataStatementRepository) 101 { 102 $this->rpEntity = $relayingParty; 103 104 $this->coseAlgorithmManagerFactory = new ManagerFactory(); 105 $this->coseAlgorithmManagerFactory->add('RS1', new RSA\RS1()); 106 $this->coseAlgorithmManagerFactory->add('RS256', new RSA\RS256()); 107 $this->coseAlgorithmManagerFactory->add('RS384', new RSA\RS384()); 108 $this->coseAlgorithmManagerFactory->add('RS512', new RSA\RS512()); 109 $this->coseAlgorithmManagerFactory->add('PS256', new RSA\PS256()); 110 $this->coseAlgorithmManagerFactory->add('PS384', new RSA\PS384()); 111 $this->coseAlgorithmManagerFactory->add('PS512', new RSA\PS512()); 112 $this->coseAlgorithmManagerFactory->add('ES256', new ECDSA\ES256()); 113 $this->coseAlgorithmManagerFactory->add('ES256K', new ECDSA\ES256K()); 114 $this->coseAlgorithmManagerFactory->add('ES384', new ECDSA\ES384()); 115 $this->coseAlgorithmManagerFactory->add('ES512', new ECDSA\ES512()); 116 $this->coseAlgorithmManagerFactory->add('Ed25519', new EdDSA\Ed25519()); 117 118 $this->selectedAlgorithms = ['RS256', 'RS512', 'PS256', 'PS512', 'ES256', 'ES512', 'Ed25519']; 119 $this->publicKeyCredentialSourceRepository = $publicKeyCredentialSourceRepository; 120 $this->tokenBindingHandler = new TokenBindingNotSupportedHandler(); 121 $this->extensionOutputCheckerHandler = new ExtensionOutputCheckerHandler(); 122 $this->metadataStatementRepository = $metadataStatementRepository; 123 } 124 125 /** 126 * @param string[] $selectedAlgorithms 127 */ 128 public function setSelectedAlgorithms(array $selectedAlgorithms): void 129 { 130 $this->selectedAlgorithms = $selectedAlgorithms; 131 } 132 133 public function setTokenBindingHandler(TokenBindingNotSupportedHandler $tokenBindingHandler): void 134 { 135 $this->tokenBindingHandler = $tokenBindingHandler; 136 } 137 138 public function addAlgorithm(string $alias, Algorithm $algorithm): void 139 { 140 $this->coseAlgorithmManagerFactory->add($alias, $algorithm); 141 $this->selectedAlgorithms[] = $alias; 142 $this->selectedAlgorithms = array_unique($this->selectedAlgorithms); 143 } 144 145 public function setExtensionOutputCheckerHandler(ExtensionOutputCheckerHandler $extensionOutputCheckerHandler): void 146 { 147 $this->extensionOutputCheckerHandler = $extensionOutputCheckerHandler; 148 } 149 150 /** 151 * @param PublicKeyCredentialDescriptor[] $excludedPublicKeyDescriptors 152 */ 153 public function generatePublicKeyCredentialCreationOptions(PublicKeyCredentialUserEntity $userEntity, ?string $attestationMode = PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_NONE, array $excludedPublicKeyDescriptors = [], ?AuthenticatorSelectionCriteria $criteria = null, ?AuthenticationExtensionsClientInputs $extensions = null): PublicKeyCredentialCreationOptions 154 { 155 $coseAlgorithmManager = $this->coseAlgorithmManagerFactory->create($this->selectedAlgorithms); 156 $publicKeyCredentialParametersList = []; 157 foreach ($coseAlgorithmManager->all() as $algorithm) { 158 $publicKeyCredentialParametersList[] = new PublicKeyCredentialParameters( 159 PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, 160 $algorithm::identifier() 161 ); 162 } 163 $criteria = $criteria ?? new AuthenticatorSelectionCriteria(); 164 $extensions = $extensions ?? new AuthenticationExtensionsClientInputs(); 165 $challenge = random_bytes($this->challengeSize); 166 167 return new PublicKeyCredentialCreationOptions( 168 $this->rpEntity, 169 $userEntity, 170 $challenge, 171 $publicKeyCredentialParametersList, 172 $this->timeout, 173 $excludedPublicKeyDescriptors, 174 $criteria, 175 $attestationMode, 176 $extensions 177 ); 178 } 179 180 /** 181 * @param PublicKeyCredentialDescriptor[] $allowedPublicKeyDescriptors 182 */ 183 public function generatePublicKeyCredentialRequestOptions(?string $userVerification = PublicKeyCredentialRequestOptions::USER_VERIFICATION_REQUIREMENT_PREFERRED, array $allowedPublicKeyDescriptors = [], ?AuthenticationExtensionsClientInputs $extensions = null): PublicKeyCredentialRequestOptions 184 { 185 return new PublicKeyCredentialRequestOptions( 186 random_bytes($this->challengeSize), 187 $this->timeout, 188 $this->rpEntity->getId(), 189 $allowedPublicKeyDescriptors, 190 $userVerification, 191 $extensions ?? new AuthenticationExtensionsClientInputs() 192 ); 193 } 194 195 public function loadAndCheckAttestationResponse(string $data, PublicKeyCredentialCreationOptions $publicKeyCredentialCreationOptions, ServerRequestInterface $serverRequest): PublicKeyCredentialSource 196 { 197 $attestationStatementSupportManager = $this->getAttestationStatementSupportManager(); 198 $attestationObjectLoader = new AttestationObjectLoader($attestationStatementSupportManager); 199 $publicKeyCredentialLoader = new PublicKeyCredentialLoader($attestationObjectLoader); 200 201 $publicKeyCredential = $publicKeyCredentialLoader->load($data); 202 $authenticatorResponse = $publicKeyCredential->getResponse(); 203 Assertion::isInstanceOf($authenticatorResponse, AuthenticatorAttestationResponse::class, 'Not an authenticator attestation response'); 204 205 $authenticatorAttestationResponseValidator = new AuthenticatorAttestationResponseValidator( 206 $attestationStatementSupportManager, 207 $this->publicKeyCredentialSourceRepository, 208 $this->tokenBindingHandler, 209 $this->extensionOutputCheckerHandler 210 ); 211 212 return $authenticatorAttestationResponseValidator->check($authenticatorResponse, $publicKeyCredentialCreationOptions, $serverRequest); 213 } 214 215 public function loadAndCheckAssertionResponse(string $data, PublicKeyCredentialRequestOptions $publicKeyCredentialRequestOptions, ?PublicKeyCredentialUserEntity $userEntity, ServerRequestInterface $serverRequest): PublicKeyCredentialSource 216 { 217 $attestationStatementSupportManager = $this->getAttestationStatementSupportManager(); 218 $attestationObjectLoader = new AttestationObjectLoader($attestationStatementSupportManager); 219 $publicKeyCredentialLoader = new PublicKeyCredentialLoader($attestationObjectLoader); 220 221 $publicKeyCredential = $publicKeyCredentialLoader->load($data); 222 $authenticatorResponse = $publicKeyCredential->getResponse(); 223 Assertion::isInstanceOf($authenticatorResponse, AuthenticatorAssertionResponse::class, 'Not an authenticator assertion response'); 224 225 $authenticatorAssertionResponseValidator = new AuthenticatorAssertionResponseValidator( 226 $this->publicKeyCredentialSourceRepository, 227 null, 228 $this->tokenBindingHandler, 229 $this->extensionOutputCheckerHandler, 230 $this->coseAlgorithmManagerFactory->create($this->selectedAlgorithms) 231 ); 232 233 return $authenticatorAssertionResponseValidator->check( 234 $publicKeyCredential->getRawId(), 235 $authenticatorResponse, 236 $publicKeyCredentialRequestOptions, 237 $serverRequest, 238 null !== $userEntity ? $userEntity->getId() : null 239 ); 240 } 241 242 public function enforceAndroidSafetyNetVerification(ClientInterface $client, string $apiKey, RequestFactoryInterface $requestFactory): void 243 { 244 $this->httpClient = $client; 245 $this->googleApiKey = $apiKey; 246 $this->requestFactory = $requestFactory; 247 } 248 249 private function getAttestationStatementSupportManager(): AttestationStatementSupportManager 250 { 251 $attestationStatementSupportManager = new AttestationStatementSupportManager(); 252 $attestationStatementSupportManager->add(new NoneAttestationStatementSupport()); 253 if (null !== $this->metadataStatementRepository) { 254 $coseAlgorithmManager = $this->coseAlgorithmManagerFactory->create($this->selectedAlgorithms); 255 $attestationStatementSupportManager->add(new FidoU2FAttestationStatementSupport(null, $this->metadataStatementRepository)); 256 $attestationStatementSupportManager->add(new AndroidSafetyNetAttestationStatementSupport($this->httpClient, $this->googleApiKey, $this->requestFactory, 2000, 60000, $this->metadataStatementRepository)); 257 $attestationStatementSupportManager->add(new AndroidKeyAttestationStatementSupport(null, $this->metadataStatementRepository)); 258 $attestationStatementSupportManager->add(new TPMAttestationStatementSupport($this->metadataStatementRepository)); 259 $attestationStatementSupportManager->add(new PackedAttestationStatementSupport(null, $coseAlgorithmManager, $this->metadataStatementRepository)); 260 } 261 262 return $attestationStatementSupportManager; 263 } 264 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |