| +-------------------------------------------------------------------------+ */ class enigma_driver_phpssl extends enigma_driver { private $rc; private $homedir; private $user; 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 mixed NULL on success, enigma_error on failure */ 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; } public function encrypt($text, $keys, $sign_key = null) {} public function decrypt($text, $keys = [], &$signature = null) {} public function sign($text, $key, $mode = null) {} 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; } public function import($content, $isfile = false, $passwords = []) {} public function export($key, $with_private = false, $passwords = []) {} public function list_keys($pattern = '') {} public function get_key($keyid) {} public function gen_key($data) {} public function delete_key($keyid) {} /** * Returns a name of the hash algorithm used for the last * signing operation. * * @return string Hash algorithm name e.g. sha1 */ public function signature_algorithm() {} /** * Converts Crypt_GPG_Key object into Enigma's key object * * @param Crypt_GPG_Key $key Key object * * @return enigma_key Key object */ private function parse_key($key) {} private function get_openssl_error() { $tmp = []; while ($errorstr = openssl_error_string()) { $tmp[] = $errorstr; } return implode("\n", array_values($tmp)); } 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; } }