[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/defuse/php-encryption/src/ -> RuntimeTests.php (source)

   1  <?php
   2  
   3  namespace Defuse\Crypto;
   4  
   5  use Defuse\Crypto\Exception as Ex;
   6  
   7  /*
   8   * We're using static class inheritance to get access to protected methods
   9   * inside Crypto. To make it easy to know where the method we're calling can be
  10   * found, within this file, prefix calls with `Crypto::` or `RuntimeTests::`,
  11   * and don't use `self::`.
  12   */
  13  
  14  class RuntimeTests extends Crypto
  15  {
  16      /**
  17       * Runs the runtime tests.
  18       *
  19       * @throws Ex\EnvironmentIsBrokenException
  20       * @return void
  21       */
  22      public static function runtimeTest()
  23      {
  24          // 0: Tests haven't been run yet.
  25          // 1: Tests have passed.
  26          // 2: Tests are running right now.
  27          // 3: Tests have failed.
  28          static $test_state = 0;
  29  
  30          if ($test_state === 1 || $test_state === 2) {
  31              return;
  32          }
  33  
  34          if ($test_state === 3) {
  35              /* If an intermittent problem caused a test to fail previously, we
  36               * want that to be indicated to the user with every call to this
  37               * library. This way, if the user first does something they really
  38               * don't care about, and just ignores all exceptions, they won't get
  39               * screwed when they then start to use the library for something
  40               * they do care about. */
  41              throw new Ex\EnvironmentIsBrokenException('Tests failed previously.');
  42          }
  43  
  44          try {
  45              $test_state = 2;
  46  
  47              Core::ensureFunctionExists('openssl_get_cipher_methods');
  48              if (\in_array(Core::CIPHER_METHOD, \openssl_get_cipher_methods()) === false) {
  49                  throw new Ex\EnvironmentIsBrokenException(
  50                      'Cipher method not supported. This is normally caused by an outdated ' .
  51                      'version of OpenSSL (and/or OpenSSL compiled for FIPS compliance). ' .
  52                      'Please upgrade to a newer version of OpenSSL that supports ' .
  53                      Core::CIPHER_METHOD . ' to use this library.'
  54                  );
  55              }
  56  
  57              RuntimeTests::AESTestVector();
  58              RuntimeTests::HMACTestVector();
  59              RuntimeTests::HKDFTestVector();
  60  
  61              RuntimeTests::testEncryptDecrypt();
  62              Core::ensureTrue(Core::ourStrlen(Key::createNewRandomKey()->getRawBytes()) === Core::KEY_BYTE_SIZE);
  63  
  64              Core::ensureTrue(Core::ENCRYPTION_INFO_STRING !== Core::AUTHENTICATION_INFO_STRING);
  65          } catch (Ex\EnvironmentIsBrokenException $ex) {
  66              // Do this, otherwise it will stay in the "tests are running" state.
  67              $test_state = 3;
  68              throw $ex;
  69          }
  70  
  71          // Change this to '0' make the tests always re-run (for benchmarking).
  72          $test_state = 1;
  73      }
  74  
  75      /**
  76       * High-level tests of Crypto operations.
  77       *
  78       * @throws Ex\EnvironmentIsBrokenException
  79       * @return void
  80       */
  81      private static function testEncryptDecrypt()
  82      {
  83          $key  = Key::createNewRandomKey();
  84          $data = "EnCrYpT EvErYThInG\x00\x00";
  85  
  86          // Make sure encrypting then decrypting doesn't change the message.
  87          $ciphertext = Crypto::encrypt($data, $key, true);
  88          try {
  89              $decrypted = Crypto::decrypt($ciphertext, $key, true);
  90          } catch (Ex\WrongKeyOrModifiedCiphertextException $ex) {
  91              // It's important to catch this and change it into a
  92              // Ex\EnvironmentIsBrokenException, otherwise a test failure could trick
  93              // the user into thinking it's just an invalid ciphertext!
  94              throw new Ex\EnvironmentIsBrokenException();
  95          }
  96          Core::ensureTrue($decrypted === $data);
  97  
  98          // Modifying the ciphertext: Appending a string.
  99          try {
 100              Crypto::decrypt($ciphertext . 'a', $key, true);
 101              throw new Ex\EnvironmentIsBrokenException();
 102          } catch (Ex\WrongKeyOrModifiedCiphertextException $e) { /* expected */
 103          }
 104  
 105          // Modifying the ciphertext: Changing an HMAC byte.
 106          $indices_to_change = [
 107              0, // The header.
 108              Core::HEADER_VERSION_SIZE + 1, // the salt
 109              Core::HEADER_VERSION_SIZE + Core::SALT_BYTE_SIZE + 1, // the IV
 110              Core::HEADER_VERSION_SIZE + Core::SALT_BYTE_SIZE + Core::BLOCK_BYTE_SIZE + 1, // the ciphertext
 111          ];
 112  
 113          foreach ($indices_to_change as $index) {
 114              try {
 115                  $ciphertext[$index] = \chr((\ord($ciphertext[$index]) + 1) % 256);
 116                  Crypto::decrypt($ciphertext, $key, true);
 117                  throw new Ex\EnvironmentIsBrokenException();
 118              } catch (Ex\WrongKeyOrModifiedCiphertextException $e) { /* expected */
 119              }
 120          }
 121  
 122          // Decrypting with the wrong key.
 123          $key        = Key::createNewRandomKey();
 124          $data       = 'abcdef';
 125          $ciphertext = Crypto::encrypt($data, $key, true);
 126          $wrong_key  = Key::createNewRandomKey();
 127          try {
 128              Crypto::decrypt($ciphertext, $wrong_key, true);
 129              throw new Ex\EnvironmentIsBrokenException();
 130          } catch (Ex\WrongKeyOrModifiedCiphertextException $e) { /* expected */
 131          }
 132  
 133          // Ciphertext too small.
 134          $key        = Key::createNewRandomKey();
 135          $ciphertext = \str_repeat('A', Core::MINIMUM_CIPHERTEXT_SIZE - 1);
 136          try {
 137              Crypto::decrypt($ciphertext, $key, true);
 138              throw new Ex\EnvironmentIsBrokenException();
 139          } catch (Ex\WrongKeyOrModifiedCiphertextException $e) { /* expected */
 140          }
 141      }
 142  
 143      /**
 144       * Test HKDF against test vectors.
 145       *
 146       * @throws Ex\EnvironmentIsBrokenException
 147       * @return void
 148       */
 149      private static function HKDFTestVector()
 150      {
 151          // HKDF test vectors from RFC 5869
 152  
 153          // Test Case 1
 154          $ikm    = \str_repeat("\x0b", 22);
 155          $salt   = Encoding::hexToBin('000102030405060708090a0b0c');
 156          $info   = Encoding::hexToBin('f0f1f2f3f4f5f6f7f8f9');
 157          $length = 42;
 158          $okm    = Encoding::hexToBin(
 159              '3cb25f25faacd57a90434f64d0362f2a' .
 160              '2d2d0a90cf1a5a4c5db02d56ecc4c5bf' .
 161              '34007208d5b887185865'
 162          );
 163          $computed_okm = Core::HKDF('sha256', $ikm, $length, $info, $salt);
 164          Core::ensureTrue($computed_okm === $okm);
 165  
 166          // Test Case 7
 167          $ikm    = \str_repeat("\x0c", 22);
 168          $length = 42;
 169          $okm    = Encoding::hexToBin(
 170              '2c91117204d745f3500d636a62f64f0a' .
 171              'b3bae548aa53d423b0d1f27ebba6f5e5' .
 172              '673a081d70cce7acfc48'
 173          );
 174          $computed_okm = Core::HKDF('sha1', $ikm, $length, '', null);
 175          Core::ensureTrue($computed_okm === $okm);
 176      }
 177  
 178      /**
 179       * Test HMAC against test vectors.
 180       *
 181       * @throws Ex\EnvironmentIsBrokenException
 182       * @return void
 183       */
 184      private static function HMACTestVector()
 185      {
 186          // HMAC test vector From RFC 4231 (Test Case 1)
 187          $key     = \str_repeat("\x0b", 20);
 188          $data    = 'Hi There';
 189          $correct = 'b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7';
 190          Core::ensureTrue(
 191              \hash_hmac(Core::HASH_FUNCTION_NAME, $data, $key) === $correct
 192          );
 193      }
 194  
 195      /**
 196       * Test AES against test vectors.
 197       *
 198       * @throws Ex\EnvironmentIsBrokenException
 199       * @return void
 200       */
 201      private static function AESTestVector()
 202      {
 203          // AES CTR mode test vector from NIST SP 800-38A
 204          $key = Encoding::hexToBin(
 205              '603deb1015ca71be2b73aef0857d7781' .
 206              '1f352c073b6108d72d9810a30914dff4'
 207          );
 208          $iv        = Encoding::hexToBin('f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff');
 209          $plaintext = Encoding::hexToBin(
 210              '6bc1bee22e409f96e93d7e117393172a' .
 211              'ae2d8a571e03ac9c9eb76fac45af8e51' .
 212              '30c81c46a35ce411e5fbc1191a0a52ef' .
 213              'f69f2445df4f9b17ad2b417be66c3710'
 214          );
 215          $ciphertext = Encoding::hexToBin(
 216              '601ec313775789a5b7a7f504bbf3d228' .
 217              'f443e3ca4d62b59aca84e990cacaf5c5' .
 218              '2b0930daa23de94ce87017ba2d84988d' .
 219              'dfc9c58db67aada613c2dd08457941a6'
 220          );
 221  
 222          $computed_ciphertext = Crypto::plainEncrypt($plaintext, $key, $iv);
 223          Core::ensureTrue($computed_ciphertext === $ciphertext);
 224  
 225          $computed_plaintext = Crypto::plainDecrypt($ciphertext, $key, $iv, Core::CIPHER_METHOD);
 226          Core::ensureTrue($computed_plaintext === $plaintext);
 227      }
 228  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer