1 ;;; mml2015.el --- MIME Security with Pretty Good Privacy (PGP)
2 ;; Copyright (C) 2000 Free Software Foundation, Inc.
4 ;; Author: Shenghuo Zhu <zsh@cs.rochester.edu>
5 ;; Keywords: PGP MIME MML
7 ;; This file is part of GNU Emacs.
9 ;; GNU Emacs is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 2, or (at your
12 ;; option) any later version.
14 ;; GNU Emacs is distributed in the hope that it will be useful, but
15 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 ;; General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING. If not, write to the
21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
26 ;; Installation: put the following statements in ~/.gnus:
28 ;; (require 'gnus-art)
30 ;; You may have to make sure that the directory where this file lives
31 ;; is mentioned in `load-path'.
33 ;; Insert an attribute, postprocess=pgp-sign (or pgp-encrypt), into
34 ;; the mml tag to be signed (or encrypted).
38 (defvar mml2015-decrypt-function 'mailcrypt-decrypt)
39 (defvar mml2015-verify-function 'mailcrypt-verify)
42 (defun mml2015-decrypt (handle)
45 ((setq child (mm-find-part-by-type (cdr handle)
46 "application/octet-stream"))
49 (mm-insert-part child)
50 (setq result (funcall mml2015-decrypt-function))
52 (error "Decrypting error."))
53 (setq handles (mm-dissect-buffer t)))
54 (setq gnus-article-mime-handles
55 (append (if (listp (car gnus-article-mime-handles))
56 gnus-article-mime-handles
57 (list gnus-article-mime-handles))
58 (if (listp (car handles))
61 (gnus-mime-display-part handles)))
63 (if (y-or-n-p "Corrupted pgp-encrypted part. Abort?" )
64 (error "Corrupted pgp-encrypted part.")
65 (gnus-mime-display-mixed (cdr handle)))))))
67 ;; FIXME: mm-dissect-buffer loses information of micalg and the
68 ;; original header of signed part.
70 (defun mml2015-verify (handle)
71 (if (y-or-n-p "Verify signed part?" )
72 (let (child result hash)
74 (unless (setq child (mm-find-part-by-type
75 (cdr handle) "application/pgp-signature" t))
76 (error "Corrupted pgp-signature part."))
77 (insert "-----BEGIN PGP SIGNED MESSAGE-----\n")
78 (insert (format "Hash: %s\n\n" (read-string "Hash: " "SHA1")))
79 (mm-insert-part child)
80 (goto-char (point-max))
83 (unless (setq child (mm-find-part-by-type
84 (cdr handle) "application/pgp-signature"))
85 (error "Corrupted pgp-signature part."))
86 (mm-insert-part child)
87 (setq result (funcall mml2015-verify-function))
89 (error "Verify error.")))))
90 (gnus-mime-display-part
92 (cdr handle) "application/pgp-signature" t)))
94 (defvar mml2015-mailcrypt-prefix 0)
97 (defun mml2015-mailcrypt-sign (cont)
98 (mailcrypt-sign mml2015-mailcrypt-prefix)
100 (funcall mml-boundary-function (incf mml-multipart-number)))
101 (scheme-alist (funcall (or mc-default-scheme
102 (cdr (car mc-schemes)))))
104 (goto-char (point-min))
105 (unless (re-search-forward (cdr (assq 'signed-begin-line scheme-alist)))
106 (error "Cannot find signed begin line." ))
107 (goto-char (match-beginning 0))
109 (unless (looking-at "Hash:[ \t]*\\([a-zA-Z0-9]+\\)")
110 (error "Cannot not find PGP hash." ))
111 (setq hash (match-string 1))
112 (unless (re-search-forward "^$" nil t)
113 (error "Cannot not find PGP message." ))
115 (delete-region (point-min) (point))
116 (insert (format "Content-Type: multipart/signed; boundary=\"%s\";\n"
118 (insert (format "\tmicalg=pgp-%s; protocol=\"application/pgp-signature\"\n"
121 (insert (format "--%s\n" boundary))
122 (unless (re-search-forward (cdr (assq 'signed-end-line scheme-alist)))
123 (error "Cannot find signature part." ))
124 (goto-char (match-beginning 0))
125 (unless (re-search-backward "^-+BEGIN" nil t)
126 (error "Cannot find signature part." ))
127 (goto-char (match-beginning 0))
128 (insert (format "--%s\n" boundary))
129 (insert "Content-Type: application/pgp-signature\n\n")
130 (goto-char (point-max))
131 (insert (format "--%s--\n" boundary))
132 (goto-char (point-max))))
135 (defun mml2015-mailcrypt-encrypt (cont)
137 ;; You have to input the receiptant.
138 (mailcrypt-encrypt mml2015-mailcrypt-prefix)
140 (funcall mml-boundary-function (incf mml-multipart-number))))
141 (goto-char (point-min))
142 (insert (format "Content-Type: multipart/encrypted; boundary=\"%s\";\n"
144 (insert "\tprotocol=\"application/pgp-encrypted\"\n\n")
145 (insert (format "--%s\n" boundary))
146 (insert "Content-Type: application/pgp-encrypted\n\n")
147 (insert "Version: 1\n\n")
148 (insert (format "--%s\n" boundary))
149 (insert "Content-Type: application/octet-stream\n\n")
150 (goto-char (point-max))
151 (insert (format "--%s--\n" boundary))
152 (goto-char (point-max))))
155 (defun mml2015-setup ()
156 (setq mml-generate-mime-postprocess-function 'mml-postprocess)
157 ; (push '("multipart/signed" . mml2015-verify)
158 ; gnus-mime-multipart-functions)
159 (push '("multipart/encrypted" . mml2015-decrypt)
160 gnus-mime-multipart-functions))
164 ;;; mml2015.el ends here