Skip to content

Commit

Permalink
fix: fix authenticatorData format (#402)
Browse files Browse the repository at this point in the history
  • Loading branch information
asbiin authored Sep 6, 2022
1 parent 296a804 commit 155ae8c
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 10 deletions.
7 changes: 7 additions & 0 deletions src/Services/Webauthn.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Illuminate\Contracts\Auth\Authenticatable as User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use LaravelWebauthn\Events\WebauthnLogin;
use LaravelWebauthn\Events\WebauthnLoginData;
use LaravelWebauthn\Events\WebauthnRegister;
Expand All @@ -12,8 +13,10 @@
use LaravelWebauthn\Services\Webauthn\CredentialAssertionValidator;
use LaravelWebauthn\Services\Webauthn\CredentialAttestationValidator;
use LaravelWebauthn\Services\Webauthn\RequestOptionsFactory;
use ParagonIE\ConstantTime\Base64UrlSafe;
use Webauthn\PublicKeyCredentialCreationOptions;
use Webauthn\PublicKeyCredentialRequestOptions;
use Webauthn\Util\Base64;

class Webauthn extends WebauthnRepository
{
Expand Down Expand Up @@ -132,6 +135,10 @@ public static function prepareAssertion(User $user): PublicKeyCredentialRequestO
*/
public static function validateAssertion(User $user, array $credentials): bool
{
if (($authenticatorData = Arr::get($credentials, 'response.authenticatorData')) !== null) {
Arr::set($credentials, 'response.authenticatorData', Base64UrlSafe::encodeUnpadded(Base64::decode($authenticatorData)));
}

return app(CredentialAssertionValidator::class)($user, $credentials);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Services/Webauthn/CredentialAttestationValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ protected function pullPublicKey(User $user): PublicKeyCredentialCreationOptions
try {
return PublicKeyCredentialCreationOptions::createFromArray($this->cache->pull($this->cacheKey($user)));
} catch (\Exception $e) {
Log::debug('Webauthn publickKey deserialize error', ['exception' => $e]);
Log::debug('Webauthn publicKey deserialize error', ['exception' => $e]);
abort(404);
}
}
Expand Down
33 changes: 33 additions & 0 deletions tests/Unit/Models/Casts/Base64Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace LaravelWebauthn\Tests\Unit\Models;

use LaravelWebauthn\Models\Casts\Base64;
use LaravelWebauthn\Models\WebauthnKey;
use LaravelWebauthn\Tests\FeatureTestCase;

class Base64Test extends FeatureTestCase
{
/**
* @test
* @dataProvider dataProvider
*/
public function it_deserialize_credentialId($credentialId, $expected)
{
$webauthnKey = new WebauthnKey();

$bin = (new Base64)->get($webauthnKey, 'credentialId', $credentialId, []);

$this->assertEquals($expected, (new Base64)->set($webauthnKey, 'credentialId', $bin, []));
}

public function dataProvider()
{
return [
[
'xrXvxSyol4aHHmmYLBcJyln6pAHgjc/+6UnE2EX4ZGl5Vw82/AjX/5wryErEUfeIBU4djcj2HMXWv0e+Ck/GbA==',
'xrXvxSyol4aHHmmYLBcJyln6pAHgjc_-6UnE2EX4ZGl5Vw82_AjX_5wryErEUfeIBU4djcj2HMXWv0e-Ck_GbA==',
],
];
}
}
16 changes: 8 additions & 8 deletions tests/Unit/Services/WebauthnTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,20 +117,20 @@ public function test_do_authenticate()
$this->assertInstanceOf(\Webauthn\PublicKeyCredentialRequestOptions::class, $publicKey);

$data = [
'id' => Base64UrlSafe::encode($webauthnKey->credentialId),
'id' => Base64UrlSafe::encodeUnpadded($webauthnKey->credentialId),
'rawId' => Base64UrlSafe::encode($webauthnKey->credentialId),
'type' => 'public-key',
'response' => [
'clientDataJSON' => Base64UrlSafe::encode(json_encode([
'clientDataJSON' => Base64UrlSafe::encodeUnpadded(json_encode([
'type' => 'webauthn.get',
'challenge' => Base64UrlSafe::encode($publicKey->getChallenge()),
'challenge' => Base64UrlSafe::encodeUnpadded($publicKey->getChallenge()),
'origin' => 'https://localhost',
'tokenBinding' => [
'status' => 'supported',
'id' => 'id',
],
])),
'authenticatorData' => Base64UrlSafe::encode(
'authenticatorData' => Base64UrlSafe::encodeUnpadded(
hash('sha256', 'localhost', true). // rp_id_hash
pack('C', 65). // flags
pack('N', 1). // signCount
Expand Down Expand Up @@ -176,20 +176,20 @@ public function test_wrong_do_authenticate()
private function getAttestationData($publicKey)
{
return [
'id' => Base64UrlSafe::encode('0'),
'id' => Base64UrlSafe::encodeUnpadded('0'),
'rawId' => Base64UrlSafe::encode('0'),
'type' => 'public-key',
'response' => [
'clientDataJSON' => Base64UrlSafe::encode(json_encode([
'clientDataJSON' => Base64UrlSafe::encodeUnpadded(json_encode([
'type' => 'webauthn.create',
'challenge' => Base64UrlSafe::encode($publicKey->getChallenge()),
'challenge' => Base64UrlSafe::encodeUnpadded($publicKey->getChallenge()),
'origin' => 'https://localhost',
'tokenBinding' => [
'status' => 'supported',
'id' => 'id',
],
])),
'attestationObject' => Base64UrlSafe::encode((string) (new MapObject([
'attestationObject' => Base64UrlSafe::encodeUnpadded((string) (new MapObject([
new MapItem(
new TextStringObject('authData'),
new TextStringObject(
Expand Down
2 changes: 1 addition & 1 deletion tests/database/factories/WebauthnKeyFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
'name' => $faker->word,
'counter' => 0,
'credentialId' => function (array $data) {
return Base64UrlSafe::encode($data['user_id']);
return Base64UrlSafe::encodeUnpadded($data['user_id']);
},
'type' => 'public-key',
'transports' => [],
Expand Down

0 comments on commit 155ae8c

Please sign in to comment.