Skip to content

Commit 2d93c73

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 2d93c73

File tree

1 file changed

+43
-13
lines changed

1 file changed

+43
-13
lines changed

src/Library/Core/Util/Base64UrlSafe.php

Lines changed: 43 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,16 @@ 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(
96+
self::safeSubstr($encodedString, 0, $srcLen),
97+
SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING
98+
);
99+
} catch (SodiumException $ex) {
100+
throw new RangeException($ex->getMessage(), $ex->getCode(), $ex);
101+
}
102+
}
68103
} else {
69104
$encodedString = rtrim($encodedString, '=');
70105
$srcLen = self::safeStrlen($encodedString);
@@ -120,26 +155,21 @@ public static function decode(string $encodedString, bool $strictPadding = false
120155
return $dest;
121156
}
122157

123-
public static function decodeNoPadding(string $encodedString): string
158+
public static function decodeNoPadding(#[SensitiveParameter] string $encodedString): string
124159
{
125160
$srcLen = self::safeStrlen($encodedString);
126161
if ($srcLen === 0) {
127162
return '';
128163
}
129164
if (($srcLen & 3) === 0) {
130-
if ($encodedString[$srcLen - 1] === '=') {
165+
if ($encodedString[$srcLen - 1] === '=' || $encodedString[$srcLen - 2] === '=') {
131166
throw new InvalidArgumentException("decodeNoPadding() doesn't tolerate padding");
132167
}
133-
if (($srcLen & 3) > 1) {
134-
if ($encodedString[$srcLen - 2] === '=') {
135-
throw new InvalidArgumentException("decodeNoPadding() doesn't tolerate padding");
136-
}
137-
}
138168
}
139169
return static::decode($encodedString, true);
140170
}
141171

142-
private static function doEncode(string $src, bool $pad = true): string
172+
private static function doEncode(#[SensitiveParameter] string $src, bool $pad = true): string
143173
{
144174
$dest = '';
145175
$srcLen = self::safeStrlen($src);
@@ -204,12 +234,12 @@ private static function encode6Bits(int $src): string
204234
return pack('C', $src + $diff);
205235
}
206236

207-
private static function safeStrlen(string $str): int
237+
private static function safeStrlen(#[SensitiveParameter] string $str): int
208238
{
209239
return strlen($str);
210240
}
211241

212-
private static function safeSubstr(string $str, int $start = 0, $length = null): string
242+
private static function safeSubstr(#[SensitiveParameter] string $str, int $start = 0, $length = null): string
213243
{
214244
if ($length === 0) {
215245
return '';

0 commit comments

Comments
 (0)