Rev 827 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 827 | Rev 874 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | <?php |
1 | <?php |
2 | declare(strict_types=1); |
2 | declare(strict_types=1); |
3 | namespace ParagonIE\ConstantTime; |
3 | namespace ParagonIE\ConstantTime; |
4 | 4 | ||
- | 5 | use InvalidArgumentException; |
|
- | 6 | use RangeException; |
|
- | 7 | use TypeError; |
|
- | 8 | ||
5 | /** |
9 | /** |
6 | * Copyright (c) 2016 - 2018 Paragon Initiative Enterprises. |
10 | * Copyright (c) 2016 - 2022 Paragon Initiative Enterprises. |
7 | * Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com) |
11 | * Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com) |
8 | * |
12 | * |
9 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
13 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | * of this software and associated documentation files (the "Software"), to deal |
14 | * of this software and associated documentation files (the "Software"), to deal |
11 | * in the Software without restriction, including without limitation the rights |
15 | * in the Software without restriction, including without limitation the rights |
Line 38... | Line 42... | ||
38 | * |
42 | * |
39 | * Base64 character set "[A-Z][a-z][0-9]+/" |
43 | * Base64 character set "[A-Z][a-z][0-9]+/" |
40 | * |
44 | * |
41 | * @param string $binString |
45 | * @param string $binString |
42 | * @return string |
46 | * @return string |
- | 47 | * |
|
43 | * @throws \TypeError |
48 | * @throws TypeError |
44 | */ |
49 | */ |
45 | public static function encode(string $binString): string |
50 | public static function encode(string $binString): string |
46 | { |
51 | { |
47 | return static::doEncode($binString, true); |
52 | return static::doEncode($binString, true); |
48 | } |
53 | } |
Line 52... | Line 57... | ||
52 | * |
57 | * |
53 | * Base64 character set "[A-Z][a-z][0-9]+/" |
58 | * Base64 character set "[A-Z][a-z][0-9]+/" |
54 | * |
59 | * |
55 | * @param string $src |
60 | * @param string $src |
56 | * @return string |
61 | * @return string |
- | 62 | * |
|
57 | * @throws \TypeError |
63 | * @throws TypeError |
58 | */ |
64 | */ |
59 | public static function encodeUnpadded(string $src): string |
65 | public static function encodeUnpadded(string $src): string |
60 | { |
66 | { |
61 | return static::doEncode($src, false); |
67 | return static::doEncode($src, false); |
62 | } |
68 | } |
63 | 69 | ||
64 | /** |
70 | /** |
65 | * @param string $src |
71 | * @param string $src |
66 | * @param bool $pad Include = padding? |
72 | * @param bool $pad Include = padding? |
67 | * @return string |
73 | * @return string |
- | 74 | * |
|
68 | * @throws \TypeError |
75 | * @throws TypeError |
69 | */ |
76 | */ |
70 | protected static function doEncode(string $src, bool $pad = true): string |
77 | protected static function doEncode(string $src, bool $pad = true): string |
71 | { |
78 | { |
72 | $dest = ''; |
79 | $dest = ''; |
73 | $srcLen = Binary::safeStrlen($src); |
80 | $srcLen = Binary::safeStrlen($src); |
Line 117... | Line 124... | ||
117 | * Base64 character set "./[A-Z][a-z][0-9]" |
124 | * Base64 character set "./[A-Z][a-z][0-9]" |
118 | * |
125 | * |
119 | * @param string $encodedString |
126 | * @param string $encodedString |
120 | * @param bool $strictPadding |
127 | * @param bool $strictPadding |
121 | * @return string |
128 | * @return string |
- | 129 | * |
|
122 | * @throws \RangeException |
130 | * @throws RangeException |
123 | * @throws \TypeError |
131 | * @throws TypeError |
124 | * @psalm-suppress RedundantCondition |
132 | * @psalm-suppress RedundantCondition |
125 | */ |
133 | */ |
126 | public static function decode(string $encodedString, bool $strictPadding = false): string |
134 | public static function decode(string $encodedString, bool $strictPadding = false): string |
127 | { |
135 | { |
128 | // Remove padding |
136 | // Remove padding |
Line 139... | Line 147... | ||
139 | $srcLen--; |
147 | $srcLen--; |
140 | } |
148 | } |
141 | } |
149 | } |
142 | } |
150 | } |
143 | if (($srcLen & 3) === 1) { |
151 | if (($srcLen & 3) === 1) { |
144 | throw new \RangeException( |
152 | throw new RangeException( |
145 | 'Incorrect padding' |
153 | 'Incorrect padding' |
146 | ); |
154 | ); |
147 | } |
155 | } |
148 | if ($encodedString[$srcLen - 1] === '=') { |
156 | if ($encodedString[$srcLen - 1] === '=') { |
149 | throw new \RangeException( |
157 | throw new RangeException( |
150 | 'Incorrect padding' |
158 | 'Incorrect padding' |
151 | ); |
159 | ); |
152 | } |
160 | } |
153 | } else { |
161 | } else { |
154 | $encodedString = \rtrim($encodedString, '='); |
162 | $encodedString = \rtrim($encodedString, '='); |
Line 187... | Line 195... | ||
187 | 'CC', |
195 | 'CC', |
188 | ((($c0 << 2) | ($c1 >> 4)) & 0xff), |
196 | ((($c0 << 2) | ($c1 >> 4)) & 0xff), |
189 | ((($c1 << 4) | ($c2 >> 2)) & 0xff) |
197 | ((($c1 << 4) | ($c2 >> 2)) & 0xff) |
190 | ); |
198 | ); |
191 | $err |= ($c0 | $c1 | $c2) >> 8; |
199 | $err |= ($c0 | $c1 | $c2) >> 8; |
- | 200 | if ($strictPadding) { |
|
- | 201 | $err |= ($c2 << 6) & 0xff; |
|
- | 202 | } |
|
192 | } elseif ($i + 1 < $srcLen) { |
203 | } elseif ($i + 1 < $srcLen) { |
193 | $c1 = static::decode6Bits($chunk[2]); |
204 | $c1 = static::decode6Bits($chunk[2]); |
194 | $dest .= \pack( |
205 | $dest .= \pack( |
195 | 'C', |
206 | 'C', |
196 | ((($c0 << 2) | ($c1 >> 4)) & 0xff) |
207 | ((($c0 << 2) | ($c1 >> 4)) & 0xff) |
197 | ); |
208 | ); |
198 | $err |= ($c0 | $c1) >> 8; |
209 | $err |= ($c0 | $c1) >> 8; |
- | 210 | if ($strictPadding) { |
|
- | 211 | $err |= ($c1 << 4) & 0xff; |
|
- | 212 | } |
|
199 | } elseif ($strictPadding) { |
213 | } elseif ($strictPadding) { |
200 | $err |= 1; |
214 | $err |= 1; |
201 | } |
215 | } |
202 | } |
216 | } |
203 | $check = ($err === 0); |
217 | $check = ($err === 0); |
204 | if (!$check) { |
218 | if (!$check) { |
205 | throw new \RangeException( |
219 | throw new RangeException( |
206 | 'Base64::decode() only expects characters in the correct base64 alphabet' |
220 | 'Base64::decode() only expects characters in the correct base64 alphabet' |
207 | ); |
221 | ); |
208 | } |
222 | } |
209 | return $dest; |
223 | return $dest; |
210 | } |
224 | } |
211 | 225 | ||
212 | /** |
226 | /** |
- | 227 | * @param string $encodedString |
|
- | 228 | * @return string |
|
- | 229 | */ |
|
- | 230 | public static function decodeNoPadding(string $encodedString): string |
|
- | 231 | { |
|
- | 232 | $srcLen = Binary::safeStrlen($encodedString); |
|
- | 233 | if ($srcLen === 0) { |
|
- | 234 | return ''; |
|
- | 235 | } |
|
- | 236 | if (($srcLen & 3) === 0) { |
|
- | 237 | if ($encodedString[$srcLen - 1] === '=') { |
|
- | 238 | throw new InvalidArgumentException( |
|
- | 239 | "decodeNoPadding() doesn't tolerate padding" |
|
- | 240 | ); |
|
- | 241 | } |
|
- | 242 | if (($srcLen & 3) > 1) { |
|
- | 243 | if ($encodedString[$srcLen - 2] === '=') { |
|
- | 244 | throw new InvalidArgumentException( |
|
- | 245 | "decodeNoPadding() doesn't tolerate padding" |
|
- | 246 | ); |
|
- | 247 | } |
|
- | 248 | } |
|
- | 249 | } |
|
- | 250 | return static::decode( |
|
- | 251 | $encodedString, |
|
- | 252 | true |
|
- | 253 | ); |
|
- | 254 | } |
|
- | 255 | ||
- | 256 | /** |
|
213 | * Uses bitwise operators instead of table-lookups to turn 6-bit integers |
257 | * Uses bitwise operators instead of table-lookups to turn 6-bit integers |
214 | * into 8-bit integers. |
258 | * into 8-bit integers. |
215 | * |
259 | * |
216 | * Base64 character set: |
260 | * Base64 character set: |
217 | * [A-Z] [a-z] [0-9] + / |
261 | * [A-Z] [a-z] [0-9] + / |