/**
* Parse signed data.
*
* @param boolean $sig_only Only do signature checking?
*
* @return mixed See self::_getEmbeddedMimeParts().
*/
protected function _parseSignedData($sig_only = false)
{
$iterator = $this->_mimepart->partIterator();
$iterator->rewind();
if (!($curr = $iterator->current())) {
return null;
}
$base_id = $curr->getMimeId();
$iterator->next();
if (!($curr = $iterator->current())) {
// application/pkcs-7-mime might be the base part.
// See RFC 5751 3.4.2
$data_id = $base_id;
} else {
$data_id = $curr->getMimeId();
}
$id_ob = new Horde_Mime_Id($data_id);
$sig_id = $id_ob->idArithmetic($id_ob::ID_NEXT);
/* Initialize inline data. */
$status = new IMP_Mime_Status($this->_mimepart, _("The data in this part has been digitally signed via S/MIME."));
$status->icon('mime/encryption.png', 'S/MIME');
$cache = $this->getConfigParam('imp_contents')->getViewCache();
$cache->smime[$base_id] = array('sig' => $sig_id, 'status' => $status, 'wrap' => 'mimePartWrap');
if (!IMP_Smime::enabled()) {
$status->addText(_("S/MIME support is not enabled so the digital signature is unable to be verified."));
return null;
}
$imp_contents = $this->getConfigParam('imp_contents');
$stream = $imp_contents->isEmbedded($base_id) ? $this->_mimepart->getMetadata('imp-smime-decrypt')->stream : $this->_getPartStream($base_id);
$raw_text = $this->_mimepart->replaceEOL($stream, Horde_Mime_Part::RFC_EOL);
$this->_initSmime();
$sig_result = null;
if ($GLOBALS['prefs']->getValue('smime_verify') || $GLOBALS['injector']->getInstance('Horde_Variables')->smime_verify_msg) {
try {
$sig_result = $this->_impsmime->verifySignature($raw_text);
if ($sig_result->verify) {
$status->action(IMP_Mime_Status::SUCCESS);
} else {
$status->action(IMP_Mime_Status::WARNING);
}
if (!is_array($sig_result->email)) {
$sig_result->email = array($sig_result->email);
}
$email = implode(', ', $sig_result->email);
$cache->smime[$base_id]['wrap'] = 'mimePartWrapValid';
$status->addText($sig_result->msg);
if (!empty($sig_result->cert)) {
$cert = $this->_impsmime->parseCert($sig_result->cert);
if (isset($cert['certificate']['subject']['CommonName']) && strcasecmp($email, $cert['certificate']['subject']['CommonName']) !== 0) {
$email = $cert['certificate']['subject']['CommonName'] . ' (' . trim($email) . ')';
}
}
if (!empty($sig_result->cert) && isset($sig_result->email) && $GLOBALS['registry']->hasMethod('contacts/addField') && $GLOBALS['prefs']->getValue('add_source')) {
$status->addText(sprintf(_("Sender: %s"), $imp_contents->linkViewJS($this->_mimepart, 'view_attach', htmlspecialchars($email), array('jstext' => _("View certificate details"), 'params' => array('mode' => IMP_Contents::RENDER_INLINE, 'view_smime_key' => 1)))));
foreach ($sig_result->email as $single_email) {
try {
$this->_impsmime->getPublicKey($single_email);
} catch (Horde_Exception $e) {
$imple = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Imple')->create('IMP_Ajax_Imple_ImportEncryptKey', array('mime_id' => $base_id, 'muid' => strval($imp_contents->getIndicesOb()), 'type' => 'smime'));
$status->addText(Horde::link('#', '', '', '', '', '', '', array('id' => $imple->getDomId())) . _("Save the certificate to your Address Book.") . '</a>');
break;
}
}
} elseif (strlen($email)) {
$status->addText(sprintf(_("Sender: %s"), htmlspecialchars($email)));
}
} catch (Horde_Exception $e) {
$status->action(IMP_Mime_Status::ERROR);
$cache->smime[$base_id]['wrap'] = 'mimePartWrapInvalid';
$status->addText($e->getMessage());
}
} else {
$status->addMimeAction('smimeVerifyMsg', _("Click to verify the data."));
}
if ($sig_only) {
return;
}
if (!($subpart = $imp_contents->getMimePart($sig_id))) {
try {
$msg_data = $this->_impsmime->extractSignedContents($raw_text);
$subpart = Horde_Mime_Part::parseMessage($msg_data, array('forcemime' => true));
} catch (Horde_Exception $e) {
$status->addText($e->getMessage());
return null;
}
}
return $subpart;
}