diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index 33d84dd18d712..04e747bc7b5ce 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -2236,6 +2236,88 @@ private function addMailerSection(ArrayNodeDefinition $rootNode, callable $enabl
->end()
->end()
->end()
+ ->arrayNode('dkim_signer')
+ ->addDefaultsIfNotSet()
+ ->fixXmlConfig('option')
+ ->canBeEnabled()
+ ->info('DKIM signer configuration')
+ ->children()
+ ->scalarNode('key')
+ ->info('Key content, or path to key (in PEM format with the `file://` prefix)')
+ ->defaultValue('')
+ ->cannotBeEmpty()
+ ->end()
+ ->scalarNode('domain')->defaultValue('')->end()
+ ->scalarNode('select')->defaultValue('')->end()
+ ->scalarNode('passphrase')
+ ->info('The private key passphrase')
+ ->defaultValue('')
+ ->end()
+ ->arrayNode('options')
+ ->performNoDeepMerging()
+ ->normalizeKeys(false)
+ ->useAttributeAsKey('name')
+ ->prototype('variable')->end()
+ ->end()
+ ->end()
+ ->end()
+ ->arrayNode('smime_signer')
+ ->addDefaultsIfNotSet()
+ ->canBeEnabled()
+ ->info('S/MIME signer configuration')
+ ->children()
+ ->scalarNode('key')
+ ->info('Path to key (in PEM format)')
+ ->defaultValue('')
+ ->cannotBeEmpty()
+ ->end()
+ ->scalarNode('certificate')
+ ->info('Path to certificate (in PEM format without the `file://` prefix)')
+ ->defaultValue('')
+ ->cannotBeEmpty()
+ ->end()
+ ->scalarNode('passphrase')
+ ->info('The private key passphrase')
+ ->defaultNull()
+ ->end()
+ ->scalarNode('extra_certificates')->defaultNull()->end()
+ ->integerNode('sign_options')->defaultNull()->end()
+ ->end()
+ ->end()
+ ->arrayNode('smime_encrypter')
+ ->addDefaultsIfNotSet()
+ ->canBeEnabled()
+ ->info('S/MIME encrypter configuration')
+ ->children()
+ ->scalarNode('certificate')
+ ->info('Path to certificate (in PEM format without the `file://` prefix)')
+ ->defaultValue('')
+ ->cannotBeEmpty()
+ ->end()
+ ->integerNode('cipher')
+ ->info('A set of algorithms used to encrypt the message')
+ ->defaultNull()
+ ->beforeNormalization()
+ ->always(function ($v): ?int {
+ if (null === $v) {
+ return null;
+ }
+ if (\defined('OPENSSL_CIPHER_'.$v)) {
+ return \constant('OPENSSL_CIPHER_'.$v);
+ }
+
+ throw new \InvalidArgumentException(\sprintf('"%s" is not a valid OPENSSL cipher.', $v));
+ })
+ ->end()
+ ->validate()
+ ->ifTrue(function ($v) {
+ return \extension_loaded('openssl') && null !== $v && !\defined('OPENSSL_CIPHER_'.$v);
+ })
+ ->thenInvalid('You must provide a valid cipher.')
+ ->end()
+ ->end()
+ ->end()
+ ->end()
->end()
->end()
->end()
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index f6160d49315b0..56cba363bfaa1 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -112,7 +112,10 @@
use Symfony\Component\Lock\Store\StoreFactory;
use Symfony\Component\Mailer\Bridge as MailerBridge;
use Symfony\Component\Mailer\Command\MailerTestCommand;
+use Symfony\Component\Mailer\EventListener\DkimSignedMessageListener;
use Symfony\Component\Mailer\EventListener\MessengerTransportListener;
+use Symfony\Component\Mailer\EventListener\SmimeEncryptedMessageListener;
+use Symfony\Component\Mailer\EventListener\SmimeSignedMessageListener;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mercure\HubRegistry;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
@@ -2837,6 +2840,48 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co
$container->removeDefinition('mailer.messenger_transport_listener');
}
+ if ($config['dkim_signer']['enabled']) {
+ if (!class_exists(DkimSignedMessageListener::class)) {
+ throw new LogicException('DKIM signed messages support cannot be enabled as this version of the Mailer component does not support it.');
+ }
+ $dkimSigner = $container->getDefinition('mailer.dkim_signer');
+ $dkimSigner->setArgument(0, $config['dkim_signer']['key']);
+ $dkimSigner->setArgument(1, $config['dkim_signer']['domain']);
+ $dkimSigner->setArgument(2, $config['dkim_signer']['select']);
+ $dkimSigner->setArgument(3, $config['dkim_signer']['options']);
+ $dkimSigner->setArgument(4, $config['dkim_signer']['passphrase']);
+ } else {
+ $container->removeDefinition('mailer.dkim_signer');
+ $container->removeDefinition('mailer.dkim_signer.listener');
+ }
+
+ if ($config['smime_signer']['enabled']) {
+ if (!class_exists(SmimeSignedMessageListener::class)) {
+ throw new LogicException('SMIME signed messages support cannot be enabled as this version of the Mailer component does not support it.');
+ }
+ $smimeSigner = $container->getDefinition('mailer.smime_signer');
+ $smimeSigner->setArgument(0, $config['smime_signer']['key']);
+ $smimeSigner->setArgument(1, $config['smime_signer']['certificate']);
+ $smimeSigner->setArgument(2, $config['smime_signer']['passphrase']);
+ $smimeSigner->setArgument(3, $config['smime_signer']['extra_certificates']);
+ $smimeSigner->setArgument(4, $config['smime_signer']['sign_options']);
+ } else {
+ $container->removeDefinition('mailer.smime_signer');
+ $container->removeDefinition('mailer.smime_signer.listener');
+ }
+
+ if ($config['smime_encrypter']['enabled']) {
+ if (!class_exists(SmimeEncryptedMessageListener::class)) {
+ throw new LogicException('S/MIME encrypted messages support cannot be enabled as this version of the Mailer component does not support it.');
+ }
+ $smimeDecrypter = $container->getDefinition('mailer.smime_encrypter');
+ $smimeDecrypter->setArgument(0, $config['smime_encrypter']['certificate']);
+ $smimeDecrypter->setArgument(1, $config['smime_encrypter']['cipher']);
+ } else {
+ $container->removeDefinition('mailer.smime_encrypter');
+ $container->removeDefinition('mailer.smime_encrypter.listener');
+ }
+
if ($webhookEnabled) {
$loader->load('mailer_webhook.php');
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.php
index 9eb545ca268ea..25b3fefdbfb00 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/mailer.php
@@ -12,16 +12,22 @@
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use Symfony\Component\Mailer\Command\MailerTestCommand;
+use Symfony\Component\Mailer\EventListener\DkimSignedMessageListener;
use Symfony\Component\Mailer\EventListener\EnvelopeListener;
use Symfony\Component\Mailer\EventListener\MessageListener;
use Symfony\Component\Mailer\EventListener\MessageLoggerListener;
use Symfony\Component\Mailer\EventListener\MessengerTransportListener;
+use Symfony\Component\Mailer\EventListener\SmimeEncryptedMessageListener;
+use Symfony\Component\Mailer\EventListener\SmimeSignedMessageListener;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mailer\Messenger\MessageHandler;
use Symfony\Component\Mailer\Transport;
use Symfony\Component\Mailer\Transport\TransportInterface;
use Symfony\Component\Mailer\Transport\Transports;
+use Symfony\Component\Mime\Crypto\DkimSigner;
+use Symfony\Component\Mime\Crypto\SMimeEncrypter;
+use Symfony\Component\Mime\Crypto\SMimeSigner;
return static function (ContainerConfigurator $container) {
$container->services()
@@ -78,6 +84,48 @@
->set('mailer.messenger_transport_listener', MessengerTransportListener::class)
->tag('kernel.event_subscriber')
+ ->set('mailer.dkim_signer', DkimSigner::class)
+ ->args([
+ abstract_arg('key'),
+ abstract_arg('domain'),
+ abstract_arg('select'),
+ abstract_arg('options'),
+ abstract_arg('passphrase'),
+ ])
+
+ ->set('mailer.smime_signer', SMimeSigner::class)
+ ->args([
+ abstract_arg('key'),
+ abstract_arg('certificate'),
+ abstract_arg('passphrase'),
+ abstract_arg('extraCertificates'),
+ abstract_arg('signOptions'),
+ ])
+
+ ->set('mailer.smime_encrypter', SMimeEncrypter::class)
+ ->args([
+ abstract_arg('certificate'),
+ abstract_arg('cipher'),
+ ])
+
+ ->set('mailer.dkim_signer.listener', DkimSignedMessageListener::class)
+ ->args([
+ service(DkimSigner::class),
+ ])
+ ->tag('kernel.event_subscriber')
+
+ ->set('mailer.smime_signer.listener', SmimeSignedMessageListener::class)
+ ->args([
+ service('mailer.smime_signer'),
+ ])
+ ->tag('kernel.event_subscriber')
+
+ ->set('mailer.smime_encrypter.listener', SmimeEncryptedMessageListener::class)
+ ->args([
+ service('mailer.smime_encrypter'),
+ ])
+ ->tag('kernel.event_subscriber')
+
->set('console.command.mailer_test', MailerTestCommand::class)
->args([
service('mailer.transports'),
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
index 0f90f1cfc4cae..e2edb6aa0c417 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
@@ -789,6 +789,9 @@
+
+
+
@@ -811,6 +814,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
index e8ca9873f1a70..69557cc8f4436 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
@@ -922,6 +922,27 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor
'enabled' => !class_exists(FullStack::class) && class_exists(Mailer::class),
'message_bus' => null,
'headers' => [],
+ 'dkim_signer' => [
+ 'enabled' => false,
+ 'options' => [],
+ 'key' => '',
+ 'domain' => '',
+ 'select' => '',
+ 'passphrase' => '',
+ ],
+ 'smime_signer' => [
+ 'enabled' => false,
+ 'key' => '',
+ 'certificate' => '',
+ 'passphrase' => null,
+ 'extra_certificates' => null,
+ 'sign_options' => null,
+ ],
+ 'smime_encrypter' => [
+ 'enabled' => false,
+ 'certificate' => '',
+ 'cipher' => null,
+ ],
],
'notifier' => [
'enabled' => !class_exists(FullStack::class) && class_exists(Notifier::class),
diff --git a/src/Symfony/Component/Mailer/CHANGELOG.md b/src/Symfony/Component/Mailer/CHANGELOG.md
index aa7d8b4d52855..f876701168c59 100644
--- a/src/Symfony/Component/Mailer/CHANGELOG.md
+++ b/src/Symfony/Component/Mailer/CHANGELOG.md
@@ -7,6 +7,7 @@ CHANGELOG
* Add DSN param `retry_period` to override default email transport retry period
* Add `Dsn::getBooleanOption()`
* Add DSN param `source_ip` to allow binding to a (specific) IPv4 or IPv6 address.
+ * Add `DkimSignedMessageListener`, `SmimeEncryptedMessageListener`, and `SmimeSignedMessageListener`
7.2
---
diff --git a/src/Symfony/Component/Mailer/EventListener/DkimSignedMessageListener.php b/src/Symfony/Component/Mailer/EventListener/DkimSignedMessageListener.php
new file mode 100644
index 0000000000000..cc16a72c42065
--- /dev/null
+++ b/src/Symfony/Component/Mailer/EventListener/DkimSignedMessageListener.php
@@ -0,0 +1,46 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Mailer\EventListener;
+
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\Mailer\Event\MessageEvent;
+use Symfony\Component\Mime\Crypto\DkimSigner;
+use Symfony\Component\Mime\Message;
+
+/**
+ * Signs messages using DKIM.
+ *
+ * @author Elías Fernández
+ */
+class DkimSignedMessageListener implements EventSubscriberInterface
+{
+ public function __construct(
+ private DkimSigner $signer,
+ ) {
+ }
+
+ public function onMessage(MessageEvent $event): void
+ {
+ $message = $event->getMessage();
+ if (!$message instanceof Message) {
+ return;
+ }
+ $event->setMessage($this->signer->sign($message));
+ }
+
+ public static function getSubscribedEvents(): array
+ {
+ return [
+ MessageEvent::class => ['onMessage', -128],
+ ];
+ }
+}
diff --git a/src/Symfony/Component/Mailer/EventListener/SmimeEncryptedMessageListener.php b/src/Symfony/Component/Mailer/EventListener/SmimeEncryptedMessageListener.php
new file mode 100644
index 0000000000000..3b01c1d1c999b
--- /dev/null
+++ b/src/Symfony/Component/Mailer/EventListener/SmimeEncryptedMessageListener.php
@@ -0,0 +1,47 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Mailer\EventListener;
+
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\Mailer\Event\MessageEvent;
+use Symfony\Component\Mime\Crypto\SMimeEncrypter;
+use Symfony\Component\Mime\Message;
+
+/**
+ * Encrypts messages using S/MIME.
+ *
+ * @author Elías Fernández
+ */
+class SmimeEncryptedMessageListener implements EventSubscriberInterface
+{
+ public function __construct(
+ private SMimeEncrypter $encrypter,
+ ) {
+ }
+
+ public function onMessage(MessageEvent $event): void
+ {
+ $message = $event->getMessage();
+ if (!$message instanceof Message) {
+ return;
+ }
+
+ $event->setMessage($this->encrypter->encrypt($message));
+ }
+
+ public static function getSubscribedEvents(): array
+ {
+ return [
+ MessageEvent::class => ['onMessage', -128],
+ ];
+ }
+}
diff --git a/src/Symfony/Component/Mailer/EventListener/SmimeSignedMessageListener.php b/src/Symfony/Component/Mailer/EventListener/SmimeSignedMessageListener.php
new file mode 100644
index 0000000000000..d94578f75a640
--- /dev/null
+++ b/src/Symfony/Component/Mailer/EventListener/SmimeSignedMessageListener.php
@@ -0,0 +1,47 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Mailer\EventListener;
+
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\Mailer\Event\MessageEvent;
+use Symfony\Component\Mime\Crypto\SMimeSigner;
+use Symfony\Component\Mime\Message;
+
+/**
+ * Signs messages using S/MIME.
+ *
+ * @author Elías Fernández
+ */
+class SmimeSignedMessageListener implements EventSubscriberInterface
+{
+ public function __construct(
+ private SMimeSigner $signer,
+ ) {
+ }
+
+ public function onMessage(MessageEvent $event): void
+ {
+ $message = $event->getMessage();
+ if (!$message instanceof Message) {
+ return;
+ }
+
+ $event->setMessage($this->signer->sign($message));
+ }
+
+ public static function getSubscribedEvents(): array
+ {
+ return [
+ MessageEvent::class => ['onMessage', -128],
+ ];
+ }
+}
diff --git a/src/Symfony/Component/Mailer/Tests/EventListener/DkimSignedMessageListenerTest.php b/src/Symfony/Component/Mailer/Tests/EventListener/DkimSignedMessageListenerTest.php
new file mode 100644
index 0000000000000..5419cfb6e6b7f
--- /dev/null
+++ b/src/Symfony/Component/Mailer/Tests/EventListener/DkimSignedMessageListenerTest.php
@@ -0,0 +1,64 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Mailer\Tests\EventListener;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Mailer\Envelope;
+use Symfony\Component\Mailer\Event\MessageEvent;
+use Symfony\Component\Mailer\EventListener\DkimSignedMessageListener;
+use Symfony\Component\Mime\Address;
+use Symfony\Component\Mime\Crypto\DkimSigner;
+use Symfony\Component\Mime\Header\Headers;
+use Symfony\Component\Mime\Header\MailboxListHeader;
+use Symfony\Component\Mime\Message;
+use Symfony\Component\Mime\Part\TextPart;
+
+class DkimSignedMessageListenerTest extends TestCase
+{
+ /**
+ * @requires extension openssl
+ */
+ public function testDkimMessageSigningProcess()
+ {
+ $signer = new DkimSigner(<<onMessage($event);
+ $this->assertNotSame($message, $event->getMessage());
+ $this->assertTrue($event->getMessage()->getHeaders()->has('DKIM-Signature'));
+ $this->assertFalse($message->getHeaders()->has('DKIM-Signature'));
+ }
+}
diff --git a/src/Symfony/Component/Mailer/Tests/EventListener/SmimeEncryptedMessageListenerTest.php b/src/Symfony/Component/Mailer/Tests/EventListener/SmimeEncryptedMessageListenerTest.php
new file mode 100644
index 0000000000000..365b55a47dfec
--- /dev/null
+++ b/src/Symfony/Component/Mailer/Tests/EventListener/SmimeEncryptedMessageListenerTest.php
@@ -0,0 +1,49 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Mailer\Tests\EventListener;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Mailer\Envelope;
+use Symfony\Component\Mailer\Event\MessageEvent;
+use Symfony\Component\Mailer\EventListener\SmimeEncryptedMessageListener;
+use Symfony\Component\Mime\Address;
+use Symfony\Component\Mime\Crypto\SMimeEncrypter;
+use Symfony\Component\Mime\Header\Headers;
+use Symfony\Component\Mime\Header\MailboxListHeader;
+use Symfony\Component\Mime\Message;
+use Symfony\Component\Mime\Part\SMimePart;
+use Symfony\Component\Mime\Part\TextPart;
+
+class SmimeEncryptedMessageListenerTest extends TestCase
+{
+ /**
+ * @requires extension openssl
+ */
+ public function testSmimeMessageSigningProcess()
+ {
+ $encrypter = new SMimeEncrypter(\dirname(__DIR__).'/Fixtures/sign.crt');
+ $listener = new SmimeEncryptedMessageListener($encrypter);
+ $message = new Message(
+ new Headers(
+ new MailboxListHeader('From', [new Address('sender@example.com')])
+ ),
+ new TextPart('hello')
+ );
+ $envelope = new Envelope(new Address('sender@example.com'), [new Address('r1@example.com')]);
+ $event = new MessageEvent($message, $envelope, 'default');
+
+ $listener->onMessage($event);
+ $this->assertNotSame($message, $event->getMessage());
+ $this->assertInstanceOf(TextPart::class, $message->getBody());
+ $this->assertInstanceOf(SMimePart::class, $event->getMessage()->getBody());
+ }
+}
diff --git a/src/Symfony/Component/Mailer/Tests/EventListener/SmimeSignedMessageListenerTest.php b/src/Symfony/Component/Mailer/Tests/EventListener/SmimeSignedMessageListenerTest.php
new file mode 100644
index 0000000000000..178c04c1ddebc
--- /dev/null
+++ b/src/Symfony/Component/Mailer/Tests/EventListener/SmimeSignedMessageListenerTest.php
@@ -0,0 +1,49 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Mailer\Tests\EventListener;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\Mailer\Envelope;
+use Symfony\Component\Mailer\Event\MessageEvent;
+use Symfony\Component\Mailer\EventListener\SmimeSignedMessageListener;
+use Symfony\Component\Mime\Address;
+use Symfony\Component\Mime\Crypto\SMimeSigner;
+use Symfony\Component\Mime\Header\Headers;
+use Symfony\Component\Mime\Header\MailboxListHeader;
+use Symfony\Component\Mime\Message;
+use Symfony\Component\Mime\Part\SMimePart;
+use Symfony\Component\Mime\Part\TextPart;
+
+class SmimeSignedMessageListenerTest extends TestCase
+{
+ /**
+ * @requires extension openssl
+ */
+ public function testSmimeMessageSigningProcess()
+ {
+ $signer = new SMimeSigner(\dirname(__DIR__).'/Fixtures/sign.crt', \dirname(__DIR__).'/Fixtures/sign.key');
+ $listener = new SmimeSignedMessageListener($signer);
+ $message = new Message(
+ new Headers(
+ new MailboxListHeader('From', [new Address('sender@example.com')])
+ ),
+ new TextPart('hello')
+ );
+ $envelope = new Envelope(new Address('sender@example.com'), [new Address('r1@example.com')]);
+ $event = new MessageEvent($message, $envelope, 'default');
+
+ $listener->onMessage($event);
+ $this->assertNotSame($message, $event->getMessage());
+ $this->assertInstanceOf(TextPart::class, $message->getBody());
+ $this->assertInstanceOf(SMimePart::class, $event->getMessage()->getBody());
+ }
+}
diff --git a/src/Symfony/Component/Mailer/Tests/Fixtures/sign.crt b/src/Symfony/Component/Mailer/Tests/Fixtures/sign.crt
new file mode 100644
index 0000000000000..3bac07338e4cc
--- /dev/null
+++ b/src/Symfony/Component/Mailer/Tests/Fixtures/sign.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDSDCCAjACFHnviuUTH+p8Ox4/II5dP8RfabgDMA0GCSqGSIb3DQEBCwUAMEwx
+FzAVBgNVBAMMDlN5bWZvbnlNaW1lIENBMRQwEgYDVQQKDAtTeW1mb255TWltZTEO
+MAwGA1UEBwwFUGFyaXMxCzAJBgNVBAYTAkZSMCAXDTIzMDQxOTA5NDgxNVoYDzI0
+MjMwMTEyMDk0ODE1WjBzMRswGQYDVQQDDBJmYWJpZW5Ac3ltZm9ueS5jb20xFDAS
+BgNVBAoMC1N5bWZvbnlNaW1lMQ4wDAYDVQQHDAVQYXJpczELMAkGA1UEBhMCRlIx
+ITAfBgkqhkiG9w0BCQEWEmZhYmllbkBzeW1mb255LmNvbTCCASIwDQYJKoZIhvcN
+AQEBBQADggEPADCCAQoCggEBANc97d5pdVD4VI17re0V4wPpOXq1GaKbHlLaRAzS
+7Snq4qmvzG5SqQHlcTu4tgxOWNhx2UjP/B0n5DWNUdVxpakIlVYhj6mOrUuTG4ky
+R+nf4hc0NB+2lRzFMJxFU+Or+wqEo1UxachP7YCOCYjehIWbSkh/uOuKdmgCM9KR
+l0qSVZaJRJtReFf2EU+FATVmqzIkzJ//s+JhYD34BYAszqH3xp62TEira7Nd5eUg
+aXTphZRaZ8LHi3EfhVpPOYdEMCPJzJIYaD1k3PstaUAyh2arnrvJX6kY5c3mVdvO
+5FSN+uLT/5cVplXKKCz2hCcabNwHYV2asNR3nugo87f49YECAwEAATANBgkqhkiG
+9w0BAQsFAAOCAQEASieUGzFtDxFazCkB0SGziCjRthH96svLH0nUlF5uurycLO+H
+oth62er/RjelqlS6xQNMhK/IQMoWCNW9uPYfvxjgC7k1FZGADkc3VnB3EYE1bcyC
+rKvBl3Ubh2NYtKI4z2rEuWWaCyurhLK7+B50K03y4dXuJ39Q3N6Qk1E+SWhwOWwu
+C8bCSX4HA/cTOfoZvVof1jrKHU6OepW1uaG+8H24NNNf+q7l4YZa92lu3vputbO2
+UKIaY+YWszVyKsrHleg5Xzt+6B6buLTr8ThuLVlSXiFl9OucmlrwyF/vhyThOk3V
+Fva8dIJK4ukmLM276tEUPx1vDxwIoe1SPgKJrg==
+-----END CERTIFICATE-----
diff --git a/src/Symfony/Component/Mailer/Tests/Fixtures/sign.key b/src/Symfony/Component/Mailer/Tests/Fixtures/sign.key
new file mode 100644
index 0000000000000..f08067d95bea6
--- /dev/null
+++ b/src/Symfony/Component/Mailer/Tests/Fixtures/sign.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDXPe3eaXVQ+FSN
+e63tFeMD6Tl6tRmimx5S2kQM0u0p6uKpr8xuUqkB5XE7uLYMTljYcdlIz/wdJ+Q1
+jVHVcaWpCJVWIY+pjq1LkxuJMkfp3+IXNDQftpUcxTCcRVPjq/sKhKNVMWnIT+2A
+jgmI3oSFm0pIf7jrinZoAjPSkZdKklWWiUSbUXhX9hFPhQE1ZqsyJMyf/7PiYWA9
++AWALM6h98aetkxIq2uzXeXlIGl06YWUWmfCx4txH4VaTzmHRDAjycySGGg9ZNz7
+LWlAModmq567yV+pGOXN5lXbzuRUjfri0/+XFaZVyigs9oQnGmzcB2FdmrDUd57o
+KPO3+PWBAgMBAAECggEALgFg3wXD60VUzzPVAkSIE/0sybc9LjYBBnz8CBCqW+gG
+P/YhGCCHWq4npHfvw1QYpdS5uFgqHzI4UyDsUZabrbQ1tSXxvrBOBoYAH/Q1Dj5J
+5SNFk9Sy7OYR5Ijl7BcFjqM4hPxNi6DX1v8k9xH2mdcOCs5v4DplYgg8euCfCXM2
+mQuAGRGG/FEsnTzHbTfGEywjFuagkbBjeWUWwFsV1cA62ZuxJHRs+QREG6j/3Qzo
+jPV9IwfaS+vbZY9p46alf3Hnes/K3rC32FFkS6vszO9gAlK/1JJLWq4iBZNLYhK5
+IpIvpl1/ZN6OKChHHCO8v7fQMGygvfkXBleA/iXj9QKBgQD5zuzWlZze79odDtX6
+3YMbaLO5taJexw1tYEW4iOG4imQvqdXPTYcmRztRr34EV85SkehPjv5XnDm48vmA
+WxaqbuMqbklGNwfqDAs2P+BxunDfJh5+dHoR90N+dTBCP7nB155jRB9aJSLiA+fu
+s3g18BUE4mvUcY8q3Tf41mx9JQKBgQDck6yxRB5w/jermYJ2GBXLwl17c4KE7sqD
+Yl317fGZ1bEaWOvcNTmQRpaLYj0R75vW3vjWuZv0ivTTBoclYsHafEfD1OGHTvvv
+1x6kfdaGG1eHZbLO+potfpD0febMtixUiw4YQlQf1m1+yuXQsGFFCSsTood4vcuu
+11XINrg+LQKBgQDnwoSUaOXLJ3eSMetv/Qbf7PmhN9RWXhIlAYZtuADCdxKP7d9B
+nsneR4PPOyOM3/G5RUjkVuO9YGFlJ3c3EEstAAednAg7Ll8XUuksAYM3wCNrxC/S
+XjnKZT6nGg4VyI2MO4Dk05TKy11blwgcu0CxufWmPHKR/HE48Vg2cqjgSQKBgE3F
+V5cswFrwlypOtrvypASypAk54eQC2a5XSW/DlHK78HSss4Rx07j12nCMk6G2TMkG
+1s/Go6EmOUoKPC5HUrg5J4h5j4cIpzWaMHio0bF5BHR9u/zUSPYPcQZzOaQl+x1X
+5gFRqZ2MGhEhcsQQ3Erd/60tmfxNVvpvfBRajr2FAoGAFsd5mwyF1ERyE2MX5M8u
+FiMkMayi5qMgL5QiSi/Bj6xd8LuY63ToP/Ieuhj4D0E5sA7FdlwAb0Jicb7V+qYk
+UCcSBFAgWQjLNcGlcHSUKNmIK4HqZCDVgTEVdgF2CODETeX10LUyApI127xfQ8mN
+WG+PNll+wd6xemltZsVscaQ=
+-----END PRIVATE KEY-----