Skip to content

Commit

Permalink
Restructure base64URL handling (#46)
Browse files Browse the repository at this point in the history
The conversion is only really done in the context of a BinaryString, so
having the logic split out into a different class didn't make a lot of
sense. As a result, it's being consolidated. In addition to
organization, this should make completion of #41 easier, specifically
for emitting formats that match
`PublicKeyCredential.parse{Creation|Request}OptionsFromJSON()` methods.
Firehed authored Nov 18, 2023
1 parent bd0fae5 commit f89a112
Showing 6 changed files with 27 additions and 29 deletions.
6 changes: 6 additions & 0 deletions src/BinaryString.php
Original file line number Diff line number Diff line change
@@ -41,6 +41,12 @@ public static function fromBase64(string $base64): BinaryString
return new BinaryString($binary);
}

public function toBase64Url(): string
{
$base64 = base64_encode($this->unwrap());
return rtrim(strtr($base64, ['+' => '-', '/' => '_']), '=');
}

/**
* Turns a list of 8-bit integers into a BinaryString
*
23 changes: 0 additions & 23 deletions src/Codecs/Base64Url.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/CreateResponse.php
Original file line number Diff line number Diff line change
@@ -58,7 +58,7 @@ public function verify(
$this->fail('7.1.8', 'C.challenge');
}

$b64u = Codecs\Base64Url::encode($challenge->getBinary()->unwrap());
$b64u = $challenge->getBinary()->toBase64Url();
if (!hash_equals($b64u, $cdjChallenge)) {
$this->fail('7.1.8', 'C.challenge');
}
2 changes: 1 addition & 1 deletion src/GetResponse.php
Original file line number Diff line number Diff line change
@@ -109,7 +109,7 @@ public function verify(
$this->fail('7.2.12', 'C.challenge');
}

$b64u = Codecs\Base64Url::encode($challenge->getBinary()->unwrap());
$b64u = $challenge->getBinary()->toBase64Url();
if (!hash_equals($b64u, $cdjChallenge)) {
$this->fail('7.2.12', 'C.challenge');
}
15 changes: 15 additions & 0 deletions tests/BinaryStringTest.php
Original file line number Diff line number Diff line change
@@ -90,6 +90,21 @@ public function testReadUint32(): void
self::assertSame('plaintext', $this->default->getRemaining());
}

public function testBase64UrlIdentity(): void
{
$data = random_bytes(64);
$wrapped = new BinaryString($data);
$b64u = $wrapped->toBase64Url();
$decoded = BinaryString::fromBase64Url($b64u);
self::assertSame($data, $decoded->unwrap());
}

public function testBase64UrlDecode(): void
{
$decoded = BinaryString::fromBase64Url('PDw_Pz8-Pg');
self::assertSame('<<???>>', $decoded->unwrap());
}

/**
* @return array{BinaryString, BinaryString, bool}[]
*/
8 changes: 4 additions & 4 deletions tests/ChallengeManagerTestTrait.php
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ public function testMostRecentChallengeCanBeRetrieved(): void
{
$cm = $this->getChallengeManager();
$c = $cm->createChallenge();
$cdjValue = Codecs\Base64Url::encode($c->getBinary()->unwrap());
$cdjValue = $c->getBinary()->toBase64Url();

$found = $cm->useFromClientDataJSON($cdjValue);
self::assertInstanceOf(ChallengeInterface::class, $found);
@@ -32,7 +32,7 @@ public function testMostRecentChallengeCanBeRetrievedOnlyOnce(): void
{
$cm = $this->getChallengeManager();
$c = $cm->createChallenge();
$cdjValue = Codecs\Base64Url::encode($c->getBinary()->unwrap());
$cdjValue = $c->getBinary()->toBase64Url();

$found = $cm->useFromClientDataJSON($cdjValue);
$again = $cm->useFromClientDataJSON($cdjValue);
@@ -46,7 +46,7 @@ public function testNoChallengeIsReturnedIfManagerIsEmpty(): void
$cm = $this->getChallengeManager();

$c = Challenge::random();
$cdjValue = Codecs\Base64Url::encode($c->getBinary()->unwrap());
$cdjValue = $c->getBinary()->toBase64Url();

$found = $cm->useFromClientDataJSON($cdjValue);

@@ -59,7 +59,7 @@ public function testRetrievalDoesNotCreateChallengeFromUserData(): void
$c = $cm->createChallenge();

$userChallenge = Challenge::random();
$cdjValue = Codecs\Base64Url::encode($userChallenge->getBinary()->unwrap());
$cdjValue = $userChallenge->getBinary()->toBase64Url();

$retrieved = $cm->useFromClientDataJSON($cdjValue);
// The implmentation may return the previously-stored value or null,

0 comments on commit f89a112

Please sign in to comment.