Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signature SMIME not valid #1913

Open
6 tasks done
taufikpras opened this issue Dec 9, 2019 · 8 comments
Open
6 tasks done

Signature SMIME not valid #1913

taufikpras opened this issue Dec 9, 2019 · 8 comments

Comments

@taufikpras
Copy link

taufikpras commented Dec 9, 2019

When I send email with digital signature (SMIME), the signature considered to be not valid

Please check these things before submitting your issue:

  • Read the error message you're seeing - it often tells you what is wrong, and may contain useful links & instructions
  • Make sure you're using the latest version of PHPMailer
  • Check that your problem is not dealt with in the troubleshooting guide, especially if you're having problems connecting to Gmail or GoDaddy
  • Include sufficient code to reproduce your problem
  • If you're having an SMTP issue, include the debug output generated with SMTPDebug = 2 set
  • If you have a question about how to use PHPMailer (rather than reporting a bug in it), tag a question on Stack Overflow with phpmailer, but search first!

Problem description

Code to reproduce

`<?php
require DIR . "/vendor/autoload.php";

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

$mail = new PHPMailer(true);

try {
//Server settings
$mail->SMTPDebug = SMTP::DEBUG_SERVER; // Enable verbose debug output
$mail->isSMTP(); // Send using SMTP
$mail->Host = "somehost"; // Set the SMTP server to send through
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = "somemail@somehost"; // SMTP username
$mail->Password = "password"; // SMTP password
$mail->SMTPSecure = "tls"; // Enable TLS encryption; PHPMailer::ENCRYPTION_SMTPS also accepted
$mail->Port = 587; // TCP port to connect to

//Recipients
$mail->setFrom("somemail@somehost", "somemail");
$mail->addAddress("taufik@gmail.com", "taufik");     // Add a recipient

// Content
$mail->isHTML(true);                                  // Set email format to HTML
$mail->Subject = "Here is the subject";
$mail->Body    = "This is the HTML message body <b>in bold!</b>";

$mail->sign(
  "clcert.pem",
  "key.pem",
  "secret",
  "chain.pem"
);

$mail->send();
echo "Message has been sent";

} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}

?>`

Debug output

not-valid

@XL-2000
Copy link

XL-2000 commented Dec 14, 2019

Please use the debug option and provide debug output.
For me, signing works perfect.
My first guess, without any additional debug info, is that you should provide absolute paths for your signing files (key / pem files)

@encedo
Copy link

encedo commented Jun 12, 2020

Hi

I had the same problem. After hours of investigation, the root cause was 'Content-Transfer-Encoding' changed by the mail server from '8bit' to '7bit'. Because it is a part of a signed S/MIME signed message body, the signature is broken.

Have no clue why but after adding $mail->Encoding = '7bit'; all works well (default is '8bit'). Tested on Outlook, Thunderbird, Gmail and Zimbra.

Aby idea why the mail servers change encoding (inside S/MIME part)? Or it is just my Zimbra mail server :/

Chris

@Synchro
Copy link
Member

Synchro commented Jun 12, 2020

The encoding is changed because it's an RFC recommendation (if not a requirement) - if a part does not need the enhanced semantics and processing that are implied by 8bit, then it should be downgraded to 7bit. For example, if you have a part that is text/html; charset=utf-8, normally you might expect that to use 8bit, however, if it doesn't actually use any 8-bit characters (i.e. it's all ASCII), then 7bit will work fine. PHPMailer does this downgrade automatically, and it does not surprise me if other systems do too.

I can see that if this downgrade occurs after the message has been signed, then that could break the signature. As you say, setting it to 7bit will avoid that happening.

@encedo
Copy link

encedo commented Jun 12, 2020

In my case, PHPMailer is used by backend to email notifications like password reset, confirmation etc. Message body is in HTML, parsed on-fly by mustache, I need UTF-8 (as user names are encoded in UTF-8) as well. My current setup include:

    $mail->Encoding = '7bit';
    $mail->CharSet = 'utf-8';

and finally, no issues occur.

Consider updating an example so it will work out of the box for any user.

Chris

@encedo
Copy link

encedo commented Jun 12, 2020

(..) PHPMailer does this downgrade automatically, and it does not surprise me if other systems do too.

Are you sure? In my case HTML input body to openssl_pkcs7_sign() is 8bit encoded and output is 8but as well. The mail server performs downgrade that brokes S/MIME.

@Synchro
Copy link
Member

Synchro commented Jun 12, 2020

PHPMailer does it here and here, which only happens while sending. Those downgrades do not involve changing the content at all - it's possible to use 8-bit UTF-8 chars in 7-bit environments but you would have to apply other encodings like quoted-printable or base64 to et the content survive intact.

I guess the server might have identified other circumstances where it can apply similar downgrades?

@encedo
Copy link

encedo commented Jun 12, 2020

Well, I have spent more time investigating...

You are right, there is an automatic encoding downgrade. The issue is somewhere else, inside getMailMIME() function - here which will append 'Content-Transfer-Encoding' as '8bit' before any encoding downgrade. This header is a subject to be modified by the mail server and break the signature. Moreover, 8bit characters from HTML file are escaped anyway so is there any possibility to have 8bit chars inside a msg body?

The fix is simple - calling of the getMailMIME() inside createBody() have to be after the downgrade and it has to take into account local variable (as $this->Encoding is not changed during downgrade).

I hope it helps.

Chris

@Synchro
Copy link
Member

Synchro commented Jun 12, 2020

Thanks for looking into it! The Encoding property is set at the message level; it's possible for MIME parts within it to use different encodings, so long as they are compatible. For example if your top-level encoding is 8bit, you can have 7bit parts (because it's a subset), but the reverse is not true. This is why the downgrades applied to individual parts does not touch the value of Encoding. Note that PHPMailer does not downgrade if a part uses 8-bit chars - note the use of the has8bitchars() method.

If you're using 8bit, you can use all 8-bit charsets (e.g. ISO-8859 and UTF-8) directly in message parts without any extra transfer encoding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants