diff --git a/admin/tool/mfa/factor/totp/extlib/ParagonIE/ConstantTime/Base32.php b/admin/tool/mfa/factor/totp/extlib/ParagonIE/ConstantTime/Base32.php index 761053e9391..48d00b9911e 100644 --- a/admin/tool/mfa/factor/totp/extlib/ParagonIE/ConstantTime/Base32.php +++ b/admin/tool/mfa/factor/totp/extlib/ParagonIE/ConstantTime/Base32.php @@ -1,8 +1,13 @@ $chunk */ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 8)); + /** @var int $c0 */ $c0 = static::$method($chunk[1]); + /** @var int $c1 */ $c1 = static::$method($chunk[2]); + /** @var int $c2 */ $c2 = static::$method($chunk[3]); + /** @var int $c3 */ $c3 = static::$method($chunk[4]); + /** @var int $c4 */ $c4 = static::$method($chunk[5]); + /** @var int $c5 */ $c5 = static::$method($chunk[6]); + /** @var int $c6 */ $c6 = static::$method($chunk[7]); + /** @var int $c7 */ $c7 = static::$method($chunk[8]); $dest .= \pack( @@ -247,15 +312,23 @@ abstract class Base32 implements EncoderInterface } // The last chunk, which may have padding: if ($i < $srcLen) { + /** @var array $chunk */ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); + /** @var int $c0 */ $c0 = static::$method($chunk[1]); if ($i + 6 < $srcLen) { + /** @var int $c1 */ $c1 = static::$method($chunk[2]); + /** @var int $c2 */ $c2 = static::$method($chunk[3]); + /** @var int $c3 */ $c3 = static::$method($chunk[4]); + /** @var int $c4 */ $c4 = static::$method($chunk[5]); + /** @var int $c5 */ $c5 = static::$method($chunk[6]); + /** @var int $c6 */ $c6 = static::$method($chunk[7]); $dest .= \pack( @@ -266,11 +339,19 @@ abstract class Base32 implements EncoderInterface (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff ); $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6) >> 8; + if ($strictPadding) { + $err |= ($c6 << 5) & 0xff; + } } elseif ($i + 5 < $srcLen) { + /** @var int $c1 */ $c1 = static::$method($chunk[2]); + /** @var int $c2 */ $c2 = static::$method($chunk[3]); + /** @var int $c3 */ $c3 = static::$method($chunk[4]); + /** @var int $c4 */ $c4 = static::$method($chunk[5]); + /** @var int $c5 */ $c5 = static::$method($chunk[6]); $dest .= \pack( @@ -282,9 +363,13 @@ abstract class Base32 implements EncoderInterface ); $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5) >> 8; } elseif ($i + 4 < $srcLen) { + /** @var int $c1 */ $c1 = static::$method($chunk[2]); + /** @var int $c2 */ $c2 = static::$method($chunk[3]); + /** @var int $c3 */ $c3 = static::$method($chunk[4]); + /** @var int $c4 */ $c4 = static::$method($chunk[5]); $dest .= \pack( @@ -294,9 +379,15 @@ abstract class Base32 implements EncoderInterface (($c3 << 4) | ($c4 >> 1) ) & 0xff ); $err |= ($c0 | $c1 | $c2 | $c3 | $c4) >> 8; + if ($strictPadding) { + $err |= ($c4 << 7) & 0xff; + } } elseif ($i + 3 < $srcLen) { + /** @var int $c1 */ $c1 = static::$method($chunk[2]); + /** @var int $c2 */ $c2 = static::$method($chunk[3]); + /** @var int $c3 */ $c3 = static::$method($chunk[4]); $dest .= \pack( @@ -305,8 +396,13 @@ abstract class Base32 implements EncoderInterface (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff ); $err |= ($c0 | $c1 | $c2 | $c3) >> 8; + if ($strictPadding) { + $err |= ($c3 << 4) & 0xff; + } } elseif ($i + 2 < $srcLen) { + /** @var int $c1 */ $c1 = static::$method($chunk[2]); + /** @var int $c2 */ $c2 = static::$method($chunk[3]); $dest .= \pack( @@ -315,7 +411,11 @@ abstract class Base32 implements EncoderInterface (($c1 << 6) | ($c2 << 1) ) & 0xff ); $err |= ($c0 | $c1 | $c2) >> 8; + if ($strictPadding) { + $err |= ($c2 << 6) & 0xff; + } } elseif ($i + 1 < $srcLen) { + /** @var int $c1 */ $c1 = static::$method($chunk[2]); $dest .= \pack( @@ -323,6 +423,9 @@ abstract class Base32 implements EncoderInterface (($c0 << 3) | ($c1 >> 2) ) & 0xff ); $err |= ($c0 | $c1) >> 8; + if ($strictPadding) { + $err |= ($c1 << 6) & 0xff; + } } else { $dest .= \pack( 'C', @@ -331,8 +434,9 @@ abstract class Base32 implements EncoderInterface $err |= ($c0) >> 8; } } - if ($err !== 0) { - throw new \RangeException( + $check = ($err === 0); + if (!$check) { + throw new RangeException( 'Base32::doDecode() only expects characters in the correct base32 alphabet' ); } @@ -340,25 +444,31 @@ abstract class Base32 implements EncoderInterface } /** - * Base32 Decoding + * Base32 Encoding * * @param string $src * @param bool $upper * @param bool $pad * @return string + * @throws TypeError */ - protected static function doEncode($src, $upper = \false, $pad = \true) - { + protected static function doEncode( + #[\SensitiveParameter] + string $src, + bool $upper = false, + $pad = true + ): string { // We do this to reduce code duplication: $method = $upper ? 'encode5BitsUpper' : 'encode5Bits'; - + $dest = ''; $srcLen = Binary::safeStrlen($src); // Main loop (no padding): for ($i = 0; $i + 5 <= $srcLen; $i += 5) { + /** @var array $chunk */ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 5)); $b0 = $chunk[1]; $b1 = $chunk[2]; @@ -377,6 +487,7 @@ abstract class Base32 implements EncoderInterface } // The last chunk, which may have padding: if ($i < $srcLen) { + /** @var array $chunk */ $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); $b0 = $chunk[1]; if ($i + 3 < $srcLen) { @@ -427,4 +538,4 @@ abstract class Base32 implements EncoderInterface } return $dest; } -} \ No newline at end of file +} diff --git a/admin/tool/mfa/factor/totp/extlib/ParagonIE/ConstantTime/Binary.php b/admin/tool/mfa/factor/totp/extlib/ParagonIE/ConstantTime/Binary.php index 3ee6cc8da0b..a958f2f7c88 100644 --- a/admin/tool/mfa/factor/totp/extlib/ParagonIE/ConstantTime/Binary.php +++ b/admin/tool/mfa/factor/totp/extlib/ParagonIE/ConstantTime/Binary.php @@ -1,8 +1,11 @@ = 0) { - $length = self::safeStrlen($str) - $start; - } else { - $length = -$start; - } - } - // $length calculation above might result in a 0-length string - if ($length === 0) { - return ''; - } - return \mb_substr($str, $start, $length, '8bit'); - } + #[\SensitiveParameter] + string $str, + int $start = 0, + ?int $length = null + ): string { if ($length === 0) { return ''; } - // Unlike mb_substr(), substr() doesn't accept null for length - if (!is_null($length)) { + if (\function_exists('mb_substr')) { + return \mb_substr($str, $start, $length, '8bit'); + } + // Unlike mb_substr(), substr() doesn't accept NULL for length + if ($length !== null) { return \substr($str, $start, $length); } else { return \substr($str, $start); } } -} \ No newline at end of file +} diff --git a/admin/tool/mfa/factor/totp/extlib/ParagonIE/ConstantTime/EncoderInterface.php b/admin/tool/mfa/factor/totp/extlib/ParagonIE/ConstantTime/EncoderInterface.php index 76568dcf7a2..9cafbf96c83 100644 --- a/admin/tool/mfa/factor/totp/extlib/ParagonIE/ConstantTime/EncoderInterface.php +++ b/admin/tool/mfa/factor/totp/extlib/ParagonIE/ConstantTime/EncoderInterface.php @@ -1,8 +1,9 @@ extlib/ParagonIE/ConstantTime Constant-Time Encoding - 2.1.1 + 3.0.0 MIT https://github.com/paragonie/constant_time_encoding