2000-10-30 08:38:12 ShengHuo ZHU <zsh@cs.rochester.edu>
[gnus] / lisp / mml2015.el
1 ;;; mml2015.el --- MIME Security with Pretty Good Privacy (PGP)
2 ;; Copyright (C) 2000 Free Software Foundation, Inc.
3
4 ;; Author: Shenghuo Zhu <zsh@cs.rochester.edu>
5 ;; Keywords: PGP MIME MML
6
7 ;; This file is part of GNU Emacs.
8
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.
13
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.
18
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.
23
24 ;;; Commentary:
25
26 ;; Installation: put the following statements in ~/.gnus:
27 ;;    (require 'mml2015)
28 ;;    (require 'gnus-art)
29 ;;    (mml2015-setup)
30 ;; You may have to make sure that the directory where this file lives
31 ;; is mentioned in `load-path'.
32 ;; 
33 ;; Insert an attribute, postprocess=pgp-sign (or pgp-encrypt), into
34 ;; the mml tag to be signed (or encrypted).
35
36 ;;; Code:
37
38 (eval-when-compile (require 'cl))
39 (require 'mm-decode)
40
41 (defvar mml2015-decrypt-function 'mailcrypt-decrypt)
42 (defvar mml2015-verify-function 'mailcrypt-verify)
43 (defvar mml2015-encrypt-function 'mml2015-mailcrypt-encrypt)
44 (defvar mml2015-sign-function 'mml2015-mailcrypt-sign)
45
46 ;;;###autoload
47 (defun mml2015-decrypt (handle ctl)
48   (let (child handles result)
49     (unless (setq child (mm-find-part-by-type (cdr handle) 
50                                               "application/octet-stream"))
51       (error "Corrupted pgp-encrypted part."))
52     (with-temp-buffer
53       (mm-insert-part child)
54       (setq result (funcall mml2015-decrypt-function))
55       (unless (car result)
56         (error "Decrypting error."))
57       (setq handles (mm-dissect-buffer t)))
58     (mm-destroy-parts handle)
59     (if (listp (car handles))
60         handles
61       (list handles))))
62
63 (defun mml2015-fix-micalg (alg)
64   (if (and alg (string-match "^pgp-" alg))
65       (substring alg (match-end 0))
66     alg))
67
68 ;;;###autoload
69 (defun mml2015-verify (handle ctl)
70   (let (part)
71     (unless (setq part (mm-find-raw-part-by-type 
72                          ctl "application/pgp-signature" t))
73       (error "Corrupted pgp-signature part."))
74     (with-temp-buffer
75       (insert "-----BEGIN PGP SIGNED MESSAGE-----\n")
76       (insert (format "Hash: %s\n\n" 
77                       (or (mml2015-fix-micalg
78                            (mail-content-type-get ctl 'micalg))
79                           "SHA1")))
80       (insert part)
81       (goto-char (point-max))
82       (unless (bolp)
83         (insert "\n"))
84       (unless (setq part (mm-find-part-by-type 
85                            (cdr handle) "application/pgp-signature"))
86         (error "Corrupted pgp-signature part."))
87       (mm-insert-part part)
88       (unless (funcall mml2015-verify-function)
89         (error "Verify error.")))))
90
91 (eval-and-compile
92   (autoload 'mc-encrypt-generic "mc-toplev")
93   (autoload 'mc-cleanup-recipient-headers "mc-toplev")
94   (autoload 'mc-sign-generic "mc-toplev"))
95
96 (eval-when-compile
97   (defvar mc-default-scheme)
98   (defvar mc-schemes))
99
100 (defun mml2015-mailcrypt-sign (cont)
101   (mc-sign-generic (message-options-get 'message-sender)
102                    nil nil nil nil)
103   (let ((boundary 
104          (funcall mml-boundary-function (incf mml-multipart-number)))
105         (scheme-alist (funcall (or mc-default-scheme 
106                                    (cdr (car mc-schemes)))))
107         hash)
108     (goto-char (point-min))
109     (unless (re-search-forward (cdr (assq 'signed-begin-line scheme-alist)))
110       (error "Cannot find signed begin line." ))
111     (goto-char (match-beginning 0))
112     (forward-line 1)
113     (unless (looking-at "Hash:[ \t]*\\([a-zA-Z0-9]+\\)")
114       (error "Cannot not find PGP hash." ))
115     (setq hash (match-string 1))
116     (unless (re-search-forward "^$" nil t)
117       (error "Cannot not find PGP message." ))
118     (forward-line 1)
119     (delete-region (point-min) (point))
120     (insert (format "Content-Type: multipart/signed; boundary=\"%s\";\n"
121                     boundary))
122     (insert (format "\tmicalg=pgp-%s; protocol=\"application/pgp-signature\"\n"
123                     hash))
124     (insert "\n")
125     (insert (format "--%s\n" boundary))
126     (unless (re-search-forward (cdr (assq 'signed-end-line scheme-alist)))
127       (error "Cannot find signature part." ))
128     (goto-char (match-beginning 0))
129     (unless (re-search-backward "^-+BEGIN" nil t)
130       (error "Cannot find signature part." ))
131     (goto-char (match-beginning 0))
132     (insert (format "--%s\n" boundary))
133     (insert "Content-Type: application/pgp-signature\n\n")
134     (goto-char (point-max))
135     (insert (format "--%s--\n" boundary))
136     (goto-char (point-max))))
137
138
139 (defun mml2015-mailcrypt-encrypt (cont)
140   (mc-encrypt-generic 
141    (or (message-options-get 'message-recipients)
142        (message-options-set 'message-recipients
143                             (mc-cleanup-recipient-headers 
144                              (read-string "Recipients: ")))))
145   (let ((boundary 
146          (funcall mml-boundary-function (incf mml-multipart-number))))
147     (goto-char (point-min))
148     (insert (format "Content-Type: multipart/encrypted; boundary=\"%s\";\n"
149                     boundary))
150     (insert "\tprotocol=\"application/pgp-encrypted\"\n\n")
151     (insert (format "--%s\n" boundary))
152     (insert "Content-Type: application/pgp-encrypted\n\n")
153     (insert "Version: 1\n\n")
154     (insert (format "--%s\n" boundary))
155     (insert "Content-Type: application/octet-stream\n\n")
156     (goto-char (point-max))
157     (insert (format "--%s--\n" boundary))
158     (goto-char (point-max))))
159
160 ;;;###autoload
161 (defun mml2015-encrypt (cont)
162   (funcall mml2015-encrypt-function cont))
163
164 ;;;###autoload
165 (defun mml2015-sign (cont)
166   (funcall mml2015-sign-function cont))
167
168 ;;;###autoload
169 (defun mml2015-setup ()
170   )
171
172 (provide 'mml2015)
173
174 ;;; mml2015.el ends here