[Mew-dist 15624] Re: Mew-1.95b91: bad PGP signature event

Brad Allen Ulmo at example.com
2000年 12月 25日 (月) 21:01:33 JST


Hi esteemed Mew programmers and hackers,

I have found the answer.  It *almost* (but *not quite*) is entirely
within PGP/MIME RFC 2015.

Legend for clarity:  CR = 0D base 16
                     LF = 0A base 16
                   CRLF = CR immediately followed by LF
                     NL = New Line (algebraic meaning: abstract:  not
                          binary-specified in and of itself:
                          binary encoding extremely context-specific)
                          NL DOES NOT MEAN THE UNIX NEWLINE CHARACTER
                          LF; NL MEANS THE SYMBOLIC NL THING.  It is
                          irrelevent for purposes of this definition
                          how it is represented.  I'll note that in
                          Unix it is *usually* represented with a LF
                          character byte, BUT: 1) NOT ALL THE TIME;
                          2) '\n', while CONCEPTUAL and BOUND BY ANSI
                          TO A SPECIFIC VALUE, THOSE TWO THINGS
                          (THE CONCEPT AND ANSI BOUNDING THE VALUE)
                          ARE NOT LINKED IN THIS CASE! and 3) in this
                          legend IT DOES NOT MEAN CR!
                   CRNL = CR immediately followed by NL
                          which obviously means 0D base 16 followed by
                          an abstract NL object (by now any innocent
                          bystanders are beginning to see the issue
                          I'm about to discuss in this message)
                 [....] = encoded data ``....'' between brackets will
                          not hurt outside or be hurt from outside


It says each line *must* end with CRLF at a certain stage (see first
excerpt below).  What this means is the data before signature is made
*must* be transport-ready *before* signature creation; Mew *must*
detect unsafely illegal things such as CRNL and face a conversion such
as Quoted-Printable or Base64-Encoding so it shows up as
[PROTECTED-WHATEVER-CR]NL so the processing can continue (converts
that to [PROTECTED-WHATEVER-CR]CRLF) (necessary for compliance with
RFC 2015).  Mew can issue a warning, prompt for solution and refuse to
continue without that solution (such as "you must pick
quoted-printable, base64-encoding, or other solution, or I will not
send the message").  I have thus identified an issue where Mew needs
to do an extra verification step.  The step I see Mew going through
are like this:

... chugging along in other steps of the procedure ...
... time to do the signing steps ...
... data converted to its type/subtype specific canonical form ...
    (that's what it says in the RFC; I don't exactly know what it
    means right off; will need to read MIME RFCs to understand it)
    For text/plain, NL->CRLF, WHICH MEANS that instead:
    for text/plain:
    1.  Check for CRNL.  If found:
        A.  WARN USER THIS IS THE CASE.  Often the user just wants to
            get rid of them on his own, and go back to editing;
            give message like:
            i. "You attempted to encode text/plain, but you have CRNL in
                your document, and that is not allowed in text/plain."
            -or- (must look up MIME standard for text/plain to find
                 out if loose CRs are allowed ...)
               "You attempted to encode text/plain, but you have CRs in
                your document, and that is not allowed in text/plain."
            -and-

            ii. "Your choices are as follows:  a) abort this step and
             continue editing your message so that you can fix it
             correctly such as chaning its type, reorganizing it, or
             eliminating the noncompliant text/plain characters;
             b) change its type; c) strip all of the CRs;
             (maybe if standard allows it -- I DO NOT THINK SO) e) go to
             content-transfer-encoding step to take care of this."

... Apply appropriate Content-Transfer-Encoding ...
    Check for CRNL (at this point, it may be CRLFLF? depends on the
    way you programmed it symbolically); if it is there, a
    Content-Transfer-Encoding MUST be applied that moves the CR away
    from the NL: force options:
    i.  "You did not choose an appropriate content-transfer-encoding
         type for your message because I found a CRNL.  Your options:
         a) go back to editing and I can choose another content-
         transfer-encoding or remove the CRs or whatever; b) choose
         a binary content-transfer encoding; c) choose a
         quoted-printable content-transfer encoding; d) strip all the
         CRs off and use the current content-transfer encoding of ___"

... sign as stated below.


I hope that was clear enough.  In short, Mew has to do one quick
hand-holding in that case.  Instead, it let me let it violate the RFC
for PGP/MIME and thus my message was affirmatively in a state with
undefined consequences, and I *cannot* blame that horrible "sendmail"
program as much as I'd like to for this particular case.

