mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-03 04:29:28 +01:00
WIP of SMIME support: First attempt to decrypt a smime encrypted message
This commit is contained in:
parent
dc4a825c54
commit
2d8b8fc5dc
@ -35,25 +35,35 @@ class Smime extends Horde_Crypt_Smime
|
||||
'application/pkcs7-signature',
|
||||
);
|
||||
|
||||
/**
|
||||
* SMIME signature only types
|
||||
* @var type
|
||||
*/
|
||||
static $SMIME_SIGNATURE_ONLY_TYPES = array (
|
||||
'application/x-pkcs7-signature',
|
||||
'application/pkcs7-signature',
|
||||
'multipart/signed'
|
||||
);
|
||||
|
||||
/*
|
||||
* SMIME public key regular expresion
|
||||
*/
|
||||
static public $pubkey_regexp = '/-----BEGIN PUBLIC KEY-----.*-----END PUBLIC KEY-----\r?\n/s/';
|
||||
static public $pubkey_regexp = '/-----BEGIN PUBLIC KEY-----.*-----END PUBLIC KEY-----\r?\n/s';
|
||||
|
||||
/*
|
||||
* SMIME encrypted private key regular expresion
|
||||
*/
|
||||
static public $privkey_encrypted_regexp = '/-----BEGIN ENCRYPTED PRIVATE KEY-----.*-----END ENCRYPTED PRIVATE KEY-----\r?\n/s/';
|
||||
static public $privkey_encrypted_regexp = '/-----BEGIN ENCRYPTED PRIVATE KEY-----.*-----END ENCRYPTED PRIVATE KEY-----\r?\n/s';
|
||||
|
||||
/*
|
||||
* SMIME private key regular expresion
|
||||
*/
|
||||
static public $privkey_regexp = '/-----BEGIN PRIVATE KEY-----.*-----END PRIVATE KEY-----\r?\n/s/';
|
||||
static public $privkey_regexp = '/-----BEGIN PRIVATE KEY-----.*-----END PRIVATE KEY-----\r?\n/s';
|
||||
|
||||
/*
|
||||
* SMIME certificate regular expresion
|
||||
*/
|
||||
static public $certificate_regexp = '/-----BEGIN CERTIFICATE-----.*-----END CERTIFICATE-----\r?\n/s/';
|
||||
static public $certificate_regexp = '/-----BEGIN CERTIFICATE-----.*-----END CERTIFICATE-----\r?\n/s';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -77,6 +87,18 @@ class Smime extends Horde_Crypt_Smime
|
||||
return in_array($_mime, self::$SMIME_TYPES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given mime type is smime type of signature only
|
||||
*
|
||||
* @param string $_mime mimetype
|
||||
*
|
||||
* @return type
|
||||
*/
|
||||
public static function isSmimeSignatureOnly ($_mime)
|
||||
{
|
||||
return in_array($_mime, self::$SMIME_SIGNATURE_ONLY_TYPES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the openssl is supported
|
||||
*
|
||||
@ -96,7 +118,8 @@ class Smime extends Horde_Crypt_Smime
|
||||
/**
|
||||
* Extract public key from certificate
|
||||
*
|
||||
* @param type $cert
|
||||
* @param string $cert content of certificate in PEM format
|
||||
*
|
||||
* @return string returns public key
|
||||
*/
|
||||
public function get_publickey ($cert)
|
||||
@ -109,11 +132,12 @@ class Smime extends Horde_Crypt_Smime
|
||||
/**
|
||||
* Extract certificates info from a p12 file
|
||||
*
|
||||
* @param string $pkcs12
|
||||
* @param string $passphrase
|
||||
* @param string $pkcs12 content of p12 file in string
|
||||
* @param string $passphrase = '', passphrase to unlock the p12 file
|
||||
*
|
||||
* @return boolean|array returns array of certs info or false if not successful
|
||||
*/
|
||||
public function extractCertPKCS12 ($pkcs12, $passphrase)
|
||||
public function extractCertPKCS12 ($pkcs12, $passphrase = '')
|
||||
{
|
||||
$certs = array ();
|
||||
if (openssl_pkcs12_read($pkcs12, $certs, $passphrase))
|
||||
|
@ -2011,6 +2011,8 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
||||
if (is_array($smimeData))
|
||||
{
|
||||
$error_msg[] = $smimeData['msg'];
|
||||
if ($smimeData['signed'])
|
||||
{
|
||||
$linkData = array
|
||||
(
|
||||
'menuaction' => 'mail.mail_ui.getAttachment',
|
||||
@ -2021,6 +2023,12 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
||||
);
|
||||
$content['smimeSigUrl'] = Egw::link('/index.php',$linkData);
|
||||
}
|
||||
if ($smimeData['required_password'])
|
||||
{
|
||||
$response = Api\Json\Response::get();
|
||||
$response->call('app.mail.smimeRequestPassphrase');
|
||||
}
|
||||
}
|
||||
|
||||
//error_log(__METHOD__.__LINE__.array2string($attachments));
|
||||
$attachmentHTMLBlock = self::createAttachmentBlock($attachments, $rowID, $uid, $mailbox);
|
||||
@ -2091,6 +2099,35 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
||||
$etpl->exec('mail.mail_ui.displayMessage',$content,$sel_options,$readonlys,$preserv,2);
|
||||
}
|
||||
|
||||
/**
|
||||
* decrypt given smime encrypted message
|
||||
*
|
||||
* @param string $_message
|
||||
* @param string $_passphrase
|
||||
* @return array|string return
|
||||
*/
|
||||
function decryptSmimeBody ($_message, $_passphrase = '')
|
||||
{
|
||||
$AB_bo = new addressbook_bo();
|
||||
$credents = Mail\Credentials::read($this->mail_bo->profileID, Mail\Credentials::SMIME, $GLOBALS['egw_info']['user']['account_id']);
|
||||
$certkey = $AB_bo->get_smime_keys($GLOBALS['egw_info']['user']['account_email']);
|
||||
if (!$this->smime->verifyPassphrase($credents['acc_smime_password'], $_passphrase))
|
||||
{
|
||||
return array (
|
||||
'password_required' => true,
|
||||
'msg' => 'Authentication failure!'
|
||||
);
|
||||
}
|
||||
|
||||
$params = array (
|
||||
'type' => 'message',
|
||||
'pubkey' => $certkey[$GLOBALS['egw_info']['user']['account_email']],
|
||||
'privkey' => $credents['acc_smime_password'],
|
||||
'passphrase'=> $_passphrase
|
||||
);
|
||||
return $this->smime->decrypt($_message, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve certificate from smime attachment
|
||||
*
|
||||
@ -2102,21 +2139,40 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
||||
*/
|
||||
function resolveSmimeAttachment (&$attachments, $_uid, $_partID, $_mailbox)
|
||||
{
|
||||
$smime = new Mail\Smime;
|
||||
$this->smime = new Mail\Smime;
|
||||
|
||||
foreach ($attachments as $key => $attachment)
|
||||
{
|
||||
if (Mail\Smime::isSmime($attachment['mimeType']))
|
||||
{
|
||||
$message = $this->mail_bo->getMessageRawBody($_uid, $_partID, $_mailbox);
|
||||
$cert = $smime->verify($message);
|
||||
|
||||
if (!Mail\Smime::isSmimeSignatureOnly($attachment['mimeType']))
|
||||
{
|
||||
try {
|
||||
$message = $this->decryptSmimeBody($message);
|
||||
} catch (Exception $ex) {
|
||||
return array('msg', $ex->getMessage());
|
||||
}
|
||||
}
|
||||
try {
|
||||
$cert = $this->smime->verify($message);
|
||||
$data = array (
|
||||
'verify' => $cert->verify,
|
||||
'cert' => $cert->cert,
|
||||
'msg' => $cert->msg,
|
||||
'certHtml' => $smime->certToHTML($cert->cert),
|
||||
'partID' => $attachment['partID']
|
||||
'certHtml' => $this->smime->certToHTML($cert->cert),
|
||||
'partID' => $attachment['partID'],
|
||||
'signed' => true,
|
||||
'message' => $message
|
||||
);
|
||||
|
||||
} catch (Exception $ex) {
|
||||
$data = array (
|
||||
'signed' => false,
|
||||
'message' => $message
|
||||
);
|
||||
}
|
||||
unset ($attachments[$key]);
|
||||
}
|
||||
}
|
||||
@ -2930,7 +2986,18 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
|
||||
$structure = $this->mail_bo->getStructure($uid, $partID, $mailbox, false);
|
||||
$calendar_part = null;
|
||||
$bodyParts = $this->mail_bo->getMessageBody($uid, ($htmlOptions?$htmlOptions:''), $partID, $structure, false, $mailbox, $calendar_part);
|
||||
$mimeType = $structure->getType();
|
||||
if (Mail\Smime::isSmime( $mimeType) && !Mail\Smime::isSmimeSignatureOnly($mimeType))
|
||||
{
|
||||
$smimeAttachments = array ( array('mimeType' => $mimeType));
|
||||
$smime = $this->resolveSmimeAttachment($smimeAttachments, $uid, 0, $mailbox);
|
||||
|
||||
if ($smime['message'])
|
||||
{
|
||||
$bodyParts[0]['body'] = $smime['message'];
|
||||
}
|
||||
|
||||
}
|
||||
// for meeting requests (multipart alternative with text/calendar part) let calendar render it
|
||||
if ($calendar_part && isset($GLOBALS['egw_info']['user']['apps']['calendar']))
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user