Skip to content

Commit 5af2498

Browse files
committed
Improve Base64UrlSafe performance when ext-sodium is installed
These adjustments are only applying the changes made in paragonie/constant_time_encoding between 2.6.3 and 2.8.2 See: https://github.com/paragonie/constant_time_encoding/compare/v2.6.3..v2.8.2
1 parent 795bb30 commit 5af2498

File tree

1 file changed

+40
-13
lines changed

1 file changed

+40
-13
lines changed

src/Library/Core/Util/Base64UrlSafe.php

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,18 @@
66

77
use InvalidArgumentException;
88
use RangeException;
9+
use SensitiveParameter;
10+
use SodiumException;
11+
use function extension_loaded;
12+
use function pack;
13+
use function rtrim;
14+
use function sodium_base642bin;
15+
use function sodium_bin2base64;
916
use function strlen;
17+
use function substr;
18+
use function unpack;
19+
use const SODIUM_BASE64_VARIANT_URLSAFE;
20+
use const SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING;
1021

1122
/**
1223
* Copyright (c) 2016 - 2022 Paragon Initiative Enterprises.
@@ -33,17 +44,31 @@
3344

3445
final readonly class Base64UrlSafe
3546
{
36-
public static function encode(string $binString): string
47+
public static function encode(#[SensitiveParameter] string $binString): string
3748
{
49+
if (extension_loaded('sodium')) {
50+
try {
51+
return sodium_bin2base64($binString, SODIUM_BASE64_VARIANT_URLSAFE);
52+
} catch (SodiumException $ex) {
53+
throw new RangeException($ex->getMessage(), $ex->getCode(), $ex);
54+
}
55+
}
3856
return static::doEncode($binString, true);
3957
}
4058

41-
public static function encodeUnpadded(string $src): string
59+
public static function encodeUnpadded(#[SensitiveParameter] string $src): string
4260
{
61+
if (extension_loaded('sodium')) {
62+
try {
63+
return sodium_bin2base64($src, SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING);
64+
} catch (SodiumException $ex) {
65+
throw new RangeException($ex->getMessage(), $ex->getCode(), $ex);
66+
}
67+
}
4368
return static::doEncode($src, false);
4469
}
4570

46-
public static function decode(string $encodedString, bool $strictPadding = false): string
71+
public static function decode(#[SensitiveParameter] string $encodedString, bool $strictPadding = false): string
4772
{
4873
$srcLen = self::safeStrlen($encodedString);
4974
if ($srcLen === 0) {
@@ -65,6 +90,13 @@ public static function decode(string $encodedString, bool $strictPadding = false
6590
if ($encodedString[$srcLen - 1] === '=') {
6691
throw new RangeException('Incorrect padding');
6792
}
93+
if (extension_loaded('sodium')) {
94+
try {
95+
return sodium_base642bin(self::safeSubstr($encodedString, 0, $srcLen), SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING);
96+
} catch (SodiumException $ex) {
97+
throw new RangeException($ex->getMessage(), $ex->getCode(), $ex);
98+
}
99+
}
68100
} else {
69101
$encodedString = rtrim($encodedString, '=');
70102
$srcLen = self::safeStrlen($encodedString);
@@ -120,26 +152,21 @@ public static function decode(string $encodedString, bool $strictPadding = false
120152
return $dest;
121153
}
122154

123-
public static function decodeNoPadding(string $encodedString): string
155+
public static function decodeNoPadding(#[SensitiveParameter] string $encodedString): string
124156
{
125157
$srcLen = self::safeStrlen($encodedString);
126158
if ($srcLen === 0) {
127159
return '';
128160
}
129161
if (($srcLen & 3) === 0) {
130-
if ($encodedString[$srcLen - 1] === '=') {
162+
if ($encodedString[$srcLen - 1] === '=' || $encodedString[$srcLen - 2] === '=') {
131163
throw new InvalidArgumentException("decodeNoPadding() doesn't tolerate padding");
132164
}
133-
if (($srcLen & 3) > 1) {
134-
if ($encodedString[$srcLen - 2] === '=') {
135-
throw new InvalidArgumentException("decodeNoPadding() doesn't tolerate padding");
136-
}
137-
}
138165
}
139166
return static::decode($encodedString, true);
140167
}
141168

142-
private static function doEncode(string $src, bool $pad = true): string
169+
private static function doEncode(#[SensitiveParameter] string $src, bool $pad = true): string
143170
{
144171
$dest = '';
145172
$srcLen = self::safeStrlen($src);
@@ -204,12 +231,12 @@ private static function encode6Bits(int $src): string
204231
return pack('C', $src + $diff);
205232
}
206233

207-
private static function safeStrlen(string $str): int
234+
private static function safeStrlen(#[SensitiveParameter] string $str): int
208235
{
209236
return strlen($str);
210237
}
211238

212-
private static function safeSubstr(string $str, int $start = 0, $length = null): string
239+
private static function safeSubstr(#[SensitiveParameter] string $str, int $start = 0, $length = null): string
213240
{
214241
if ($length === 0) {
215242
return '';

0 commit comments

Comments
 (0)