PLEASE NOTE: do NOT just short-circuit the ideas I presented above;
WHAT I MEAN BY THIS is do NOT just ``magically erase all CRs or other
types of bad character combinations'' or ``without asking apply
encoding to protect stray CRs or other types of bad character
combinations'', because THIS WILL CAUSE PROBLEMS TOO such as (in the
case of just erasing CRs without asking, munging data; and in the case
of changing encodings without asking, not getting data out the way the
user intended and not knowing which level and spot the user had his
oversight in and therefore the mailer (Mew) oughtent try to
second-guess how it should have happened (if you want that buggy scary
behavoir, just buy Micro$&!+).

AS A MATTER OF FACT, if someone can hand-hold me through the elisp
function flows that run this particular stuff, I can pin-point the
changes that need to be made for you, and you can mindlessly implement
the specific elisp codings I told you you can do.  Just telling me all
the function names where this happens could help ...

ok two more things for me to do:

* RFC MIME to check out whether stray CRs or all other character
  combos in text/plain are allowed (or any are not allowed) in the
  first place way up there; obviosly, once I read the MIME RFCs, there
  may be efficiencies to be had in the procedural programming with
  respect to things discussed in this message and other things not
  discussed in this message.
* look at Mew codings myself to see if I can figure it out quickly
  enough to fix it myself without any help ...

Once again, I will send this email NOW without having done those last
two steps because I don't want to fall asleep before you get this.

Brad Allen <Ulmo at example.com>




Excerpts from RFC 2015:


`` (2)  An appropriate Content-Transfer-Encoding is then applied. Each
        line of the encoded data MUST end with the canonical <CR><LF>
        sequence.''

This is part of a very, very clera section of that RFC -- I'll just
include it here:


``````````````````````````````````````````````````````````````````````````````

5.  PGP signed data

   PGP signed messages are denoted by the "multipart/signed" content
   type, described in [1], with a "protocol" parameter which MUST have a
   value of "application/pgp-signature" (MUST be quoted).  The "micalg"



Elkins                      Standards Track                     [Page 3]

RFC 2015                 MIME Security with PGP             October 1996


   parameter MUST have a value of "pgp-<hash-symbol>", where <hash-
   symbol> identifies the message integrity check (MIC) used to generate
   the signature.  The currently defined values for <hash-symbol> are
   "md5" for the MD5 checksum, and "sha1" for the SHA.1 algorithm.

   The multipart/signed body MUST consist of exactly two parts.  The
   first part contains the signed data in MIME canonical format,
   including a set of appropriate content headers describing the data.

   The second body MUST contain the PGP digital signature.  It MUST be
   labeled with a content type of "application/pgp-signature".

   When the PGP digital signature is generated:

   (1)  The data to be signed must first be converted to its
        type/subtype specific canonical form.  For text/plain, this
        means conversion to an appropriate character set and conversion
        of line endings to the canonical <CR><LF> sequence.

   (2)  An appropriate Content-Transfer-Encoding is then applied. Each
        line of the encoded data MUST end with the canonical <CR><LF>
        sequence.

   (3)  MIME content headers are then added to the body, each ending
        with the canonical <CR><LF> sequence.

   (4)  As described in [1], the digital signature MUST be calculated
        over both the data to be signed and its set of content headers.

   (5)  The signature MUST be generated detached from the signed data
        so that the process does not alter the signed data in any way.

[^^ There is one good thing here:  it carries some of the headers with it.
 ^^ However, it skimps on how many headers; I want message-id, to, from,
 ^^ etc. all signed too!  And date ... -ulmo]

   Example message:

     From: Michael Elkins <elkins at example.com>
     To: Michael Elkins <elkins at example.com>
     Mime-Version: 1.0
     Content-Type: multipart/signed; boundary=bar; micalg=pgp-md5;
     protocol="application/pgp-signature"

     --bar
     & Content-Type: text/plain; charset=iso-8859-1
     & Content-Transfer-Encoding: quoted-printable
     &
     & =A1Hola!
     &
     & Did you know that talking to yourself is a sign of senility?
     &



Elkins                      Standards Track                     [Page 4]

RFC 2015                 MIME Security with PGP             October 1996


     & It's generally a good idea to encode lines that begin with
     & From=20because some mail transport agents will insert a greater-
     & than (>) sign, thus invalidating the signature.
     &
     & Also, in some cases it might be desirable to encode any   =20
     &railing whitespace that occurs on lines in order to ensure  =20
     & that the message signature is not invalidated when passing =20
     & a gateway that modifies such whitespace (like BITNET). =20
     &
     & me

     --bar
     Content-Type: application/pgp-signature

    -----BEGIN PGP MESSAGE-----
   Version: 2.6.2

   iQCVAwUBMJrRF2N9oWBghPDJAQE9UQQAtl7LuRVndBjrk4EqYBIb3h5QXIX/LC//
   jJV5bNvkZIGPIcEmI5iFd9boEgvpirHtIREEqLQRkYNoBActFBZmh9GC3C041WGq
   uMbrbxc+nIs1TIKlA08rVi9ig/2Yh7LFrK5Ein57U/W72vgSxLhe/zhdfolT9Brn
   HOxEa44b+EI=
   =ndaj
   -----END PGP MESSAGE-----

   --bar--

   The "&"s in the previous example indicate the portion of the data
   over which the signature was calculated.

   Though not required, it is generally a good idea to use Quoted-
   Printable encoding in the first step (writing out the data to be
   signed in MIME canonical format) if any of the lines in the data
   begin with "From ", and encode the "F".  This will avoid an MTA
   inserting a ">" in front of the line, thus invalidating the
   signature!

   Upon receipt of a signed message, an application MUST:

   (1)  Convert line endings to the canonical <CR><LF> sequence before
        the signature can be verified.  This is necessary since the
        local MTA may have converted to a local end of line convention.

   (2)  Pass both the signed data and its associated content headers
        along with the PGP signature to the signature verification
        service.

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

After you read this excerpt, I deplore you to go back and read that
entire RFC exactly so that you have a clear idea of how to do all the
other types too with regards to the warning I'm mentioning above (six
total types -- sign, encrypt, sign and encrypt, sign then encrypt,
undo a sign and encrypt or sign then encrypt into only a sign, and
key).
-------------- next part --------------
テキスト形式以外の添付ファイルを保管しました...
ファイル名: 無し
型:         application/pgp-signature
サイズ:     230 バイト
説明:       無し
URL:        <http://www.mew.org/pipermail/mew-dist/attachments/20001225/2175c9dc/attachment.bin>


Mew-dist メーリングリストの案内