mirror of
https://github.com/roundcube/roundcubemail.git
synced 2026-02-27 21:04:02 +01:00
222 lines
6.6 KiB
PHP
222 lines
6.6 KiB
PHP
<?php
|
|
|
|
/*
|
|
+-------------------------------------------------------------------------+
|
|
| S/MIME driver for the Enigma Plugin |
|
|
| |
|
|
| Copyright (C) The Roundcube Dev Team |
|
|
| |
|
|
| Licensed under the GNU General Public License version 3 or |
|
|
| any later version with exceptions for skins & plugins. |
|
|
| See the README file for a full license statement. |
|
|
+-------------------------------------------------------------------------+
|
|
| Author: Aleksander Machniak <alec@alec.pl> |
|
|
+-------------------------------------------------------------------------+
|
|
*/
|
|
|
|
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;
|
|
}
|
|
}
|