/** * Execute a block of code. * * @param string $code * @param boolean $cache * @param boolean $do_not_eval * @return mixed */ protected static function coreEval(string $code, bool $cache = false, bool $do_not_eval = false) { \clearstatcache(); if ($do_not_eval || \Airship\is_disabled('eval')) { if ($cache) { if (!\file_exists(ROOT . "/tmp/cache/gear")) { \mkdir(ROOT . "/tmp/cache/gear", 0777); \clearstatcache(); } $hashed = Base64UrlSafe::encode(CryptoUtil::raw_hash($code, 33)); if (!\file_exists(ROOT . '/tmp/cache/gear/' . $hashed . '.tmp.php')) { \file_put_contents(ROOT . '/tmp/cache/gear/' . $hashed . '.tmp.php', '<?php' . "\n" . $code); } return self::sandboxRequire(ROOT . '/cache/' . $hashed . '.tmp.php'); } else { if (!\file_exists(ROOT . '/tmp/gear')) { \mkdir(ROOT . '/tmp/gear', 0777); \clearstatcache(); } $file = \Airship\tempnam('gear-', 'php', ROOT . '/tmp/gear'); \file_put_contents($file, '<?php' . "\n" . $code); \clearstatcache(); $ret = self::sandboxRequire($file); \unlink($file); \clearstatcache(); return $ret; } } else { return eval($code); } }
/** * Calculate the Merkle root, taking care to distinguish between * leaves and branches (0x01 for the nodes, 0x00 for the branches) * to protect against second-preimage attacks * * @return string */ protected function calculateRoot() : string { $size = \count($this->nodes); if ($size < 1) { return ''; } $hash = []; // Population (Use self::MERKLE_LEAF as a prefix) for ($i = 0; $i < $size; ++$i) { $hash[$i] = self::MERKLE_LEAF . $this->personalization . $this->nodes[$i]->getHash(true, $this->outputSize, $this->personalization); } // Calculation (Use self::MERKLE_BRANCH as a prefix) do { $tmp = []; $j = 0; for ($i = 0; $i < $size; $i += 2) { if (empty($hash[$i + 1])) { $tmp[$j] = $hash[$i]; } else { $tmp[$j] = Util::raw_hash(self::MERKLE_BRANCH . $this->personalization . $hash[$i] . $hash[$i + 1], $this->outputSize); } ++$j; } $hash = $tmp; $size >>= 1; } while ($size > 1); // We should only have one value left: $this->rootCalculated = true; return \array_shift($hash); }
/** * Get a hash of the data (defaults to hex encoded) * * @param bool $raw * * These two aren't really meant to be used externally: * @param int $outputSize * @param string $personalization * * @return string */ public function getHash(bool $raw = false, int $outputSize = \Sodium\CRYPTO_GENERICHASH_BYTES, string $personalization = '') : string { if ($raw) { return Util::raw_hash($personalization . $this->data, $outputSize); } return Util::hash($personalization . $this->data, $outputSize); }
/** * @covers File::checksum() */ public function testChecksum() { $csum = File::checksum(__DIR__ . '/tmp/paragon_avatar.png', null, false); $this->assertSame($csum, "09f9f74a0e742d057ca08394db4c2e444be88c0c94fe9a914c3d3758c7eccafb" . "8dd286e3d6bc37f353e76c0c5aa2036d978ca28ffaccfa59f5dc1f076c5517a0"); $data = \Sodium\randombytes_buf(32); \file_put_contents(__DIR__ . '/tmp/garbage.dat', $data); $hash = Util::raw_hash($data, 64); $file = File::checksum(__DIR__ . '/tmp/garbage.dat', null, true); $this->assertSame($hash, $file); \unlink(__DIR__ . '/tmp/garbage.dat'); }