From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Sebastian Fieber Newsgroups: gmane.emacs.bugs Subject: bug#40397: 28.0.50; epg decrypt does not verify signed content in smime Date: Mon, 06 Apr 2020 02:04:58 +0200 Message-ID: <874ktxtr6d.fsf@web.de> References: <87imih5am2.fsf@web.de> <87r1x4dujl.fsf@web.de> <87lfna22eh.fsf@web.de> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="86147"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) To: 40397@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon Apr 06 02:07:10 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jLFIC-000MIk-FL for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 06 Apr 2020 02:07:08 +0200 Original-Received: from localhost ([::1]:52900 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jLFI9-0005cD-BE for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 05 Apr 2020 20:07:06 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:42057) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jLFHA-0005bz-C3 for bug-gnu-emacs@gnu.org; Sun, 05 Apr 2020 20:06:06 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jLFH8-0005qL-Cw for bug-gnu-emacs@gnu.org; Sun, 05 Apr 2020 20:06:04 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:35366) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jLFH8-0005pf-36 for bug-gnu-emacs@gnu.org; Sun, 05 Apr 2020 20:06:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1jLFH7-0006VU-Rw; Sun, 05 Apr 2020 20:06:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Sebastian Fieber Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org, bugs@gnus.org Resent-Date: Mon, 06 Apr 2020 00:06:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 40397 X-GNU-PR-Package: emacs,gnus Original-Received: via spool by 40397-submit@debbugs.gnu.org id=B40397.158613151024841 (code B ref 40397); Mon, 06 Apr 2020 00:06:01 +0000 Original-Received: (at 40397) by debbugs.gnu.org; 6 Apr 2020 00:05:10 +0000 Original-Received: from localhost ([127.0.0.1]:46911 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jLFGH-0006SY-WF for submit@debbugs.gnu.org; Sun, 05 Apr 2020 20:05:10 -0400 Original-Received: from mout.web.de ([212.227.15.3]:50995) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1jLFGE-0006Rc-6z for 40397@debbugs.gnu.org; Sun, 05 Apr 2020 20:05:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1586131500; bh=Pwq65vujkK3dLEd6Dcu2bxsO/NZ+4Q3gA2z4p9hQT2I=; h=X-UI-Sender-Class:From:To:Subject:References:Date:In-Reply-To; b=eELMsddVZt8Hc7rw4W8K6BQcFKMQTiIa0ZpuPfQdTS3x1bYP2S+8RiBp4U0gwMRxS rzdpd/uqDLOJjmFhfFMkCzxHOpJESIkI+k/mfErt4e5/4lRlGwPHe/NyH/7cI0c60E uSSK40NsBMSgtD43My5fvlKAagklWFpaSuCTNWLo= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Original-Received: from comedian ([93.202.163.134]) by smtp.web.de (mrweb004 [213.165.67.108]) with ESMTPSA (Nemesis) id 0LZkTs-1itraJ3JlM-00lYow for <40397@debbugs.gnu.org>; Mon, 06 Apr 2020 02:04:59 +0200 In-Reply-To: <87lfna22eh.fsf@web.de> (Sebastian Fieber's message of "Sun, 05 Apr 2020 02:37:42 +0200") X-Provags-ID: V03:K1:bi0vJKYnNYvH2BLAtF1sKsUvaPF5CYlmm2lFN+EkMA7C5jzLxwX vBuBpr7H8cVEHwtXbZTN6VTynbDpR9OFmJaqQ9zBAm9nynBjPIZ49TU9ZkKQqMDWEArn4Yd GbyiBp2VV2JsbG7dAi6nl7uvfIEipxbRVhwPHWkR2hPeF0l2mOSXNleOTSYewG8VL8XOzRV duVetDtcFQMhBcDDlF+zA== X-UI-Out-Filterresults: notjunk:1;V03:K0:8WjlaBr1JT0=:m95iiRoZ3ZV06Ry8eAKybO yYnXj3llcR+oZMzEHcMHNDPTawS3nXJuFA/BPXOrzw33i0HkeA7DrhiAec/Xyamc6JZL7Ispn 0Ph5Ur+tbQ/19pglgeIehXDmh/z+Qiea7XK0dmivgHO2lQF9qFAIaEco7kJ1/gfOh+4djJnSO bf0W9HOzh3yBquitNSDWN6COHinwpSqAg+AbXzvwjaQ5vDOxjqOxqCm+PItfbOis/mWaIrVEi ZD2voPGIDtnf8qvE5ubmmDrlXrzhCWulVuETSTQDRwSJ/6XLzlKLVPOAIyAl6Y5fs7WegyUZc RMbmIUFSFZoUbh0Vz2hETXWf+WsRAcrBarP/AVhSE/sXTh/rw4EwIjI1ayO8MDhA+C2+gPGDL I4hyI+xmNXDx8uQqf4EUDC5KiFTk3yxQDCh5hoGChwv+O0xR9PzzjYMaGbDpfV9uwZ2hWXPve i4+AzPLhclLQQtB510vMVIzCoZnPO3sa/hW0ltoPAzViqbacMhoZu7ybBg22tkCOtC0r4Yb6q KCNhJpaprHBx78IoldGKoVLAZSLSOnuVG9I9PByL3tLdsVdnPDToXoSHkC4wJqcSNdGrcI7Te qP5pNYJKnlbq1Xa6TMY/UK2j+PhR6LoUVuchKnL8K5RmshAAv3Qfhc0k9rbSHIcvEw6OL+sNx IumDwwh13DHpPxSQOjBRS4+MwIXDGVTNXyenv68M9fmAPPKjb5HH/qjNW5Ny8I6KSk/VGaV4w H62Vry3x0y6g2G+0chB9nopM64yySs7tphVFYZGpyLWbcCO0ih3sClg/6Ep94yh7XTkiKez+ X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:178070 Archived-At: --=-=-= Content-Type: text/plain On So, Apr 05 2020, Sebastian Fieber wrote: > I just had some time to look into this even further and I noticed that > the mm-sec buttons for signatures/encryption are not displayed for the > whole application/pkcs7-mime stuff, too. I am working on a patch to fix > this. > > I think most of the code would look like the one in mml-smime.el (the > calls to mm-sec-* and getting error/success messages from epg). The > hard part is to get the mm-security-handle or better the information > added about the pkcs7-mime signature by the mm-sec-* calls to some > function that will add these (which is gnus-mime-display-security ?). > The problem here is that the part is lost when the signature is verified > as the actual signed content parts will have replace it. > > Best regards > Sebastian Hey, here is the resulting more thorough patch replacing the one before. It's not finished completely as error handling and reporting via mm-sec-error is still missing in mm-view-pkcs7-[decrypt/verify]. But displaying verification and encryption information via gnus-mime-display-security does work (at least in the good case). See the patch for more information. I'd welcome any comments :) --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-fix-bug-40397.patch Content-Transfer-Encoding: quoted-printable =46rom 2d623b52c7810a293ad8309018ebc4973f1ff2e3 Mon Sep 17 00:00:00 2001 From: fallchildren Date: Sat, 4 Apr 2020 01:16:12 +0200 Subject: [PATCH] fix bug #40397 This fixes S/MIME encrypted AND signed mails where in the encrypted pkcs7 envelope is a signed pkcs7 structure. - don't force Content-type header to text/plain in front of decrypted content for smime decryption using mm-view-pkcs7 - structure the result of mm-dissect-buffer of application/pkcs7-mime like a multipart mail so there is no loosing of information of verification and decryption results which can now be displayed by gnus-mime-display-security - adjust gnus-mime-display-part to handle application/pkcs7-mime like multipart/encrypted or multipart/signed - add dummy entries to mm-verify-function-alist and mm-decrypt-function-alist so gnus-mime-display-security correctly displays "S/MIME" and not "unknown protocol" - adjust mm-possibly-verify-or-decrypt to check for smime-type to ask wether to verfiy or decrypt part and not to ask to decrypt either way - adjust mm-view-pkcs7-decrypt and verify to call mm-sec-status so success information can be displayed by gnus-mime-display-security - in mm-view-pkcs7-decrypt also replace "^M\n" with newline and not only "\r\n" - I have no idea why this is needed TODO: mm-view-pkcs7-decrypt and verify error handling and reporting. ATM there is only the good case implemented - at least for reporting with gnus-mime-display-security. =2D-- lisp/gnus/gnus-art.el | 28 ++++++++++++++++ lisp/gnus/mm-decode.el | 74 +++++++++++++++++++++++++++++------------- lisp/gnus/mm-view.el | 32 +++++++++++++++--- 3 files changed, 108 insertions(+), 26 deletions(-) diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 6b9610d312..4ab629eda0 100644 =2D-- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -5986,6 +5986,34 @@ If nil, don't show those extra buttons." ((equal (car handle) "multipart/encrypted") (gnus-add-wash-type 'encrypted) (gnus-mime-display-security handle)) + ;; pkcs7-mime handling: + ;; + ;; although not really multipart these are structured internally by + ;; mm-dissect-buffer like multipart to not discard the decryption + ;; and verification results + ;; + ;; application/pkcs7-mime + ((and (equal (car handle) "application/pkcs7-mime") + (equal (mm-handle-multipart-ctl-parameter handle 'protocol) + "application/pkcs7-mime_signed-data")) + (gnus-add-wash-type 'signed) + (gnus-mime-display-security handle)) + ((and (equal (car handle) "application/pkcs7-mime") + (equal (mm-handle-multipart-ctl-parameter handle 'protocol) + "application/pkcs7-mime_enveloped-data")) + (gnus-add-wash-type 'encrypted) + (gnus-mime-display-security handle)) + ;; application/x-pkcs7-mime + ((and (equal (car handle) "application/x-pkcs7-mime") + (equal (mm-handle-multipart-ctl-parameter handle 'protocol) + "application/x-pkcs7-mime_signed-data")) + (gnus-add-wash-type 'signed) + (gnus-mime-display-security handle)) + ((and (equal (car handle) "application/x-pkcs7-mime") + (equal (mm-handle-multipart-ctl-parameter handle 'protocol) + "application/x-pkcs7-mime_enveloped-data")) + (gnus-add-wash-type 'encrypted) + (gnus-mime-display-security handle)) ;; Other multiparts are handled like multipart/mixed. (t (gnus-mime-display-mixed (cdr handle))))) diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el index 96695aabfd..5af2e50f66 100644 =2D-- a/lisp/gnus/mm-decode.el +++ b/lisp/gnus/mm-decode.el @@ -473,6 +473,7 @@ The file will be saved in the directory `mm-tmp-direct= ory'.") (autoload 'mml2015-verify-test "mml2015") (autoload 'mml-smime-verify "mml-smime") (autoload 'mml-smime-verify-test "mml-smime") +(autoload 'mm-view-pkcs7-verify "mm-view") (defvar mm-verify-function-alist '(("application/pgp-signature" mml2015-verify "PGP" mml2015-verify-test= ) @@ -481,7 +482,15 @@ The file will be saved in the directory `mm-tmp-direc= tory'.") ("application/pkcs7-signature" mml-smime-verify "S/MIME" mml-smime-verify-test) ("application/x-pkcs7-signature" mml-smime-verify "S/MIME" - mml-smime-verify-test))) + mml-smime-verify-test) + ("application/x-pkcs7-signature" mml-smime-verify "S/MIME" + mml-smime-verify-test) + ;; these are only used for security-buttons and contain the + ;; smime-type after the underscore + ("application/pkcs7-mime_signed-data" mm-view-pkcs7-verify "S/MIME" + nil) + ("application/x-pkcs7-mime_signed-data" mml-view-pkcs7-verify "S/MIME= " + nil))) (defcustom mm-verify-option 'never "Option of verifying signed parts. @@ -500,11 +509,16 @@ result of the verification." (autoload 'mml2015-decrypt "mml2015") (autoload 'mml2015-decrypt-test "mml2015") +(autoload 'mm-view-pkcs7-decrypt "mm-view") (defvar mm-decrypt-function-alist '(("application/pgp-encrypted" mml2015-decrypt "PGP" mml2015-decrypt-te= st) ("application/x-gnus-pgp-encrypted" mm-uu-pgp-encrypted-extract-1 "PG= P" - mm-uu-pgp-encrypted-test))) + mm-uu-pgp-encrypted-test) + ;; these are only used for security-buttons and contain the + ;; smime-type after the underscore + ("application/pkcs7-mime_enveloped-data" mm-view-pkcs7-decrypt "S/MIM= E" nil) + ("application/x-pkcs7-mime_enveloped-data" mm-view-pkcs7-decrypt "S/M= IME" nil))) (defcustom mm-decrypt-option nil "Option of decrypting encrypted parts. @@ -682,14 +696,23 @@ MIME-Version header before proceeding." (car ctl)) (cons (car ctl) (mm-dissect-multipart ctl from)))) (t - (mm-possibly-verify-or-decrypt - (mm-dissect-singlepart - ctl - (and cte (intern (downcase (mail-header-strip-cte cte)))) - no-strict-mime - (and cd (mail-header-parse-content-disposition cd)) - description id) - ctl from)))) + (let* ((intermediate-result + (mm-possibly-verify-or-decrypt + (mm-dissect-singlepart + ctl + (and cte (intern (downcase (mail-header-strip-cte cte)))) + no-strict-mime + (and cd (mail-header-parse-content-disposition cd)) + description id) + ctl from))) + (when (and (equal type "application") + (or (equal subtype "pkcs7-mime") + (equal subtype "x-pkcs7-mime"))) + ;; if this is a pkcs7-mime lets treat this special and + ;; more like multipart so the pkcs7-mime part does not + ;; get ignored + (setq intermediate-result (list (car ctl) intermediate-res= ult))) + intermediate-result)))) (when id (when (string-match " *<\\(.*\\)> *" id) (setq id (match-string 1 id))) @@ -759,7 +782,7 @@ MIME-Version header before proceeding." (mb enable-multibyte-characters) beg) (goto-char (point-min)) - (search-forward-regexp "^\n" nil 'move) ;; There might be no body. + (search-forward-regexp "^?\n" nil 'move) ;; There might be no body. (setq beg (point)) (with-current-buffer (generate-new-buffer " *mm*") @@ -1672,17 +1695,24 @@ If RECURSIVE, search recursively." (cond ((or (equal type "application/x-pkcs7-mime") (equal type "application/pkcs7-mime")) - (with-temp-buffer - (when (and (cond - ((eq mm-decrypt-option 'never) nil) - ((eq mm-decrypt-option 'always) t) - ((eq mm-decrypt-option 'known) t) - (t (y-or-n-p - (format "Decrypt (S/MIME) part? ")))) - (mm-view-pkcs7 parts from)) - (goto-char (point-min)) - (insert "Content-type: text/plain\n\n") - (setq parts (mm-dissect-buffer t))))) + (let* ((smime-type (cdr (assoc 'smime-type ctl))) + (envelope-p (string=3D smime-type "enveloped-data")) + (decrypt-or-sign-option (if envelope-p + mm-decrypt-option + mm-sign-option)) + (question (if envelope-p + "Decrypt (S/MIME) part? " + "Verify signed (S/MIME) part? "))) + (with-temp-buffer + (when (and (cond + ((eq decrypt-or-sign-option 'never) nil) + ((eq decrypt-or-sign-option 'always) t) + ((eq decrypt-or-sign-option 'known) t) + (t (y-or-n-p + (format question)))) + (mm-view-pkcs7 parts from)) + (goto-char (point-min)) + (setq parts (mm-dissect-buffer t)))))) ((equal subtype "signed") (unless (and (setq protocol (mm-handle-multipart-ctl-parameter ctl 'protocol)) diff --git a/lisp/gnus/mm-view.el b/lisp/gnus/mm-view.el index 828ac633dc..4c7350b55a 100644 =2D-- a/lisp/gnus/mm-view.el +++ b/lisp/gnus/mm-view.el @@ -591,8 +591,20 @@ If MODE is not set, try to find mode automatically." (with-temp-buffer (insert-buffer-substring (mm-handle-buffer handle)) (goto-char (point-min)) - (let ((part (base64-decode-string (buffer-string)))) - (epg-verify-string (epg-make-context 'CMS) part)))) + (let* ((part (base64-decode-string (buffer-string))) + (context (epg-make-context 'CMS)) + (plain (epg-verify-string context part))) + (mm-sec-status + 'gnus-info + (epg-verify-result-to-string (epg-context-result-for contex= t 'verify)) + 'gnus-details + nil + 'protocol + ;; just mimik pkcs7-signature actually we are in pkcs7-mime + (concat (substring-no-properties (caadr handle)) + "_" + (cdr (assoc 'smime-type (cadr handle))))) + plain))) (with-temp-buffer (insert "MIME-Version: 1.0\n") (mm-insert-headers "application/pkcs7-mime" "base64" "smime.p7m") @@ -612,7 +624,19 @@ If MODE is not set, try to find mode automatically." ;; Use EPG/gpgsm (let ((part (base64-decode-string (buffer-string)))) (erase-buffer) - (insert (epg-decrypt-string (epg-make-context 'CMS) part))) + (insert + (let* ((context (epg-make-context 'CMS)) + (plain (epg-decrypt-string context part))) + (mm-sec-status + 'gnus-info + "OK" + 'gnus-details + nil + 'protocol + (concat (substring-no-properties (caadr handle)) + "_" + (cdr (assoc 'smime-type (cadr handle))))) + plain))) ;; Use openssl (insert "MIME-Version: 1.0\n") (mm-insert-headers "application/pkcs7-mime" "base64" "smime.p7m") @@ -626,7 +650,7 @@ If MODE is not set, try to find mode automatically." smime-keys nil nil nil (car-safe (car-safe smime-keys))))) from)) (goto-char (point-min)) - (while (search-forward "\r\n" nil t) + (while (search-forward-regexp "\r\n|=0D\n" nil t) (replace-match "\n")) (goto-char (point-min))) =2D- 2.25.2 --=-=-=--