summaryrefslogtreecommitdiff
path: root/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2019-11-17 20:45:02 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2019-11-17 20:45:02 +0100
commit8df3db566a3a937b45ebf11adb90d265e6f5e2d4 (patch)
tree4d541098d751d5a9acf8c12f6fb9f308ace066ac /vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers
downloadflyspray-8df3db566a3a937b45ebf11adb90d265e6f5e2d4.tar.xz
initial checking of customized version 1.0rc9
Diffstat (limited to 'vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers')
-rw-r--r--vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/DKIMSignerTest.php225
-rw-r--r--vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/OpenDKIMSignerTest.php45
-rw-r--r--vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/SMimeSignerTest.php554
3 files changed, 824 insertions, 0 deletions
diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/DKIMSignerTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/DKIMSignerTest.php
new file mode 100644
index 0000000..5eda223
--- /dev/null
+++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/DKIMSignerTest.php
@@ -0,0 +1,225 @@
+<?php
+
+class Swift_Signers_DKIMSignerTest extends \SwiftMailerTestCase
+{
+ protected function setUp()
+ {
+ if (PHP_VERSION_ID < 50400 && !defined('OPENSSL_ALGO_SHA256')) {
+ $this->markTestSkipped('skipping because of https://bugs.php.net/bug.php?id=61421');
+ }
+ }
+
+ public function testBasicSigningHeaderManipulation()
+ {
+ $headers = $this->_createHeaders();
+ $messageContent = 'Hello World';
+ $signer = new Swift_Signers_DKIMSigner(file_get_contents(dirname(dirname(dirname(__DIR__))).'/_samples/dkim/dkim.test.priv'), 'dummy.nxdomain.be', 'dummySelector');
+ /* @var $signer Swift_Signers_HeaderSigner */
+ $altered = $signer->getAlteredHeaders();
+ $signer->reset();
+ // Headers
+ $signer->setHeaders($headers);
+ // Body
+ $signer->startBody();
+ $signer->write($messageContent);
+ $signer->endBody();
+ // Signing
+ $signer->addSignature($headers);
+ }
+
+ // SHA1 Signing
+ public function testSigningSHA1()
+ {
+ $headerSet = $this->_createHeaderSet();
+ $messageContent = 'Hello World';
+ $signer = new Swift_Signers_DKIMSigner(file_get_contents(dirname(dirname(dirname(__DIR__))).'/_samples/dkim/dkim.test.priv'), 'dummy.nxdomain.be', 'dummySelector');
+ $signer->setHashAlgorithm('rsa-sha1');
+ $signer->setSignatureTimestamp('1299879181');
+ $altered = $signer->getAlteredHeaders();
+ $this->assertEquals(array('DKIM-Signature'), $altered);
+ $signer->reset();
+ $signer->setHeaders($headerSet);
+ $this->assertFalse($headerSet->has('DKIM-Signature'));
+ $signer->startBody();
+ $signer->write($messageContent);
+ $signer->endBody();
+ $signer->addSignature($headerSet);
+ $this->assertTrue($headerSet->has('DKIM-Signature'));
+ $dkim = $headerSet->getAll('DKIM-Signature');
+ $sig = reset($dkim);
+ $this->assertEquals($sig->getValue(), 'v=1; a=rsa-sha1; bh=wlbYcY9O9OPInGJ4D0E/rGsvMLE=; d=dummy.nxdomain.be; h=; i=@dummy.nxdomain.be; s=dummySelector; t=1299879181; b=RMSNelzM2O5MAAnMjT3G3/VF36S3DGJXoPCXR001F1WDReu0prGphWjuzK/m6V1pwqQL8cCNg Hi74mTx2bvyAvmkjvQtJf1VMUOCc9WHGcm1Yec66I3ZWoNMGSWZ1EKAm2CtTzyG0IFw4ml9DI wSkyAFxlgicckDD6FibhqwX4w=');
+ }
+
+ // SHA256 Signing
+ public function testSigning256()
+ {
+ $headerSet = $this->_createHeaderSet();
+ $messageContent = 'Hello World';
+ $signer = new Swift_Signers_DKIMSigner(file_get_contents(dirname(dirname(dirname(__DIR__))).'/_samples/dkim/dkim.test.priv'), 'dummy.nxdomain.be', 'dummySelector');
+ $signer->setHashAlgorithm('rsa-sha256');
+ $signer->setSignatureTimestamp('1299879181');
+ $altered = $signer->getAlteredHeaders();
+ $this->assertEquals(array('DKIM-Signature'), $altered);
+ $signer->reset();
+ $signer->setHeaders($headerSet);
+ $this->assertFalse($headerSet->has('DKIM-Signature'));
+ $signer->startBody();
+ $signer->write($messageContent);
+ $signer->endBody();
+ $signer->addSignature($headerSet);
+ $this->assertTrue($headerSet->has('DKIM-Signature'));
+ $dkim = $headerSet->getAll('DKIM-Signature');
+ $sig = reset($dkim);
+ $this->assertEquals($sig->getValue(), 'v=1; a=rsa-sha256; bh=f+W+hu8dIhf2VAni89o8lF6WKTXi7nViA4RrMdpD5/U=; d=dummy.nxdomain.be; h=; i=@dummy.nxdomain.be; s=dummySelector; t=1299879181; b=jqPmieHzF5vR9F4mXCAkowuphpO4iJ8IAVuioh1BFZ3VITXZj5jlOFxULJMBiiApm2keJirnh u4mzogj444QkpT3lJg8/TBGAYQPdcvkG3KC0jdyN6QpSgpITBJG2BwWa+keXsv2bkQgLRAzNx qRhP45vpHCKun0Tg9LrwW/KCg=');
+ }
+
+ // Relaxed/Relaxed Hash Signing
+ public function testSigningRelaxedRelaxed256()
+ {
+ $headerSet = $this->_createHeaderSet();
+ $messageContent = 'Hello World';
+ $signer = new Swift_Signers_DKIMSigner(file_get_contents(dirname(dirname(dirname(__DIR__))).'/_samples/dkim/dkim.test.priv'), 'dummy.nxdomain.be', 'dummySelector');
+ $signer->setHashAlgorithm('rsa-sha256');
+ $signer->setSignatureTimestamp('1299879181');
+ $signer->setBodyCanon('relaxed');
+ $signer->setHeaderCanon('relaxed');
+ $altered = $signer->getAlteredHeaders();
+ $this->assertEquals(array('DKIM-Signature'), $altered);
+ $signer->reset();
+ $signer->setHeaders($headerSet);
+ $this->assertFalse($headerSet->has('DKIM-Signature'));
+ $signer->startBody();
+ $signer->write($messageContent);
+ $signer->endBody();
+ $signer->addSignature($headerSet);
+ $this->assertTrue($headerSet->has('DKIM-Signature'));
+ $dkim = $headerSet->getAll('DKIM-Signature');
+ $sig = reset($dkim);
+ $this->assertEquals($sig->getValue(), 'v=1; a=rsa-sha256; bh=f+W+hu8dIhf2VAni89o8lF6WKTXi7nViA4RrMdpD5/U=; d=dummy.nxdomain.be; h=; i=@dummy.nxdomain.be; s=dummySelector; c=relaxed/relaxed; t=1299879181; b=gzOI+PX6HpZKQFzwwmxzcVJsyirdLXOS+4pgfCpVHQIdqYusKLrhlLeFBTNoz75HrhNvGH6T0 Rt3w5aTqkrWfUuAEYt0Ns14GowLM7JojaFN+pZ4eYnRB3CBBgW6fee4NEMD5WPca3uS09tr1E 10RYh9ILlRtl+84sovhx5id3Y=');
+ }
+
+ // Relaxed/Simple Hash Signing
+ public function testSigningRelaxedSimple256()
+ {
+ $headerSet = $this->_createHeaderSet();
+ $messageContent = 'Hello World';
+ $signer = new Swift_Signers_DKIMSigner(file_get_contents(dirname(dirname(dirname(__DIR__))).'/_samples/dkim/dkim.test.priv'), 'dummy.nxdomain.be', 'dummySelector');
+ $signer->setHashAlgorithm('rsa-sha256');
+ $signer->setSignatureTimestamp('1299879181');
+ $signer->setHeaderCanon('relaxed');
+ $altered = $signer->getAlteredHeaders();
+ $this->assertEquals(array('DKIM-Signature'), $altered);
+ $signer->reset();
+ $signer->setHeaders($headerSet);
+ $this->assertFalse($headerSet->has('DKIM-Signature'));
+ $signer->startBody();
+ $signer->write($messageContent);
+ $signer->endBody();
+ $signer->addSignature($headerSet);
+ $this->assertTrue($headerSet->has('DKIM-Signature'));
+ $dkim = $headerSet->getAll('DKIM-Signature');
+ $sig = reset($dkim);
+ $this->assertEquals($sig->getValue(), 'v=1; a=rsa-sha256; bh=f+W+hu8dIhf2VAni89o8lF6WKTXi7nViA4RrMdpD5/U=; d=dummy.nxdomain.be; h=; i=@dummy.nxdomain.be; s=dummySelector; c=relaxed; t=1299879181; b=dLPJNec5v81oelyzGOY0qPqTlGnQeNfUNBOrV/JKbStr3NqWGI9jH4JAe2YvO2V32lfPNoby1 4MMzZ6EPkaZkZDDSPa+53YbCPQAlqiD9QZZIUe2UNM33HN8yAMgiWEF5aP7MbQnxeVZMfVLEl 9S8qOImu+K5JZqhQQTL0dgLwA=');
+ }
+
+ // Simple/Relaxed Hash Signing
+ public function testSigningSimpleRelaxed256()
+ {
+ $headerSet = $this->_createHeaderSet();
+ $messageContent = 'Hello World';
+ $signer = new Swift_Signers_DKIMSigner(file_get_contents(dirname(dirname(dirname(__DIR__))).'/_samples/dkim/dkim.test.priv'), 'dummy.nxdomain.be', 'dummySelector');
+ $signer->setHashAlgorithm('rsa-sha256');
+ $signer->setSignatureTimestamp('1299879181');
+ $signer->setBodyCanon('relaxed');
+ $altered = $signer->getAlteredHeaders();
+ $this->assertEquals(array('DKIM-Signature'), $altered);
+ $signer->reset();
+ $signer->setHeaders($headerSet);
+ $this->assertFalse($headerSet->has('DKIM-Signature'));
+ $signer->startBody();
+ $signer->write($messageContent);
+ $signer->endBody();
+ $signer->addSignature($headerSet);
+ $this->assertTrue($headerSet->has('DKIM-Signature'));
+ $dkim = $headerSet->getAll('DKIM-Signature');
+ $sig = reset($dkim);
+ $this->assertEquals($sig->getValue(), 'v=1; a=rsa-sha256; bh=f+W+hu8dIhf2VAni89o8lF6WKTXi7nViA4RrMdpD5/U=; d=dummy.nxdomain.be; h=; i=@dummy.nxdomain.be; s=dummySelector; c=simple/relaxed; t=1299879181; b=M5eomH/zamyzix9kOes+6YLzQZxuJdBP4x3nP9zF2N26eMLG2/cBKbnNyqiOTDhJdYfWPbLIa 1CWnjST0j5p4CpeOkGYuiE+M4TWEZwhRmRWootlPO3Ii6XpbBJKFk1o9zviS7OmXblUUE4aqb yRSIMDhtLdCK5GlaCneFLN7RQ=');
+ }
+
+ private function _createHeaderSet()
+ {
+ $cache = new Swift_KeyCache_ArrayKeyCache(new Swift_KeyCache_SimpleKeyCacheInputStream());
+ $factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory();
+ $contentEncoder = new Swift_Mime_ContentEncoder_Base64ContentEncoder();
+
+ $headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder(new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8'));
+ $paramEncoder = new Swift_Encoder_Rfc2231Encoder(new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8'));
+ $grammar = new Swift_Mime_Grammar();
+ $headers = new Swift_Mime_SimpleHeaderSet(new Swift_Mime_SimpleHeaderFactory($headerEncoder, $paramEncoder, $grammar));
+
+ return $headers;
+ }
+
+ /**
+ * @return Swift_Mime_Headers
+ */
+ private function _createHeaders()
+ {
+ $x = 0;
+ $cache = new Swift_KeyCache_ArrayKeyCache(new Swift_KeyCache_SimpleKeyCacheInputStream());
+ $factory = new Swift_CharacterReaderFactory_SimpleCharacterReaderFactory();
+ $contentEncoder = new Swift_Mime_ContentEncoder_Base64ContentEncoder();
+
+ $headerEncoder = new Swift_Mime_HeaderEncoder_QpHeaderEncoder(new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8'));
+ $paramEncoder = new Swift_Encoder_Rfc2231Encoder(new Swift_CharacterStream_ArrayCharacterStream($factory, 'utf-8'));
+ $grammar = new Swift_Mime_Grammar();
+ $headerFactory = new Swift_Mime_SimpleHeaderFactory($headerEncoder, $paramEncoder, $grammar);
+ $headers = $this->getMockery('Swift_Mime_HeaderSet');
+
+ $headers->shouldReceive('listAll')
+ ->zeroOrMoreTimes()
+ ->andReturn(array('From', 'To', 'Date', 'Subject'));
+ $headers->shouldReceive('has')
+ ->zeroOrMoreTimes()
+ ->with('From')
+ ->andReturn(true);
+ $headers->shouldReceive('getAll')
+ ->zeroOrMoreTimes()
+ ->with('From')
+ ->andReturn(array($headerFactory->createMailboxHeader('From', 'test@test.test')));
+ $headers->shouldReceive('has')
+ ->zeroOrMoreTimes()
+ ->with('To')
+ ->andReturn(true);
+ $headers->shouldReceive('getAll')
+ ->zeroOrMoreTimes()
+ ->with('To')
+ ->andReturn(array($headerFactory->createMailboxHeader('To', 'test@test.test')));
+ $headers->shouldReceive('has')
+ ->zeroOrMoreTimes()
+ ->with('Date')
+ ->andReturn(true);
+ $headers->shouldReceive('getAll')
+ ->zeroOrMoreTimes()
+ ->with('Date')
+ ->andReturn(array($headerFactory->createTextHeader('Date', 'Fri, 11 Mar 2011 20:56:12 +0000 (GMT)')));
+ $headers->shouldReceive('has')
+ ->zeroOrMoreTimes()
+ ->with('Subject')
+ ->andReturn(true);
+ $headers->shouldReceive('getAll')
+ ->zeroOrMoreTimes()
+ ->with('Subject')
+ ->andReturn(array($headerFactory->createTextHeader('Subject', 'Foo Bar Text Message')));
+ $headers->shouldReceive('addTextHeader')
+ ->zeroOrMoreTimes()
+ ->with('DKIM-Signature', \Mockery::any())
+ ->andReturn(true);
+ $headers->shouldReceive('getAll')
+ ->zeroOrMoreTimes()
+ ->with('DKIM-Signature')
+ ->andReturn(array($headerFactory->createTextHeader('DKIM-Signature', 'Foo Bar Text Message')));
+
+ return $headers;
+ }
+}
diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/OpenDKIMSignerTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/OpenDKIMSignerTest.php
new file mode 100644
index 0000000..ce99bc6
--- /dev/null
+++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/OpenDKIMSignerTest.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @todo
+ */
+class Swift_Signers_OpenDKIMSignerTest extends \SwiftMailerTestCase
+{
+ protected function setUp()
+ {
+ if (!extension_loaded('opendkim')) {
+ $this->markTestSkipped(
+ 'Need OpenDKIM extension run these tests.'
+ );
+ }
+ }
+
+ public function testBasicSigningHeaderManipulation()
+ {
+ }
+
+ // Default Signing
+ public function testSigningDefaults()
+ {
+ }
+
+ // SHA256 Signing
+ public function testSigning256()
+ {
+ }
+
+ // Relaxed/Relaxed Hash Signing
+ public function testSigningRelaxedRelaxed256()
+ {
+ }
+
+ // Relaxed/Simple Hash Signing
+ public function testSigningRelaxedSimple256()
+ {
+ }
+
+ // Simple/Relaxed Hash Signing
+ public function testSigningSimpleRelaxed256()
+ {
+ }
+}
diff --git a/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/SMimeSignerTest.php b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/SMimeSignerTest.php
new file mode 100644
index 0000000..5069c1f
--- /dev/null
+++ b/vendor/swiftmailer/swiftmailer/tests/unit/Swift/Signers/SMimeSignerTest.php
@@ -0,0 +1,554 @@
+<?php
+
+class Swift_Signers_SMimeSignerTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var Swift_StreamFilters_StringReplacementFilterFactory
+ */
+ protected $replacementFactory;
+
+ protected $samplesDir;
+
+ protected function setUp()
+ {
+ $this->replacementFactory = Swift_DependencyContainer::getInstance()
+ ->lookup('transport.replacementfactory');
+
+ $this->samplesDir = str_replace('\\', '/', realpath(__DIR__.'/../../../_samples/')).'/';
+ }
+
+ public function testUnSingedMessage()
+ {
+ $message = Swift_SignedMessage::newInstance('Wonderful Subject')
+ ->setFrom(array('john@doe.com' => 'John Doe'))
+ ->setTo(array('receiver@domain.org', 'other@domain.org' => 'A name'))
+ ->setBody('Here is the message itself');
+
+ $this->assertEquals('Here is the message itself', $message->getBody());
+ }
+
+ public function testSingedMessage()
+ {
+ $message = Swift_SignedMessage::newInstance('Wonderful Subject')
+ ->setFrom(array('john@doe.com' => 'John Doe'))
+ ->setTo(array('receiver@domain.org', 'other@domain.org' => 'A name'))
+ ->setBody('Here is the message itself');
+
+ $signer = new Swift_Signers_SMimeSigner();
+ $signer->setSignCertificate($this->samplesDir.'smime/sign.crt', $this->samplesDir.'smime/sign.key');
+ $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
+Content-Type: text/plain; charset=utf-8
+Content-Transfer-Encoding: quoted-printable
+
+Here is the message itself
+--$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;
+ $this->assertValidVerify($expectedBody, $messageStream);
+ unset($messageStream);
+ }
+
+ public function testSingedMessageExtraCerts()
+ {
+ $message = Swift_SignedMessage::newInstance('Wonderful Subject')
+ ->setFrom(array('john@doe.com' => 'John Doe'))
+ ->setTo(array('receiver@domain.org', 'other@domain.org' => 'A name'))
+ ->setBody('Here is the message itself');
+
+ $signer = new Swift_Signers_SMimeSigner();
+ $signer->setSignCertificate($this->samplesDir.'smime/sign2.crt', $this->samplesDir.'smime/sign2.key', PKCS7_DETACHED, $this->samplesDir.'smime/intermediate.crt');
+ $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
+Content-Type: text/plain; charset=utf-8
+Content-Transfer-Encoding: quoted-printable
+
+Here is the message itself
+--$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;
+ $this->assertValidVerify($expectedBody, $messageStream);
+ unset($messageStream);
+ }
+
+ public function testSingedMessageBinary()
+ {
+ $message = Swift_SignedMessage::newInstance('Wonderful Subject')
+ ->setFrom(array('john@doe.com' => 'John Doe'))
+ ->setTo(array('receiver@domain.org', 'other@domain.org' => 'A name'))
+ ->setBody('Here is the message itself');
+
+ $signer = new Swift_Signers_SMimeSigner();
+ $signer->setSignCertificate($this->samplesDir.'smime/sign.crt', $this->samplesDir.'smime/sign.key', PKCS7_BINARY);
+ $message->attachSigner($signer);
+
+ $messageStream = $this->newFilteredStream();
+ $message->toByteStream($messageStream);
+ $messageStream->commit();
+
+ $entityString = $messageStream->getContent();
+ $headers = self::getHeadersOfMessage($entityString);
+
+ if (!preg_match('#^application/(x\-)?pkcs7-mime; smime-type=signed\-data;#', $headers['content-type'])) {
+ $this->fail('Content-type does not match.');
+
+ return false;
+ }
+
+ $this->assertEquals($headers['content-transfer-encoding'], 'base64');
+ $this->assertEquals($headers['content-disposition'], 'attachment; filename="smime.p7m"');
+
+ $expectedBody = '(?:^[a-zA-Z0-9\/\\r\\n+]*={0,2})';
+
+ $messageStreamClean = $this->newFilteredStream();
+
+ $this->assertValidVerify($expectedBody, $messageStream);
+ unset($messageStreamClean, $messageStream);
+ }
+
+ public function testSingedMessageWithAttachments()
+ {
+ $message = Swift_SignedMessage::newInstance('Wonderful Subject')
+ ->setFrom(array('john@doe.com' => 'John Doe'))
+ ->setTo(array('receiver@domain.org', 'other@domain.org' => 'A name'))
+ ->setBody('Here is the message itself');
+
+ $message->attach(Swift_Attachment::fromPath($this->samplesDir.'/files/textfile.zip'));
+
+ $signer = new Swift_Signers_SMimeSigner();
+ $signer->setSignCertificate($this->samplesDir.'smime/sign.crt', $this->samplesDir.'smime/sign.key');
+ $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
+Content-Type: multipart/mixed;
+ boundary="([a-z0-9\\'\\(\\)\\+_\\-,\\.\\/:=\\?\\ ]{0,69}[a-z0-9\\'\\(\\)\\+_\\-,\\.\\/:=\\?])"
+
+
+--\\1
+Content-Type: text/plain; charset=utf-8
+Content-Transfer-Encoding: quoted-printable
+
+Here is the message itself
+
+--\\1
+Content-Type: application/zip; name=textfile\\.zip
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename=textfile\\.zip
+
+UEsDBAoAAgAAAMi6VjiOTiKwLgAAAC4AAAAMABUAdGV4dGZpbGUudHh0VVQJAAN3vr5Hd76\\+R1V4
+BAD1AfUBVGhpcyBpcyBwYXJ0IG9mIGEgU3dpZnQgTWFpbGVyIHY0IHNtb2tlIHRlc3QuClBLAQIX
+AwoAAgAAAMi6VjiOTiKwLgAAAC4AAAAMAA0AAAAAAAEAAACkgQAAAAB0ZXh0ZmlsZS50eHRVVAUA
+A3e\\+vkdVeAAAUEsFBgAAAAABAAEARwAAAG0AAAAAAA==
+
+--\\1--
+
+--$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;
+
+ $this->assertValidVerify($expectedBody, $messageStream);
+ unset($messageStream);
+ }
+
+ public function testEncryptedMessage()
+ {
+ $message = Swift_SignedMessage::newInstance('Wonderful Subject')
+ ->setFrom(array('john@doe.com' => 'John Doe'))
+ ->setTo(array('receiver@domain.org', 'other@domain.org' => 'A name'))
+ ->setBody('Here is the message itself');
+
+ $originalMessage = $this->cleanMessage($message->toString());
+
+ $signer = new Swift_Signers_SMimeSigner();
+ $signer->setEncryptCertificate($this->samplesDir.'smime/encrypt.crt');
+ $message->attachSigner($signer);
+
+ $messageStream = new Swift_ByteStream_TemporaryFileByteStream();
+ $message->toByteStream($messageStream);
+ $messageStream->commit();
+
+ $entityString = $messageStream->getContent();
+ $headers = self::getHeadersOfMessage($entityString);
+
+ if (!preg_match('#^application/(x\-)?pkcs7-mime; smime-type=enveloped\-data;#', $headers['content-type'])) {
+ $this->fail('Content-type does not match.');
+
+ return false;
+ }
+
+ $expectedBody = '(?:^[a-zA-Z0-9\/\\r\\n+]*={0,2})';
+
+ $decryptedMessageStream = new Swift_ByteStream_TemporaryFileByteStream();
+
+ if (!openssl_pkcs7_decrypt($messageStream->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($decryptedMessageStream, $messageStream);
+ }
+
+ public function testEncryptedMessageWithMultipleCerts()
+ {
+ $message = Swift_SignedMessage::newInstance('Wonderful Subject')
+ ->setFrom(array('john@doe.com' => 'John Doe'))
+ ->setTo(array('receiver@domain.org', 'other@domain.org' => 'A name'))
+ ->setBody('Here is the message itself');
+
+ $originalMessage = $this->cleanMessage($message->toString());
+
+ $signer = new Swift_Signers_SMimeSigner();
+ $signer->setEncryptCertificate(array($this->samplesDir.'smime/encrypt.crt', $this->samplesDir.'smime/encrypt2.crt'));
+ $message->attachSigner($signer);
+
+ $messageStream = new Swift_ByteStream_TemporaryFileByteStream();
+ $message->toByteStream($messageStream);
+ $messageStream->commit();
+
+ $entityString = $messageStream->getContent();
+ $headers = self::getHeadersOfMessage($entityString);
+
+ if (!preg_match('#^application/(x\-)?pkcs7-mime; smime-type=enveloped\-data;#', $headers['content-type'])) {
+ $this->fail('Content-type does not match.');
+
+ return false;
+ }
+
+ $expectedBody = '(?:^[a-zA-Z0-9\/\\r\\n+]*={0,2})';
+
+ $decryptedMessageStream = new Swift_ByteStream_TemporaryFileByteStream();
+
+ if (!openssl_pkcs7_decrypt($messageStream->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($decryptedMessageStream);
+
+ $decryptedMessageStream = new Swift_ByteStream_TemporaryFileByteStream();
+
+ if (!openssl_pkcs7_decrypt($messageStream->getPath(), $decryptedMessageStream->getPath(), 'file://'.$this->samplesDir.'smime/encrypt2.crt', array('file://'.$this->samplesDir.'smime/encrypt2.key', 'swift'))) {
+ $this->fail(sprintf('Decrypt of the message failed. Internal error "%s".', openssl_error_string()));
+ }
+
+ $this->assertEquals($originalMessage, $decryptedMessageStream->getContent());
+ unset($decryptedMessageStream, $messageStream);
+ }
+
+ public function testSignThenEncryptedMessage()
+ {
+ $message = Swift_SignedMessage::newInstance('Wonderful Subject')
+ ->setFrom(array('john@doe.com' => 'John Doe'))
+ ->setTo(array('receiver@domain.org', 'other@domain.org' => 'A name'))
+ ->setBody('Here is the message itself');
+
+ $signer = new Swift_Signers_SMimeSigner();
+ $signer->setSignCertificate($this->samplesDir.'smime/sign.crt', $this->samplesDir.'smime/sign.key');
+ $signer->setEncryptCertificate($this->samplesDir.'smime/encrypt.crt');
+ $message->attachSigner($signer);
+
+ $messageStream = new Swift_ByteStream_TemporaryFileByteStream();
+ $message->toByteStream($messageStream);
+ $messageStream->commit();
+
+ $entityString = $messageStream->getContent();
+ $headers = self::getHeadersOfMessage($entityString);
+
+ if (!preg_match('#^application/(x\-)?pkcs7-mime; smime-type=enveloped\-data;#', $headers['content-type'])) {
+ $this->fail('Content-type does not match.');
+
+ return false;
+ }
+
+ $expectedBody = '(?:^[a-zA-Z0-9\/\\r\\n+]*={0,2})';
+
+ $decryptedMessageStream = new Swift_ByteStream_TemporaryFileByteStream();
+
+ if (!openssl_pkcs7_decrypt($messageStream->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()));
+ }
+
+ $entityString = $decryptedMessageStream->getContent();
+ $headers = self::getHeadersOfMessage($entityString);
+
+ if (!($boundary = $this->getBoundary($headers['content-type']))) {
+ return false;
+ }
+
+ $expectedBody = <<<OEL
+This is an S/MIME signed message
+
+--$boundary
+Content-Type: text/plain; charset=utf-8
+Content-Transfer-Encoding: quoted-printable
+
+Here is the message itself
+--$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, $decryptedMessageStream)) {
+ return false;
+ }
+
+ unset($decryptedMessageStream, $messageStream);
+ }
+
+ public function testEncryptThenSignMessage()
+ {
+ $message = Swift_SignedMessage::newInstance('Wonderful Subject')
+ ->setFrom(array('john@doe.com' => 'John Doe'))
+ ->setTo(array('receiver@domain.org', 'other@domain.org' => 'A name'))
+ ->setBody('Here is the message itself');
+
+ $originalMessage = $this->cleanMessage($message->toString());
+
+ $signer = Swift_Signers_SMimeSigner::newInstance();
+ $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);
+ }
+
+ protected function assertValidVerify($expected, Swift_ByteStream_TemporaryFileByteStream $messageStream)
+ {
+ $actual = $messageStream->getContent();
+
+ // File is UNIX encoded so convert them to correct line ending
+ $expected = str_replace("\n", "\r\n", $expected);
+
+ $actual = trim(self::getBodyOfMessage($actual));
+ if (!$this->assertRegExp('%^'.$expected.'$\s*%m', $actual)) {
+ return false;
+ }
+
+ $opensslOutput = new Swift_ByteStream_TemporaryFileByteStream();
+ $verify = openssl_pkcs7_verify($messageStream->getPath(), null, $opensslOutput->getPath(), array($this->samplesDir.'smime/ca.crt'));
+
+ if (false === $verify) {
+ $this->fail('Verification of the message failed.');
+
+ return false;
+ } elseif (-1 === $verify) {
+ $this->fail(sprintf('Verification of the message failed. Internal error "%s".', openssl_error_string()));
+
+ return false;
+ }
+
+ return true;
+ }
+
+ protected function getBoundary($contentType)
+ {
+ if (!preg_match('/boundary=("[^"]+"|(?:[^\s]+|$))/is', $contentType, $contentTypeData)) {
+ $this->fail('Failed to find Boundary parameter');
+
+ return false;
+ }
+
+ return trim($contentTypeData[1], '"');
+ }
+
+ protected function newFilteredStream()
+ {
+ $messageStream = new Swift_ByteStream_TemporaryFileByteStream();
+ $messageStream->addFilter($this->replacementFactory->createFilter("\r\n", "\n"), 'CRLF to LF');
+ $messageStream->addFilter($this->replacementFactory->createFilter("\n", "\r\n"), 'LF to CRLF');
+
+ return $messageStream;
+ }
+
+ protected static function getBodyOfMessage($message)
+ {
+ return substr($message, strpos($message, "\r\n\r\n"));
+ }
+
+ /**
+ * Strips of the sender headers and Mime-Version.
+ *
+ * @param Swift_ByteStream_TemporaryFileByteStream $messageStream
+ * @param Swift_ByteStream_TemporaryFileByteStream $inputStream
+ */
+ protected function cleanMessage($content)
+ {
+ $newContent = '';
+
+ $headers = self::getHeadersOfMessage($content);
+ foreach ($headers as $headerName => $value) {
+ if (!in_array($headerName, array('content-type', 'content-transfer-encoding', 'content-disposition'))) {
+ continue;
+ }
+
+ $headerName = explode('-', $headerName);
+ $headerName = array_map('ucfirst', $headerName);
+ $headerName = implode('-', $headerName);
+
+ if (strlen($value) > 62) {
+ $value = wordwrap($value, 62, "\n ");
+ }
+
+ $newContent .= "$headerName: $value\r\n";
+ }
+
+ return $newContent."\r\n".ltrim(self::getBodyOfMessage($content));
+ }
+
+ /**
+ * Returns the headers of the message.
+ *
+ * Header-names are lowercase.
+ *
+ * @param string $message
+ *
+ * @return array
+ */
+ protected static function getHeadersOfMessage($message)
+ {
+ $headersPosEnd = strpos($message, "\r\n\r\n");
+ $headerData = substr($message, 0, $headersPosEnd);
+ $headerLines = explode("\r\n", $headerData);
+
+ if (empty($headerLines)) {
+ return array();
+ }
+
+ $headers = array();
+
+ foreach ($headerLines as $headerLine) {
+ if (ctype_space($headerLines[0]) || false === strpos($headerLine, ':')) {
+ $headers[$currentHeaderName] .= ' '.trim($headerLine);
+ continue;
+ }
+
+ $header = explode(':', $headerLine, 2);
+ $currentHeaderName = strtolower($header[0]);
+ $headers[$currentHeaderName] = trim($header[1]);
+ }
+
+ return $headers;
+ }
+}