diff --git a/dev/Mime/Utils.js b/dev/Mime/Utils.js index 7ee9170e3..1092298f3 100644 --- a/dev/Mime/Utils.js +++ b/dev/Mime/Utils.js @@ -76,6 +76,7 @@ export function MimeToMessage(data, message) message.smimeSigned({ micAlg: type.micalg, bodyPart: part, + sigPart: part.parts[1], // For importing detached: true }); } diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php index 493360a4e..13b098013 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php @@ -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 ]; diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/SMime.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/SMime.php index da525db42..b6ef6f016 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/SMime.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/SMime.php @@ -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); +*/ + } } diff --git a/snappymail/v/0.0.0/app/libraries/snappymail/smime/openssl.php b/snappymail/v/0.0.0/app/libraries/snappymail/smime/openssl.php index 2d7ed6a74..776aed98e 100644 --- a/snappymail/v/0.0.0/app/libraries/snappymail/smime/openssl.php +++ b/snappymail/v/0.0.0/app/libraries/snappymail/smime/openssl.php @@ -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)