php-mime-mail-parser / php-mime-mail-parser

A fully tested email parser for PHP 8.0+ (mailparse extension wrapper).
https://mailcare.io
MIT License
901 stars 195 forks source link

Add Support for Parsing S/MIME Signed Emails with smime.p7m Attachments #321

Open piernik opened 4 years ago

piernik commented 4 years ago

Here is my email. Parser don't see any contents only one attachment smime.p7m.

Here is header

Return-Path: <Roxxxx.Filixxxxx@warszawa.lasy.gov.pl>
Received: from mail2.lasy.gov.pl (212.244.241.4) (HELO mail2.lasy.gov.pl)
 by iqxx.home.pl (89.161.164.54) with SMTP (IdeaSmtpServer 0.83.415)
 id e4e463637aefa757; Wed, 24 Jun 2020 09:32:23 +0200
Received: from GEX0000-0657.ad.lasy.gov.pl (unknown [10.0.250.157])
    by ForwarderEX.mail.lasy.gov.pl (Postfix) with ESMTP id 230F830766AF
    for <Jaxx.Janxxxx@iqxx.pl>; Wed, 24 Jun 2020 09:32:23 +0200 (CEST)
Received: from GEX0000-0660.ad.lasy.gov.pl (10.0.250.160) by
 GEX0000-0657.ad.lasy.gov.pl (10.0.250.157) with Microsoft SMTP Server
 (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id
 15.1.1913.5; Wed, 24 Jun 2020 09:32:22 +0200
Received: from GEX0000-0660.ad.lasy.gov.pl ([fe80::9418:7c0b:841e:baf1]) by
 GEX0000-0660.ad.lasy.gov.pl ([fe80::9418:7c0b:841e:baf1%20]) with mapi id
 15.01.1913.007; Wed, 24 Jun 2020 09:32:22 +0200
From: Robxxxx Filixxxxx <Roxxxx.Filixxxxx@warszawa.lasy.gov.pl>
To: "Jaxx Janxxxx - iqxx Polska Sp. z o.o."
    <Jaxx.Janxxxx@iqxx.pl>
CC: =?utf-8?B?TWljaGHFgiBNcsOzd2N6ecWEc2tp?=
    <Mixxxx.Mrowxxxxx@warszawa.lasy.gov.pl>
Subject: RE: iqxx Polska umowa na UPS APC - EPO
Thread-Topic: iqxx Polska umowa na UPS APC - EPO
Thread-Index: AQHWSWzvq7tpiCAGwE+VsPP9CzZinajnX1ag
Date: Wed, 24 Jun 2020 07:32:22 +0000
Message-ID: <fc1e3b3bc42d4b15b1e891e99517103b@warszawa.lasy.gov.pl>
References: <AqAJ0cK50QqdfZm6O2EAq3NuFgcNTC6ojCt9OGtxXBo@api.infirma.pl>
In-Reply-To: <AqAJ0cK50QqdfZm6O2EAq3NuFgcNTC6ojCt9OGtxXBo@api.infirma.pl>
Accept-Language: pl-PL, en-US
Content-Language: pl-PL
X-MS-Has-Attach: yes
X-MS-TNEF-Correlator:
x-originating-ip: [10.17.0.60]
Content-Type: application/pkcs7-mime; smime-type=signed-data;
    name="smime.p7m"
Content-Disposition: attachment; filename="smime.p7m"
Content-Transfer-Encoding: base64
MIME-Version: 1.0

MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCAJIAEggGVQ29u
dGVudC1UeXBlOiBtdWx0aXBhcnQvcmVsYXRlZDsNCglib3VuZGFyeT0iLS0tLT1fTmV4dFBhcnRf
MDAwXzAwNjlfMDFENjRBMEEuNTlBQzcwRDAiDQoNClRoaXMgaXMgYSBtdWx0aXBhcnQgbWVzc2Fn
ZSBpbiBNSU1FIGZvcm1hdC4NCg0KLS0tLS0tPV9OZXh0UGFydF8wMDBfMDA2OV8wMUQ2NEEwQS41
OUFDNzBEMA0KQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvYWx0ZXJuYXRpdmU7DQoJYm91bmRhcnk9
Ii0tLS09X05leHRQYXJ0XzAwMV8wMDZBXzAxRDY0QTBBLjU5QUM3MEQwIg0KDQoNCi0tLS0tLT1f
TmV4dFBhcnRfMDAxXzAwNkFfMDFENjRBMEEuNTlBQzcwRDANCkNvbnRlbnQtVHlwZTogdGV4dC9w
bGFpbjsNCgljaGFyc2V0PSJ1dGYtOCINCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IDhiaXQN
..............

Is there a way to parse this email?

In widows' mail I can see email contents correctly.

sanmai commented 4 years ago

smime.p7m needs a separate viewer or a library. This is reportedly possible to do with OpenSSL like so:

openssl pkcs12 -in <key file.p7m> -out <key_file.pem> -nodes
piernik commented 4 years ago

You are saying that I am not able to parse this email with php-mime-mail-parser? Am I able to parse it with php at all?

eXorus commented 4 years ago

Yes this lib only parse "normal" emails, an we can't parse encrypted emails.

It could be a feature request, but not sure to have time now. The workaround for you is to use another lib to decode theses emails.

piernik commented 4 years ago

Your lib is best so if You can implement it would be great.

Can You give me some hints how to do it myself?

sanmai commented 4 years ago

Provided you have a key to decrypt this file, you can use proc_open() to ask OpenSSL to decrypt this file for you.

piernik commented 4 years ago

But I don't have a key :) This email isn't mine - it's from my CRM's customer. But even without key why I can see email contents in windows' mail app?

sanmai commented 4 years ago

Well, if you can share this smime.p7m, I can have a closer look.

piernik commented 4 years ago

I send it to You via Your email

sanmai commented 4 years ago

I was able to see the content of the email with the following command:

openssl smime -verify -noverify -in email-with-smime-p7m.eml

Then you can feed the output back to the library.

Above the -noverify might need to be omitted if you want to actually verify the email.

piernik commented 4 years ago

thanks - I'll try to implement

caugner commented 4 years ago

I think it should be possible to extract the content using openssl_pcks7_verify(), as described here: https://www.php.net/manual/en/function.openssl-pkcs7-verify.php#113835

Edit: Here's my implementation:

<?php
function parse_pkcs7(string $header_and_body): ?string
{
    $prefix = sys_get_temp_dir() . DIRECTORY_SEPARATOR . "pkcs7_" . microtime(true);

    $msg = "$prefix.eml";
    $pem = "$prefix.pem";
    $out = "$prefix.out";

    try {
        file_put_contents($msg, $header_and_body);

        if (!openssl_pkcs7_verify($msg, PKCS7_NOVERIFY, $pem)) {
            return null;
        }

        if (!openssl_pkcs7_verify($msg, PKCS7_NOVERIFY, $pem, [], $pem, $out)) {
            return null;
        }

        $body = file_get_contents($out);

        if (empty($body)) {
            // S/MIME mail with empty content
            return null;
        }

        return $body;
    } finally {
        foreach ([$msg, $pem, $out] as $file) {
            if (file_exists($file)) {
                unlink($file);
            }
        }
    }
}
eXorus commented 4 years ago

Great @caugner I reopened the issue to integrate it in php-mime-mail-parser

caugner commented 4 years ago

Note: In PHP 8.0 it should be possible to reduce the snippet to a single openssl_pkcs7_verify call thanks to Named Arguments:

openssl_pkcs7_verify(filename: $msg, flags: PKCS7_NOVERIFY, content: $out)
MrBalum commented 1 month ago

@eXorus can we expect that a fix will be added. if not please announce it :)

eXorus commented 1 month ago

Hi @MrBalum,

This isn't actually a bug fix, but rather a feature request to add support for parsing emails with openssl_pkcs7_verify. Since this is an open-source project, I do my best to maintain it, but I welcome any PRs that would like to add this functionality to the code.

At the moment, I can't commit to a specific delivery date as I'm currently working on other projects.

Thanks for your understanding!