Automaticaly import S/MIME certificates that are found in signatures #259

This commit is contained in:
the-djmaze 2024-02-20 17:42:26 +01:00
parent 3d168b4688
commit 6ce08726b4
4 changed files with 71 additions and 1 deletions

View file

@ -76,6 +76,7 @@ export function MimeToMessage(data, message)
message.smimeSigned({
micAlg: type.micalg,
bodyPart: part,
sigPart: part.parts[1], // For importing
detached: true
});
}

View file

@ -348,6 +348,7 @@ class Message implements \JsonSerializable
} else if ($oPart->isSMimeSigned()) {
$oMessage->smimeSigned = [
'partId' => $oPart->PartID(),
'sigPartId' => $oPart->SubParts()[1]->PartID(),
'micAlg' => $oHeaders ? (string) $oHeaders->ParameterValue(MimeHeader::CONTENT_TYPE, 'micalg') : '',
'detached' => true
];

View file

@ -148,6 +148,57 @@ trait SMime
$result = $this->SMIME()->verify($sBody, null, !$bDetached);
// Import the certificates automatically
$sBody = $this->GetActionParam('sigPart', '');
$sPartId = $this->GetActionParam('sigPartId', '') ?: $sPartId;
if (!$sBody && $sPartId) {
$sBody = $oImapClient->Fetch(
[FetchType::BODY_PEEK.'['.$sPartId.']'],
$iUid,
true
)[0]->GetFetchValue(FetchType::BODY.'['.$sPartId.']');
}
if ($sBody) {
$sBody = \trim($sBody);
$certificates = [];
\openssl_pkcs7_read(
"-----BEGIN CERTIFICATE-----\n\n{$sBody}\n-----END CERTIFICATE-----",
$certificates
) || \error_log("OpenSSL openssl_pkcs7_read: " . \openssl_error_string());
foreach ($certificates as $certificate) {
$this->SMIME()->storeCertificate($certificate);
}
}
return $this->DefaultResponse($result);
}
public function DoSMimeImportCertificatesFromMessage() : array
{
/*
$sBody = $this->GetActionParam('sigPart', '');
if (!$sBody) {
$sPartId = $this->GetActionParam('sigPartId', '') ?: $this->GetActionParam('partId', '');
$this->initMailClientConnection();
$oImapClient = $this->ImapClient();
$oImapClient->FolderExamine($this->GetActionParam('folder', ''));
$sBody = $oImapClient->Fetch([
FetchType::BODY_PEEK.'['.$sPartId.']'
], (int) $this->GetActionParam('uid', 0), true)[0]
->GetFetchValue(FetchType::BODY.'['.$sPartId.']');
}
$sBody = \trim($sBody);
$certificates = [];
\openssl_pkcs7_read(
"-----BEGIN CERTIFICATE-----\n\n{$sBody}\n-----END CERTIFICATE-----",
$certificates
);
foreach ($certificates as $certificate) {
$this->SMIME()->storeCertificate($certificate);
}
return $this->DefaultResponse($certificates);
*/
}
}

View file

@ -30,7 +30,24 @@ class OpenSSL
return \file_get_contents("{$this->homedir}/{$filename}");
}
public function certificates() : array
public function storeCertificate(string $certificate) : bool
{
$data = \openssl_x509_parse(\openssl_x509_read($certificate));
if (!$data) {
\error_log("OpenSSL parse: " . \openssl_error_string());
return false;
}
$key = \str_replace(':', '', $data['extensions']['subjectKeyIdentifier'] ?? $data['hash']);
$filename = "{$this->homedir}/{$key}.crt";
if (!\file_exists($filename)) {
\file_put_contents("{$this->homedir}/{$key}.crt", $certificate);
// \unlink("{$this->homedir}/certificates.json");
$this->certificates(true);
}
return true;
}
public function certificates(bool $force = false) : array
{
$cacheFile = "{$this->homedir}/certificates.json";
$result = \file_exists($cacheFile)