Skip to content

Commit

Permalink
Adjust credential storage to use base64url instead of plain base64 (#81)
Browse files Browse the repository at this point in the history
This promotes internal consistency of data formats, and due to how the
decoding process works is fully backward-compatible. There are a couple
of remaining touch points, about half of which are related to
certificate formatting which must remain as such.
Firehed authored Mar 26, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent dae5e0a commit 23be5ad
Showing 3 changed files with 41 additions and 8 deletions.
4 changes: 4 additions & 0 deletions src/BinaryString.php
Original file line number Diff line number Diff line change
@@ -26,6 +26,10 @@ public function __construct(
) {
}

/**
* This accepts strings encoded in either standard base64 or base64url,
* since it converts the latter to the former while decoding.
*/
public static function fromBase64Url(string $base64Url): BinaryString
{
$base64 = strtr($base64Url, ['-' => '+', '_' => '/']);
13 changes: 5 additions & 8 deletions src/Codecs/Credential.php
Original file line number Diff line number Diff line change
@@ -22,8 +22,8 @@
* an opaque string without inspection or modification. This library makes
* the following promises:
*
* - The opaque strings will not be outside of the base64 character range
* (A-Za-z0-9/+=)
* - The opaque strings will not be outside of the base64(+url) character range
* (A-Za-z0-9-_/+=)
* - The opaque strings are versioned, and if a new version is introduced,
* there will be an upgrade/conversion path
* - The opaque strings will not exceed 64KiB (65535 bytes)
@@ -46,7 +46,7 @@
* Format spec:
*
* A CredentialObj shall be encoded to a string.
* That string shall be a base64-encoded representation of:
* That string shall be a base64url-encoded representation of:
*
* [ version ] [ version-specific data ]
*
@@ -220,7 +220,7 @@ private function encodeV2(CredentialInterface $credential): string

$binary = pack(self::PACK_UINT8, $version) . $versionSpecificFormat;

return base64_encode($binary);
return (new BinaryString($binary))->toBase64Url();
}

/**
@@ -253,10 +253,7 @@ private static function parseTransportFlags(int $flags): array

public function decode(string $encoded): CredentialInterface
{
$binary = base64_decode($encoded, true);
assert($binary !== false);

$bytes = new BinaryString($binary);
$bytes = BinaryString::fromBase64Url($encoded);

$version = $bytes->readUint8();
assert(($version & 0x80) === 0, 'High bit in version must not be set');
32 changes: 32 additions & 0 deletions tests/Codecs/CredentialTest.php
Original file line number Diff line number Diff line change
@@ -146,6 +146,11 @@ public static function v2Credentials(): array
'v+hUUYF9qszFOeJYoCfBEY2BoiJYIBuUBOTsbnswM3PD9Lj61GTyVQBalOm2' .
'8aW5GWVNe7kOMQ==',
],
'no att cert base64url' => [
'AgsACv69Y58M4y3CsWkAADEXAAAATaUBAgMmIAEhWCBOknC_s6jMNgiYeThI' .
'v-hUUYF9qszFOeJYoCfBEY2BoiJYIBuUBOTsbnswM3PD9Lj61GTyVQBalOm2' .
'8aW5GWVNe7kOMQ',
],
'saved att cert' => [
'AhgACr/Sj9YstWchvM4AADBlAAAATaUBAgMmIAEhWCBOknC/s6jMNgiYeThI' .
'v+hUUYF9qszFOeJYoCfBEY2BoiJYIBuUBOTsbnswM3PD9Lj61GTyVQBalOm2' .
@@ -173,6 +178,33 @@ public static function v2Credentials(): array
'N0J5YmFvQSIsIm9yaWdpbiI6Imh0dHA6Ly9sb2NhbGhvc3Q6Nzc3NyIsInR5' .
'cGUiOiJ3ZWJhdXRobi5jcmVhdGUifQ=='
],
'saved att cert base64url' => [
'AhgACr_Sj9YstWchvM4AADBlAAAATaUBAgMmIAEhWCBOknC_s6jMNgiYeThI' .
'v-hUUYF9qszFOeJYoCfBEY2BoiJYIBuUBOTsbnswM3PD9Lj61GTyVQBalOm2' .
'8aW5GWVNe7kODAAAA20AAAB1o2NmbXRoZmlkby11MmZnYXR0U3RtdKJjeDVj' .
'gVkCMTCCAi0wggEXoAMCAQICBAW2BXkwCwYJKoZIhvcNAQELMC4xLDAqBgNV' .
'BAMTI1l1YmljbyBVMkYgUm9vdCBDQSBTZXJpYWwgNDU3MjAwNjMxMCAXDTE0' .
'MDgwMTAwMDAwMFoYDzIwNTAwOTA0MDAwMDAwWjAoMSYwJAYDVQQDDB1ZdWJp' .
'Y28gVTJGIEVFIFNlcmlhbCA5NTgxNTAzMzBZMBMGByqGSM49AgEGCCqGSM49' .
'AwEHA0IABP243rOh7XDrY2wGbrYAaZal-XD8tduI_DswXUHllm8MG1S4Uv7w' .
'oJB-0X87_8KdTTIbnPioSizqoDjKvTXVmN6jJjAkMCIGCSsGAQQBgsQKAgQV' .
'MS4zLjYuMS40LjEuNDE0ODIuMS4xMAsGCSqGSIb3DQEBCwOCAQEAftP7bMwl' .
'IBP4LyGMKjfaYDHSDn8wgdr8rrEo_H-bIzkUv7ZNYTXxfOIh-nZPRT7xJzqM' .
'6WWVZEK7Lx5HSD9zfcvJi1hTd_71CycOAon4hDbxrc9JsmIe5eMC31VbmrdC' .
'cuBp-RgUmz3sTxIiixDA-I3javWKdLtEK4WuAFNkvaZwIFj8Hy2Hm1MBEepg' .
'6Gxj8X-llEzIPwqiaYSLPuOIpsCeawWVP8u49H6Don4AcqY8Mq1khk6SbXES' .
'-hmX94OWVvuzK-j3iJ0PAUVRmiev3Y5GsEykKQ2FQLY0uIYWHnWIyGKZ3N1k' .
'NdFnijpvCnSCnE3T9ww1JNHd8W14rdIbZGNzaWdYSDBGAiEA6Q_IoHy9emgq' .
'byDa_5id6H0_MJvAkT28HNb0iEO36MUCIQDD-UZZBz0PIZUrJ77OliPPmtFO' .
'SOW_u1vzX7aYe4lcLWhhdXRoRGF0YVjESZYN5YgOjGh0NBcPZHZgW4_krrmi' .
'hjLHmVzzuoMdl2NBAAAAAAAAAAAAAAAAAAAAAAAAAAAAQHyt9XuGzGoH2Hhm' .
'Gh_lNyFaCv-v9V79jigJZuZ5LtnWuOw9Ph-WfrA1HeHw33tqFbQ_5AYjo6E6' .
'atlqFXZ6NRqlAQIDJiABIVggaORWdx8A3Tw55VDl5Hi3H-RC_TxUJvuyeFjT' .
'FHz4zHwiWCC2nNEOYCncBKKLJpU536AHVsp4sHIJWtt8fAqF5ihlmHsiY2hh' .
'bGxlbmdlIjoiNkVScmZFSVNYaXJYTm1iX1hMa0NlM2REdml0cEdkYVlvX3FY' .
'N0J5YmFvQSIsIm9yaWdpbiI6Imh0dHA6Ly9sb2NhbGhvc3Q6Nzc3NyIsInR5' .
'cGUiOiJ3ZWJhdXRobi5jcmVhdGUifQ'
],
];
}

0 comments on commit 23be5ad

Please sign in to comment.