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.
  • Loading branch information
Firehed committed Mar 26, 2024
1 parent dae5e0a commit 23be5ad
Show file tree
Hide file tree
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
Expand Up @@ -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, ['-' => '+', '_' => '/']);
Expand Down
13 changes: 5 additions & 8 deletions src/Codecs/Credential.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 ]
*
Expand Down Expand Up @@ -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();
}

/**
Expand Down Expand Up @@ -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');
Expand Down
32 changes: 32 additions & 0 deletions tests/Codecs/CredentialTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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' .
Expand Down Expand Up @@ -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'
],
];
}

Expand Down

0 comments on commit 23be5ad

Please sign in to comment.