diff --git a/admin/inc/class.admin_mail.inc.php b/admin/inc/class.admin_mail.inc.php
index ec09e706db..ccd0a037f9 100644
--- a/admin/inc/class.admin_mail.inc.php
+++ b/admin/inc/class.admin_mail.inc.php
@@ -896,9 +896,7 @@ class admin_mail
if (!empty($content['acc_smime_password']))
{
- $AB_bo = new addressbook_bo();
- $smime_cert = $AB_bo->get_smime_keys($content['acc_smime_username']);
- $content['smime_cert'] = $smime_cert[$content['acc_smime_username']];
+ $readonlys['smime_export_p12'] = false;
}
}
catch(Api\Exception\NotFound $e) {
@@ -1036,7 +1034,7 @@ class admin_mail
$content['called_for'] : $GLOBALS['egw_info']['user']['account_id'];
}
// SMIME SAVE
- if (isset($content['smimeKeyUpload']) || $content['smime_cert'] && $content['acc_smime_password'])
+ if (isset($content['smimeKeyUpload']))
{
$smime = new Mail\Smime;
$content['acc_smime_username'] = $smime->getEmailFromKey($content['smime_cert']);
@@ -1044,10 +1042,10 @@ class admin_mail
if (($pkcs12 = file_get_contents($content['smimeKeyUpload']['tmp_name'])) &&
$content['smimeKeyUpload']['type'] == 'application/x-pkcs12')
{
- $cert_info = $smime->extractCertPKCS12($pkcs12, $content['smime_pkcs12_password']);
+ $cert_info = Mail\Smime::extractCertPKCS12($pkcs12, $content['smime_pkcs12_password']);
if (is_array($cert_info))
{
- $content['acc_smime_password'] = $cert_info['pkey'];
+ $content['acc_smime_password'] = $pkcs12;
$content['smime_cert'] = $cert_info['cert'];
if ($content['smime_cert'])
{
@@ -1063,10 +1061,6 @@ class admin_mail
$tpl->set_validation_error('smimeKeyUpload', lang('Could not extract private key from given p12 file. Either the p12 file is broken or password is wrong!'));
}
}
- elseif ($content['smime_cert'] && $content['acc_smime_password'])
- {
- $AB_bo->set_smime_keys(array($content['acc_smime_username'] => $content['smime_cert']));
- }
}
self::fix_account_id_0($content['account_id'], true);
$content = Mail\Account::write($content, $content['called_for'] || !$this->is_admin ?
diff --git a/admin/js/app.js b/admin/js/app.js
index 76dd871c99..c0b8f8c4c8 100644
--- a/admin/js/app.js
+++ b/admin/js/app.js
@@ -1163,29 +1163,16 @@ app.classes.admin = AppJS.extend(
/**
* Export content of given field into relevant file
- * @param string _field
*/
- smime_exportKey: function (_field)
+ smime_exportCert: function ()
{
var $a = jQuery(document.createElement('a')).appendTo('body').hide();
- var widget = {};
- switch (_field)
- {
- case 'privkey':
- widget = this.et2.getWidgetById('acc_smime_password');
- $a.attr({
- download: 'private_key.key',
- href: 'data:application/x-iwork-keynote-sffkey;charset=utf-8,' + encodeURI(widget.getValue())
- });
- break;
- case 'cert':
- widget = this.et2.getWidgetById('smime_cert');
- $a.attr({
- download: 'cert.crt',
- href: 'data:application/pkix-cert;charset=utf-8,' + encodeURI(widget.getValue())
- });
- break;
- }
+ var acc_id = this.et2.getArrayMgr("content").getEntry('acc_id');
+ var url = window.egw_webserverUrl+'/index.php?';
+ url += 'menuaction=mail.mail_ui.smimeExportCert';
+ url += '&acc_id='+acc_id;
+ $a.prop('href',url);
+ $a.prop('download',"");
$a[0].click();
$a.remove();
},
diff --git a/admin/templates/default/mailaccount.xet b/admin/templates/default/mailaccount.xet
index 98a0cbb688..fa999b450a 100644
--- a/admin/templates/default/mailaccount.xet
+++ b/admin/templates/default/mailaccount.xet
@@ -303,24 +303,18 @@
-
-
-
+
-
-
-
-
-
-
+
+
diff --git a/api/src/Mail.php b/api/src/Mail.php
index 8cf2e9357c..c4c28dce7a 100644
--- a/api/src/Mail.php
+++ b/api/src/Mail.php
@@ -7424,9 +7424,9 @@ class Mail
private function _decryptSmimeBody ($_message, $_passphrase = '')
{
$AB_bo = new \addressbook_bo();
- $credents = Mail\Credentials::read($this->profileID, Mail\Credentials::SMIME, $GLOBALS['egw_info']['user']['account_id']);
- $certkey = $AB_bo->get_smime_keys($credents['acc_smime_username']);
- if (!$this->smime->verifyPassphrase($credents['acc_smime_password'], $_passphrase))
+ $acc_smime = Mail\Smime::get_acc_smime($this->profileID, $_passphrase);
+ $certkey = $AB_bo->get_smime_keys($acc_smime['acc_smime_username']);
+ if (!$this->smime->verifyPassphrase($acc_smime['pkey'], $_passphrase))
{
return array (
'password_required' => true,
@@ -7436,8 +7436,8 @@ class Mail
$params = array (
'type' => 'message',
- 'pubkey' => $certkey[$credents['acc_smime_username']],
- 'privkey' => $credents['acc_smime_password'],
+ 'pubkey' => $certkey[$acc_smime['acc_smime_username']],
+ 'privkey' => $acc_smime['pkey'],
'passphrase'=> $_passphrase
);
return $this->smime->decrypt($_message, $params);
diff --git a/api/src/Mail/Smime.php b/api/src/Mail/Smime.php
index 1ecfc9fa65..ee491b8461 100644
--- a/api/src/Mail/Smime.php
+++ b/api/src/Mail/Smime.php
@@ -13,6 +13,7 @@
namespace EGroupware\Api\Mail;
use Horde_Mime_Part;
use Horde_Crypt_Smime;
+use EGroupware\Api;
/**
* EMailAdmin generic base class for SMTP
*/
@@ -156,7 +157,7 @@ class Smime extends Horde_Crypt_Smime
*
* @return boolean|array returns array of certs info or false if not successful
*/
- public function extractCertPKCS12 ($pkcs12, $passphrase = '')
+ public static function extractCertPKCS12 ($pkcs12, $passphrase = '')
{
$certs = $out = array ();
if (openssl_pkcs12_read($pkcs12, $certs, $passphrase))
@@ -233,4 +234,38 @@ class Smime extends Horde_Crypt_Smime
}
return $result;
}
+
+ /**
+ * Method to extract smime related info from credential table
+ *
+ * @param type $acc_id acc id of mail account
+ * @param type $passphrase = '' protect private key by passphrase
+ * @return mixed return array of smime info or false if fails
+ */
+ public static function get_acc_smime($acc_id, $passphrase = '')
+ {
+ if (Api\Cache::getSession('mail', 'smime_passphrase'))
+ {
+ $passphrase = Api\Cache::getSession('mail', 'smime_passphrase');
+ }
+ $acc_smime = Credentials::read(
+ $acc_id,
+ Credentials::SMIME,
+ $GLOBALS['egw_info']['user']['account_id']
+ );
+ foreach ($acc_smime as $key => $val)
+ {
+ // remove other imap stuffs but smime
+ if (!preg_match("/acc_smime/", $key)) unset($acc_smime[$key]);
+ }
+ if ($acc_smime['acc_smime_password'])
+ {
+ $extracted = self::extractCertPKCS12(
+ $acc_smime['acc_smime_password'],
+ $passphrase
+ );
+ return array_merge($acc_smime, is_array($extracted) ? $extracted : array());
+ }
+ return false;
+ }
}
diff --git a/api/src/Mailer.php b/api/src/Mailer.php
index c8f6f43892..599fe306e7 100644
--- a/api/src/Mailer.php
+++ b/api/src/Mailer.php
@@ -1164,7 +1164,7 @@ class Mailer extends Horde_Mime_Mail
'privkey' => $params['senderPrivKey'],
'passphrase'=> $params['passphrase'],
'sigtype' => 'detach',
- 'certs' => ''
+ 'certs' => $params['extracerts']
);
// parameters to pass on for encrypt mime part
$encrypt_params = array(
diff --git a/mail/inc/class.mail_compose.inc.php b/mail/inc/class.mail_compose.inc.php
index 9744e3b076..3dc5016ce6 100644
--- a/mail/inc/class.mail_compose.inc.php
+++ b/mail/inc/class.mail_compose.inc.php
@@ -214,8 +214,8 @@ class mail_compose
),
);
- $credentials = Mail\Credentials::read($this->mail_bo->profileID, Mail\Credentials::SMIME, $GLOBALS['egw_info']['user']['account_id']);
- if ($credentials['acc_smime_password'])
+ $acc_smime = Mail\Smime::get_acc_smime($this->mail_bo->profileID);
+ if ($acc_smime['acc_smime_password'])
{
$actions = array_merge($actions, array(
'smime_sign' => array (
@@ -3656,12 +3656,8 @@ class mail_compose
protected function _encrypt($mail, $type, $recipients, $sender, $passphrase='')
{
$AB = new addressbook_bo();
- $params = array (
- 'senderPubKey' => '', // Sender Public key
- 'passphrase' => $passphrase, // passphrase of sender private key
- 'senderPrivKey' => '', // sender private key
- 'recipientsCerts' => array() // Recipients Certificates
- );
+ // passphrase of sender private key
+ $params['passphrase'] = $passphrase;
try
{
@@ -3670,9 +3666,9 @@ class mail_compose
$sender_cert = $AB->get_smime_keys($sender);
if (!$sender_cert) throw new Exception("Encryption failed because no certificate has been found for sender address: " . $sender);
$params['senderPubKey'] = $sender_cert[$sender];
-
- $credents = Mail\Credentials::read($this->mail_bo->profileID, Mail\Credentials::SMIME, $GLOBALS['egw_info']['user']['account_id']);
- $params['senderPrivKey'] = $credents['acc_smime_password'];
+ $acc_smime = Mail\Smime::get_acc_smime($this->mail_bo->profileID, $params['passphrase']);
+ $params['senderPrivKey'] = $acc_smime['pkey'];
+ $params['extracerts'] = $acc_smime['extracerts'];
}
if (isset($recipients) && ($type == Mail\Smime::TYPE_ENCRYPT || $type == Mail\Smime::TYPE_SIGN_ENCRYPT))
diff --git a/mail/inc/class.mail_ui.inc.php b/mail/inc/class.mail_ui.inc.php
index 937f9dc780..bf022999ad 100644
--- a/mail/inc/class.mail_ui.inc.php
+++ b/mail/inc/class.mail_ui.inc.php
@@ -56,6 +56,7 @@ class mail_ui
'importMessageFromVFS2DraftAndDisplay'=>True,
'subscription' => True,
'folderManagement' => true,
+ 'smimeExportCert' => true
);
/**
@@ -2267,6 +2268,21 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
$response->data($smime->generate_certificate($_data, $ca, null, $passphrase));
}
+ /**
+ * Export stored smime certificate in database
+ * @return boolean return false if not successful
+ */
+ function smimeExportCert()
+ {
+ if (empty($_GET['acc_id'])) return false;
+ $acc_smime = Mail\Credentials::read($_GET['acc_id'], Mail\Credentials::SMIME, $GLOBALS['egw_info']['user']['account_id']);
+ $length = 0;
+ $mime = 'application/x-pkcs12';
+ Api\Header\Content::safe($acc_smime['acc_smime_password'], "certificate.p12", $mime, $length, true, true);
+ echo $acc_smime['acc_smime_password'];
+ exit();
+ }
+
/**
* Build actions for display toolbar
*/
@@ -3111,10 +3127,10 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
}
catch(Mail\Smime\PassphraseMissing $e)
{
- $credentials = Mail\Credentials::read($this->mail_bo->profileID, Mail\Credentials::SMIME, $GLOBALS['egw_info']['user']['account_id']);
- if (empty($credentials['acc_smime_password']))
+ $acc_smime = Mail\Smime::get_acc_smime($this->mail_bo->profileID);
+ if (empty($acc_smime))
{
- self::callWizard($e->getMessage().' '.lang('Please configure your S/MIME private key in Encryption tab located at Edit Account dialog.'));
+ self::callWizard($e->getMessage().' '.lang('Please configure your S/MIME certificate in Encryption tab located at Edit Account dialog.'));
}
Framework::message($e->getMessage());
// do NOT include any default CSS