Handle S/MIME encrypt, decrypt, sign and very everywhere #259

This commit is contained in:
the-djmaze 2024-02-20 16:03:22 +01:00
parent 44a623543f
commit 5a2d2fd0e5
7 changed files with 85 additions and 48 deletions

View file

@ -1194,6 +1194,17 @@ trait Messages
$oMessage->Attachments()->Clear();
$SMIME = $this->SMIME();
$certificates = $SMIME->certificates();
// Load certificates by id
foreach ($aCertificates as &$sCertificate) {
if (!\str_contains($sCertificate, '-----BEGIN CERTIFICATE-----')) {
foreach ($certificates as $certificate) {
if ($certificate['id'] === $sCertificate) {
$sCertificate = $SMIME->getCertificate($certificate['file']);
}
}
}
}
$sEncrypted = $SMIME->encrypt($tmp, $aCertificates);
$oPart = new MimePart;

View file

@ -114,34 +114,37 @@ trait SMime
public function DoSMimeVerifyMessage() : array
{
$sFolderName = $this->GetActionParam('folder', '');
$iUid = (int) $this->GetActionParam('uid', 0);
$sPartId = $this->GetActionParam('partId', '');
$sMicAlg = $this->GetActionParam('micAlg', '');
$sBody = $this->GetActionParam('bodyPart', '');
$bDetached = !empty($this->GetActionParam('detached', 0));
if (!$sBody) {
$sFolderName = $this->GetActionParam('folder', '');
$iUid = (int) $this->GetActionParam('uid', 0);
$sPartId = $this->GetActionParam('partId', '');
$sMicAlg = $this->GetActionParam('micAlg', '');
$this->initMailClientConnection();
$oImapClient = $this->ImapClient();
$oImapClient->FolderExamine($sFolderName);
$this->initMailClientConnection();
$oImapClient = $this->ImapClient();
$oImapClient->FolderExamine($sFolderName);
if ('TEXT' === $sPartId) {
$oFetchResponse = $oImapClient->Fetch([
FetchType::BODY_PEEK.'['.$sPartId.']',
// An empty section specification refers to the entire message, including the header.
// But Dovecot does not return it with BODY.PEEK[1], so we also use BODY.PEEK[1.MIME].
FetchType::BODY_HEADER_PEEK
], $iUid, true)[0];
$sBody = $oFetchResponse->GetFetchValue(FetchType::BODY_HEADER);
} else {
$oFetchResponse = $oImapClient->Fetch([
FetchType::BODY_PEEK.'['.$sPartId.']',
// An empty section specification refers to the entire message, including the header.
// But Dovecot does not return it with BODY.PEEK[1], so we also use BODY.PEEK[1.MIME].
FetchType::BODY_PEEK.'['.$sPartId.'.MIME]'
], $iUid, true)[0];
$sBody = $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$sPartId.'.MIME]');
if ('TEXT' === $sPartId) {
$oFetchResponse = $oImapClient->Fetch([
FetchType::BODY_PEEK.'['.$sPartId.']',
// An empty section specification refers to the entire message, including the header.
// But Dovecot does not return it with BODY.PEEK[1], so we also use BODY.PEEK[1.MIME].
FetchType::BODY_HEADER_PEEK
], $iUid, true)[0];
$sBody = $oFetchResponse->GetFetchValue(FetchType::BODY_HEADER);
} else {
$oFetchResponse = $oImapClient->Fetch([
FetchType::BODY_PEEK.'['.$sPartId.']',
// An empty section specification refers to the entire message, including the header.
// But Dovecot does not return it with BODY.PEEK[1], so we also use BODY.PEEK[1.MIME].
FetchType::BODY_PEEK.'['.$sPartId.'.MIME]'
], $iUid, true)[0];
$sBody = $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$sPartId.'.MIME]');
}
$sBody .= $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$sPartId.']');
}
$sBody .= $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$sPartId.']');
$result = $this->SMIME()->verify($sBody, null, !$bDetached);

View file

@ -25,6 +25,11 @@ class OpenSSL
$this->homedir = $homedir;
}
public function getCertificate(string $filename)/* : string*/
{
return \file_get_contents("{$this->homedir}/{$filename}");
}
public function certificates() : array
{
$cacheFile = "{$this->homedir}/certificates.json";

View file

@ -123,6 +123,7 @@
<div id="mailvelope-settings" style="height:40em" data-bind="visible: canMailvelope"></div>
</details>
<!-- TODO
<details>
<summary class="legend">S/MIME Certificates</summary>
<table class="table table-hover list-table">
@ -137,7 +138,6 @@
<span data-i18n="CRYPTO/VALID_UNTIL"></span>:
<time data-time-format="FULL" data-bind="time:validTo_time_t"></time>
</td>
<!--
<td>
<a class="btn btn-small btn-danger button-confirm-delete" data-bind="css: {'delete-access': askDelete()}, click: remove"
data-i18n="GLOBAL/ARE_YOU_SURE"></a>
@ -145,8 +145,8 @@
<td>
<span class="delete-key fontastic" data-bind="visible: !askDelete(), click: openForDeletion">🗑</span>
</td>
-->
</tr>
</tbody>
</table>
</details>
-->