1 ;;; epg.el --- the EasyPG library
2 ;; Copyright (C) 1999, 2000, 2002, 2003, 2004,
3 ;; 2005, 2006 Free Software Foundation, Inc.
4 ;; Copyright (C) 2006 Daiki Ueno
6 ;; Author: Daiki Ueno <ueno@unixuser.org>
7 ;; Keywords: PGP, GnuPG
9 ;; This file is part of EasyPG.
11 ;; This program is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
16 ;; This program is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 ;; Boston, MA 02110-1301, USA.
31 (defcustom epg-gpg-program "gpg"
32 "The `gpg' executable."
36 (defvar epg-user-id nil
37 "GnuPG ID of your default identity.")
39 (defvar epg-user-id-alist nil
40 "An alist mapping from key ID to user ID.")
42 (defvar epg-read-point nil)
43 (defvar epg-pending-status-list nil)
44 (defvar epg-key-id nil)
45 (defvar epg-context nil)
46 (defvar epg-debug nil)
48 ;; from gnupg/include/cipher.h
49 (defconst epg-cipher-algorithm-alist
61 ;; from gnupg/include/cipher.h
62 (defconst epg-pubkey-algorithm-alist
70 ;; from gnupg/include/cipher.h
71 (defconst epg-digest-algorithm-alist
79 ;; from gnupg/include/cipher.h
80 (defconst epg-compress-algorithm-alist
86 (defvar epg-key-validity-alist
99 (defvar epg-key-capablity-alist
103 (?a . authentication)))
105 (defvar epg-prompt-alist nil)
107 (defun epg-make-data-from-file (file)
108 "Make a data object from FILE."
111 (defun epg-make-data-from-string (string)
112 "Make a data object from STRING."
115 (defun epg-data-file (data)
116 "Return the file of DATA."
119 (defun epg-data-string (data)
120 "Return the string of DATA."
123 (defun epg-make-context (&optional protocol armor textmode include-certs)
124 "Return a context object."
125 (vector protocol armor textmode include-certs
126 #'epg-passphrase-callback-function
127 #'epg-progress-callback-function
130 (defun epg-context-protocol (context)
131 "Return the protocol used within the context."
134 (defun epg-context-armor (context)
135 "Return t if the output shouled be ASCII armored in the CONTEXT context."
138 (defun epg-context-textmode (context)
139 "Return t if canonical text mode should be used in the CONTEXT context."
142 (defun epg-context-include-certs (context)
143 "Return how many certificates should be included in an S/MIME signed
147 (defun epg-context-passphrase-callback (context)
148 "Return the function used to query passphrase."
151 (defun epg-context-progress-callback (context)
152 "Return the function which handles progress update."
155 (defun epg-context-signers (context)
156 "Return the list of key-id for singning."
159 (defun epg-context-process (context)
160 "Return the process object of `epg-gpg-program'.
161 This function is for internal use only."
164 (defun epg-context-output-file (context)
165 "Return the output file of `epg-gpg-program'.
166 This function is for internal use only."
169 (defun epg-context-result (context)
170 "Return the result of the previous cryptographic operation."
173 (defun epg-context-set-protocol (context protocol)
174 "Set the protocol used within the context."
175 (aset context 0 protocol))
177 (defun epg-context-set-armor (context armor)
178 "Specify if the output shouled be ASCII armored in the CONTEXT context."
179 (aset context 1 armor))
181 (defun epg-context-set-textmode (context textmode)
182 "Specify if canonical text mode should be used in the CONTEXT context."
183 (aset context 2 textmode))
185 (defun epg-context-set-include-certs (context include-certs)
186 "Set how many certificates should be included in an S/MIME signed message."
187 (aset context 3 include-certs))
189 (defun epg-context-set-passphrase-callback (context
191 "Set the function used to query passphrase."
192 (aset context 4 passphrase-callback))
194 (defun epg-context-set-progress-callback (context progress-callback)
195 "Set the function which handles progress update."
196 (aset context 5 progress-callback))
198 (defun epg-context-set-signers (context signers)
199 "Set the list of key-id for singning."
200 (aset context 6 signers))
202 (defun epg-context-set-process (context process)
203 "Set the process object of `epg-gpg-program'.
204 This function is for internal use only."
205 (aset context 7 process))
207 (defun epg-context-set-output-file (context output-file)
208 "Set the output file of `epg-gpg-program'.
209 This function is for internal use only."
210 (aset context 8 output-file))
212 (defun epg-context-set-result (context result)
213 "Set the result of the previous cryptographic operation."
214 (aset context 9 result))
216 (defun epg-make-signature (status key-id user-id)
217 "Return a signature object."
218 (vector status key-id user-id nil nil))
220 (defun epg-signature-status (signature)
221 "Return the status code of SIGNATURE."
224 (defun epg-signature-key-id (signature)
225 "Return the key-id of SIGNATURE."
228 (defun epg-signature-user-id (signature)
229 "Return the user-id of SIGNATURE."
232 (defun epg-signature-validity (signature)
233 "Return the validity of SIGNATURE."
236 (defun epg-signature-fingerprint (signature)
237 "Return the fingerprint of SIGNATURE."
240 (defun epg-signature-set-status (signature status)
241 "Set the status code of SIGNATURE."
242 (aset signature 0 status))
244 (defun epg-signature-set-key-id (signature key-id)
245 "Set the key-id of SIGNATURE."
246 (aset signature 1 key-id))
248 (defun epg-signature-set-user-id (signature user-id)
249 "Set the user-id of SIGNATURE."
250 (aset signature 2 user-id))
252 (defun epg-signature-set-validity (signature validity)
253 "Set the validity of SIGNATURE."
254 (aset signature 3 validity))
256 (defun epg-signature-set-fingerprint (signature fingerprint)
257 "Set the fingerprint of SIGNATURE."
258 (aset signature 4 fingerprint))
260 (defun epg-make-key (owner-trust)
261 "Return a key object."
262 (vector owner-trust nil nil))
264 (defun epg-key-owner-trust (key)
265 "Return the owner trust of KEY."
268 (defun epg-key-sub-key-list (key)
269 "Return the sub key list of KEY."
272 (defun epg-key-user-id-list (key)
273 "Return the user ID list of KEY."
276 (defun epg-key-set-sub-key-list (key sub-key-list)
277 "Set the sub key list of KEY."
278 (aset key 1 sub-key-list))
280 (defun epg-key-set-user-id-list (key user-id-list)
281 "Set the user ID list of KEY."
282 (aset key 2 user-id-list))
284 (defun epg-make-sub-key (validity capability secret algorithm length id
285 creation-time expiration-time)
286 "Return a sub key object."
287 (vector validity capability secret algorithm length id creation-time
288 expiration-time nil))
290 (defun epg-sub-key-validity (sub-key)
291 "Return the validity of SUB-KEY."
294 (defun epg-sub-key-capability (sub-key)
295 "Return the capability of SUB-KEY."
298 (defun epg-sub-key-secret (sub-key)
299 "Return non-nil if SUB-KEY is a secret key."
302 (defun epg-sub-key-algorithm (sub-key)
303 "Return the algorithm of SUB-KEY."
306 (defun epg-sub-key-length (sub-key)
307 "Return the length of SUB-KEY."
310 (defun epg-sub-key-id (sub-key)
311 "Return the ID of SUB-KEY."
314 (defun epg-sub-key-creation-time (sub-key)
315 "Return the creation time of SUB-KEY."
318 (defun epg-sub-key-expiration-time (sub-key)
319 "Return the expiration time of SUB-KEY."
322 (defun epg-sub-key-fingerprint (sub-key)
323 "Return the fingerprint of SUB-KEY."
326 (defun epg-sub-key-set-fingerprint (sub-key fingerprint)
327 "Set the fingerprint of SUB-KEY.
328 This function is for internal use only."
329 (aset sub-key 8 fingerprint))
331 (defun epg-make-user-id (validity name)
332 "Return a user ID object."
333 (vector validity name nil))
335 (defun epg-user-id-validity (user-id)
336 "Return the validity of USER-ID."
339 (defun epg-user-id-name (user-id)
340 "Return the name of USER-ID."
343 (defun epg-user-id-signature-list (user-id)
344 "Return the signature list of USER-ID."
347 (defun epg-user-id-set-signature-list (user-id signature-list)
348 "Set the signature list of USER-ID."
349 (aset user-id 2 signature-list))
351 (defun epg-context-result-for (context name)
352 (cdr (assq name (epg-context-result context))))
354 (defun epg-context-set-result-for (context name value)
355 (let* ((result (epg-context-result context))
356 (entry (assq name result)))
359 (epg-context-set-result context (cons (cons name value) result)))))
361 (defun epg-start (context args)
362 "Start `epg-gpg-program' in a subprocess with given ARGS."
363 (let* ((args (append (list "--no-tty"
366 (if (epg-context-armor context) '("--armor"))
367 (if (epg-context-textmode context) '("--textmode"))
368 (if (epg-context-output-file context)
369 (list "--output" (epg-context-output-file context)))
371 (coding-system-for-write 'binary)
372 process-connection-type
373 (orig-mode (default-file-modes))
374 (buffer (generate-new-buffer " *epg*"))
376 (with-current-buffer buffer
377 (make-local-variable 'epg-read-point)
378 (setq epg-read-point (point-min))
379 (make-local-variable 'epg-pending-status-list)
380 (setq epg-pending-status-list nil)
381 (make-local-variable 'epg-key-id)
382 (setq epg-key-id nil)
383 (make-local-variable 'epg-context)
384 (setq epg-context context))
387 (set-default-file-modes 448)
389 (apply #'start-process "epg" buffer epg-gpg-program args)))
390 (set-default-file-modes orig-mode))
391 (set-process-filter process #'epg-process-filter)
392 (epg-context-set-process context process)))
394 (defun epg-process-filter (process input)
397 (set-buffer (get-buffer-create " *epg-debug*"))
398 (goto-char (point-max))
400 (if (buffer-live-p (process-buffer process))
402 (set-buffer (process-buffer process))
403 (goto-char (point-max))
405 (goto-char epg-read-point)
407 (while (looking-at ".*\n") ;the input line is finished
409 (if (looking-at "\\[GNUPG:] \\([A-Z_]+\\) ?\\(.*\\)")
410 (let* ((status (match-string 1))
411 (string (match-string 2))
412 (symbol (intern-soft (concat "epg-status-" status))))
413 (if (member status epg-pending-status-list)
414 (setq epg-pending-status-list nil))
417 (funcall symbol process string)))))
419 (setq epg-read-point (point)))))
421 (defun epg-read-output (context)
423 (if (fboundp 'set-buffer-multibyte)
424 (set-buffer-multibyte nil))
425 (if (file-exists-p (epg-context-output-file context))
426 (let ((coding-system-for-read (if (epg-context-textmode context)
429 (insert-file-contents (epg-context-output-file context))
432 (defun epg-wait-for-status (context status-list)
433 (with-current-buffer (process-buffer (epg-context-process context))
434 (setq epg-pending-status-list status-list)
435 (while (and (eq (process-status (epg-context-process context)) 'run)
436 epg-pending-status-list)
437 (accept-process-output (epg-context-process context) 1))))
439 (defun epg-wait-for-completion (context)
440 (if (eq (process-status (epg-context-process context)) 'run)
441 (process-send-eof (epg-context-process context)))
442 (while (eq (process-status (epg-context-process context)) 'run)
443 ;; We can't use accept-process-output instead of sit-for here
444 ;; because it may cause an interrupt during the sentinel execution.
447 (defun epg-reset (context)
448 (if (and (epg-context-process context)
449 (buffer-live-p (process-buffer (epg-context-process context))))
450 (kill-buffer (process-buffer (epg-context-process context))))
451 (epg-context-set-process context nil))
453 (defun epg-delete-output-file (context)
454 (if (and (epg-context-output-file context)
455 (file-exists-p (epg-context-output-file context)))
456 (delete-file (epg-context-output-file context))))
458 (defun epg-status-USERID_HINT (process string)
459 (if (string-match "\\`\\([^ ]+\\) \\(.*\\)" string)
460 (let* ((key-id (match-string 1 string))
461 (user-id (match-string 2 string))
462 (entry (assoc key-id epg-user-id-alist)))
464 (setcdr entry user-id)
465 (setq epg-user-id-alist (cons (cons key-id user-id)
466 epg-user-id-alist))))))
468 (defun epg-status-NEED_PASSPHRASE (process string)
469 (if (string-match "\\`\\([^ ]+\\)" string)
470 (setq epg-key-id (match-string 1 string))))
472 (defun epg-status-NEED_PASSPHRASE_SYM (process string)
473 (setq epg-key-id 'SYM))
475 (defun epg-status-NEED_PASSPHRASE_PIN (process string)
476 (setq epg-key-id 'PIN))
478 (defun epg-status-GET_HIDDEN (process string)
480 (funcall (if (consp (epg-context-passphrase-callback epg-context))
481 (car (epg-context-passphrase-callback epg-context))
482 (epg-context-passphrase-callback epg-context))
484 (if (consp (epg-context-passphrase-callback epg-context))
485 (cdr (epg-context-passphrase-callback epg-context)))))
490 (setq string (concat passphrase "\n"))
491 (fillarray passphrase 0)
492 (setq passphrase nil)
493 (process-send-string process string))
495 (fillarray string 0))))))
497 (defun epg-status-GET_BOOL (process string)
498 (let ((entry (assoc string epg-prompt-alist)))
499 (if (y-or-n-p (if entry (cdr entry) (concat string "? ")))
500 (process-send-string process "y\n")
501 (process-send-string process "n\n"))))
503 (defun epg-status-GET_LINE (process string)
504 (let* ((entry (assoc string epg-prompt-alist))
505 (string (read-string (if entry (cdr entry) (concat string ": ")))))
506 (process-send-string process (concat string "\n"))))
508 (defun epg-status-GOODSIG (process string)
509 (if (string-match "\\`\\([^ ]+\\) \\(.*\\)" string)
510 (epg-context-set-result-for
513 (cons (epg-make-signature 'good
514 (match-string 1 string)
515 (match-string 2 string))
516 (epg-context-result-for epg-context 'verify)))))
518 (defun epg-status-EXPSIG (process string)
519 (if (string-match "\\`\\([^ ]+\\) \\(.*\\)" string)
520 (epg-context-set-result-for
523 (cons (epg-make-signature 'expired
524 (match-string 1 string)
525 (match-string 2 string))
526 (epg-context-result-for epg-context 'verify)))))
528 (defun epg-status-EXPKEYSIG (process string)
529 (if (string-match "\\`\\([^ ]+\\) \\(.*\\)" string)
530 (epg-context-set-result-for
533 (cons (epg-make-signature 'expired-key
534 (match-string 1 string)
535 (match-string 2 string))
536 (epg-context-result-for epg-context 'verify)))))
538 (defun epg-status-REVKEYSIG (process string)
539 (if (string-match "\\`\\([^ ]+\\) \\(.*\\)" string)
540 (epg-context-set-result-for
543 (cons (epg-make-signature 'revoked-key
544 (match-string 1 string)
545 (match-string 2 string))
546 (epg-context-result-for epg-context 'verify)))))
548 (defun epg-status-BADSIG (process string)
549 (if (string-match "\\`\\([^ ]+\\) \\(.*\\)" string)
550 (epg-context-set-result-for
553 (cons (epg-make-signature 'bad
554 (match-string 1 string)
555 (match-string 2 string))
556 (epg-context-result-for epg-context 'verify)))))
558 (defun epg-status-VALIDSIG (process string)
559 (let ((signature (car (epg-context-result-for epg-context 'verify))))
561 (eq (epg-signature-status signature) 'good)
562 (string-match "\\`\\([^ ]+\\) " string))
563 (epg-signature-set-fingerprint signature (match-string 1 string)))))
565 (defun epg-status-TRUST_UNDEFINED (process string)
566 (let ((signature (car (epg-context-result-for epg-context 'verify))))
568 (eq (epg-signature-status signature) 'good))
569 (epg-signature-set-validity signature 'undefined))))
571 (defun epg-status-TRUST_NEVER (process string)
572 (let ((signature (car (epg-context-result-for epg-context 'verify))))
574 (eq (epg-signature-status signature) 'good))
575 (epg-signature-set-validity signature 'never))))
577 (defun epg-status-TRUST_MARGINAL (process string)
578 (let ((signature (car (epg-context-result-for epg-context 'verify))))
580 (eq (epg-signature-status signature) 'marginal))
581 (epg-signature-set-validity signature 'marginal))))
583 (defun epg-status-TRUST_FULLY (process string)
584 (let ((signature (car (epg-context-result-for epg-context 'verify))))
586 (eq (epg-signature-status signature) 'good))
587 (epg-signature-set-validity signature 'full))))
589 (defun epg-status-TRUST_ULTIMATE (process string)
590 (let ((signature (car (epg-context-result-for epg-context 'verify))))
592 (eq (epg-signature-status signature) 'good))
593 (epg-signature-set-validity signature 'ultimate))))
595 (defun epg-status-PROGRESS (process string)
596 (if (string-match "\\`\\([^ ]+\\) \\([^ ]\\) \\([0-9]+\\) \\([0-9]+\\)"
598 (funcall (if (consp (epg-context-progress-callback epg-context))
599 (car (epg-context-progress-callback epg-context))
600 (epg-context-progress-callback epg-context))
601 (match-string 1 string)
602 (match-string 2 string)
603 (string-to-number (match-string 3 string))
604 (string-to-number (match-string 4 string))
605 (if (consp (epg-context-progress-callback epg-context))
606 (cdr (epg-context-progress-callback epg-context))))))
608 (defun epg-status-DECRYPTION_FAILED (process string)
609 (epg-context-set-result-for
611 (cons 'decryption-failed
612 (epg-context-result-for epg-context 'error))))
614 (defun epg-status-NODATA (process string)
615 (epg-context-set-result-for
617 (cons (cons 'no-data (string-to-number string))
618 (epg-context-result-for epg-context 'error))))
620 (defun epg-status-UNEXPECTED (process string)
621 (epg-context-set-result-for
623 (cons (cons 'unexpected (string-to-number string))
624 (epg-context-result-for epg-context 'error))))
626 (defun epg-status-KEYEXPIRED (process string)
627 (epg-context-set-result-for
629 (cons (cons 'key-expired string)
630 (epg-context-result-for epg-context 'error))))
632 (defun epg-status-KEYREVOKED (process string)
633 (epg-context-set-result-for
636 (epg-context-result-for epg-context 'error))))
638 (defun epg-status-BADARMOR (process string)
639 (epg-context-set-result-for
642 (epg-context-result-for epg-context 'error))))
644 (defun epg-passphrase-callback-function (key-id handback)
647 "Passphrase for symmetric encryption: "
649 "Passphrase for PIN: "
650 (let ((entry (assoc key-id epg-user-id-alist)))
652 (format "Passphrase for %s %s: " key-id (cdr entry))
653 (format "Passphrase for %s: " key-id)))))))
655 (defun epg-progress-callback-function (what char current total handback)
656 (message "%s: %d%%/%d%%" what current total))
658 (defun epg-configuration ()
659 "Return a list of internal configuration parameters of `epg-gpg-program'."
662 (apply #'call-process epg-gpg-program nil (list t nil) nil
663 '("--with-colons" "--list-config"))
664 (goto-char (point-min))
665 (while (re-search-forward "^cfg:\\([^:]+\\):\\(.*\\)" nil t)
666 (setq type (intern (match-string 1))
667 config (cons (cons type
669 '(pubkey cipher digest compress))
670 (mapcar #'string-to-number
671 (delete "" (split-string
678 (defun epg-list-keys-1 (name mode)
679 (let ((args (append (list "--with-colons" "--no-greeting" "--batch"
680 "--fixed-list-mode" "--with-fingerprint"
682 (if mode "--list-secret-keys" "--list-keys"))
683 (if name (list name))))
684 keys string field index)
686 (apply #'call-process epg-gpg-program nil (list t nil) nil args)
687 (goto-char (point-min))
688 (while (re-search-forward "^[a-z][a-z][a-z]:.*" nil t)
689 (setq keys (cons (make-vector 15 nil) keys)
690 string (match-string 0)
694 (string-match "\\([^:]+\\)?:" string index))
695 (setq index (match-end 0))
696 (aset (car keys) field (match-string 1 string))
697 (setq field (1+ field))))
700 (defun epg-make-sub-key-1 (line)
702 (cdr (assq (string-to-char (aref line 1)) epg-key-validity-alist))
704 (mapcar (lambda (char) (cdr (assq char epg-key-capablity-alist)))
706 (member (aref line 0) '("sec" "ssb"))
707 (string-to-number (aref line 3))
708 (string-to-number (aref line 2))
713 (defun epg-list-keys (&optional name mode)
714 (let ((lines (epg-list-keys-1 name mode))
718 ((member (aref (car lines) 0) '("pub" "sec"))
720 (epg-key-set-sub-key-list
722 (nreverse (epg-key-sub-key-list (car keys))))
723 (epg-key-set-user-id-list
725 (nreverse (epg-key-user-id-list (car keys)))))
726 (setq keys (cons (epg-make-key
727 (cdr (assq (string-to-char (aref (car lines) 8))
728 epg-key-validity-alist)))
730 (epg-key-set-sub-key-list
732 (cons (epg-make-sub-key-1 (car lines))
733 (epg-key-sub-key-list (car keys)))))
734 ((member (aref (car lines) 0) '("sub" "ssb"))
735 (epg-key-set-sub-key-list
737 (cons (epg-make-sub-key-1 (car lines))
738 (epg-key-sub-key-list (car keys)))))
739 ((equal (aref (car lines) 0) "uid")
740 (epg-key-set-user-id-list
742 (cons (epg-make-user-id
743 (cdr (assq (string-to-char (aref (car lines) 1))
744 epg-key-validity-alist))
745 (aref (car lines) 9))
746 (epg-key-user-id-list (car keys)))))
747 ((equal (aref (car lines) 0) "fpr")
748 (epg-sub-key-set-fingerprint (car (epg-key-sub-key-list (car keys)))
749 (aref (car lines) 9))))
750 (setq lines (cdr lines)))
753 (if (fboundp 'make-temp-file)
754 (defalias 'epg-make-temp-file 'make-temp-file)
755 ;; stolen from poe.el.
756 (defun epg-make-temp-file (prefix)
757 "Create a temporary file.
758 The returned file name (created by appending some random characters at the end
759 of PREFIX, and expanding against `temporary-file-directory' if necessary),
760 is guaranteed to point to a newly created empty file.
761 You can then use `write-region' to write new data into the file."
762 (let (tempdir tempfile)
765 ;; First, create a temporary directory.
766 (while (condition-case ()
768 (setq tempdir (make-temp-name
770 (file-name-directory prefix)
772 ;; return nil or signal an error.
773 (make-directory tempdir))
775 (file-already-exists t)))
776 (set-file-modes tempdir 448)
777 ;; Second, create a temporary file in the tempdir.
778 ;; There *is* a race condition between `make-temp-name'
779 ;; and `write-region', but we don't care it since we are
780 ;; in a private directory now.
781 (setq tempfile (make-temp-name (concat tempdir "/EMU")))
782 (write-region "" nil tempfile nil 'silent)
783 (set-file-modes tempfile 384)
784 ;; Finally, make a hard-link from the tempfile.
785 (while (condition-case ()
787 (setq file (make-temp-name prefix))
788 ;; return nil or signal an error.
789 (add-name-to-file tempfile file))
791 (file-already-exists t)))
793 ;; Cleanup the tempfile.
795 (file-exists-p tempfile)
796 (delete-file tempfile))
797 ;; Cleanup the tempdir.
799 (file-directory-p tempdir)
800 (delete-directory tempdir))))))
803 (defun epg-start-decrypt (context cipher)
804 "Initiate a decrypt operation on CIPHER.
805 CIPHER is a data object.
807 If you use this function, you will need to wait for the completion of
808 `epg-gpg-program' by using `epg-wait-for-completion' and call
809 `epg-reset' to clear a temporaly output file.
810 If you are unsure, use synchronous version of this function
811 `epg-decrypt-file' or `epg-decrypt-string' instead."
812 (unless (epg-data-file cipher)
813 (error "Not a file"))
814 (epg-context-set-result context nil)
815 (epg-start context (list "--decrypt" (epg-data-file cipher)))
816 (epg-wait-for-status context '("BEGIN_DECRYPTION")))
819 (defun epg-decrypt-file (context cipher plain)
820 "Decrypt a file CIPHER and store the result to a file PLAIN.
821 If PLAIN is nil, it returns the result as a string."
825 (epg-context-set-output-file context plain)
826 (epg-context-set-output-file context
827 (epg-make-temp-file "epg-output")))
828 (epg-start-decrypt context (epg-make-data-from-file cipher))
829 (epg-wait-for-completion context)
830 (if (epg-context-result-for context 'error)
831 (error "Decryption failed"))
833 (epg-read-output context)))
835 (epg-delete-output-file context))
836 (epg-reset context)))
839 (defun epg-decrypt-string (context cipher)
840 "Decrypt a string CIPHER and return the plain text."
841 (let ((input-file (epg-make-temp-file "epg-input"))
842 (coding-system-for-write 'binary))
845 (write-region cipher nil input-file)
846 (epg-context-set-output-file context
847 (epg-make-temp-file "epg-output"))
848 (epg-start-decrypt context (epg-make-data-from-file input-file))
849 (epg-wait-for-completion context)
850 (if (epg-context-result-for context 'error)
851 (error "Decryption failed"))
852 (epg-read-output context))
853 (epg-delete-output-file context)
854 (if (file-exists-p input-file)
855 (delete-file input-file))
856 (epg-reset context))))
859 (defun epg-start-verify (context signature &optional signed-text)
860 "Initiate a verify operation on SIGNATURE.
861 SIGNATURE and SIGNED-TEXT are a data object if they are specified.
863 For a detached signature, both SIGNATURE and SIGNED-TEXT should be set.
864 For a normal or a clear text signature, SIGNED-TEXT should be nil.
866 If you use this function, you will need to wait for the completion of
867 `epg-gpg-program' by using `epg-wait-for-completion' and call
868 `epg-reset' to clear a temporaly output file.
869 If you are unsure, use synchronous version of this function
870 `epg-verify-file' or `epg-verify-string' instead."
871 (epg-context-set-result context nil)
873 ;; Detached signature.
874 (if (epg-data-file signed-text)
875 (epg-start context (list "--verify" (epg-data-file signature)
876 (epg-data-file signed-text)))
877 (epg-start context (list "--verify" (epg-data-file signature) "-"))
878 (if (eq (process-status (epg-context-process context)) 'run)
879 (process-send-string (epg-context-process context)
880 (epg-data-string signed-text))))
881 ;; Normal (or cleartext) signature.
882 (if (epg-data-file signature)
883 (epg-start context (list "--verify" (epg-data-file signature)))
884 (epg-start context (list "--verify"))
885 (if (eq (process-status (epg-context-process context)) 'run)
886 (process-send-string (epg-context-process context)
887 (epg-data-string signature))))))
890 (defun epg-verify-file (context signature &optional signed-text plain)
891 "Verify a file SIGNATURE.
892 SIGNED-TEXT and PLAIN are also a file if they are specified.
894 For a detached signature, both SIGNATURE and SIGNED-TEXT should be string.
895 For a normal or a clear text signature, SIGNED-TEXT should be nil."
899 (epg-context-set-output-file context plain)
900 (epg-context-set-output-file context
901 (epg-make-temp-file "epg-output")))
903 (epg-start-verify context
904 (epg-make-data-from-file signature)
905 (epg-make-data-from-file signed-text))
906 (epg-start-verify context
907 (epg-make-data-from-file signature)))
908 (epg-wait-for-completion context)
910 (epg-read-output context)))
912 (epg-delete-output-file context))
913 (epg-reset context)))
916 (defun epg-verify-string (context signature &optional signed-text)
917 "Verify a string SIGNATURE.
918 SIGNED-TEXT is a string if it is specified.
920 For a detached signature, both SIGNATURE and SIGNED-TEXT should be string.
921 For a normal or a clear text signature, SIGNED-TEXT should be nil."
922 (let ((coding-system-for-write 'binary)
926 (epg-context-set-output-file context
927 (epg-make-temp-file "epg-output"))
930 (setq input-file (epg-make-temp-file "epg-signature"))
931 (write-region signature nil input-file)
932 (epg-start-verify context
933 (epg-make-data-from-file input-file)
934 (epg-make-data-from-string signed-text)))
935 (epg-start-verify context (epg-make-data-from-string signature)))
936 (epg-wait-for-completion context)
937 (epg-read-output context))
938 (epg-delete-output-file context)
940 (file-exists-p input-file))
941 (delete-file input-file))
942 (epg-reset context))))
945 (defun epg-start-sign (context plain &optional mode)
946 "Initiate a sign operation on PLAIN.
947 PLAIN is a data object.
949 If optional 3rd argument MODE is 'clearsign, it makes a clear text signature.
950 If MODE is t or 'detached, it makes a detached signature.
951 Otherwise, it makes a normal signature.
953 If you use this function, you will need to wait for the completion of
954 `epg-gpg-program' by using `epg-wait-for-completion' and call
955 `epg-reset' to clear a temporaly output file.
956 If you are unsure, use synchronous version of this function
957 `epg-sign-file' or `epg-sign-string' instead."
958 (epg-context-set-result context nil)
960 (append (list (if (eq mode 'clearsign)
962 (if (or (eq mode t) (eq mode 'detached))
966 (mapcar (lambda (signer)
968 (epg-context-signers context)))
969 (if (epg-data-file plain)
970 (list (epg-data-file plain)))))
971 (epg-wait-for-status context '("BEGIN_SIGNING"))
972 (if (and (epg-data-string plain)
973 (eq (process-status (epg-context-process context)) 'run))
974 (process-send-string (epg-context-process context)
975 (epg-data-string plain))))
978 (defun epg-sign-file (context plain signature &optional mode)
979 "Sign a file PLAIN and store the result to a file SIGNATURE.
980 If SIGNATURE is nil, it returns the result as a string.
981 If optional 3rd argument MODE is 'clearsign, it makes a clear text signature.
982 If MODE is t or 'detached, it makes a detached signature.
983 Otherwise, it makes a normal signature."
987 (epg-context-set-output-file context signature)
988 (epg-context-set-output-file context
989 (epg-make-temp-file "epg-output")))
990 (epg-start-sign context (epg-make-data-from-file plain) mode)
991 (epg-wait-for-completion context)
992 (if (epg-context-result-for context 'error)
993 (error "Sign failed"))
995 (epg-read-output context)))
997 (epg-delete-output-file context))
998 (epg-reset context)))
1001 (defun epg-sign-string (context plain &optional mode)
1002 "Sign a string PLAIN and return the output as string.
1003 If optional 3rd argument MODE is 'clearsign, it makes a clear text signature.
1004 If MODE is t or 'detached, it makes a detached signature.
1005 Otherwise, it makes a normal signature."
1008 (epg-context-set-output-file context
1009 (epg-make-temp-file "epg-output"))
1010 (epg-start-sign context (epg-make-data-from-string plain) mode)
1011 (epg-wait-for-completion context)
1012 (if (epg-context-result-for context 'error)
1013 (error "Sign failed"))
1014 (epg-read-output context))
1015 (epg-delete-output-file context)
1016 (epg-reset context)))
1019 (defun epg-start-encrypt (context plain recipients
1020 &optional sign always-trust)
1021 "Initiate an encrypt operation on PLAIN.
1022 PLAIN is a data object.
1023 If RECIPIENTS is nil, it performs symmetric encryption.
1025 If you use this function, you will need to wait for the completion of
1026 `epg-gpg-program' by using `epg-wait-for-completion' and call
1027 `epg-reset' to clear a temporaly output file.
1028 If you are unsure, use synchronous version of this function
1029 `epg-encrypt-file' or `epg-encrypt-string' instead."
1030 (epg-context-set-result context nil)
1032 (append (if always-trust '("--always-trust"))
1033 (if recipients '("--encrypt") '("--symmetric"))
1037 (mapcar (lambda (signer)
1039 (epg-context-signers context)))))
1041 (mapcar (lambda (recipient)
1042 (list "-r" recipient))
1044 (if (epg-data-file plain)
1045 (list (epg-data-file plain)))))
1047 (epg-wait-for-status context '("BEGIN_SIGNING"))
1048 (if (null recipients)
1049 (epg-wait-for-status context '("BEGIN_ENCRYPTION"))))
1050 (if (and (epg-data-string plain)
1051 (eq (process-status (epg-context-process context)) 'run))
1052 (process-send-string (epg-context-process context)
1053 (epg-data-string plain))))
1056 (defun epg-encrypt-file (context plain recipients
1057 cipher &optional sign always-trust)
1058 "Encrypt a file PLAIN and store the result to a file CIPHER.
1059 If CIPHER is nil, it returns the result as a string.
1060 If RECIPIENTS is nil, it performs symmetric encryption."
1064 (epg-context-set-output-file context cipher)
1065 (epg-context-set-output-file context
1066 (epg-make-temp-file "epg-output")))
1067 (epg-start-encrypt context (epg-make-data-from-file plain)
1068 recipients sign always-trust)
1069 (epg-wait-for-completion context)
1070 (if (epg-context-result-for context 'error)
1071 (error "Encrypt failed"))
1073 (epg-read-output context)))
1075 (epg-delete-output-file context))
1076 (epg-reset context)))
1079 (defun epg-encrypt-string (context plain recipients
1080 &optional sign always-trust)
1081 "Encrypt a string PLAIN.
1082 If RECIPIENTS is nil, it performs symmetric encryption."
1085 (epg-context-set-output-file context
1086 (epg-make-temp-file "epg-output"))
1087 (epg-start-encrypt context (epg-make-data-from-string plain)
1088 recipients sign always-trust)
1089 (epg-wait-for-completion context)
1090 (if (epg-context-result-for context 'error)
1091 (error "Encrypt failed"))
1092 (epg-read-output context))
1093 (epg-delete-output-file context)
1094 (epg-reset context)))
1097 (defun epg-start-export-keys (context pattern)
1098 "Initiate an export keys operation.
1100 If you use this function, you will need to wait for the completion of
1101 `epg-gpg-program' by using `epg-wait-for-completion' and call
1102 `epg-reset' to clear a temporaly output file.
1103 If you are unsure, use synchronous version of this function
1104 `epg-export-keys' instead."
1105 (epg-context-set-result context nil)
1106 (epg-context-set-output-file context (epg-make-temp-file "epg-output"))
1107 (epg-start context (list "--export" pattern)))
1110 (defun epg-export-keys (context pattern)
1111 "Extract public keys matched with PATTERN and return them."
1114 (epg-start-export-keys context pattern)
1115 (epg-wait-for-completion context)
1116 (if (epg-context-result-for context 'error)
1117 (error "Export keys failed"))
1118 (epg-read-output context))
1119 (epg-reset context)))
1122 (defun epg-start-import-keys (context keys)
1123 "Initiate an import keys operation.
1124 KEYS is a data object.
1126 If you use this function, you will need to wait for the completion of
1127 `epg-gpg-program' by using `epg-wait-for-completion' and call
1128 `epg-reset' to clear a temporaly output file.
1129 If you are unsure, use synchronous version of this function
1130 `epg-import-keys-from-file' or `epg-import-keys-from-string' instead."
1131 (epg-context-set-result context nil)
1132 (epg-context-set-output-file context (epg-make-temp-file "epg-output"))
1133 (epg-start context (append (list "--import") (epg-data-file keys)))
1134 (if (and (epg-data-string keys)
1135 (eq (process-status (epg-context-process context)) 'run))
1136 (process-send-string (epg-context-process context)
1137 (epg-data-string keys))))
1139 (defun epg-import-keys-1 (context keys)
1142 (epg-start-import-keys context keys)
1143 (epg-wait-for-completion context)
1144 (if (epg-context-result-for context 'error)
1145 (error "Import keys failed"))
1146 (epg-read-output context))
1147 (epg-reset context)))
1150 (defun epg-import-keys-from-file (context keys)
1151 "Add keys from a file KEYS."
1152 (epg-import-keys-1 context (epg-make-data-from-file keys)))
1155 (defun epg-import-keys-from-string (context keys)
1156 "Add keys from a string KEYS."
1157 (epg-import-keys-1 context (epg-make-data-from-string keys)))
1161 ;;; epg.el ends here