First release

This commit is contained in:
Italo
2022-06-14 05:17:04 -04:00
commit b60b829b96
119 changed files with 9412 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
<?php
namespace Laragear\WebAuthn\Attestation\Creator\Pipes;
use Closure;
use Laragear\WebAuthn\Attestation\Creator\AttestationCreation;
/**
* @internal
*/
class AddAcceptedAlgorithms
{
/**
* Handle the Attestation creation
*
* @param \Laragear\WebAuthn\Attestation\Creator\AttestationCreation $attestable
* @param \Closure $next
* @return mixed
*/
public function handle(AttestationCreation $attestable, Closure $next): mixed
{
$attestable->json->set('pubKeyCredParams', [
['type' => 'public-key', 'alg' => -7],
['type' => 'public-key', 'alg' => -257],
]);
// Currently we don't support direct attestation. In other words, it won't ask
// for attestation data from the authenticator to cross-check later against
// root certificates. We may add this in the future, but not guaranteed.
$attestable->json->set('attestation', 'none');
return $next($attestable);
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace Laragear\WebAuthn\Attestation\Creator\Pipes;
use Closure;
use Illuminate\Config\Repository;
use Laragear\WebAuthn\Attestation\Creator\AttestationCreation;
/**
* @internal
*/
class AddRelyingParty
{
/**
* Create a new pipe instance.
*
* @param \Illuminate\Config\Repository $config
*/
public function __construct(protected Repository $config)
{
//
}
/**
* Handle the Attestation creation
*
* @param \Laragear\WebAuthn\Attestation\Creator\AttestationCreation $attestable
* @param \Closure $next
* @return mixed
*/
public function handle(AttestationCreation $attestable, Closure $next): mixed
{
$attestable->json->set('rp.name', $this->config->get('webauthn.relying_party.name'));
if ($id = $this->config->get('webauthn.relying_party.id')) {
$attestable->json->set('rp.id', $id);
}
return $next($attestable);
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace Laragear\WebAuthn\Attestation\Creator\Pipes;
use Closure;
use Illuminate\Support\Str;
use Laragear\WebAuthn\Attestation\Creator\AttestationCreation;
/**
* @internal
*/
class AddUserDescriptor
{
/**
* Handle the Attestation creation
*
* @param \Laragear\WebAuthn\Attestation\Creator\AttestationCreation $attestable
* @param \Closure $next
* @return mixed
*/
public function handle(AttestationCreation $attestable, Closure $next): mixed
{
$config = $attestable->user->webAuthnData();
// Create a new User UUID if it doesn't existe already in the credentials.
$config['id'] = $attestable->user->webAuthnCredentials()->value('user_id')
?: Str::uuid()->getHex()->toString();
$attestable->json->set('user', $config);
return $next($attestable);
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Laragear\WebAuthn\Attestation\Creator\Pipes;
use Closure;
use Illuminate\Config\Repository;
use Illuminate\Contracts\Cache\Factory;
use Laragear\WebAuthn\Attestation\Creator\AttestationCreation;
use Laragear\WebAuthn\Attestation\SessionChallenge;
/**
* @internal
*/
class CreateAttestationChallenge
{
use SessionChallenge;
/**
* Create a new pipe instance.
*
* @param \Illuminate\Config\Repository $config
* @param \Illuminate\Contracts\Cache\Factory $cache
*/
public function __construct(protected Repository $config, protected Factory $cache)
{
//
}
/**
* Handle the Attestation creation
*
* @param \Laragear\WebAuthn\Attestation\Creator\AttestationCreation $attestable
* @param \Closure $next
* @return mixed
*/
public function handle(AttestationCreation $attestable, Closure $next): mixed
{
$attestable->json->set('timeout', $this->config->get('webauthn.challenge.timeout') * 1000);
$challenge = $this->storeChallenge($attestable->request, $attestable->userVerification, [
'user_uuid' => $attestable->json->get('user.id'),
'user_handle' => $attestable->json->get('user.name'),
]);
$attestable->json->set('challenge', $challenge->data);
return $next($attestable);
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Laragear\WebAuthn\Attestation\Creator\Pipes;
use Closure;
use Laragear\WebAuthn\Attestation\Creator\AttestationCreation;
use Laragear\WebAuthn\Contracts\WebAuthnAuthenticatable;
use Laragear\WebAuthn\Models\WebAuthnCredential;
/**
* @internal
*/
class MayPreventDuplicateCredentials
{
/**
* Handle the Attestation creation
*
* @param \Laragear\WebAuthn\Attestation\Creator\AttestationCreation $attestable
* @param \Closure $next
* @return mixed
*/
public function handle(AttestationCreation $attestable, Closure $next): mixed
{
if ($attestable->uniqueCredentials) {
$attestable->json->set('excludeCredentials', $this->credentials($attestable->user));
}
return $next($attestable);
}
/**
* Returns a collection of credentials ready to be inserted into the Attestable JSON.
*
* @param \Laragear\WebAuthn\Contracts\WebAuthnAuthenticatable $user
* @return array
*/
protected function credentials(WebAuthnAuthenticatable $user): array
{
return $user
->webAuthnCredentials()
->get(['id', 'transports'])
->map(static function (WebAuthnCredential $credential): array {
return array_filter([
'id'=> $credential->getKey(),
'type' => 'public-key',
'transports' => $credential->transports
]);
})
->toArray();
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Laragear\WebAuthn\Attestation\Creator\Pipes;
use Closure;
use Laragear\WebAuthn\Attestation\Creator\AttestationCreation;
/**
* @internal
*/
class MayRequireUserVerification
{
/**
* Handle the Attestation creation
*
* @param \Laragear\WebAuthn\Attestation\Creator\AttestationCreation $attestable
* @param \Closure $next
* @return mixed
*/
public function handle(AttestationCreation $attestable, Closure $next): mixed
{
if ($attestable->userVerification) {
$attestable->json->set('authenticatorSelection.userVerification', $attestable->userVerification);
}
return $next($attestable);
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Laragear\WebAuthn\Attestation\Creator\Pipes;
use Closure;
use Laragear\WebAuthn\Attestation\Creator\AttestationCreation;
use Laragear\WebAuthn\WebAuthn;
/**
* @internal
*/
class SetResidentKeyConfiguration
{
/**
* Handle the Attestation creation
*
* @param \Laragear\WebAuthn\Attestation\Creator\AttestationCreation $attestable
* @param \Closure $next
* @return mixed
*/
public function handle(AttestationCreation $attestable, Closure $next): mixed
{
if ($attestable->residentKey) {
$attestable->json->set('authenticatorSelection.residentKey', $attestable->residentKey);
$verifiesUser = $attestable->residentKey === WebAuthn::RESIDENT_KEY_REQUIRED;
$attestable->json->set('authenticatorSelection.requireResidentKey', $verifiesUser);
if ($verifiesUser) {
$attestable->userVerification = WebAuthn::USER_VERIFICATION_REQUIRED;
}
}
return $next($attestable);
}
}