| +-------------------------------------------------------------------------+ */ class enigma_driver_phpssl extends enigma_driver { private $rc; private $homedir; // @phpstan-ignore-line private $user; #[Override] public function __construct($user) { $rcmail = rcmail::get_instance(); $this->rc = $rcmail; $this->user = $user; } /** * Driver initialization and environment checking. * Should only return critical errors. * * @return enigma_error|null NULL on success, enigma_error on failure */ #[Override] public function init() { $homedir = $this->rc->config->get('enigma_smime_homedir', INSTALL_PATH . '/plugins/enigma/home'); if (!$homedir) { return new enigma_error(enigma_error::INTERNAL, "Option 'enigma_smime_homedir' not specified"); } // check if homedir exists (create it if not) and is readable if (!file_exists($homedir)) { return new enigma_error(enigma_error::INTERNAL, "Keys directory doesn't exists: {$homedir}"); } if (!is_writable($homedir)) { return new enigma_error(enigma_error::INTERNAL, "Keys directory isn't writeable: {$homedir}"); } $homedir = $homedir . '/' . $this->user; // check if user's homedir exists (create it if not) and is readable if (!file_exists($homedir)) { mkdir($homedir, 0700); } if (!file_exists($homedir)) { return new enigma_error(enigma_error::INTERNAL, "Unable to create keys directory: {$homedir}"); } if (!is_writable($homedir)) { return new enigma_error(enigma_error::INTERNAL, "Unable to write to keys directory: {$homedir}"); } $this->homedir = $homedir; return null; } #[Override] public function encrypt($text, $keys, $sign_key = null) { return new enigma_error(enigma_error::INTERNAL, 'Not implemented'); } #[Override] public function decrypt($text, $keys = [], &$signature = null) { return new enigma_error(enigma_error::INTERNAL, 'Not implemented'); } #[Override] public function sign($text, $key, $mode = null) { return new enigma_error(enigma_error::INTERNAL, 'Not implemented'); } #[Override] public function verify($struct, $message) { /* // use common temp dir $msg_file = rcube_utils::temp_filename('enigmsg'); $cert_file = rcube_utils::temp_filename('enigcrt'); $fh = fopen($msg_file, 'w'); if ($struct->mime_id) { $message->get_part_body($struct->mime_id, false, 0, $fh); } else { $this->rc->storage->get_raw_body($message->uid, $fh); } fclose($fh); // @TODO: use stored certificates // try with certificate verification $sig = openssl_pkcs7_verify($msg_file, 0, $cert_file); $validity = true; if ($sig !== true) { // try without certificate verification $sig = openssl_pkcs7_verify($msg_file, \PKCS7_NOVERIFY, $cert_file); $validity = enigma_error::UNVERIFIED; } if ($sig === true) { $sig = $this->parse_sig_cert($cert_file, $validity); } else { $errorstr = $this->get_openssl_error(); $sig = new enigma_error(enigma_error::INTERNAL, $errorstr); } // remove temp files @unlink($msg_file); @unlink($cert_file); return $sig; */ return new enigma_error(enigma_error::INTERNAL, 'Not implemented'); } #[Override] public function import($content, $isfile = false, $passwords = []) { return new enigma_error(enigma_error::INTERNAL, 'Not implemented'); } #[Override] public function export($key, $with_private = false, $passwords = []) { return new enigma_error(enigma_error::INTERNAL, 'Not implemented'); } #[Override] public function list_keys($pattern = '') { return new enigma_error(enigma_error::INTERNAL, 'Not implemented'); } #[Override] public function get_key($keyid) { return new enigma_error(enigma_error::INTERNAL, 'Not implemented'); } #[Override] public function gen_key($data) { return new enigma_error(enigma_error::INTERNAL, 'Not implemented'); } #[Override] public function delete_key($keyid) { return new enigma_error(enigma_error::INTERNAL, 'Not implemented'); } /** * Returns a name of the hash algorithm used for the last * signing operation. * * @return string Hash algorithm name e.g. sha1 */ #[Override] public function signature_algorithm() { return ''; // TODO } private function get_openssl_error() { $tmp = []; while ($errorstr = openssl_error_string()) { $tmp[] = $errorstr; } return implode("\n", array_values($tmp)); } // @phpstan-ignore-next-line private function parse_sig_cert($file, $validity) { $cert = openssl_x509_parse(file_get_contents($file)); if (empty($cert) || empty($cert['subject'])) { $errorstr = $this->get_openssl_error(); return new enigma_error(enigma_error::INTERNAL, $errorstr); } $data = new enigma_signature(); $data->id = $cert['hash']; // ? $data->valid = $validity; $data->fingerprint = $cert['serialNumber']; $data->created = $cert['validFrom_time_t']; $data->expires = $cert['validTo_time_t']; $data->name = $cert['subject']['CN']; // $data->comment = ''; $data->email = $cert['subject']['emailAddress']; return $data; } }