Gnus development mailing list
 help / color / mirror / Atom feed
* Re: Request: Mails that are encrypted and/or signed using MIME
       [not found] <wtnvh4rgy4e.fsf@licia.dtek.chalmers.se>
@ 2000-01-18 21:31 ` Florian Weimer
  2000-01-19 22:43   ` Brian May
  0 siblings, 1 reply; 3+ messages in thread
From: Florian Weimer @ 2000-01-18 21:31 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 460 bytes --]

Jonas Steverud <d4jonas@dtek.chalmers.se> writes:

> I currently tries to write some code that would make Gnus and
> Mailcrypt aware of PGP-MIME.
> 
> 1. I need examples. Could someone send me one mail encrypted and one
>    mail signed with the Subject "PGP-MIME test"?

If you're doing MIME-PGP development, it's quite handy to have mutt
installed. ;)  RFC 2015 contains some examples as well.

Here're are some old explanations I wrote several months ago.


[-- Attachment #2: Type: text/plain, Size: 4352 bytes --]

I don't think that this hook can be used.  Let's have a look at the
following message which conforms to RFC 2015:

----------------------------------------------------------------------
Date: Sun, 13 Jun 1999 13:32:15 +0200
From: mutt@cygnus.stuttgart.netsurf.de
To: Florian Weimer <fw@deneb.cygnus.stuttgart.netsurf.de>
Subject: Signed with attachment
X-Gnus-Mail-Source: directory:~/Mail/INCOMING/
Message-ID: <19990613133215.B2917@deneb.cygnus.stuttgart.netsurf.de>
Mime-Version: 1.0
Content-Type: multipart/signed; boundary=YD3LsXFS42OYHhNZ; micalg=pgp-md5;
	protocol="application/pgp-signature"
X-Mailer: Mutt 0.95.1i
Lines: 50
Xref: deneb.cygnus.stuttgart.netsurf.de misc:178


--YD3LsXFS42OYHhNZ
Content-Type: multipart/mixed; boundary=ADZbWkCsHQ7r3kzd


--ADZbWkCsHQ7r3kzd
Content-Type: text/plain; charset=us-ascii
Content-Description: Message

A signed message with an attachment.


--ADZbWkCsHQ7r3kzd
Content-Type: text/plain; charset=us-ascii
Content-Description: Assembler code
Content-Disposition: attachment; filename="t.s"

	.file	"t.c"
	.version	"01.01"
gcc2_compiled.:
.text
	.align 4
.globl foo
	.type	 foo,@function
foo:
	pushl %ebp
	movl %esp,%ebp
	movl 4660,%eax
	movl %ebp,%esp
	popl %ebp
	ret
.Lfe1:
	.size	 foo,.Lfe1-foo
	.ident	"GCC: (GNU) egcs-2.91.57 19980901 (egcs-1.1 release)"

--ADZbWkCsHQ7r3kzd--

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

-----BEGIN PGP SIGNATURE-----
Version: 2.6.3i

iQBFAwUBN2OWvzyNAitYx2a1AQHgRgGA5fYIevSaZao25ZMudtaN+PDAbLIze3rn
aChV9rUthqm8lOp2nsD313AiGxpJwhr/
=eKxI
-----END PGP SIGNATURE-----

--YD3LsXFS42OYHhNZ--
----------------------------------------------------------------------

The `micalg' and `protocol' parameters in the primary `Content-Type'
header are vital, but it seems as if they aren't passed to functions
listed in `gnus-mime-multipart-functions'.  In addition, everything
between the first and second `--YD3LsXFS42OYHhNZ' boundary is covered
by the PGP signature, including the MIME headers and boundaries, which
get lost during the translation from raw message text to MIME handles.

[NOTE (January 2000): `mml-generate-multipart-alist' solves this.]

Finally, in the `multipart/encrypted' case, as shown below, the encrypted
part contains data which has to be put through the MIME translation
process as well.  This has not happend during the first translation,
because obviously, the data contained in the part wasn't readable then.

----------------------------------------------------------------------
Date: Sun, 13 Jun 1999 12:17:23 +0200
From: mutt@cygnus.stuttgart.netsurf.de
To: Florian Weimer <fw@deneb.cygnus.stuttgart.netsurf.de>
Subject: test
X-Gnus-Mail-Source: directory:~/Mail/INCOMING/
Message-ID: <19990613121723.A2917@deneb.cygnus.stuttgart.netsurf.de>
Mime-Version: 1.0
Content-Type: multipart/encrypted; boundary=Kj7319i9nmIyA2yE;
	protocol="application/pgp-encrypted"
X-Mailer: Mutt 0.95.1i
Lines: 24
Xref: deneb.cygnus.stuttgart.netsurf.de misc:177


--Kj7319i9nmIyA2yE
Content-Type: application/pgp-encrypted

Version: 1

--Kj7319i9nmIyA2yE
Content-Type: application/octet-stream

-----BEGIN PGP MESSAGE-----
Version: 2.6.3i

hIwDbSMVHQQS92EBBACFUjqnO8eDDinYfo183PYgd7GQInt3BHhZCnRP807uGwra
F2zAc4PBgGhBKYnU/nZiOZvqYVh+CA7JqjTzku0sM12RLg2R6bg2nB+V+CzOkK8R
5TQczKGI/Tyhs/ktej0pbMxR5rt5FwvDuB8hcCNKPPTfaeu/4RQsfnlaxsJXm4Q8
AzyNAitYx2a1AQGAug9oiCsl6+omafWxqlJBohEjXJCKjAASE9pfBHNqk6vhUMx3
qbLv6ai7AXOa9voApgAAAFwh2dnqGHsvY9WxPhIGgwkE9/CdjCX8p+jIG50F05Qe
HUyZLv61ibRCm8EYEO2SBUO0brS2u7wtJuOhtGO03SLiDuPuZh2gaqIkpB7xwDxv
T3BUKwC4W9ZIVybX7A==
=oXnI
-----END PGP MESSAGE-----

--Kj7319i9nmIyA2yE--
----------------------------------------------------------------------

The encrypted data looks like this (but it might contain attachments
and other MIME mess as well):

----------------------------------------------------------------------
Content-Type: text/plain; charset=us-ascii

Just another test
----------------------------------------------------------------------


IMHO, an appropiate hook into `mm-dissect-buffer' would allow
to do all these things in a relatively straightforward manner.
`gnus-mime-multipart-functions' could be used to put information gathered
during the MIME translation process (signer, valid/invalid signature,
beginning/end of signed data) into the *Article* buffer in a nicely
formatted form.

[...]

[-- Attachment #3: Type: text/plain, Size: 780 bytes --]


> 2. Anyone else who writes or have written anything like this? I will
>    contact the people behind Mailcrypt ASAP.

Below you find a message I sent to them a few months ago which summarizes
the changes required for proper detached signature handling.  I'm afraid,
but I didn't get a reply.

I'm working on a clean interface to GnuPG which is written from scratch,
but I got carried away once more, this time by some Emacs bugs. :-/

Currently, it's complicated to get meaningful and machine-readable
status codes for signatures from GnuPG or even PGP.  A coworker of mine
is working on a proposal for machine-readable status codes for OpenPGP
signatures with standardized semantics.  Discussions has just begun,
but we plan to provide a sample implementation based on GnuPG.


[-- Attachment #4: Type: message/rfc822, Size: 9848 bytes --]

From: Florian Weimer <fw@deneb.cygnus.argh.org>
To: Len Budney <lbudney@pobox.com>
Subject: Mailcrypt support for detached signatures
Date: 10 Oct 1999 19:44:31 +0200
Message-ID: <87zoxrqfeo.fsf@deneb.cygnus.argh.org>

Hi!

I'm working on MIME/PGP support for Pterodactyl Gnus.  Of course,
I'd like to use Mailcrypt, but I've discovered a few shortcomings:

* No support for detached signatures.

For the signing part, this is mostly trivial.  Something like this
could do the trick:

(defun rfc2015-pgp-mc-sign-buffer (&optional id)
  "Replace the text in the current buffer with detached PGP signature.

If non-nil, ID specifies the user ID which is used for signing.

This function is a modifed version of `mc-pgp-sign-region' which
generates a detached signature as required by RFC 2015. (All the code
is based on Mailcrypt 3.5.3.)

  (let ((process-environment process-environment)
	(buffer (get-buffer-create mc-buffer-name))
	passwd args key)
    (setq key (mc-pgp-lookup-key (or id mc-pgp-user-id)))
    (setq passwd
	  (mc-activate-passwd
	   (cdr key)
	   (format "PGP passphrase for %s (%s): " (car key) (cdr key))))
    (setenv "PGPPASSFD" "0")
    (setq args (list
                "-fasbt" "+verbose=1" "+language=en"
                "+batchmode" "-u" (cdr key)))
    (mc-process-region (point-min) (point-max) passwd mc-pgp-path args
			   'mc-pgp-generic-parser buffer)))

(As you can see, I care only about PGP 2.6.x support at the moment.)
There's a minor efficiency problem: the data which is being signed is
replaced by the signature, but this doesn't matter currently.

The verification is quite a bit harder.  I had to modify
`mc-process-region' because the original didn't suit the needs.
Of course, the following is nothing more than a quick hack, but you'll
get the idea anyway:

(defun rfc2015-pgp-mc-process (passwd program args parser &optional buffer)
  "Like `mc-process-region', but doesn't send any data to PGP.
PARSER is called with one argument, the exit status of PROGRAM."
  (let ((obuf (current-buffer))
	(process-connection-type nil)
	mybuf result rgn proc)
    (unwind-protect
	(progn
	  (setq mybuf (or buffer (generate-new-buffer " *mailcrypt temp")))
	  (set-buffer mybuf)
	  (erase-buffer)
	  (set-buffer obuf)
	  (buffer-disable-undo mybuf)
	  (setq proc
		(apply 'start-process "*PGP*" mybuf program args))
	  (if passwd
	      (progn
		(process-send-string proc (concat passwd "\n"))
		(or mc-passwd-timeout (mc-deactivate-passwd t))))
	  (process-send-eof proc)
	  (while (eq 'run (process-status proc))
	    (accept-process-output proc 5))
	  (setq result (process-exit-status proc))
	  ;; Hack to force a status_notify() in Emacs 19.29
	  (delete-process proc)
	  (set-buffer mybuf)
	  (goto-char (point-max))
	  (if (re-search-backward "\nProcess \\*PGP.*\n\\'" nil t)
	      (delete-region (match-beginning 0) (match-end 0)))
	  (goto-char (point-min))
	  ;; CRNL -> NL
	  (while (search-forward "\r\n" nil t)
	    (replace-match "\n"))
	  ;; Hurm.  FIXME; must get better result codes.
	  (if (stringp result)
	      (error "%s exited abnormally: '%s'" program result)
	    (funcall parser result)))
      ;; Cleanup even on nonlocal exit
      (if (and proc (eq 'run (process-status proc)))
	  (interrupt-process proc))
      (set-buffer obuf)
      (or buffer (null mybuf) (kill-buffer mybuf)))))

This addresses the output-replaces-input problem:

(defun rfc2015-mc-process-region-preserve (beg end passwd program args parser &optional buffer)
  "Like `mc-process-region', but the region isn't replaced.
PARSER is called with one argument, the exit status of PROGRAM."
  (let ((obuf (current-buffer))
	(process-connection-type nil)
	mybuf result rgn proc)
    (unwind-protect
	(progn
	  (setq mybuf (or buffer (generate-new-buffer " *mailcrypt temp")))
	  (set-buffer mybuf)
	  (erase-buffer)
	  (set-buffer obuf)
	  (buffer-disable-undo mybuf)
	  (setq proc
		(apply 'start-process "*PGP*" mybuf program args))
	  (if passwd
	      (progn
		(process-send-string proc (concat passwd "\n"))
		(or mc-passwd-timeout (mc-deactivate-passwd t))))
	  (process-send-region proc beg end)
	  (process-send-eof proc)
	  (while (eq 'run (process-status proc))
	    (accept-process-output proc 5))
	  (setq result (process-exit-status proc))
	  ;; Hack to force a status_notify() in Emacs 19.29
	  (delete-process proc)
	  (set-buffer mybuf)
	  (goto-char (point-max))
	  (if (re-search-backward "\nProcess \\*PGP.*\n\\'" nil t)
	      (delete-region (match-beginning 0) (match-end 0)))
	  (goto-char (point-min))
	  ;; CRNL -> NL
	  (while (search-forward "\r\n" nil t)
	    (replace-match "\n"))
	  ;; Hurm.  FIXME; must get better result codes.
	  (if (stringp result)
	      (error "%s exited abnormally: '%s'" program result)
	    (funcall parser result)))
      ;; Cleanup even on nonlocal exit
      (if (and proc (eq 'run (process-status proc)))
	  (interrupt-process proc))
      (set-buffer obuf)
      (or buffer (null mybuf) (kill-buffer mybuf)))))

Here's the parser for the PGP output.  Note that the report status
gives quite a lot information on the signature quality (see below for
an additional comment on this issue).

(defun rfc2015-pgp-mc-verify-parser (result)
  "Parse PGP output in current buffer."
  (goto-char (point-min))
  (or
   ;; Valid signature.
   (save-excursion
     (when (re-search-forward "^Good signature from user \"" nil t)
       (goto-char (match-beginning 0))
       (let* ((start (point))
              (trusted 
               (save-excursion
                 (goto-char (point-min))
                 ;; Is signature trusted?
                 (if (re-search-forward "^WARNING:  Because this public key is not certified" nil t)
                     'good-no-confidence
                   'good)))
              (msg (progn (forward-line 2)
                          (buffer-substring-no-properties start (point))))
              (message (if (eq trusted 'good)
                           msg
                         (concat msg "WARNING: This key is not certified by a trusted signature
.\n"))))
         (cons trusted message))))
   ;; Invalid signature.
   (save-excursion
     (when (re-search-forward "^Bad signature from user \"" nil t)
       (goto-char (match-beginning 0))
       (let ((start (point)))
         (forward-line 2)
         (cons 'bad
               (buffer-substring-no-properties start (point))))))
   ;; Unknown public key.
   (save-excursion
     (when (re-search-forward "Key matching expected Key ID [0-9A-E]\\{8,8\\} not found" nil t)
       (cons 'unknown
             (concat "Can't check signature integrity.\n"
                     (buffer-substring-no-properties
                      (match-beginning 0) (match-end 0))
                     ".\n"))))
   ;; Unknown error.
   (cons 'unknown "An internal error occured.\n")))

Now the verification function:

(defun rfc2015-pgp-mc-verify-buffer (message signature)
  "Check string MESSAGE against string SIGNATURE using PGP.

On success, returns a pair (QUALITY . STRING) where QUALITY is one of
the symbols `good', `good-no-confidence' (signature is good, but
there's not much confidence in the public key), `bad', `unknown'
(public key isn't available) and STRING is an explanatory message.

In case of a fatal error, `nil' is returned."
  (let ((message-file
         (concat (temp-directory) "/" (make-temp-name "gnusmsg")))
        (signature-file 
         (concat (temp-directory) "/" (make-temp-name "gnussig")))
        (buffer (get-buffer-create mc-buffer-name))
        args)
    (unwind-protect
        (progn
          ;; Save message.
          (with-temp-file message-file
            (insert message)
            (rfc2015-normalize-buffer))
          ;; Save signature.
          (with-temp-file signature-file
            (insert signature))

          ;; Prepare call to PGP.
          (setq args `(,signature-file ,message-file "+verbose=1" 
                                       "+batchmode" "+language=en"))
          (if mc-pgp-alternate-keyring
              (setq args `(,@args ,(format "+pubring=%s"
                                           mc-pgp-alternate-keyring))))
          (with-temp-buffer
            (rfc2015-pgp-mc-process
             nil mc-pgp-path args 
             'rfc2015-pgp-mc-verify-parser buffer)))
      ;; Always delete temporary files.
      (ignore-errors (delete-file message-file))
      (ignore-errors (delete-file signature-file)))))

* Information on signature qualtiy is missing.

Key management is one of the most critical issues with cryptography.
Currently, Mailcrypt doesn't give to the user much information on
the quality of a signature it encounters, which is a major deficiency
(IMHO).  The above functions try to address this as far as the signature
verification process is concerned, distinguishing good signatures, good
signatures by an untrusted key, and bad signatures.  Similar things have
to be implemented for the decryption process as well (which might have to
deal with a signature, too). (For MIME/PGP support, I'm only interested
in appropriate signature quality indication from the backend functions.
My Gnus extension will provide its own user interface anyway.)



These are the issues I'd like to discuss.  I think it would be great if
some upcoming release of Mailcrypt solved these problems.  (Of course,
I could distribute the functions along with my Gnus extension, but this
might become cumbersome as Mailcrypt development continues and changes
the internal interfaces.)  I'm glad if I can answer any questions,
and feel free to use the code if you think it might be useful.

Regards,
Florian

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Request: Mails that are encrypted and/or signed using MIME
  2000-01-18 21:31 ` Request: Mails that are encrypted and/or signed using MIME Florian Weimer
@ 2000-01-19 22:43   ` Brian May
  2000-01-19 23:35     ` Bruce Stephens
  0 siblings, 1 reply; 3+ messages in thread
From: Brian May @ 2000-01-19 22:43 UTC (permalink / raw)


>>>>> "Florian" == Florian Weimer <fw@s.netic.de> writes:

    Florian> Jonas Steverud <d4jonas@dtek.chalmers.se> writes:
    >> I currently tries to write some code that would make Gnus and
    >> Mailcrypt aware of PGP-MIME.
    >> 
    >> 1. I need examples. Could someone send me one mail encrypted
    >> and one mail signed with the Subject "PGP-MIME test"?

    Florian> If you're doing MIME-PGP development, it's quite handy to
    Florian> have mutt installed. ;) RFC 2015 contains some examples
    Florian> as well.

I will second that.. mutts handling of MIME-PGP seems to be
excellent.

If you need anyone to test any code, then please let me know...

As far as I am concerned, MIME-PGP support is currently the most
important feature lacking from Gnus/Mailcrypt.
-- 
Brian May <bmay@csse.monash.edu.au>



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Request: Mails that are encrypted and/or signed using MIME
  2000-01-19 22:43   ` Brian May
@ 2000-01-19 23:35     ` Bruce Stephens
  0 siblings, 0 replies; 3+ messages in thread
From: Bruce Stephens @ 2000-01-19 23:35 UTC (permalink / raw)


Brian May <bmay@csse.monash.edu.au> writes:

[...]

> I will second that.. mutts handling of MIME-PGP seems to be
> excellent.

exmh is OK for simple stuff, too.

> If you need anyone to test any code, then please let me know...
> 
> As far as I am concerned, MIME-PGP support is currently the most
> important feature lacking from Gnus/Mailcrypt.

I'd like S/MIME, too (using the stuff in openssl 0.9.5, not yet
released).  PGP/MIME support will help this too, I suspect.  Probably
the same Gnus features required by these could be used for other
purposes, too.



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2000-01-19 23:35 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <wtnvh4rgy4e.fsf@licia.dtek.chalmers.se>
2000-01-18 21:31 ` Request: Mails that are encrypted and/or signed using MIME Florian Weimer
2000-01-19 22:43   ` Brian May
2000-01-19 23:35     ` Bruce Stephens

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).