Get S/MIME encryption working #259

This commit is contained in:
the-djmaze 2024-02-20 12:38:57 +01:00
parent 196dffa8d8
commit 1762198642
4 changed files with 60 additions and 39 deletions

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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);
}
}