public function testEncryptThenSignMessage()
{
$message = (new Swift_Message('Wonderful Subject'))->setFrom(array('*****@*****.**' => 'John Doe'))->setTo(array('*****@*****.**', '*****@*****.**' => 'A name'))->setBody('Here is the message itself');
$originalMessage = $this->cleanMessage($message->toString());
$signer = new Swift_Signers_SMimeSigner();
$signer->setSignCertificate($this->samplesDir . 'smime/sign.crt', $this->samplesDir . 'smime/sign.key');
$signer->setEncryptCertificate($this->samplesDir . 'smime/encrypt.crt');
$signer->setSignThenEncrypt(false);
$message->attachSigner($signer);
$messageStream = $this->newFilteredStream();
$message->toByteStream($messageStream);
$messageStream->commit();
$entityString = $messageStream->getContent();
$headers = self::getHeadersOfMessage($entityString);
if (!($boundary = $this->getBoundary($headers['content-type']))) {
return false;
}
$expectedBody = <<<OEL
This is an S/MIME signed message
--{$boundary}
(?P<encrypted_message>MIME-Version: 1\\.0
Content-Disposition: attachment; filename="smime\\.p7m"
Content-Type: application/(x\\-)?pkcs7-mime; smime-type=enveloped-data; name="smime\\.p7m"
Content-Transfer-Encoding: base64
(?:^[a-zA-Z0-9\\/\\r\\n+]*={0,2})
)--{$boundary}
Content-Type: application/(x\\-)?pkcs7-signature; name="smime\\.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime\\.p7s"
(?:^[a-zA-Z0-9\\/\\r\\n+]*={0,2})
--{$boundary}--
OEL;
if (!$this->assertValidVerify($expectedBody, $messageStream)) {
return false;
}
$expectedBody = str_replace("\n", "\r\n", $expectedBody);
if (!preg_match('%' . $expectedBody . '*%m', $entityString, $entities)) {
$this->fail('Failed regex match.');
return false;
}
$messageStreamClean = new Swift_ByteStream_TemporaryFileByteStream();
$messageStreamClean->write($entities['encrypted_message']);
$decryptedMessageStream = new Swift_ByteStream_TemporaryFileByteStream();
if (!openssl_pkcs7_decrypt($messageStreamClean->getPath(), $decryptedMessageStream->getPath(), 'file://' . $this->samplesDir . 'smime/encrypt.crt', array('file://' . $this->samplesDir . 'smime/encrypt.key', 'swift'))) {
$this->fail(sprintf('Decrypt of the message failed. Internal error "%s".', openssl_error_string()));
}
$this->assertEquals($originalMessage, $decryptedMessageStream->getContent());
unset($messageStreamClean, $messageStream, $decryptedMessageStream);
}