diff --git a/dev/View/Popup/Compose.js b/dev/View/Popup/Compose.js index 3cbbeeba9..69530f487 100644 --- a/dev/View/Popup/Compose.js +++ b/dev/View/Popup/Compose.js @@ -1545,24 +1545,34 @@ export class ComposePopupView extends AbstractViewPopup { } } if (encrypt) { - Object.entries(PgpUserStore.getPublicKeyOfEmails(recipients) || {}).forEach(([k,v]) => - params.autocrypt.push({addr:k, keydata:v.replace(/-----(BEGIN|END) PGP PUBLIC KEY BLOCK-----/g, '').trim()}) - ); + const autocrypt = () => + Object.entries(PgpUserStore.getPublicKeyOfEmails(recipients) || {}).forEach(([k,v]) => + params.autocrypt.push({ + addr: k, + keydata: v.replace(/-----(BEGIN|END) PGP PUBLIC KEY BLOCK-----/g, '').trim() + }) + ); if ('openpgp' == encrypt) { // Doesn't encrypt attachments params.encrypted = await OpenPGPUserStore.encrypt(data.toString(), recipients); params.signed = ''; + autocrypt(); } else if ('gnupg' == encrypt) { // Does encrypt attachments params.encryptFingerprints = JSON.stringify(GnuPGUserStore.getPublicKeyFingerprints(recipients)); -// } else { -// // S/MIME -// params.encryptCertificates = []; + autocrypt(); +/* + } else if (identity && identity.smimeCertificate()) { + // TODO: S/MIME certificates of all recipients + params.encryptCertificates = [identity.smimeCertificate()]; + } +*/ } else { throw 'Encryption with ' + encrypt + ' not yet implemented'; } } } + return params; } } diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Mime/Part.php b/snappymail/v/0.0.0/app/libraries/MailSo/Mime/Part.php index 5c6f52a8c..655012df2 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Mime/Part.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Mime/Part.php @@ -194,14 +194,14 @@ class Part return \MailSo\Base\StreamWrappers\SubStreams::CreateStream($aSubStreams); } - public function addEncrypted(string $sEncrypted, string $sType) + public function addPgpEncrypted(string $sEncrypted) { $oPart = new self; - $oPart->Headers->AddByName(Enumerations\Header::CONTENT_TYPE, 'multipart/encrypted; protocol="'.$sType.'"'); + $oPart->Headers->AddByName(Enumerations\Header::CONTENT_TYPE, 'multipart/encrypted; protocol="application/pgp-encrypted"'); $this->SubParts->append($oPart); $oSubPart = new self; - $oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_TYPE, $sType); + $oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_TYPE, 'application/pgp-encrypted'); $oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_DISPOSITION, 'attachment'); $oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_TRANSFER_ENCODING, '7Bit'); $oSubPart->Body = \MailSo\Base\ResourceRegistry::CreateMemoryResourceFromString('Version: 1'); @@ -209,27 +209,12 @@ class Part $oSubPart = new self; $oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_TYPE, 'application/octet-stream'); - if ('application/pgp-encrypted' === $sType) { - $oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_DISPOSITION, 'inline; filename="msg.asc"'); - } - if ('application/pkcs7-mime' === $sType) { - $oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_DISPOSITION, 'inline; filename="msg.p7m"'); - } + $oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_DISPOSITION, 'inline; filename="msg.asc"'); $oSubPart->Headers->AddByName(Enumerations\Header::CONTENT_TRANSFER_ENCODING, '7Bit'); $oSubPart->Body = \MailSo\Base\ResourceRegistry::CreateMemoryResourceFromString($sEncrypted); $oPart->SubParts->append($oSubPart); } - public function addPgpEncrypted(string $sEncrypted) - { - $this->addEncrypted($sEncrypted, 'application/pgp-encrypted'); - } - - public function addSMimeEncrypted(string $sEncrypted) - { - $this->addEncrypted($sEncrypted, 'application/pkcs7-mime'); - } - public function addPlain(string $sPlain) { $oPart = new self; diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Messages.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Messages.php index e28dc0ed6..70fa9da84 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Messages.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Messages.php @@ -1179,22 +1179,31 @@ trait Messages } $oMessage->addPgpEncrypted($GPG->encryptStream($fp)); } else { - $aCertificates = \json_decode($this->GetActionParam('encryptCertificates', ''), true); + $aCertificates = $this->GetActionParam('encryptCertificates', []); if ($aCertificates) { - $tmp = new \SnappyMail\File\Temporary('mimepart'); - $tmp->writeFromStream($oMessage->GetRootPart()->ToStream()); + $oBody = $oMessage->GetRootPart(); + $resource = $oBody->ToStream(); + \MailSo\Base\StreamFilters\LineEndings::appendTo($resource); + $tmp = new \SnappyMail\File\Temporary('mimepart'); + $tmp->writeFromStream($resource); + + $oBody->Body = null; + $oBody->SubParts->Clear(); $oMessage->SubParts->Clear(); $oMessage->Attachments()->Clear(); $SMIME = $this->SMIME(); -/* - foreach ($aCertificates as $sCertificate) { - $SMIME->addEncryptKey($sCertificate); - } -*/ $sEncrypted = $SMIME->encrypt($tmp, $aCertificates); - $oMessage->addSMimeEncrypted($sEncrypted); + + $oPart = new MimePart; + $oMessage->SubParts->append($oPart); + $oPart->Headers->AddByName( + MimeEnumHeader::CONTENT_TYPE, + 'application/pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"' + ); + $oPart->Headers->AddByName(MimeEnumHeader::CONTENT_TRANSFER_ENCODING, 'base64'); + $oPart->Body = $sEncrypted; } } 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 0b81f8f1b..92740f0b4 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 @@ -162,7 +162,24 @@ class OpenSSL )) { throw new \RuntimeException('OpenSSL encrypt: ' . \openssl_error_string()); } - return $output->getContents(); + + /** + * Only fetch the body part + */ + $fp = $output->fopen(); + // Skip headers + while (\trim(\fgets($fp))); + // Fetch the body + $encrypted = ''; + do { + $line = \fgets($fp); + if (!\trim($line)) { + return $encrypted; + } + $encrypted .= $line; + } while (true); + + return $data; } public function sign(/*string|Temporary*/$input, bool $detached = true) @@ -188,7 +205,7 @@ class OpenSSL } /** - * Only fetch the signed part + * Only fetch the signed body part */ $fp = $output->fopen(); $micalg = ''; @@ -209,13 +226,13 @@ class OpenSSL // Skip headers while (\trim(\fgets($fp))); // Fetch the body - $data = ''; + $signature = ''; do { $line = \fgets($fp); if (!\trim($line)) { - return $data; + return $signature; } - $data .= $line; + $signature .= $line; } while (true); } }