From d54a6cbdf5febda582644c0c38fc3719cffcc278 Mon Sep 17 00:00:00 2001 From: Clemens Schwaighofer Date: Wed, 17 Apr 2024 10:13:32 +0900 Subject: [PATCH] Remove mb encode mimeheader special code and replace it with default function call --- src/Convert/MimeEncode.php | 36 +++---------------- src/Security/SymmetricEncryption.php | 32 ++++++++++------- .../Convert/CoreLibsConvertMimeEncodeTest.php | 34 +++++++++++------- 3 files changed, 46 insertions(+), 56 deletions(-) diff --git a/src/Convert/MimeEncode.php b/src/Convert/MimeEncode.php index 73a3254..013b27e 100644 --- a/src/Convert/MimeEncode.php +++ b/src/Convert/MimeEncode.php @@ -15,6 +15,7 @@ class MimeEncode /** * wrapper function for mb mime convert * for correct conversion with long strings + * NOTE: This is only a wrapper for mb_encode_mimeheader to stay compatible * * @param string $string string to encode * @param string $encoding target encoding @@ -29,38 +30,9 @@ class MimeEncode $current_internal_encoding = mb_internal_encoding(); // set internal encoding, so the mimeheader encode works correctly mb_internal_encoding($encoding); - // if a subject, make a work around for the broken mb_mimencode - $pos = 0; - // after 36 single bytes characters, - // if then comes MB, it is broken - // has to 2 x 36 < 74 so the mb_encode_mimeheader - // 74 hardcoded split does not get triggered - $split = 36; - $_string = ''; - while ($pos < mb_strlen($string, $encoding)) { - $output = mb_strimwidth($string, $pos, $split, "", $encoding); - $pos += mb_strlen($output, $encoding); - // if the strinlen is 0 here, get out of the loop - if (!mb_strlen($output, $encoding)) { - $pos += mb_strlen($string, $encoding); - } - $_string_encoded = mb_encode_mimeheader($output, $encoding); - // only make linebreaks if we have mime encoded code inside - // the space only belongs in the second line - if ($_string && preg_match("/^=\?/", $_string_encoded)) { - $_string .= $line_break . " "; - } elseif ( - // hack for plain text with space at the end - mb_strlen($output, $encoding) == $split && - mb_substr($output, -1, 1, $encoding) == " " - ) { - // if output ends with space, add one more - $_string_encoded .= " "; - } - $_string .= $_string_encoded; - } - // strip out any spaces BEFORE a line break - $string = str_replace(" " . $line_break, $line_break, $_string); + // use the internal convert to mime header + // it works from PHP 8.2 on + $string = mb_encode_mimeheader($string, $encoding, 'B', $line_break); // before we end, reset internal encoding mb_internal_encoding($current_internal_encoding); // return mime encoded string diff --git a/src/Security/SymmetricEncryption.php b/src/Security/SymmetricEncryption.php index 2586e94..8062fb5 100644 --- a/src/Security/SymmetricEncryption.php +++ b/src/Security/SymmetricEncryption.php @@ -22,15 +22,12 @@ use SodiumException; class SymmetricEncryption { /** - * Encrypt a message + * create key and check validity * - * @param string $message Message to encrypt - * @param string $key Encryption key (as hex string) - * @return string - * @throws \Exception - * @throws \RangeException + * @param string $key The key from which the binary key will be created + * @return string Binary key string */ - public static function encrypt(string $message, string $key): string + public static function createKey(string $key): string { try { $key = CreateKey::hex2bin($key); @@ -43,6 +40,21 @@ class SymmetricEncryption . 'SODIUM_CRYPTO_SECRETBOX_KEYBYTES bytes long).' ); } + return $key; + } + + /** + * Encrypt a message + * + * @param string $message Message to encrypt + * @param string $key Encryption key (as hex string) + * @return string + * @throws \Exception + * @throws \RangeException + */ + public static function encrypt(string $message, string $key): string + { + $key = self::createKey($key); $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); $cipher = base64_encode( @@ -68,11 +80,7 @@ class SymmetricEncryption */ public static function decrypt(string $encrypted, string $key): string { - try { - $key = CreateKey::hex2bin($key); - } catch (SodiumException $e) { - throw new \Exception('Invalid hex key'); - } + $key = self::createKey($key); $decoded = base64_decode($encrypted); $nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit'); $ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit'); diff --git a/test/phpunit/Convert/CoreLibsConvertMimeEncodeTest.php b/test/phpunit/Convert/CoreLibsConvertMimeEncodeTest.php index 00b1055..1c2c47c 100644 --- a/test/phpunit/Convert/CoreLibsConvertMimeEncodeTest.php +++ b/test/phpunit/Convert/CoreLibsConvertMimeEncodeTest.php @@ -33,15 +33,14 @@ final class CoreLibsConvertMimeEncodeTest extends TestCase 'The quick brown fox jumps over the lazy sheep that sleeps in the ravine ' . 'and has no idea what is going on here', 'UTF-8', - 'The quick brown fox jumps over the lazy sheep that sleeps in the ravine ' - . 'and has no idea what is going on here' + "The quick brown fox jumps over the lazy sheep that sleeps in the ravine and\r\n" + . ' has no idea what is going on here' ], 'standard with special chars UTF-8' => [ 'This is ümläßtと漢字もカタカナ!!^$%&', 'UTF-8', - 'This is =?UTF-8?B?w7xtbMOkw59044Go5ryi5a2X44KC44Kr44K/44Kr44OK77yBIV4k?=' - . "\r\n" - . ' =?UTF-8?B?JQ==?=&' + "This is =?UTF-8?B?w7xtbMOkw59044Go5ryi5a2X44KC44Kr44K/44Kr44OK77yBIV4k?=\r\n" + . ' =?UTF-8?B?JSY=?=' ], '35 chars and space at the end UTF-8' => [ '12345678901234567890123456789012345 ' @@ -62,9 +61,8 @@ final class CoreLibsConvertMimeEncodeTest extends TestCase . 'is there a space?', 'UTF-8', "=?UTF-8?B?44Kr44K/44Kr44OK44Kr44K/44Kr44OK44GL44Gq44Kr44K/44Kr44OK44Kr?=\r\n" - . " =?UTF-8?B?44K/44Kr44OK?=\r\n" - . " =?UTF-8?B?44GL44Gq44Kr44K/44Kr44OK44Kr44K/44Kr44OK44GL44Gq44Kr44K/44Kr?=\r\n" - . " =?UTF-8?B?44OK44Kr44K/?= is there a =?UTF-8?B?c3BhY2U/?=" + . " =?UTF-8?B?44K/44Kr44OK44GL44Gq44Kr44K/44Kr44OK44Kr44K/44Kr44OK44GL44Gq?=\r\n" + . " =?UTF-8?B?44Kr44K/44Kr44OK44Kr44K/IGlzIHRoZXJlIGEgc3BhY2U/?=" ] ]; } @@ -85,16 +83,28 @@ final class CoreLibsConvertMimeEncodeTest extends TestCase // print "MIME: -" . $encoded . "-\n"; $this->assertEquals( $expected, - $encoded + $encoded, + "__mbMimeEncode" ); $decoded = mb_decode_mimeheader($encoded); - // print "INPUT : " . $input . "\n"; - // print "DECODED: " . $decoded . "\n"; + // print "ENCODED: " . $encoded . "\n"; + // print "INPUT : " . $input . " | " . mb_strlen($input) . "\n"; + // print "DECODED: " . $decoded . " | " . mb_strlen($decoded) . "\n"; + // $test_enc = mb_encode_mimeheader($input, $encoding); + // $test_dec = mb_decode_mimeheader($test_enc); + // print "TEST ENC: " . $test_enc . "\n"; // back compare decoded $this->assertEquals( $input, - $decoded + $decoded, + "mb_decode_mimeheader" ); + + // $this->assertEquals( + // $input, + // $test_dec, + // 'mb_encode_to_decode' + // ); } }