| +-------------------------------------------------------------------------+ */ class enigma_driver_phpssl extends enigma_driver { private $rc; private $homedir; private $user; 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 */ 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; } function encrypt($text, $keys) { } function decrypt($text, $keys = array()) { } function sign($text, $key, $passwd, $mode = null) { } function verify($struct, $message) { // use common temp dir $temp_dir = $this->rc->config->get('temp_dir'); $msg_file = tempnam($temp_dir, 'rcmMsg'); $cert_file = tempnam($temp_dir, 'rcmCert'); $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) { } public function list_keys($pattern='') { } public function get_key($keyid) { } public function gen_key($data) { } public function delete_key($keyid) { } public function delete_privkey($keyid) { } public function delete_pubkey($keyid) { } /** * Converts Crypt_GPG_Key object into Enigma's key object * * @param Crypt_GPG_Key Key object * * @return enigma_key Key object */ private function parse_key($key) { /* $ekey = new enigma_key(); foreach ($key->getUserIds() as $idx => $user) { $id = new enigma_userid(); $id->name = $user->getName(); $id->comment = $user->getComment(); $id->email = $user->getEmail(); $id->valid = $user->isValid(); $id->revoked = $user->isRevoked(); $ekey->users[$idx] = $id; } $ekey->name = trim($ekey->users[0]->name . ' <' . $ekey->users[0]->email . '>'); foreach ($key->getSubKeys() as $idx => $subkey) { $skey = new enigma_subkey(); $skey->id = $subkey->getId(); $skey->revoked = $subkey->isRevoked(); $skey->created = $subkey->getCreationDate(); $skey->expires = $subkey->getExpirationDate(); $skey->fingerprint = $subkey->getFingerprint(); $skey->has_private = $subkey->hasPrivate(); $skey->can_sign = $subkey->canSign(); $skey->can_encrypt = $subkey->canEncrypt(); $ekey->subkeys[$idx] = $skey; }; $ekey->id = $ekey->subkeys[0]->id; return $ekey; */ } private function get_openssl_error() { $tmp = array(); while ($errorstr = openssl_error_string()) { $tmp[] = $errorstr; } return join("\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; } }