+ */
+interface SmimeCertificateRepositoryInterface
+{
+ /**
+ * @return ?string The path to the certificate. null if not found
+ */
+ public function findCertificatePathFor(string $email): ?string;
+}
diff --git a/src/Symfony/Component/Mailer/EventListener/SmimeEncryptedMessageListener.php b/src/Symfony/Component/Mailer/EventListener/SmimeEncryptedMessageListener.php
index 3b01c1d1c999b..24bc574e83fbe 100644
--- a/src/Symfony/Component/Mailer/EventListener/SmimeEncryptedMessageListener.php
+++ b/src/Symfony/Component/Mailer/EventListener/SmimeEncryptedMessageListener.php
@@ -21,10 +21,11 @@
*
* @author Elías Fernández
*/
-class SmimeEncryptedMessageListener implements EventSubscriberInterface
+final class SmimeEncryptedMessageListener implements EventSubscriberInterface
{
public function __construct(
- private SMimeEncrypter $encrypter,
+ private readonly SmimeCertificateRepositoryInterface $smimeRepository,
+ private readonly ?int $cipher = null,
) {
}
@@ -34,8 +35,24 @@ public function onMessage(MessageEvent $event): void
if (!$message instanceof Message) {
return;
}
+ if (!$message->getHeaders()->has('X-SMime-Encrypt')) {
+ return;
+ }
+ $message->getHeaders()->remove('X-SMime-Encrypt');
+ $certificatePaths = [];
+ foreach ($event->getEnvelope()->getRecipients() as $recipient) {
+ $certificatePath = $this->smimeRepository->findCertificatePathFor($recipient->getAddress());
+ if (null === $certificatePath) {
+ return;
+ }
+ $certificatePaths[] = $certificatePath;
+ }
+ if (0 === \count($certificatePaths)) {
+ return;
+ }
+ $encrypter = new SMimeEncrypter($certificatePaths, $this->cipher);
- $event->setMessage($this->encrypter->encrypt($message));
+ $event->setMessage($encrypter->encrypt($message));
}
public static function getSubscribedEvents(): array
diff --git a/src/Symfony/Component/Mailer/Tests/EventListener/SmimeEncryptedMessageListenerTest.php b/src/Symfony/Component/Mailer/Tests/EventListener/SmimeEncryptedMessageListenerTest.php
index 365b55a47dfec..a4c4af73625dd 100644
--- a/src/Symfony/Component/Mailer/Tests/EventListener/SmimeEncryptedMessageListenerTest.php
+++ b/src/Symfony/Component/Mailer/Tests/EventListener/SmimeEncryptedMessageListenerTest.php
@@ -14,11 +14,12 @@
use PHPUnit\Framework\TestCase;
use Symfony\Component\Mailer\Envelope;
use Symfony\Component\Mailer\Event\MessageEvent;
+use Symfony\Component\Mailer\EventListener\SmimeCertificateRepositoryInterface;
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\Header\UnstructuredHeader;
use Symfony\Component\Mime\Message;
use Symfony\Component\Mime\Part\SMimePart;
use Symfony\Component\Mime\Part\TextPart;
@@ -28,13 +29,15 @@ class SmimeEncryptedMessageListenerTest extends TestCase
/**
* @requires extension openssl
*/
- public function testSmimeMessageSigningProcess()
+ public function testSmimeMessageEncryptionProcess()
{
- $encrypter = new SMimeEncrypter(\dirname(__DIR__).'/Fixtures/sign.crt');
- $listener = new SmimeEncryptedMessageListener($encrypter);
+ $repository = $this->createMock(SmimeCertificateRepositoryInterface::class);
+ $repository->method('findCertificatePathFor')->willReturn(\dirname(__DIR__).'/Fixtures/sign.crt');
+ $listener = new SmimeEncryptedMessageListener($repository);
$message = new Message(
new Headers(
- new MailboxListHeader('From', [new Address('sender@example.com')])
+ new MailboxListHeader('From', [new Address('sender@example.com')]),
+ new UnstructuredHeader('X-SMime-Encrypt', 'true'),
),
new TextPart('hello')
);
@@ -45,5 +48,59 @@ public function testSmimeMessageSigningProcess()
$this->assertNotSame($message, $event->getMessage());
$this->assertInstanceOf(TextPart::class, $message->getBody());
$this->assertInstanceOf(SMimePart::class, $event->getMessage()->getBody());
+ $this->assertFalse($event->getMessage()->getHeaders()->has('X-SMime-Encrypt'));
+ }
+
+ /**
+ * @requires extension openssl
+ */
+ public function testMessageNotEncryptedWhenOneRecipientCertificateIsMissing()
+ {
+ $repository = $this->createMock(SmimeCertificateRepositoryInterface::class);
+ $repository->method('findCertificatePathFor')->willReturnOnConsecutiveCalls(\dirname(__DIR__).'/Fixtures/sign.crt', null);
+ $listener = new SmimeEncryptedMessageListener($repository);
+ $message = new Message(
+ new Headers(
+ new MailboxListHeader('From', [new Address('sender@example.com')]),
+ new UnstructuredHeader('X-SMime-Encrypt', 'true'),
+ ),
+ new TextPart('hello')
+ );
+ $envelope = new Envelope(new Address('sender@example.com'), [
+ new Address('r1@example.com'),
+ new Address('r2@example.com'),
+ ]);
+ $event = new MessageEvent($message, $envelope, 'default');
+
+ $listener->onMessage($event);
+ $this->assertSame($message, $event->getMessage());
+ $this->assertInstanceOf(TextPart::class, $message->getBody());
+ $this->assertInstanceOf(TextPart::class, $event->getMessage()->getBody());
+ }
+
+ /**
+ * @requires extension openssl
+ */
+ public function testMessageNotExplicitlyAskedForNonEncryption()
+ {
+ $repository = $this->createMock(SmimeCertificateRepositoryInterface::class);
+ $repository->method('findCertificatePathFor')->willReturn(\dirname(__DIR__).'/Fixtures/sign.crt');
+ $listener = new SmimeEncryptedMessageListener($repository);
+ $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'),
+ new Address('r2@example.com'),
+ ]);
+ $event = new MessageEvent($message, $envelope, 'default');
+
+ $listener->onMessage($event);
+ $this->assertSame($message, $event->getMessage());
+ $this->assertInstanceOf(TextPart::class, $message->getBody());
+ $this->assertInstanceOf(TextPart::class, $event->getMessage()->getBody());
}
}
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy