<?php
/**
 * @copyright (c) Kufer Software GmbH, Oderstraße 7, D-84453 Mühldorf
 */

namespace Kufer\Web\Admin\Classes\Pages\ajax;

class PageAjaxSignedExecution extends \PageAjax
{
  public function getPage()
  {
    $err = function(string $msg) {
      $msg = 'Signed-Execution: ' . $msg;
      \Logger::logg($msg, 20);

      header('Content-Type: application/json');

      $errors = array($msg);
      while (($opensslerr = openssl_error_string()) !== false) {
        $errors[] = $opensslerr;
      }

      return \JsonOperations::encodeJustStrings(array(
        'errors' => $errors
      ));
    };

    try {
      $publicKey = openssl_get_publickey(@file_get_contents(\FSOperations::path(__DIR__, 'signed-execution-public.pem')));
      if ($publicKey === false) {
        return $err('Konnte nicht entschlüsselt werden (public key)');
      }

      $data = fopen('data://application/octet-stream;base64,' . \PostOperations::getVarValue('content'), 'r');
      if ($data === false) {
        return $err('Fehler beim Lesen der Nachricht (stream)');
      }

      $bits = openssl_pkey_get_details($publicKey)['bits'] ?? 4096;
      $keyEncrypted = fread($data, $bits / 8);
      if ($keyEncrypted === false) {
        fclose($data);

        return $err('Konnte nicht entschlüsselt werden (key)');
      }

      $key = '';
      if (!openssl_public_decrypt($keyEncrypted, $key, $publicKey, OPENSSL_PKCS1_PADDING)) {
        fclose($data);

        return $err('Konnte nicht entschlüsselt werden (key decrypt)');
      }
      $key = substr($key, 0, 16);

      $iv = fread($data, 16);
      if ($iv === false) {
        fclose($data);

        return $err('Konnte nicht entschlüsselt werden (iv)');
      }

      $out = openssl_decrypt(stream_get_contents($data), 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $iv);
      fclose($data);

      if ($out === false) {
        return $err('Konnte nicht entschlüsselt werden (aes)');
      }

      if (!\StringOperations::startsWith($out, '<?php')) {
        return $err('Muss mit <?php starten');
      }

      $out = \StringOperations::substr($out, \StringOperations::strlen('<?php'));

      \Logger::logg('Signed-Execution: Wird ausgeführt', 11);
      eval($out);

      return '';
    } catch (\Exception $ex) {
      \Logger::logg($ex, 40);

      return $err($ex->getMessage());
    } catch (\Error $ex) {
      \Logger::logg($ex, 40);

      return $err($ex->getMessage());
    }
  }
}