6
6
7
7
use InvalidArgumentException ;
8
8
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 ;
9
16
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 ;
10
21
11
22
/**
12
23
* Copyright (c) 2016 - 2022 Paragon Initiative Enterprises.
33
44
34
45
final readonly class Base64UrlSafe
35
46
{
36
- public static function encode (string $ binString ): string
47
+ public static function encode (#[SensitiveParameter] string $ binString ): string
37
48
{
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
+ }
38
56
return static ::doEncode ($ binString , true );
39
57
}
40
58
41
- public static function encodeUnpadded (string $ src ): string
59
+ public static function encodeUnpadded (#[SensitiveParameter] string $ src ): string
42
60
{
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
+ }
43
68
return static ::doEncode ($ src , false );
44
69
}
45
70
46
- public static function decode (string $ encodedString , bool $ strictPadding = false ): string
71
+ public static function decode (#[SensitiveParameter] string $ encodedString , bool $ strictPadding = false ): string
47
72
{
48
73
$ srcLen = self ::safeStrlen ($ encodedString );
49
74
if ($ srcLen === 0 ) {
@@ -65,6 +90,13 @@ public static function decode(string $encodedString, bool $strictPadding = false
65
90
if ($ encodedString [$ srcLen - 1 ] === '= ' ) {
66
91
throw new RangeException ('Incorrect padding ' );
67
92
}
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
+ }
68
100
} else {
69
101
$ encodedString = rtrim ($ encodedString , '= ' );
70
102
$ srcLen = self ::safeStrlen ($ encodedString );
@@ -120,26 +152,21 @@ public static function decode(string $encodedString, bool $strictPadding = false
120
152
return $ dest ;
121
153
}
122
154
123
- public static function decodeNoPadding (string $ encodedString ): string
155
+ public static function decodeNoPadding (#[SensitiveParameter] string $ encodedString ): string
124
156
{
125
157
$ srcLen = self ::safeStrlen ($ encodedString );
126
158
if ($ srcLen === 0 ) {
127
159
return '' ;
128
160
}
129
161
if (($ srcLen & 3 ) === 0 ) {
130
- if ($ encodedString [$ srcLen - 1 ] === '= ' ) {
162
+ if ($ encodedString [$ srcLen - 1 ] === '= ' || $ encodedString [ $ srcLen - 2 ] === ' = ' ) {
131
163
throw new InvalidArgumentException ("decodeNoPadding() doesn't tolerate padding " );
132
164
}
133
- if (($ srcLen & 3 ) > 1 ) {
134
- if ($ encodedString [$ srcLen - 2 ] === '= ' ) {
135
- throw new InvalidArgumentException ("decodeNoPadding() doesn't tolerate padding " );
136
- }
137
- }
138
165
}
139
166
return static ::decode ($ encodedString , true );
140
167
}
141
168
142
- private static function doEncode (string $ src , bool $ pad = true ): string
169
+ private static function doEncode (#[SensitiveParameter] string $ src , bool $ pad = true ): string
143
170
{
144
171
$ dest = '' ;
145
172
$ srcLen = self ::safeStrlen ($ src );
@@ -204,12 +231,12 @@ private static function encode6Bits(int $src): string
204
231
return pack ('C ' , $ src + $ diff );
205
232
}
206
233
207
- private static function safeStrlen (string $ str ): int
234
+ private static function safeStrlen (#[SensitiveParameter] string $ str ): int
208
235
{
209
236
return strlen ($ str );
210
237
}
211
238
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
213
240
{
214
241
if ($ length === 0 ) {
215
242
return '' ;
0 commit comments