|
|
1.1 root 1: Subject: Using PGP with Emacs Rmail
2: Date: 9 Oct 1992 14:39:10 GMT
3: From: [email protected] (Robert Anderson)
4: Lines: 319
5:
6:
7: PGP with GNU Emacs Rmail Revision 1
8: ------------------------ October 2, 1992
9:
10: Here are some notes on using PGP 2.0 on a Unix platform, using
11: the Gnu Emacs "rmail" package to send and receive mail.
12:
13: First, it is inherently insecure to use PGP, or any encryption
14: program, on a multi-user system. There are just too many ways
15: for the system operators, or even ordinary users, to spy on what
16: you are doing. However, many people are only able to send and
17: receive mail on such machines, and it still may be useful for
18: them to be able to use PGP. The security is nowhere near as
19: great as it would be on a laptop PC which you keep chained to
20: your wrist at all times, but it should be good enough for casual
21: privacy.
22:
23:
24: FILTERING
25:
26:
27: PGP 2.0 has a "filter" mode invoked with the "-f" switch. Many
28: Unix mail reading tools have the ability to pass messages, or
29: portions of messages, through filter programs, returning the
30: result to the editing buffer. This general approach is what I
31: will discuss, as it applies specifically to Gnu Emacs. (I use
32: Gnu Emacs version 18.55.3, of Friday, July 26, 1991. But most of
33: the features discussed here should apply to almost any current
34: Gnu Emacs.)
35:
36: The Emacs command to pass a portion of a buffer through a filter
37: is "shell-command-on-region". On my machine, it is mapped to the
38: key M-|, which I activate by typing the escape key and then the
39: vertical bar key. By giving a prefix argument to this function,
40: which I do by typing control-U just before the M-|, the function
41: replaces the text in the buffer with the output of the filter.
42:
43:
44: ENCRYPTION
45:
46:
47: To encrypt a message, then, I first compose the message using the
48: "mail" function of Emacs. Then I set the Emacs "region" to
49: contain the message text (but not the headers at the top of the
50: message). This I do by the function "mark-whole-buffer", which
51: is mapped to control-X H on my system, then advancing the "point"
52: (cursor) down from the top of the page using control-N until I am
53: at the first line of the message I am sending. (This is the line
54: just beyond the separator line which Emacs creates called "--text
55: follows this line--".) This is how a sample message buffer will
56: look at this point:
57:
58: To: [email protected]
59: Subject: Test of PGP with Emacs
60: --text follows this line--
61: Dear XYZ:
62: I hope you enjoy this encrypted PGP message.
63: Love, ABC.
64:
65: (The cursor is on the "D" of "Dear", and the "mark", which you
66: can't see, is at the end of the buffer.)
67:
68: With the region properly set to enclose the message text, I now
69: want to filter the message through PGP. The general idea is to
70: use control-U followed by M-|, but a problem arises if I do this.
71:
72: PGP, when run in filter mode, produces encrypted or decrypted
73: output based on its input. But in addition, it also produces a
74: few informational messages, such as the version information that
75: is printed for every run. PGP goes to some trouble to separate
76: these two kinds of output, putting the encrypted output to
77: "standard out", and the informational messages to "standard
78: error". Unfortunately, Emacs undoes PGP's efforts, combining
79: standard out and standard error into one stream. The result is
80: that using this Emacs filter function brings back not just the
81: encrypted message, but also the PGP informational messages. This
82: is what the output looks like:
83:
84: To: [email protected]
85: Subject: Test of PGP with Emacs
86: --text follows this line--
87: Pretty Good Privacy 2.0 - Public-key encryption for the masses.
88: (c) 1990-1992 Philip Zimmermann, Phil's Pretty Good Software. 2 Sep 92
89: Date: 1992/10/02 22:10 GMT
90:
91:
92: Recipient's public key will be used to encrypt.
93: Key for user ID: XYZ
94: 382-bit key, Key ID 5E7ADD, created 1992/09/27
95: .-----BEGIN PGP MESSAGE-----
96: Version: 2.0
97:
98: hDwC2RA+W2deet0BAX4iI1FcS9qz57OA2pd3T/tr7wcwzW5mHocwvlND+Un0aYac
99: Kq4qwjxpxr5rY/ABEAymAAAAWnZfbPeqdeXZGkFqCUny9tnVuew9JfSkzaGVIbpS
100: aTOxzNcWP7hgHVCW4FUyFgCUmGGBgIbbSUwisrQsMo0lUH4UxUjjKLYav+RGs8Z6
101: 9SG3RzAnnpEdAhSSbQ==
102: =zAPP
103: -----END PGP MESSAGE-----
104:
105: This can be cleaned up manually by deleting all the characters
106: from the "Pretty Good Privacy" header down to the "." just before
107: "-----BEGIN PGP MESSAGE-----". But this is tedious. To avoid
108: this problem, I created a very simple shell script which I use to
109: run PGP. It looks like this:
110:
111: :
112: exec pgp $* 2>/dev/null
113:
114: I call this script "pgpq". The first line is just a colon, and
115: the second line just remaps standard error to /dev/null, causing
116: it to disappear, and passes all arguments along to PGP. The
117: result is that PGP's informational messages do not appear back in
118: the Emacs buffer when I run it as "pgpq".
119:
120: With this script, I can encrypt messages to be sent to other
121: people within Emacs. First I set the region with control-X H
122: followed by a few control-N's. Then I type control-U M-|. Emacs
123: prompts with the query "Shell command on region:". For
124: encryption of a message to user XYZ, I type:
125:
126: pgpq -fea XYZ
127:
128: The command is given as "pgpq" to get a cleaner output as
129: described above. The option letter "f" means to use filter mode;
130: "e" means to encrypt, and "a" means to get ASCII output. The
131: user name comes next. (For information on how to also sign a
132: message, see below.) The output of this command, for the example
133: above, looks like:
134:
135: To: [email protected]
136: Subject: Test of PGP with Emacs
137: --text follows this line--
138: -----BEGIN PGP MESSAGE-----
139: Version: 2.0
140:
141: hDwC2RA+W2deet0BAX4omw4gByFkFaHFko7qPBVq1Yh7EpgHnbZ5EebqFiQjr61I
142: Bz6t1tQZSloNJ4KhTYOmAAAAWi2Ja/oM0LvEi9fumi4IdKDQJ44ihatrM0AEYUi5
143: CVJjj5YCuQUl5XT/s5cG+Gu6R5fTPtmQ94iBmIMUjOw+yEcCkIa5B87PmJJDusMC
144: f1K8VWsc2A2oAJIWqg==
145: =uvLF
146: -----END PGP MESSAGE-----
147:
148: Assuming user XYZ is on my key ring, the text of the message in
149: my buffer has been replaced by the encrypted form of the text. I
150: can then send the message on its way as usual.
151:
152:
153: DECRYPTION
154:
155:
156: I decrypt my incoming mail "in place", substituting the decrypted
157: text in place of the encrypted message. To do this using the
158: Emacs rmail package, the incoming mail message must be made
159: writable, using the "rmail-edit-current-message" function, mapped
160: to the letter "w" on my system. Then the steps below can be used
161: to decrypt the message. Afterwards, the "rmail-cease-edit"
162: function, mapped to "control-C control-C" on my system, is used
163: to "write back" the decrypted message. (If you like, after
164: reading the decrypted message but before writing it back you can
165: use "rmail-abort-edit", "control-C control-]" on my system, to
166: discard your changes and leave the encrypted message in place.)
167:
168: Decrypting an incoming message can be done in a similar manner to
169: encryption. First I set the Emacs "region" to enclose the PGP
170: portion of the message. Then it is piped through the "pgpq"
171: filter to get the decrypted result.
172:
173: However, the new element in the case of decryption is the need to
174: enter a pass phrase to activate your secret key. I solve this by
175: using the "PGPPASS" environment variable. If PGP is trying to
176: read your secret key and this environment variable exists, it
177: will try to use the value of this variable as your pass phrase.
178:
179: So, to do decryption, it is necessary to set this environment
180: variable before running the filter. This could be done by
181: setting the variable before Emacs is started, so it will inherit
182: the value from the shell. However, I use the Emacs variable
183: "process-environment", which contains the environment variables
184: and their values which are passed to sub-shells and filter
185: processes. I wrote a few small Emacs functions to make it easier
186: to set and clear PGPPASS from the "process-environment" variable.
187: They are:
188:
189:
190: ; PGP support
191: ; Strip from list-of-strings l, any string which matches str
192: (defun stripstrlist (l str)
193: (cond (l (cond ((string-match str (car l))
194: (stripstrlist (cdr l) str))
195: (t (cons (car l) (stripstrlist (cdr l) str)))))))
196:
197: ; Set PGPPASS environment variable from argument
198: (defun pgp-passphrase (arg)
199: (interactive "sPGP pass phrase: ")
200: (setq process-environment
201: (cons (concat "PGPPASS=" arg)
202: (stripstrlist process-environment "^PGPPASS="))))
203:
204: ; Clear PGPPASS environment variable
205: (defun clear-pgp-passphrase ()
206: (interactive)
207: (setq process-environment (stripstrlist process-environment "^PGPPASS=")))
208:
209:
210: I put this code in my Emacs startup file, ".emacs". To use it, I
211: do "M-X pgp-passphrase" to set the pass phrase. It prompts me,
212: and I enter the pass phrase I use. Generally, I set it once and
213: leave it set for the duration of an Emacs session, but I also can
214: use "M-X clear-pgp-passphrase" to clear the pass phrase from the
215: process-environment variable.
216:
217: Having set the pass phrase, decryption of incoming messages is
218: straightforward. I set the region, do control-U M-X, and when
219: Emacs prompts with "Shell command on region:" I reply:
220:
221: pgpq -f
222:
223: This causes the message to be decrypted, and the output to be put
224: back in the buffer, overwriting the encrypted data. Here is the
225: buffer before decryption:
226:
227: To: [email protected]
228: Subject: Test of PGP with Emacs
229: --text follows this line--
230: -----BEGIN PGP MESSAGE-----
231: Version: 2.0
232:
233: hDwC2RA+W2deet0BAX4omw4gByFkFaHFko7qPBVq1Yh7EpgHnbZ5EebqFiQjr61I
234: Bz6t1tQZSloNJ4KhTYOmAAAAWi2Ja/oM0LvEi9fumi4IdKDQJ44ihatrM0AEYUi5
235: CVJjj5YCuQUl5XT/s5cG+Gu6R5fTPtmQ94iBmIMUjOw+yEcCkIa5B87PmJJDusMC
236: f1K8VWsc2A2oAJIWqg==
237: =uvLF
238: -----END PGP MESSAGE-----
239:
240: And here it is after setting the PGP pass phrase, putting the
241: region around the "PGP MESSAGE" part, and running "pgpq -f":
242:
243: To: [email protected]
244: Subject: Test of PGP with Emacs
245: --text follows this line--
246: Dear XYZ:
247: I hope you enjoy this encrypted PGP message.
248: Love, ABC.
249:
250:
251: SIGNING AND ENCRYPTING
252:
253:
254: The technique of setting the PGPPASS environment variable also
255: allows you to sign your outgoing messages along with encrypting
256: them. Use the "M-X pgp-passphrase" command to set your PGP pass
257: phrase, then encrypt the outgoing message with the command:
258:
259: pgpq -safe XYZ
260:
261: This tells PGP to sign, ascii-encode, use filter mode, and
262: encrypt the output for user XYZ.
263:
264:
265: WHEN THINGS GO WRONG
266:
267:
268: Once in a while, you will pass a message through PGP for
269: encryption or decryption, and instead of getting replacement
270: text, your message simply vanishes. Don't panic. The Emacs
271: "undo" function, mapped to control-X U on my system, can be used
272: to recover your message.
273:
274: Probably what happened was that PGP had some problem in either
275: encrypting or decrypting the message. Maybe you misspelled the
276: User ID so that it wasn't found on the keyring. Or maybe an
277: incoming message was mistakenly encrypted in someone else's key,
278: or was in a mode which PGP can't handle when used as a filter
279: (see below).
280:
281: The best way to diagnose the problem is to first bring the
282: message back with "undo" as just described, then to re-run the
283: filter command, but to use "pgp" rather than "pgpq". This will
284: cause the PGP informational messages to be put into your buffer.
285: Usually these will make clear what the problem is. Give another
286: "undo" to get back to the original message after reading this
287: output.
288:
289:
290: PROBLEMS AND LIMITATIONS
291:
292:
293: There are some problems associated with using PGP in this mode.
294: Probably the biggest is that in decrypting, the informational
295: messages are thrown away. This means that you lose information
296: about any incoming signed messages as far as whether the
297: signatures are valid or not. In fact, you won't even know that
298: the messages are signed.
299:
300: The pgpq script could be enhanced to pipe standard error to some
301: filter program that could look at the informational output from
302: PGP and print a warning message (which would appear back in the
303: buffer along with the decrypted message) if, say, an invalid
304: signature was found. More work is needed in this area.
305:
306: Another problem arises if PGP is used with conventional
307: encryption (using the -c flag). Conventional encryption prompts
308: for a pass phrase, but it does not check the PGPPASS environment
309: variable, or any other such variable. At present, conventional
310: encryption and decryption cannot be done in filter mode under
311: Emacs.
312:
313: Any other features of PGP which would require interaction with
314: the user, such as decrypting a key and trying to add it to the
315: key ring, will also not work in this filter mode. The test cases
316: which I have tried work about as well as they can (e.g. when
317: decrypting a key in filter mode, PGP shows the contents of the
318: key but doesn't ask if it should be added to your key ring), but
319: for some of these functions you will have to fire up PGP outside
320: of Emacs.
321: --
322: ------------
323: Bob Anderson
324: [email protected]
325:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.