From cbbae3be0807cdca91fd3c56409288fd7af59ba3 Mon Sep 17 00:00:00 2001 From: Katsumi Yamaoka Date: Wed, 11 Apr 2012 00:13:17 +0000 Subject: [PATCH] Import epa.texi from Emacs; remove PGG files --- lisp/ChangeLog | 9 + lisp/dgnushack.el | 1 - lisp/lpath.el | 5 +- lisp/pgg-def.el | 98 -------- lisp/pgg-gpg.el | 410 ------------------------------- lisp/pgg-parse.el | 523 ---------------------------------------- lisp/pgg-pgp.el | 257 -------------------- lisp/pgg-pgp5.el | 258 -------------------- lisp/pgg.el | 597 ---------------------------------------------- texi/ChangeLog | 8 + texi/Makefile.in | 10 +- texi/epa.texi | 498 ++++++++++++++++++++++++++++++++++++++ texi/pgg.texi | 506 --------------------------------------- 13 files changed, 522 insertions(+), 2658 deletions(-) delete mode 100644 lisp/pgg-def.el delete mode 100644 lisp/pgg-gpg.el delete mode 100644 lisp/pgg-parse.el delete mode 100644 lisp/pgg-pgp.el delete mode 100644 lisp/pgg-pgp5.el delete mode 100644 lisp/pgg.el create mode 100644 texi/epa.texi delete mode 100644 texi/pgg.texi diff --git a/lisp/ChangeLog b/lisp/ChangeLog index a753cf675..cbe96c067 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,12 @@ +2012-04-11 Katsumi Yamaoka + + pgg-def.el, pgg-gpg.el, pgg-parse.el, pgg-pgp.el, pgg-pgp5.el, pgg.el: + Remove. + + dgnushack.el (pgg-snarf-keys-region): Remove autoload. + + lpath.el (pgg-parse-crc24-string, pgg-parse-crc24): Remove declaration. + 2012-04-10 Lars Magne Ingebrigtsen * mml.el (mml-generate-mime): Allow specifying what the top-level part diff --git a/lisp/dgnushack.el b/lisp/dgnushack.el index 29b695870..f7c11eefb 100644 --- a/lisp/dgnushack.el +++ b/lisp/dgnushack.el @@ -197,7 +197,6 @@ (autoload 'mail-fetch-field "mail-utils") (autoload 'make-annotation "annotations") (autoload 'make-display-table "disp-table") - (autoload 'pgg-snarf-keys-region "pgg" nil t) (autoload 'pp "pp") (autoload 'ps-despool "ps-print" nil t) (autoload 'ps-spool-buffer "ps-print" nil t) diff --git a/lisp/lpath.el b/lisp/lpath.el index 91613a221..7c4d14a65 100644 --- a/lisp/lpath.el +++ b/lisp/lpath.el @@ -107,11 +107,10 @@ (maybe-fbind '(ccl-execute-on-string char-charset charsetp coding-system-get find-charset-region - get-charset-property pgg-display-output-buffer pgg-parse-crc24-string - unicode-precedence-list)) + get-charset-property pgg-display-output-buffer unicode-precedence-list)) (maybe-bind '(current-language-environment - language-info-alist pgg-parse-crc24))) + language-info-alist))) (unless (featurep 'file-coding) (maybe-fbind diff --git a/lisp/pgg-def.el b/lisp/pgg-def.el deleted file mode 100644 index ec208ea81..000000000 --- a/lisp/pgg-def.el +++ /dev/null @@ -1,98 +0,0 @@ -;;; pgg-def.el --- functions/macros for defining PGG functions - -;; Copyright (C) 1999, 2002-2012 Free Software Foundation, Inc. - -;; Author: Daiki Ueno -;; Created: 1999/11/02 -;; Keywords: PGP, OpenPGP, GnuPG -;; Package: pgg -;; Obsolete-since: 24.1 - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software: you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs. If not, see . - -;;; Code: - -(defgroup pgg () - "Glue for the various PGP implementations." - :group 'mime - :version "22.1") - -(defcustom pgg-default-scheme 'gpg - "Default PGP scheme." - :group 'pgg - :type '(choice (const :tag "GnuPG" gpg) - (const :tag "PGP 5" pgp5) - (const :tag "PGP" pgp))) - -(defcustom pgg-default-user-id (user-login-name) - "User ID of your default identity." - :group 'pgg - :type 'string) - -(defcustom pgg-default-keyserver-address "subkeys.pgp.net" - "Host name of keyserver." - :group 'pgg - :type 'string) - -(defcustom pgg-query-keyserver nil - "Whether PGG queries keyservers for missing keys when verifying messages." - :version "22.1" - :group 'pgg - :type 'boolean) - -(defcustom pgg-encrypt-for-me t - "If t, encrypt all outgoing messages with user's public key." - :group 'pgg - :type 'boolean) - -(defcustom pgg-cache-passphrase t - "If t, cache passphrase." - :group 'pgg - :type 'boolean) - -(defcustom pgg-passphrase-cache-expiry 16 - "How many seconds the passphrase is cached. -Whether the passphrase is cached at all is controlled by -`pgg-cache-passphrase'." - :group 'pgg - :type 'integer) - -(defcustom pgg-passphrase-coding-system nil - "Coding system to encode passphrase." - :group 'pgg - :type 'coding-system) - -(defvar pgg-messages-coding-system nil - "Coding system used when reading from a PGP external process.") - -(defvar pgg-status-buffer " *PGG status*") -(defvar pgg-errors-buffer " *PGG errors*") -(defvar pgg-output-buffer " *PGG output*") - -(defvar pgg-echo-buffer "*PGG-echo*") - -(defvar pgg-scheme nil - "Current scheme of PGP implementation.") - -(defvar pgg-text-mode nil - "If t, inform the recipient that the input is text.") - -(defmacro pgg-truncate-key-identifier (key) - `(if (> (length ,key) 8) (substring ,key -8) ,key)) - -(provide 'pgg-def) - -;;; pgg-def.el ends here diff --git a/lisp/pgg-gpg.el b/lisp/pgg-gpg.el deleted file mode 100644 index 03de093f6..000000000 --- a/lisp/pgg-gpg.el +++ /dev/null @@ -1,410 +0,0 @@ -;;; pgg-gpg.el --- GnuPG support for PGG. - -;; Copyright (C) 1999-2000, 2002-2012 Free Software Foundation, Inc. - -;; Author: Daiki Ueno -;; Symmetric encryption and gpg-agent support added by: -;; Sascha Wilde -;; Created: 1999/10/28 -;; Keywords: PGP, OpenPGP, GnuPG -;; Package: pgg -;; Obsolete-since: 24.1 - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software: you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs. If not, see . - -;;; Code: - -(eval-when-compile - (require 'cl) ; for gpg macros - (require 'pgg)) - -(defgroup pgg-gpg () - "GnuPG interface." - :group 'pgg) - -(defcustom pgg-gpg-program "gpg" - "The GnuPG executable." - :group 'pgg-gpg - :type 'string) - -(defcustom pgg-gpg-extra-args nil - "Extra arguments for every GnuPG invocation." - :group 'pgg-gpg - :type '(repeat (string :tag "Argument"))) - -(defcustom pgg-gpg-recipient-argument "--recipient" - "GnuPG option to specify recipient." - :group 'pgg-gpg - :type '(choice (const :tag "New `--recipient' option" "--recipient") - (const :tag "Old `--remote-user' option" "--remote-user"))) - -(defcustom pgg-gpg-use-agent t - "Whether to use gnupg agent for key caching." - :group 'pgg-gpg - :type 'boolean) - -(defvar pgg-gpg-user-id nil - "GnuPG ID of your default identity.") - -(defun pgg-gpg-process-region (start end passphrase program args) - (let* ((use-agent (and (null passphrase) (pgg-gpg-use-agent-p))) - (output-file-name (pgg-make-temp-file "pgg-output")) - (args - `("--status-fd" "2" - ,@(if use-agent '("--use-agent") - (if passphrase '("--passphrase-fd" "0"))) - "--yes" ; overwrite - "--output" ,output-file-name - ,@pgg-gpg-extra-args ,@args)) - (output-buffer pgg-output-buffer) - (errors-buffer pgg-errors-buffer) - (orig-mode (default-file-modes)) - (process-connection-type nil) - (inhibit-redisplay t) - process status exit-status - passphrase-with-newline - encoded-passphrase-with-new-line) - (with-current-buffer (get-buffer-create errors-buffer) - (buffer-disable-undo) - (erase-buffer)) - (unwind-protect - (progn - (set-default-file-modes 448) - (let ((coding-system-for-write 'binary)) - (setq process - (apply #'start-process "*GnuPG*" errors-buffer - program args))) - (set-process-sentinel process #'ignore) - (when passphrase - (setq passphrase-with-newline (concat passphrase "\n")) - (if pgg-passphrase-coding-system - (progn - (setq encoded-passphrase-with-new-line - (encode-coding-string - passphrase-with-newline - (coding-system-change-eol-conversion - pgg-passphrase-coding-system 'unix))) - (pgg-clear-string passphrase-with-newline)) - (setq encoded-passphrase-with-new-line passphrase-with-newline - passphrase-with-newline nil)) - (process-send-string process encoded-passphrase-with-new-line)) - (process-send-region process start end) - (process-send-eof process) - (while (eq 'run (process-status process)) - (accept-process-output process 5)) - ;; Accept any remaining pending output coming after the - ;; status change. - (accept-process-output process 5) - (setq status (process-status process) - exit-status (process-exit-status process)) - (delete-process process) - (with-current-buffer (get-buffer-create output-buffer) - (buffer-disable-undo) - (erase-buffer) - (if (file-exists-p output-file-name) - (let ((coding-system-for-read (if pgg-text-mode - 'raw-text - 'binary))) - (insert-file-contents output-file-name))) - (set-buffer errors-buffer) - (if (memq status '(stop signal)) - (error "%s exited abnormally: '%s'" program exit-status)) - (if (= 127 exit-status) - (error "%s could not be found" program)))) - (if passphrase-with-newline - (pgg-clear-string passphrase-with-newline)) - (if encoded-passphrase-with-new-line - (pgg-clear-string encoded-passphrase-with-new-line)) - (if (and process (eq 'run (process-status process))) - (interrupt-process process)) - (if (file-exists-p output-file-name) - (delete-file output-file-name)) - (set-default-file-modes orig-mode)))) - -(defun pgg-gpg-possibly-cache-passphrase (passphrase &optional key notruncate) - (if (and passphrase - pgg-cache-passphrase - (progn - (goto-char (point-min)) - (re-search-forward "^\\[GNUPG:] \\(GOOD_PASSPHRASE\\>\\)\\|\\(SIG_CREATED\\)" nil t))) - (pgg-add-passphrase-to-cache - (or key - (progn - (goto-char (point-min)) - (if (re-search-forward - "^\\[GNUPG:] NEED_PASSPHRASE\\(_PIN\\)? \\w+ ?\\w*" nil t) - (substring (match-string 0) -8)))) - passphrase - notruncate))) - -(defvar pgg-gpg-all-secret-keys 'unknown) - -(defun pgg-gpg-lookup-all-secret-keys () - "Return all secret keys present in secret key ring." - (when (eq pgg-gpg-all-secret-keys 'unknown) - (setq pgg-gpg-all-secret-keys '()) - (let ((args (list "--with-colons" "--no-greeting" "--batch" - "--list-secret-keys"))) - (with-temp-buffer - (apply #'call-process pgg-gpg-program nil t nil args) - (goto-char (point-min)) - (while (re-search-forward - "^\\(sec\\|pub\\):[^:]*:[^:]*:[^:]*:\\([^:]*\\)" nil t) - (push (substring (match-string 2) 8) - pgg-gpg-all-secret-keys))))) - pgg-gpg-all-secret-keys) - -(defun pgg-gpg-lookup-key (string &optional type) - "Search keys associated with STRING." - (let ((args (list "--with-colons" "--no-greeting" "--batch" - (if type "--list-secret-keys" "--list-keys") - string))) - (with-temp-buffer - (apply #'call-process pgg-gpg-program nil t nil args) - (goto-char (point-min)) - (if (re-search-forward "^\\(sec\\|pub\\):[^:]*:[^:]*:[^:]*:\\([^:]*\\)" - nil t) - (substring (match-string 2) 8))))) - -(defun pgg-gpg-lookup-key-owner (string &optional all) - "Search keys associated with STRING and return owner of identified key. - -The value may be just the bare key id, or it may be a combination of the -user name associated with the key and the key id, with the key id enclosed -in \"<...>\" angle brackets. - -Optional ALL non-nil means search all keys, including secret keys." - (let ((args (list "--with-colons" "--no-greeting" "--batch" - (if all "--list-secret-keys" "--list-keys") - string)) - (key-regexp (concat "^\\(sec\\|pub\\|uid\\)" - ":[^:]*:[^:]*:[^:]*:\\([^:]*\\):[^:]*" - ":[^:]*:[^:]*:[^:]*:\\([^:]+\\):"))) - (with-temp-buffer - (apply #'call-process pgg-gpg-program nil t nil args) - (goto-char (point-min)) - (if (re-search-forward key-regexp - nil t) - (match-string 3))))) - -(defun pgg-gpg-key-id-from-key-owner (key-owner) - (cond ((not key-owner) nil) - ;; Extract bare key id from outermost paired angle brackets, if any: - ((string-match "[^<]*<\\(.+\\)>[^>]*" key-owner) - (substring key-owner (match-beginning 1)(match-end 1))) - (key-owner))) - -(defun pgg-gpg-encrypt-region (start end recipients &optional sign passphrase) - "Encrypt the current region between START and END. - -If optional argument SIGN is non-nil, do a combined sign and encrypt. - -If optional PASSPHRASE is not specified, it will be obtained from the -passphrase cache or user." - (let* ((pgg-gpg-user-id (or pgg-gpg-user-id pgg-default-user-id)) - (passphrase (or passphrase - (when (and sign (not (pgg-gpg-use-agent-p))) - (pgg-read-passphrase - (format "GnuPG passphrase for %s: " - pgg-gpg-user-id) - pgg-gpg-user-id)))) - (args - (append - (list "--batch" "--armor" "--always-trust" "--encrypt") - (if pgg-text-mode (list "--textmode")) - (if sign (list "--sign" "--local-user" pgg-gpg-user-id)) - (if (or recipients pgg-encrypt-for-me) - (apply #'nconc - (mapcar (lambda (rcpt) - (list pgg-gpg-recipient-argument rcpt)) - (append recipients - (if pgg-encrypt-for-me - (list pgg-gpg-user-id))))))))) - (pgg-gpg-process-region start end passphrase pgg-gpg-program args) - (when sign - (with-current-buffer pgg-errors-buffer - ;; Possibly cache passphrase under, e.g. "jas", for future sign. - (pgg-gpg-possibly-cache-passphrase passphrase pgg-gpg-user-id) - ;; Possibly cache passphrase under, e.g. B565716F, for future decrypt. - (pgg-gpg-possibly-cache-passphrase passphrase))) - (pgg-process-when-success))) - -(defun pgg-gpg-encrypt-symmetric-region (start end &optional passphrase) - "Encrypt the current region between START and END with symmetric cipher. - -If optional PASSPHRASE is not specified, it will be obtained from the -passphrase cache or user." - (let* ((passphrase (or passphrase - (when (not (pgg-gpg-use-agent-p)) - (pgg-read-passphrase - "GnuPG passphrase for symmetric encryption: ")))) - (args - (append (list "--batch" "--armor" "--symmetric" ) - (if pgg-text-mode (list "--textmode"))))) - (pgg-gpg-process-region start end passphrase pgg-gpg-program args) - (pgg-process-when-success))) - -(defun pgg-gpg-decrypt-region (start end &optional passphrase) - "Decrypt the current region between START and END. - -If optional PASSPHRASE is not specified, it will be obtained from the -passphrase cache or user." - (let* ((current-buffer (current-buffer)) - (message-keys (with-temp-buffer - (insert-buffer-substring current-buffer) - (pgg-decode-armor-region (point-min) (point-max)))) - (secret-keys (pgg-gpg-lookup-all-secret-keys)) - ;; XXX the user is stuck if they need to use the passphrase for - ;; any but the first secret key for which the message is - ;; encrypted. ideally, we would incrementally give them a - ;; chance with subsequent keys each time they fail with one. - (key (pgg-gpg-select-matching-key message-keys secret-keys)) - (key-owner (and key (pgg-gpg-lookup-key-owner key t))) - (key-id (pgg-gpg-key-id-from-key-owner key-owner)) - (pgg-gpg-user-id (or key-id key - pgg-gpg-user-id pgg-default-user-id)) - (passphrase (or passphrase - (when (not (pgg-gpg-use-agent-p)) - (pgg-read-passphrase - (format (if (pgg-gpg-symmetric-key-p message-keys) - "Passphrase for symmetric decryption: " - "GnuPG passphrase for %s: ") - (or key-owner "??")) - pgg-gpg-user-id)))) - (args '("--batch" "--decrypt"))) - (pgg-gpg-process-region start end passphrase pgg-gpg-program args) - (with-current-buffer pgg-errors-buffer - (pgg-gpg-possibly-cache-passphrase passphrase pgg-gpg-user-id) - (goto-char (point-min)) - (re-search-forward "^\\[GNUPG:] DECRYPTION_OKAY\\>" nil t)))) - -;;;###autoload -(defun pgg-gpg-symmetric-key-p (message-keys) - "True if decoded armor MESSAGE-KEYS has symmetric encryption indicator." - (let (result) - (dolist (key message-keys result) - (when (and (eq (car key) 3) - (member '(symmetric-key-algorithm) key)) - (setq result key))))) - -(defun pgg-gpg-select-matching-key (message-keys secret-keys) - "Choose a key from MESSAGE-KEYS that matches one of the keys in SECRET-KEYS." - (loop for message-key in message-keys - for message-key-id = (and (equal (car message-key) 1) - (cdr (assq 'key-identifier - (cdr message-key)))) - for key = (and message-key-id (pgg-lookup-key message-key-id 'encrypt)) - when (and key (member key secret-keys)) return key)) - -(defun pgg-gpg-sign-region (start end &optional cleartext passphrase) - "Make detached signature from text between START and END." - (let* ((pgg-gpg-user-id (or pgg-gpg-user-id pgg-default-user-id)) - (passphrase (or passphrase - (when (not (pgg-gpg-use-agent-p)) - (pgg-read-passphrase - (format "GnuPG passphrase for %s: " - pgg-gpg-user-id) - pgg-gpg-user-id)))) - (args - (append (list (if cleartext "--clearsign" "--detach-sign") - "--armor" "--batch" "--verbose" - "--local-user" pgg-gpg-user-id) - (if pgg-text-mode (list "--textmode")))) - (inhibit-read-only t) - buffer-read-only) - (pgg-gpg-process-region start end passphrase pgg-gpg-program args) - (with-current-buffer pgg-errors-buffer - ;; Possibly cache passphrase under, e.g. "jas", for future sign. - (pgg-gpg-possibly-cache-passphrase passphrase pgg-gpg-user-id) - ;; Possibly cache passphrase under, e.g. B565716F, for future decrypt. - (pgg-gpg-possibly-cache-passphrase passphrase)) - (pgg-process-when-success))) - -(defun pgg-gpg-verify-region (start end &optional signature) - "Verify region between START and END as the detached signature SIGNATURE." - (let ((args '("--batch" "--verify"))) - (when (stringp signature) - (setq args (append args (list signature)))) - (setq args (append args '("-"))) - (pgg-gpg-process-region start end nil pgg-gpg-program args) - (with-current-buffer pgg-errors-buffer - (goto-char (point-min)) - (while (re-search-forward "^gpg: \\(.*\\)\n" nil t) - (with-current-buffer pgg-output-buffer - (insert-buffer-substring pgg-errors-buffer - (match-beginning 1) (match-end 0))) - (delete-region (match-beginning 0) (match-end 0))) - (goto-char (point-min)) - (re-search-forward "^\\[GNUPG:] GOODSIG\\>" nil t)))) - -(defun pgg-gpg-insert-key () - "Insert public key at point." - (let* ((pgg-gpg-user-id (or pgg-gpg-user-id pgg-default-user-id)) - (args (list "--batch" "--export" "--armor" - pgg-gpg-user-id))) - (pgg-gpg-process-region (point)(point) nil pgg-gpg-program args) - (insert-buffer-substring pgg-output-buffer))) - -(defun pgg-gpg-snarf-keys-region (start end) - "Add all public keys in region between START and END to the keyring." - (let ((args '("--import" "--batch" "-")) status) - (pgg-gpg-process-region start end nil pgg-gpg-program args) - (set-buffer pgg-errors-buffer) - (goto-char (point-min)) - (when (re-search-forward "^\\[GNUPG:] IMPORT_RES\\>" nil t) - (setq status (buffer-substring (match-end 0) - (progn (end-of-line)(point))) - status (vconcat (mapcar #'string-to-number (split-string status)))) - (erase-buffer) - (insert (format "Imported %d key(s). -\tArmor contains %d key(s) [%d bad, %d old].\n" - (+ (aref status 2) - (aref status 10)) - (aref status 0) - (aref status 1) - (+ (aref status 4) - (aref status 11))) - (if (zerop (aref status 9)) - "" - "\tSecret keys are imported.\n"))) - (append-to-buffer pgg-output-buffer (point-min)(point-max)) - (pgg-process-when-success))) - -(defun pgg-gpg-update-agent () - "Try to connect to gpg-agent and send UPDATESTARTUPTTY." - (if (fboundp 'make-network-process) - (let* ((agent-info (getenv "GPG_AGENT_INFO")) - (socket (and agent-info - (string-match "^\\([^:]*\\)" agent-info) - (match-string 1 agent-info))) - (conn (and socket - (make-network-process :name "gpg-agent-process" - :host 'local :family 'local - :service socket)))) - (when (and conn (eq (process-status conn) 'open)) - (process-send-string conn "UPDATESTARTUPTTY\n") - (delete-process conn) - t)) - ;; We can't check, so assume gpg-agent is up. - t)) - -(defun pgg-gpg-use-agent-p () - "Return t if `pgg-gpg-use-agent' is t and gpg-agent is available." - (and pgg-gpg-use-agent (pgg-gpg-update-agent))) - -(provide 'pgg-gpg) - -;;; pgg-gpg.el ends here diff --git a/lisp/pgg-parse.el b/lisp/pgg-parse.el deleted file mode 100644 index c7484ddd7..000000000 --- a/lisp/pgg-parse.el +++ /dev/null @@ -1,523 +0,0 @@ -;;; pgg-parse.el --- OpenPGP packet parsing - -;; Copyright (C) 1999, 2002-2012 Free Software Foundation, Inc. - -;; Author: Daiki Ueno -;; Created: 1999/10/28 -;; Keywords: PGP, OpenPGP, GnuPG -;; Package: pgg -;; Obsolete-since: 24.1 - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software: you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs. If not, see . - -;;; Commentary: - -;; This module is based on - -;; [OpenPGP] RFC 2440: "OpenPGP Message Format" -;; by John W. Noerenberg, II , -;; Jon Callas , Lutz Donnerhacke , -;; Hal Finney and Rodney Thayer -;; (1998/11) - -;;; Code: - -(eval-when-compile - ;; For Emacs <22.2 and XEmacs. - (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))) - (require 'cl)) - -(defgroup pgg-parse () - "OpenPGP packet parsing." - :group 'pgg) - -(defcustom pgg-parse-public-key-algorithm-alist - '((1 . RSA) (2 . RSA-E) (3 . RSA-S) (16 . ELG-E) (17 . DSA) (20 . ELG)) - "Alist of the assigned number to the public key algorithm." - :group 'pgg-parse - :type '(repeat - (cons (sexp :tag "Number") (sexp :tag "Type")))) - -(defcustom pgg-parse-symmetric-key-algorithm-alist - '((1 . IDEA) (2 . 3DES) (4 . CAST5) (5 . SAFER-SK128)) - "Alist of the assigned number to the symmetric key algorithm." - :group 'pgg-parse - :type '(repeat - (cons (sexp :tag "Number") (sexp :tag "Type")))) - -(defcustom pgg-parse-hash-algorithm-alist - '((1 . MD5) (2 . SHA1) (3 . RIPEMD160) (5 . MD2) (8 . SHA256) (9 . SHA384) - (10 . SHA512)) - "Alist of the assigned number to the cryptographic hash algorithm." - :group 'pgg-parse - :type '(repeat - (cons (sexp :tag "Number") (sexp :tag "Type")))) - -(defcustom pgg-parse-compression-algorithm-alist - '((0 . nil); Uncompressed - (1 . ZIP) - (2 . ZLIB)) - "Alist of the assigned number to the compression algorithm." - :group 'pgg-parse - :type '(repeat - (cons (sexp :tag "Number") (sexp :tag "Type")))) - -(defcustom pgg-parse-signature-type-alist - '((0 . "Signature of a binary document") - (1 . "Signature of a canonical text document") - (2 . "Standalone signature") - (16 . "Generic certification of a User ID and Public Key packet") - (17 . "Persona certification of a User ID and Public Key packet") - (18 . "Casual certification of a User ID and Public Key packet") - (19 . "Positive certification of a User ID and Public Key packet") - (24 . "Subkey Binding Signature") - (31 . "Signature directly on a key") - (32 . "Key revocation signature") - (40 . "Subkey revocation signature") - (48 . "Certification revocation signature") - (64 . "Timestamp signature.")) - "Alist of the assigned number to the signature type." - :group 'pgg-parse - :type '(repeat - (cons (sexp :tag "Number") (sexp :tag "Type")))) - -(defcustom pgg-ignore-packet-checksum t; XXX - "If non-nil checksum of each ascii armored packet will be ignored." - :group 'pgg-parse - :type 'boolean) - -(defvar pgg-armor-header-lines - '("^-----BEGIN PGP MESSAGE\\(, PART [0-9]+\\(/[0-9]+\\)?\\)?-----\r?$" - "^-----BEGIN PGP PUBLIC KEY BLOCK-----\r?$" - "^-----BEGIN PGP PRIVATE KEY BLOCK-----\r?$" - "^-----BEGIN PGP SIGNATURE-----\r?$") - "Armor headers.") - -(eval-and-compile - (defalias 'pgg-char-int (if (fboundp 'char-int) - 'char-int - 'identity))) - -(defmacro pgg-format-key-identifier (string) - `(mapconcat (lambda (c) (format "%02X" (pgg-char-int c))) - ,string "") - ;; `(upcase (apply #'format "%02x%02x%02x%02x%02x%02x%02x%02x" - ;; (string-to-number-list ,string))) - ) - -(defmacro pgg-parse-time-field (bytes) - `(list (logior (lsh (car ,bytes) 8) - (nth 1 ,bytes)) - (logior (lsh (nth 2 ,bytes) 8) - (nth 3 ,bytes)) - 0)) - -(defmacro pgg-byte-after (&optional pos) - `(pgg-char-int (char-after ,(or pos `(point))))) - -(defmacro pgg-read-byte () - `(pgg-char-int (char-after (prog1 (point) (forward-char))))) - -(defmacro pgg-read-bytes-string (nbytes) - `(buffer-substring - (point) (prog1 (+ ,nbytes (point)) - (forward-char ,nbytes)))) - -(defmacro pgg-read-bytes (nbytes) - `(mapcar #'pgg-char-int (pgg-read-bytes-string ,nbytes)) - ;; `(string-to-number-list (pgg-read-bytes-string ,nbytes)) - ) - -(defmacro pgg-read-body-string (ptag) - `(if (nth 1 ,ptag) - (pgg-read-bytes-string (nth 1 ,ptag)) - (pgg-read-bytes-string (- (point-max) (point))))) - -(defmacro pgg-read-body (ptag) - `(mapcar #'pgg-char-int (pgg-read-body-string ,ptag)) - ;; `(string-to-number-list (pgg-read-body-string ,ptag)) - ) - -(defalias 'pgg-skip-bytes 'forward-char) - -(defmacro pgg-skip-header (ptag) - `(pgg-skip-bytes (nth 2 ,ptag))) - -(defmacro pgg-skip-body (ptag) - `(pgg-skip-bytes (nth 1 ,ptag))) - -(defmacro pgg-set-alist (alist key value) - `(setq ,alist (nconc ,alist (list (cons ,key ,value))))) - -(when (fboundp 'define-ccl-program) - - (define-ccl-program pgg-parse-crc24 - '(1 - ((loop - (read r0) (r1 ^= r0) (r2 ^= 0) - (r5 = 0) - (loop - (r1 <<= 1) - (r1 += ((r2 >> 15) & 1)) - (r2 <<= 1) - (if (r1 & 256) - ((r1 ^= 390) (r2 ^= 19707))) - (if (r5 < 7) - ((r5 += 1) - (repeat)))) - (repeat))))) - - (defvar pgg-parse-crc24) - - (defun pgg-parse-crc24-string (string) - (let ((h (vector nil 183 1230 nil nil nil nil nil nil))) - (ccl-execute-on-string pgg-parse-crc24 h string) - (format "%c%c%c" - (logand (aref h 1) 255) - (logand (lsh (aref h 2) -8) 255) - (logand (aref h 2) 255))))) - -(defmacro pgg-parse-length-type (c) - `(cond - ((< ,c 192) (cons ,c 1)) - ((< ,c 224) - (cons (+ (lsh (- ,c 192) 8) - (pgg-byte-after (+ 2 (point))) - 192) - 2)) - ((= ,c 255) - (cons (cons (logior (lsh (pgg-byte-after (+ 2 (point))) 8) - (pgg-byte-after (+ 3 (point)))) - (logior (lsh (pgg-byte-after (+ 4 (point))) 8) - (pgg-byte-after (+ 5 (point))))) - 5)) - (t;partial body length - '(0 . 0)))) - -(defun pgg-parse-packet-header () - (let ((ptag (pgg-byte-after)) - length-type content-tag packet-bytes header-bytes) - (if (zerop (logand 64 ptag));Old format - (progn - (setq length-type (logand ptag 3) - length-type (if (= 3 length-type) 0 (lsh 1 length-type)) - content-tag (logand 15 (lsh ptag -2)) - packet-bytes 0 - header-bytes (1+ length-type)) - (dotimes (i length-type) - (setq packet-bytes - (logior (lsh packet-bytes 8) - (pgg-byte-after (+ 1 i (point))))))) - (setq content-tag (logand 63 ptag) - length-type (pgg-parse-length-type - (pgg-byte-after (1+ (point)))) - packet-bytes (car length-type) - header-bytes (1+ (cdr length-type)))) - (list content-tag packet-bytes header-bytes))) - -(defun pgg-parse-packet (ptag) - (case (car ptag) - (1 ;Public-Key Encrypted Session Key Packet - (pgg-parse-public-key-encrypted-session-key-packet ptag)) - (2 ;Signature Packet - (pgg-parse-signature-packet ptag)) - (3 ;Symmetric-Key Encrypted Session Key Packet - (pgg-parse-symmetric-key-encrypted-session-key-packet ptag)) - ;; 4 -- One-Pass Signature Packet - ;; 5 -- Secret Key Packet - (6 ;Public Key Packet - (pgg-parse-public-key-packet ptag)) - ;; 7 -- Secret Subkey Packet - ;; 8 -- Compressed Data Packet - (9 ;Symmetrically Encrypted Data Packet - (pgg-read-body-string ptag)) - (10 ;Marker Packet - (pgg-read-body-string ptag)) - (11 ;Literal Data Packet - (pgg-read-body-string ptag)) - ;; 12 -- Trust Packet - (13 ;User ID Packet - (pgg-read-body-string ptag)) - ;; 14 -- Public Subkey Packet - ;; 60 .. 63 -- Private or Experimental Values - )) - -(defun pgg-parse-packets (&optional header-parser body-parser) - (let ((header-parser - (or header-parser - (function pgg-parse-packet-header))) - (body-parser - (or body-parser - (function pgg-parse-packet))) - result ptag) - (while (> (point-max) (1+ (point))) - (setq ptag (funcall header-parser)) - (pgg-skip-header ptag) - (push (cons (car ptag) - (save-excursion - (funcall body-parser ptag))) - result) - (if (zerop (nth 1 ptag)) - (goto-char (point-max)) - (forward-char (nth 1 ptag)))) - result)) - -(defun pgg-parse-signature-subpacket-header () - (let ((length-type (pgg-parse-length-type (pgg-byte-after)))) - (list (pgg-byte-after (+ (cdr length-type) (point))) - (1- (car length-type)) - (1+ (cdr length-type))))) - -(defun pgg-parse-signature-subpacket (ptag) - (case (car ptag) - (2 ;signature creation time - (cons 'creation-time - (let ((bytes (pgg-read-bytes 4))) - (pgg-parse-time-field bytes)))) - (3 ;signature expiration time - (cons 'signature-expiry - (let ((bytes (pgg-read-bytes 4))) - (pgg-parse-time-field bytes)))) - (4 ;exportable certification - (cons 'exportability (pgg-read-byte))) - (5 ;trust signature - (cons 'trust-level (pgg-read-byte))) - (6 ;regular expression - (cons 'regular-expression - (pgg-read-body-string ptag))) - (7 ;revocable - (cons 'revocability (pgg-read-byte))) - (9 ;key expiration time - (cons 'key-expiry - (let ((bytes (pgg-read-bytes 4))) - (pgg-parse-time-field bytes)))) - ;; 10 = placeholder for backward compatibility - (11 ;preferred symmetric algorithms - (cons 'preferred-symmetric-key-algorithm - (cdr (assq (pgg-read-byte) - pgg-parse-symmetric-key-algorithm-alist)))) - (12 ;revocation key - ) - (16 ;issuer key ID - (cons 'key-identifier - (pgg-format-key-identifier (pgg-read-body-string ptag)))) - (20 ;notation data - (pgg-skip-bytes 4) - (cons 'notation - (let ((name-bytes (pgg-read-bytes 2)) - (value-bytes (pgg-read-bytes 2))) - (cons (pgg-read-bytes-string - (logior (lsh (car name-bytes) 8) - (nth 1 name-bytes))) - (pgg-read-bytes-string - (logior (lsh (car value-bytes) 8) - (nth 1 value-bytes))))))) - (21 ;preferred hash algorithms - (cons 'preferred-hash-algorithm - (cdr (assq (pgg-read-byte) - pgg-parse-hash-algorithm-alist)))) - (22 ;preferred compression algorithms - (cons 'preferred-compression-algorithm - (cdr (assq (pgg-read-byte) - pgg-parse-compression-algorithm-alist)))) - (23 ;key server preferences - (cons 'key-server-preferences - (pgg-read-body ptag))) - (24 ;preferred key server - (cons 'preferred-key-server - (pgg-read-body-string ptag))) - ;; 25 = primary user id - (26 ;policy URL - (cons 'policy-url (pgg-read-body-string ptag))) - ;; 27 = key flags - ;; 28 = signer's user id - ;; 29 = reason for revocation - ;; 100 to 110 = internal or user-defined - )) - -(defun pgg-parse-signature-packet (ptag) - (let* ((signature-version (pgg-byte-after)) - (result (list (cons 'version signature-version))) - hashed-material field n) - (cond - ((= signature-version 3) - (pgg-skip-bytes 2) - (setq hashed-material (pgg-read-bytes 5)) - (pgg-set-alist result - 'signature-type - (cdr (assq (pop hashed-material) - pgg-parse-signature-type-alist))) - (pgg-set-alist result - 'creation-time - (pgg-parse-time-field hashed-material)) - (pgg-set-alist result - 'key-identifier - (pgg-format-key-identifier - (pgg-read-bytes-string 8))) - (pgg-set-alist result - 'public-key-algorithm (pgg-read-byte)) - (pgg-set-alist result - 'hash-algorithm (pgg-read-byte))) - ((= signature-version 4) - (pgg-skip-bytes 1) - (pgg-set-alist result - 'signature-type - (cdr (assq (pgg-read-byte) - pgg-parse-signature-type-alist))) - (pgg-set-alist result - 'public-key-algorithm - (pgg-read-byte)) - (pgg-set-alist result - 'hash-algorithm (pgg-read-byte)) - (when (>= 10000 (setq n (pgg-read-bytes 2) - n (logior (lsh (car n) 8) - (nth 1 n)))) - (save-restriction - (narrow-to-region (point)(+ n (point))) - (nconc result - (mapcar (function cdr) ;remove packet types - (pgg-parse-packets - #'pgg-parse-signature-subpacket-header - #'pgg-parse-signature-subpacket))) - (goto-char (point-max)))) - (when (>= 10000 (setq n (pgg-read-bytes 2) - n (logior (lsh (car n) 8) - (nth 1 n)))) - (save-restriction - (narrow-to-region (point)(+ n (point))) - (nconc result - (mapcar (function cdr) ;remove packet types - (pgg-parse-packets - #'pgg-parse-signature-subpacket-header - #'pgg-parse-signature-subpacket))))))) - - (setcdr (setq field (assq 'public-key-algorithm - result)) - (cdr (assq (cdr field) - pgg-parse-public-key-algorithm-alist))) - (setcdr (setq field (assq 'hash-algorithm - result)) - (cdr (assq (cdr field) - pgg-parse-hash-algorithm-alist))) - result)) - -(defun pgg-parse-public-key-encrypted-session-key-packet (ptag) - (let (result) - (pgg-set-alist result - 'version (pgg-read-byte)) - (pgg-set-alist result - 'key-identifier - (pgg-format-key-identifier - (pgg-read-bytes-string 8))) - (pgg-set-alist result - 'public-key-algorithm - (cdr (assq (pgg-read-byte) - pgg-parse-public-key-algorithm-alist))) - result)) - -(defun pgg-parse-symmetric-key-encrypted-session-key-packet (ptag) - (let (result) - (pgg-set-alist result - 'version - (pgg-read-byte)) - (pgg-set-alist result - 'symmetric-key-algorithm - (cdr (assq (pgg-read-byte) - pgg-parse-symmetric-key-algorithm-alist))) - result)) - -(defun pgg-parse-public-key-packet (ptag) - (let* ((key-version (pgg-read-byte)) - (result (list (cons 'version key-version))) - field) - (cond - ((= 3 key-version) - (pgg-set-alist result - 'creation-time - (let ((bytes (pgg-read-bytes 4))) - (pgg-parse-time-field bytes))) - (pgg-set-alist result - 'key-expiry (pgg-read-bytes 2)) - (pgg-set-alist result - 'public-key-algorithm (pgg-read-byte))) - ((= 4 key-version) - (pgg-set-alist result - 'creation-time - (let ((bytes (pgg-read-bytes 4))) - (pgg-parse-time-field bytes))) - (pgg-set-alist result - 'public-key-algorithm (pgg-read-byte)))) - - (setcdr (setq field (assq 'public-key-algorithm - result)) - (cdr (assq (cdr field) - pgg-parse-public-key-algorithm-alist))) - result)) - -;; p-d-p only calls this if it is defined, but the compiler does not -;; recognize that. -(declare-function pgg-parse-crc24-string "pgg-parse" (string)) - -(defun pgg-decode-packets () - (if (re-search-forward "^=\\([A-Za-z0-9+/]\\{4\\}\\)$" nil t) - (let ((p (match-beginning 0)) - (checksum (match-string 1))) - (delete-region p (point-max)) - (if (ignore-errors (base64-decode-region (point-min) p)) - (or (not (fboundp 'pgg-parse-crc24-string)) - pgg-ignore-packet-checksum - (string-equal (base64-encode-string (pgg-parse-crc24-string - (buffer-string))) - checksum) - (progn - (message "PGP packet checksum does not match") - nil)) - (message "PGP packet contain invalid base64") - nil)) - (message "PGP packet checksum not found") - nil)) - -(defun pgg-decode-armor-region (start end) - (save-restriction - (narrow-to-region start end) - (goto-char (point-min)) - (re-search-forward "^-+BEGIN PGP" nil t) - (delete-region (point-min) - (and (search-forward "\n\n") - (match-end 0))) - (when (pgg-decode-packets) - (goto-char (point-min)) - (pgg-parse-packets)))) - -(defun pgg-parse-armor (string) - (with-temp-buffer - (buffer-disable-undo) - (unless (featurep 'xemacs) - (set-buffer-multibyte nil)) - (insert string) - (pgg-decode-armor-region (point-min)(point)))) - -(eval-and-compile - (defalias 'pgg-string-as-unibyte (if (fboundp 'string-as-unibyte) - 'string-as-unibyte - 'identity))) - -(defun pgg-parse-armor-region (start end) - (pgg-parse-armor (pgg-string-as-unibyte (buffer-substring start end)))) - -(provide 'pgg-parse) - -;;; pgg-parse.el ends here diff --git a/lisp/pgg-pgp.el b/lisp/pgg-pgp.el deleted file mode 100644 index 8e42779a2..000000000 --- a/lisp/pgg-pgp.el +++ /dev/null @@ -1,257 +0,0 @@ -;;; pgg-pgp.el --- PGP 2.* and 6.* support for PGG. - -;; Copyright (C) 1999-2000, 2002-2012 Free Software Foundation, Inc. - -;; Author: Daiki Ueno -;; Created: 1999/11/02 -;; Keywords: PGP, OpenPGP -;; Package: pgg -;; Obsolete-since: 24.1 - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software: you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs. If not, see . - -;;; Code: - -(eval-when-compile - (require 'cl) ; for pgg macros - (require 'pgg)) - -(defgroup pgg-pgp () - "PGP 2.* and 6.* interface." - :group 'pgg) - -(defcustom pgg-pgp-program "pgp" - "PGP 2.* and 6.* executable." - :group 'pgg-pgp - :type 'string) - -(defcustom pgg-pgp-shell-file-name "/bin/sh" - "File name to load inferior shells from. -Bourne shell or its equivalent \(not tcsh) is needed for \"2>\"." - :group 'pgg-pgp - :type 'string) - -(defcustom pgg-pgp-shell-command-switch "-c" - "Switch used to have the shell execute its command line argument." - :group 'pgg-pgp - :type 'string) - -(defcustom pgg-pgp-extra-args nil - "Extra arguments for every PGP invocation." - :group 'pgg-pgp - :type '(choice - (const :tag "None" nil) - (string :tag "Arguments"))) - -(defvar pgg-pgp-user-id nil - "PGP ID of your default identity.") - -(defun pgg-pgp-process-region (start end passphrase program args) - (let* ((errors-file-name (pgg-make-temp-file "pgg-errors")) - (args - (concat args - pgg-pgp-extra-args - " 2>" (shell-quote-argument errors-file-name))) - (shell-file-name pgg-pgp-shell-file-name) - (shell-command-switch pgg-pgp-shell-command-switch) - (process-environment process-environment) - (output-buffer pgg-output-buffer) - (errors-buffer pgg-errors-buffer) - (process-connection-type nil) - process status exit-status) - (with-current-buffer (get-buffer-create output-buffer) - (buffer-disable-undo) - (erase-buffer)) - (when passphrase - (setenv "PGPPASSFD" "0")) - (unwind-protect - (progn - (let ((coding-system-for-read 'binary) - (coding-system-for-write 'binary)) - (setq process - (start-process-shell-command "*PGP*" output-buffer - (concat program " " args)))) - (set-process-sentinel process #'ignore) - (when passphrase - (process-send-string process (concat passphrase "\n"))) - (process-send-region process start end) - (process-send-eof process) - (while (eq 'run (process-status process)) - (accept-process-output process 5)) - (setq status (process-status process) - exit-status (process-exit-status process)) - (delete-process process) - (with-current-buffer output-buffer - (pgg-convert-lbt-region (point-min)(point-max) 'LF) - - (if (memq status '(stop signal)) - (error "%s exited abnormally: '%s'" program exit-status)) - (if (= 127 exit-status) - (error "%s could not be found" program)) - - (set-buffer (get-buffer-create errors-buffer)) - (buffer-disable-undo) - (erase-buffer) - (insert-file-contents errors-file-name))) - (if (and process (eq 'run (process-status process))) - (interrupt-process process)) - (condition-case nil - (delete-file errors-file-name) - (file-error nil))))) - -(defun pgg-pgp-lookup-key (string &optional type) - "Search keys associated with STRING." - (let ((args (list "+batchmode" "+language=en" "-kv" string))) - (with-current-buffer (get-buffer-create pgg-output-buffer) - (buffer-disable-undo) - (erase-buffer) - (apply #'call-process pgg-pgp-program nil t nil args) - (goto-char (point-min)) - (cond - ((re-search-forward "^pub\\s +[0-9]+/" nil t);PGP 2.* - (buffer-substring (point)(+ 8 (point)))) - ((re-search-forward "^Type" nil t);PGP 6.* - (beginning-of-line 2) - (substring - (nth 2 (split-string - (buffer-substring (point)(progn (end-of-line) (point))))) - 2)))))) - -(defun pgg-pgp-encrypt-region (start end recipients &optional sign passphrase) - "Encrypt the current region between START and END." - (let* ((pgg-pgp-user-id (or pgg-pgp-user-id pgg-default-user-id)) - (passphrase (or passphrase - (when sign - (pgg-read-passphrase - (format "PGP passphrase for %s: " - pgg-pgp-user-id) - pgg-pgp-user-id)))) - (args - (concat - "+encrypttoself=off +verbose=1 +batchmode +language=us -fate " - (if (or recipients pgg-encrypt-for-me) - (mapconcat 'shell-quote-argument - (append recipients - (if pgg-encrypt-for-me - (list pgg-pgp-user-id))) " ")) - (if sign (concat " -s -u " (shell-quote-argument pgg-pgp-user-id)))))) - (pgg-pgp-process-region start end nil pgg-pgp-program args) - (pgg-process-when-success nil))) - -(defun pgg-pgp-decrypt-region (start end &optional passphrase) - "Decrypt the current region between START and END. - -If optional PASSPHRASE is not specified, it will be obtained from the -passphrase cache or user." - (let* ((pgg-pgp-user-id (or pgg-pgp-user-id pgg-default-user-id)) - (key (pgg-pgp-lookup-key pgg-pgp-user-id 'encrypt)) - (passphrase - (or passphrase - (pgg-read-passphrase - (format "PGP passphrase for %s: " pgg-pgp-user-id) key))) - (args - "+verbose=1 +batchmode +language=us -f")) - (pgg-pgp-process-region start end passphrase pgg-pgp-program args) - (pgg-process-when-success - (if pgg-cache-passphrase - (pgg-add-passphrase-to-cache key passphrase))))) - -(defun pgg-pgp-sign-region (start end &optional clearsign passphrase) - "Make detached signature from text between START and END. - -If optional PASSPHRASE is not specified, it will be obtained from the -passphrase cache or user." - (let* ((pgg-pgp-user-id (or pgg-pgp-user-id pgg-default-user-id)) - (passphrase - (or passphrase - (pgg-read-passphrase - (format "PGP passphrase for %s: " pgg-pgp-user-id) - (pgg-pgp-lookup-key pgg-pgp-user-id 'sign)))) - (args - (concat (if clearsign "-fast" "-fbast") - " +verbose=1 +language=us +batchmode" - " -u " (shell-quote-argument pgg-pgp-user-id)))) - (pgg-pgp-process-region start end passphrase pgg-pgp-program args) - (pgg-process-when-success - (goto-char (point-min)) - (when (re-search-forward "^-+BEGIN PGP" nil t);XXX - (let ((packet - (cdr (assq 2 (pgg-parse-armor-region - (progn (beginning-of-line 2) - (point)) - (point-max)))))) - (if pgg-cache-passphrase - (pgg-add-passphrase-to-cache - (cdr (assq 'key-identifier packet)) - passphrase))))))) - -(defun pgg-pgp-verify-region (start end &optional signature) - "Verify region between START and END as the detached signature SIGNATURE." - (let* ((orig-file (pgg-make-temp-file "pgg")) - (args "+verbose=1 +batchmode +language=us") - (orig-mode (default-file-modes))) - (unwind-protect - (progn - (set-default-file-modes 448) - (let ((coding-system-for-write 'binary) - jka-compr-compression-info-list jam-zcat-filename-list) - (write-region start end orig-file))) - (set-default-file-modes orig-mode)) - (if (stringp signature) - (progn - (copy-file signature (setq signature (concat orig-file ".asc"))) - (setq args (concat args " " (shell-quote-argument signature))))) - (setq args (concat args " " (shell-quote-argument orig-file))) - (pgg-pgp-process-region (point)(point) nil pgg-pgp-program args) - (delete-file orig-file) - (if signature (delete-file signature)) - (pgg-process-when-success - (goto-char (point-min)) - (let ((case-fold-search t)) - (while (re-search-forward "^warning: " nil t) - (delete-region (match-beginning 0) - (progn (beginning-of-line 2) (point))))) - (goto-char (point-min)) - (when (re-search-forward "^\\.$" nil t) - (delete-region (point-min) - (progn (beginning-of-line 2) - (point))))))) - -(defun pgg-pgp-insert-key () - "Insert public key at point." - (let* ((pgg-pgp-user-id (or pgg-pgp-user-id pgg-default-user-id)) - (args - (concat "+verbose=1 +batchmode +language=us -kxaf " - (shell-quote-argument pgg-pgp-user-id)))) - (pgg-pgp-process-region (point)(point) nil pgg-pgp-program args) - (insert-buffer-substring pgg-output-buffer))) - -(defun pgg-pgp-snarf-keys-region (start end) - "Add all public keys in region between START and END to the keyring." - (let* ((pgg-pgp-user-id (or pgg-pgp-user-id pgg-default-user-id)) - (key-file (pgg-make-temp-file "pgg")) - (args - (concat "+verbose=1 +batchmode +language=us -kaf " - (shell-quote-argument key-file)))) - (let ((coding-system-for-write 'raw-text-dos)) - (write-region start end key-file)) - (pgg-pgp-process-region start end nil pgg-pgp-program args) - (delete-file key-file) - (pgg-process-when-success nil))) - -(provide 'pgg-pgp) - -;;; pgg-pgp.el ends here diff --git a/lisp/pgg-pgp5.el b/lisp/pgg-pgp5.el deleted file mode 100644 index c6c8cd174..000000000 --- a/lisp/pgg-pgp5.el +++ /dev/null @@ -1,258 +0,0 @@ -;;; pgg-pgp5.el --- PGP 5.* support for PGG. - -;; Copyright (C) 1999-2000, 2002-2012 Free Software Foundation, Inc. - -;; Author: Daiki Ueno -;; Created: 1999/11/02 -;; Keywords: PGP, OpenPGP -;; Package: pgg -;; Obsolete-since: 24.1 - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software: you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs. If not, see . - -;;; Code: - -(eval-when-compile - (require 'cl) ; for pgg macros - (require 'pgg)) - -(defgroup pgg-pgp5 () - "PGP 5.* interface." - :group 'pgg) - -(defcustom pgg-pgp5-pgpe-program "pgpe" - "PGP 5.* 'pgpe' executable." - :group 'pgg-pgp5 - :type 'string) - -(defcustom pgg-pgp5-pgps-program "pgps" - "PGP 5.* 'pgps' executable." - :group 'pgg-pgp5 - :type 'string) - -(defcustom pgg-pgp5-pgpk-program "pgpk" - "PGP 5.* 'pgpk' executable." - :group 'pgg-pgp5 - :type 'string) - -(defcustom pgg-pgp5-pgpv-program "pgpv" - "PGP 5.* 'pgpv' executable." - :group 'pgg-pgp5 - :type 'string) - -(defcustom pgg-pgp5-shell-file-name "/bin/sh" - "File name to load inferior shells from. -Bourne shell or its equivalent \(not tcsh) is needed for \"2>\"." - :group 'pgg-pgp5 - :type 'string) - -(defcustom pgg-pgp5-shell-command-switch "-c" - "Switch used to have the shell execute its command line argument." - :group 'pgg-pgp5 - :type 'string) - -(defcustom pgg-pgp5-extra-args nil - "Extra arguments for every PGP 5.* invocation." - :group 'pgg-pgp5 - :type '(choice - (const :tag "None" nil) - (string :tag "Arguments"))) - -(defvar pgg-pgp5-user-id nil - "PGP 5.* ID of your default identity.") - -(defun pgg-pgp5-process-region (start end passphrase program args) - (let* ((errors-file-name (pgg-make-temp-file "pgg-errors")) - (args - (append args - pgg-pgp5-extra-args - (list (concat "2>" errors-file-name)))) - (shell-file-name pgg-pgp5-shell-file-name) - (shell-command-switch pgg-pgp5-shell-command-switch) - (process-environment process-environment) - (output-buffer pgg-output-buffer) - (errors-buffer pgg-errors-buffer) - (process-connection-type nil) - process status exit-status) - (with-current-buffer (get-buffer-create output-buffer) - (buffer-disable-undo) - (erase-buffer)) - (when passphrase - (setenv "PGPPASSFD" "0")) - (unwind-protect - (progn - (let ((coding-system-for-read 'binary) - (coding-system-for-write 'binary)) - (setq process - (apply #'funcall - #'start-process-shell-command "*PGP*" output-buffer - program args))) - (set-process-sentinel process #'ignore) - (when passphrase - (process-send-string process (concat passphrase "\n"))) - (process-send-region process start end) - (process-send-eof process) - (while (eq 'run (process-status process)) - (accept-process-output process 5)) - (setq status (process-status process) - exit-status (process-exit-status process)) - (delete-process process) - (with-current-buffer output-buffer - (pgg-convert-lbt-region (point-min)(point-max) 'LF) - - (if (memq status '(stop signal)) - (error "%s exited abnormally: '%s'" program exit-status)) - (if (= 127 exit-status) - (error "%s could not be found" program)) - - (set-buffer (get-buffer-create errors-buffer)) - (buffer-disable-undo) - (erase-buffer) - (insert-file-contents errors-file-name))) - (if (and process (eq 'run (process-status process))) - (interrupt-process process)) - (condition-case nil - (delete-file errors-file-name) - (file-error nil))))) - -(defun pgg-pgp5-lookup-key (string &optional type) - "Search keys associated with STRING." - (let ((args (list "+language=en" "-l" string))) - (with-current-buffer (get-buffer-create pgg-output-buffer) - (buffer-disable-undo) - (erase-buffer) - (apply #'call-process pgg-pgp5-pgpk-program nil t nil args) - (goto-char (point-min)) - (when (re-search-forward "^sec" nil t) - (substring - (nth 2 (split-string - (buffer-substring (match-end 0)(progn (end-of-line)(point))))) - 2))))) - -(defun pgg-pgp5-encrypt-region (start end recipients &optional sign passphrase) - "Encrypt the current region between START and END." - (let* ((pgg-pgp5-user-id (or pgg-pgp5-user-id pgg-default-user-id)) - (passphrase (or passphrase - (when sign - (pgg-read-passphrase - (format "PGP passphrase for %s: " - pgg-pgp5-user-id) - pgg-pgp5-user-id)))) - (args - (append - `("+NoBatchInvalidKeys=off" "-fat" "+batchmode=1" - ,@(if (or recipients pgg-encrypt-for-me) - (apply #'append - (mapcar (lambda (rcpt) - (list "-r" - (concat "\"" rcpt "\""))) - (append recipients - (if pgg-encrypt-for-me - (list pgg-pgp5-user-id))))))) - (if sign '("-s" "-u" pgg-pgp5-user-id))))) - (pgg-pgp5-process-region start end nil pgg-pgp5-pgpe-program args) - (pgg-process-when-success nil))) - -(defun pgg-pgp5-decrypt-region (start end &optional passphrase) - "Decrypt the current region between START and END." - (let* ((pgg-pgp5-user-id (or pgg-pgp5-user-id pgg-default-user-id)) - (passphrase - (or passphrase - (pgg-read-passphrase - (format "PGP passphrase for %s: " pgg-pgp5-user-id) - (pgg-pgp5-lookup-key pgg-pgp5-user-id 'encrypt)))) - (args - '("+verbose=1" "+batchmode=1" "+language=us" "-f"))) - (pgg-pgp5-process-region start end passphrase pgg-pgp5-pgpv-program args) - (pgg-process-when-success nil))) - -(defun pgg-pgp5-sign-region (start end &optional clearsign passphrase) - "Make detached signature from text between START and END." - (let* ((pgg-pgp5-user-id (or pgg-pgp5-user-id pgg-default-user-id)) - (passphrase - (or passphrase - (pgg-read-passphrase - (format "PGP passphrase for %s: " pgg-pgp5-user-id) - (pgg-pgp5-lookup-key pgg-pgp5-user-id 'sign)))) - (args - (list (if clearsign "-fat" "-fbat") - "+verbose=1" "+language=us" "+batchmode=1" - "-u" pgg-pgp5-user-id))) - (pgg-pgp5-process-region start end passphrase pgg-pgp5-pgps-program args) - (pgg-process-when-success - (when (re-search-forward "^-+BEGIN PGP SIGNATURE" nil t);XXX - (let ((packet - (cdr (assq 2 (pgg-parse-armor-region - (progn (beginning-of-line 2) - (point)) - (point-max)))))) - (if pgg-cache-passphrase - (pgg-add-passphrase-to-cache - (cdr (assq 'key-identifier packet)) - passphrase))))))) - -(defun pgg-pgp5-verify-region (start end &optional signature) - "Verify region between START and END as the detached signature SIGNATURE." - (let ((orig-file (pgg-make-temp-file "pgg")) - (args '("+verbose=1" "+batchmode=1" "+language=us")) - (orig-mode (default-file-modes))) - (unwind-protect - (progn - (set-default-file-modes 448) - (let ((coding-system-for-write 'binary) - jka-compr-compression-info-list jam-zcat-filename-list) - (write-region start end orig-file))) - (set-default-file-modes orig-mode)) - (when (stringp signature) - (copy-file signature (setq signature (concat orig-file ".asc"))) - (setq args (append args (list signature)))) - (pgg-pgp5-process-region (point)(point) nil pgg-pgp5-pgpv-program args) - (delete-file orig-file) - (if signature (delete-file signature)) - (with-current-buffer pgg-errors-buffer - (goto-char (point-min)) - (if (re-search-forward "^Good signature" nil t) - (progn - (set-buffer pgg-output-buffer) - (insert-buffer-substring pgg-errors-buffer) - t) - nil)))) - -(defun pgg-pgp5-insert-key () - "Insert public key at point." - (let* ((pgg-pgp5-user-id (or pgg-pgp5-user-id pgg-default-user-id)) - (args - (list "+verbose=1" "+batchmode=1" "+language=us" "-x" - (concat "\"" pgg-pgp5-user-id "\"")))) - (pgg-pgp5-process-region (point)(point) nil pgg-pgp5-pgpk-program args) - (insert-buffer-substring pgg-output-buffer))) - -(defun pgg-pgp5-snarf-keys-region (start end) - "Add all public keys in region between START and END to the keyring." - (let* ((pgg-pgp5-user-id (or pgg-pgp5-user-id pgg-default-user-id)) - (key-file (pgg-make-temp-file "pgg")) - (args - (list "+verbose=1" "+batchmode=1" "+language=us" "-a" - key-file))) - (let ((coding-system-for-write 'raw-text-dos)) - (write-region start end key-file)) - (pgg-pgp5-process-region start end nil pgg-pgp5-pgpk-program args) - (delete-file key-file) - (pgg-process-when-success nil))) - -(provide 'pgg-pgp5) - -;;; pgg-pgp5.el ends here diff --git a/lisp/pgg.el b/lisp/pgg.el deleted file mode 100644 index 01c22dd2e..000000000 --- a/lisp/pgg.el +++ /dev/null @@ -1,597 +0,0 @@ -;;; pgg.el --- glue for the various PGP implementations. - -;; Copyright (C) 1999-2000, 2002-2012 Free Software Foundation, Inc. - -;; Author: Daiki Ueno -;; Symmetric encryption added by: Sascha Wilde -;; Created: 1999/10/28 -;; Keywords: PGP -;; Obsolete-since: 24.1 - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software: you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, or -;; (at your option) any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs. If not, see . - -;;; Code: - -(require 'pgg-def) -(require 'pgg-parse) -(autoload 'run-at-time "timer") - -;; Don't merge these two `eval-when-compile's. -(eval-when-compile - ;; For Emacs <22.2 and XEmacs. - (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))) - (require 'cl)) - -;;; @ utility functions -;;; - -(eval-when-compile - (when (featurep 'xemacs) - (defmacro pgg-run-at-time-1 (time repeat function args) - (if (condition-case nil - (let ((delete-itimer 'delete-itimer) - (itimer-driver-start 'itimer-driver-start) - (itimer-value 'itimer-value) - (start-itimer 'start-itimer)) - (unless (or (symbol-value 'itimer-process) - (symbol-value 'itimer-timer)) - (funcall itimer-driver-start)) - ;; Check whether there is a bug to which the difference of - ;; the present time and the time when the itimer driver was - ;; woken up is subtracted from the initial itimer value. - (let* ((inhibit-quit t) - (ctime (current-time)) - (itimer-timer-last-wakeup - (prog1 - ctime - (setcar ctime (1- (car ctime))))) - (itimer-list nil) - (itimer (funcall start-itimer "pgg-run-at-time" - 'ignore 5))) - (sleep-for 0.1) ;; Accept the timeout interrupt. - (prog1 - (> (funcall itimer-value itimer) 0) - (funcall delete-itimer itimer)))) - (error nil)) - `(let ((time ,time)) - (apply #'start-itimer "pgg-run-at-time" - ,function (if time (max time 1e-9) 1e-9) - ,repeat nil t ,args)) - `(let ((time ,time) - (itimers (list nil))) - (setcar - itimers - (apply #'start-itimer "pgg-run-at-time" - (lambda (itimers repeat function &rest args) - (let ((itimer (car itimers))) - (if repeat - (progn - (set-itimer-function - itimer - (lambda (itimer repeat function &rest args) - (set-itimer-restart itimer repeat) - (set-itimer-function itimer function) - (set-itimer-function-arguments itimer args) - (apply function args))) - (set-itimer-function-arguments - itimer - (append (list itimer repeat function) args))) - (set-itimer-function - itimer - (lambda (itimer function &rest args) - (delete-itimer itimer) - (apply function args))) - (set-itimer-function-arguments - itimer - (append (list itimer function) args))))) - 1e-9 (if time (max time 1e-9) 1e-9) - nil t itimers ,repeat ,function ,args))))))) - -(eval-and-compile - (if (featurep 'xemacs) - (progn - (defun pgg-run-at-time (time repeat function &rest args) - "Emulating function run as `run-at-time'. -TIME should be nil meaning now, or a number of seconds from now. -Return an itimer object which can be used in either `delete-itimer' -or `cancel-timer'." - (pgg-run-at-time-1 time repeat function args)) - (defun pgg-cancel-timer (timer) - "Emulate cancel-timer for xemacs." - (let ((delete-itimer 'delete-itimer)) - (funcall delete-itimer timer)))) - (defalias 'pgg-run-at-time 'run-at-time) - (defalias 'pgg-cancel-timer 'cancel-timer))) - -(defun pgg-invoke (func scheme &rest args) - (progn - (require (intern (format "pgg-%s" scheme))) - (apply 'funcall (intern (format "pgg-%s-%s" scheme func)) args))) - -(put 'pgg-save-coding-system 'lisp-indent-function 2) - -(defmacro pgg-save-coding-system (start end &rest body) - `(if (interactive-p) - (let ((buffer (current-buffer))) - (with-temp-buffer - (let (buffer-undo-list) - (insert-buffer-substring buffer ,start ,end) - (encode-coding-region (point-min)(point-max) - buffer-file-coding-system) - (prog1 (save-excursion ,@body) - (push nil buffer-undo-list) - (ignore-errors (undo)))))) - (save-restriction - (narrow-to-region ,start ,end) - ,@body))) - -(defun pgg-temp-buffer-show-function (buffer) - (let ((window (or (get-buffer-window buffer 'visible) - (split-window-vertically)))) - (set-window-buffer window buffer) - (shrink-window-if-larger-than-buffer window))) - -;; XXX `pgg-display-output-buffer' is a horrible name for this function. -;; It should be something like `pgg-situate-output-or-display-error'. -(defun pgg-display-output-buffer (start end status) - "Situate en/decryption results or pop up an error buffer. - -Text from START to END is replaced by contents of output buffer if STATUS -is true, or else the output buffer is displayed." - (if status - (pgg-situate-output start end) - (pgg-display-error-buffer))) - -(defun pgg-situate-output (start end) - "Place en/decryption result in place of current text from START to END." - (delete-region start end) - (insert-buffer-substring pgg-output-buffer) - (decode-coding-region start (point) buffer-file-coding-system)) - -(defun pgg-display-error-buffer () - "Pop up an error buffer indicating the reason for an en/decryption failure." - (let ((temp-buffer-show-function - (function pgg-temp-buffer-show-function))) - (with-output-to-temp-buffer pgg-echo-buffer - (set-buffer standard-output) - (insert-buffer-substring pgg-errors-buffer)))) - -(defvar pgg-passphrase-cache (make-vector 7 0)) - -(defvar pgg-pending-timers (make-vector 7 0) - "Hash table for managing scheduled pgg cache management timers. - -We associate key and timer, so the timer can be canceled if a new -timeout for the key is set while an old one is still pending.") - -(defun pgg-read-passphrase (prompt &optional key notruncate) - "Using PROMPT, obtain passphrase for KEY from cache or user. - -Truncate the key to 8 trailing characters unless NOTRUNCATE is true -\(default false). - -Custom variables `pgg-cache-passphrase' and `pgg-passphrase-cache-expiry' -regulate cache behavior." - (or (pgg-read-passphrase-from-cache key notruncate) - (read-passwd prompt))) - -(defun pgg-read-passphrase-from-cache (key &optional notruncate) - "Obtain passphrase for KEY from time-limited passphrase cache. - -Truncate the key to 8 trailing characters unless NOTRUNCATE is true -\(default false). - -Custom variables `pgg-cache-passphrase' and `pgg-passphrase-cache-expiry' -regulate cache behavior." - (and pgg-cache-passphrase - key (or notruncate - (setq key (pgg-truncate-key-identifier key))) - (symbol-value (intern-soft key pgg-passphrase-cache)))) - -(defun pgg-add-passphrase-to-cache (key passphrase &optional notruncate) - "Associate KEY with PASSPHRASE in time-limited passphrase cache. - -Truncate the key to 8 trailing characters unless NOTRUNCATE is true -\(default false). - -Custom variables `pgg-cache-passphrase' and `pgg-passphrase-cache-expiry' -regulate cache behavior." - - (let* ((key (if notruncate key (pgg-truncate-key-identifier key))) - (interned-timer-key (intern-soft key pgg-pending-timers)) - (old-timer (symbol-value interned-timer-key)) - new-timer) - (when old-timer - (cancel-timer old-timer) - (unintern interned-timer-key pgg-pending-timers)) - (set (intern key pgg-passphrase-cache) - passphrase) - (set (intern key pgg-pending-timers) - (pgg-run-at-time pgg-passphrase-cache-expiry nil - #'pgg-remove-passphrase-from-cache - key notruncate)))) - -(if (fboundp 'clear-string) - (defalias 'pgg-clear-string 'clear-string) - (defun pgg-clear-string (string) - (fillarray string ?_))) - -(declare-function pgg-clear-string "pgg" (string)) - -(defun pgg-remove-passphrase-from-cache (key &optional notruncate) - "Omit passphrase associated with KEY in time-limited passphrase cache. - -Truncate the key to 8 trailing characters unless NOTRUNCATE is true -\(default false). - -This is a no-op if there is not entry for KEY (eg, it's already expired. - -The memory for the passphrase is filled with underscores to clear any -references to it. - -Custom variables `pgg-cache-passphrase' and `pgg-passphrase-cache-expiry' -regulate cache behavior." - (let* ((passphrase (pgg-read-passphrase-from-cache key notruncate)) - (key (if notruncate key (pgg-truncate-key-identifier key))) - (interned-timer-key (intern-soft key pgg-pending-timers)) - (old-timer (symbol-value interned-timer-key))) - (when passphrase - (pgg-clear-string passphrase) - (unintern key pgg-passphrase-cache)) - (when old-timer - (pgg-cancel-timer old-timer) - (unintern interned-timer-key pgg-pending-timers)))) - -(defmacro pgg-convert-lbt-region (start end lbt) - `(let ((pgg-conversion-end (set-marker (make-marker) ,end))) - (goto-char ,start) - (case ,lbt - (CRLF - (while (progn - (end-of-line) - (> (marker-position pgg-conversion-end) (point))) - (insert "\r") - (forward-line 1))) - (LF - (while (re-search-forward "\r$" pgg-conversion-end t) - (replace-match "")))))) - -(put 'pgg-as-lbt 'lisp-indent-function 3) - -(defmacro pgg-as-lbt (start end lbt &rest body) - `(let ((inhibit-read-only t) - buffer-read-only - buffer-undo-list) - (pgg-convert-lbt-region ,start ,end ,lbt) - (let ((,end (point))) - ,@body) - (push nil buffer-undo-list) - (ignore-errors (undo)))) - -(put 'pgg-process-when-success 'lisp-indent-function 0) - -(defmacro pgg-process-when-success (&rest body) - `(with-current-buffer pgg-output-buffer - (if (zerop (buffer-size)) nil ,@body t))) - -(defalias 'pgg-make-temp-file - (if (fboundp 'make-temp-file) - 'make-temp-file - (lambda (prefix &optional dir-flag) - (let ((file (expand-file-name - (make-temp-name prefix) - (if (fboundp 'temp-directory) - (temp-directory) - temporary-file-directory)))) - (if dir-flag - (make-directory file)) - file)))) - -;;; @ interface functions -;;; - -;;;###autoload -(defun pgg-encrypt-region (start end rcpts &optional sign passphrase) - "Encrypt the current region between START and END for RCPTS. - -If optional argument SIGN is non-nil, do a combined sign and encrypt. - -If optional PASSPHRASE is not specified, it will be obtained from the -passphrase cache or user." - (interactive - (list (region-beginning)(region-end) - (split-string (read-string "Recipients: ") "[ \t,]+"))) - (let ((status - (pgg-save-coding-system start end - (pgg-invoke "encrypt-region" (or pgg-scheme pgg-default-scheme) - (point-min) (point-max) rcpts sign passphrase)))) - (when (interactive-p) - (pgg-display-output-buffer start end status)) - status)) - -;;;###autoload -(defun pgg-encrypt-symmetric-region (start end &optional passphrase) - "Encrypt the current region between START and END symmetric with passphrase. - -If optional PASSPHRASE is not specified, it will be obtained from the -cache or user." - (interactive "r") - (let ((status - (pgg-save-coding-system start end - (pgg-invoke "encrypt-symmetric-region" - (or pgg-scheme pgg-default-scheme) - (point-min) (point-max) passphrase)))) - (when (interactive-p) - (pgg-display-output-buffer start end status)) - status)) - -;;;###autoload -(defun pgg-encrypt-symmetric (&optional start end passphrase) - "Encrypt the current buffer using a symmetric, rather than key-pair, cipher. - -If optional arguments START and END are specified, only encrypt within -the region. - -If optional PASSPHRASE is not specified, it will be obtained from the -passphrase cache or user." - (interactive) - (let* ((start (or start (point-min))) - (end (or end (point-max))) - (status (pgg-encrypt-symmetric-region start end passphrase))) - (when (interactive-p) - (pgg-display-output-buffer start end status)) - status)) - -;;;###autoload -(defun pgg-encrypt (rcpts &optional sign start end passphrase) - "Encrypt the current buffer for RCPTS. - -If optional argument SIGN is non-nil, do a combined sign and encrypt. - -If optional arguments START and END are specified, only encrypt within -the region. - -If optional PASSPHRASE is not specified, it will be obtained from the -passphrase cache or user." - (interactive (list (split-string (read-string "Recipients: ") "[ \t,]+"))) - (let* ((start (or start (point-min))) - (end (or end (point-max))) - (status (pgg-encrypt-region start end rcpts sign passphrase))) - (when (interactive-p) - (pgg-display-output-buffer start end status)) - status)) - -;;;###autoload -(defun pgg-decrypt-region (start end &optional passphrase) - "Decrypt the current region between START and END. - -If optional PASSPHRASE is not specified, it will be obtained from the -passphrase cache or user." - (interactive "r") - (let* ((buf (current-buffer)) - (status - (pgg-save-coding-system start end - (pgg-invoke "decrypt-region" (or pgg-scheme pgg-default-scheme) - (point-min) (point-max) passphrase)))) - (when (interactive-p) - (pgg-display-output-buffer start end status)) - status)) - -;;;###autoload -(defun pgg-decrypt (&optional start end passphrase) - "Decrypt the current buffer. - -If optional arguments START and END are specified, only decrypt within -the region. - -If optional PASSPHRASE is not specified, it will be obtained from the -passphrase cache or user." - (interactive "") - (let* ((start (or start (point-min))) - (end (or end (point-max))) - (status (pgg-decrypt-region start end passphrase))) - (when (interactive-p) - (pgg-display-output-buffer start end status)) - status)) - -;;;###autoload -(defun pgg-sign-region (start end &optional cleartext passphrase) - "Make the signature from text between START and END. - -If the optional 3rd argument CLEARTEXT is non-nil, it does not create -a detached signature. - -If this function is called interactively, CLEARTEXT is enabled -and the output is displayed. - -If optional PASSPHRASE is not specified, it will be obtained from the -passphrase cache or user." - (interactive "r") - (let ((status (pgg-save-coding-system start end - (pgg-invoke "sign-region" (or pgg-scheme pgg-default-scheme) - (point-min) (point-max) - (or (interactive-p) cleartext) - passphrase)))) - (when (interactive-p) - (pgg-display-output-buffer start end status)) - status)) - -;;;###autoload -(defun pgg-sign (&optional cleartext start end passphrase) - "Sign the current buffer. - -If the optional argument CLEARTEXT is non-nil, it does not create a -detached signature. - -If optional arguments START and END are specified, only sign data -within the region. - -If this function is called interactively, CLEARTEXT is enabled -and the output is displayed. - -If optional PASSPHRASE is not specified, it will be obtained from the -passphrase cache or user." - (interactive "") - (let* ((start (or start (point-min))) - (end (or end (point-max))) - (status (pgg-sign-region start end - (or (interactive-p) cleartext) - passphrase))) - (when (interactive-p) - (pgg-display-output-buffer start end status)) - status)) - -;;;###autoload -(defun pgg-verify-region (start end &optional signature fetch) - "Verify the current region between START and END. -If the optional 3rd argument SIGNATURE is non-nil, it is treated as -the detached signature of the current region. - -If the optional 4th argument FETCH is non-nil, we attempt to fetch the -signer's public key from `pgg-default-keyserver-address'." - (interactive "r") - (let* ((packet - (if (null signature) nil - (with-temp-buffer - (buffer-disable-undo) - (unless (featurep 'xemacs) - (set-buffer-multibyte nil)) - (insert-file-contents signature) - (cdr (assq 2 (pgg-decode-armor-region - (point-min)(point-max))))))) - (key (cdr (assq 'key-identifier packet))) - status keyserver) - (and (stringp key) - pgg-query-keyserver - (setq key (concat "0x" (pgg-truncate-key-identifier key))) - (null (pgg-lookup-key key)) - (or fetch (interactive-p)) - (y-or-n-p (format "Key %s not found; attempt to fetch? " key)) - (setq keyserver - (or (cdr (assq 'preferred-key-server packet)) - pgg-default-keyserver-address)) - (pgg-fetch-key keyserver key)) - (setq status - (pgg-save-coding-system start end - (pgg-invoke "verify-region" (or pgg-scheme pgg-default-scheme) - (point-min) (point-max) signature))) - (when (interactive-p) - (let ((temp-buffer-show-function - (function pgg-temp-buffer-show-function))) - (with-output-to-temp-buffer pgg-echo-buffer - (set-buffer standard-output) - (insert-buffer-substring (if status pgg-output-buffer - pgg-errors-buffer))))) - status)) - -;;;###autoload -(defun pgg-verify (&optional signature fetch start end) - "Verify the current buffer. -If the optional argument SIGNATURE is non-nil, it is treated as -the detached signature of the current region. -If the optional argument FETCH is non-nil, we attempt to fetch the -signer's public key from `pgg-default-keyserver-address'. -If optional arguments START and END are specified, only verify data -within the region." - (interactive "") - (let* ((start (or start (point-min))) - (end (or end (point-max))) - (status (pgg-verify-region start end signature fetch))) - (when (interactive-p) - (let ((temp-buffer-show-function - (function pgg-temp-buffer-show-function))) - (with-output-to-temp-buffer pgg-echo-buffer - (set-buffer standard-output) - (insert-buffer-substring (if status pgg-output-buffer - pgg-errors-buffer))))) - status)) - -;;;###autoload -(defun pgg-insert-key () - "Insert the ASCII armored public key." - (interactive) - (pgg-invoke "insert-key" (or pgg-scheme pgg-default-scheme))) - -;;;###autoload -(defun pgg-snarf-keys-region (start end) - "Import public keys in the current region between START and END." - (interactive "r") - (pgg-save-coding-system start end - (pgg-invoke "snarf-keys-region" (or pgg-scheme pgg-default-scheme) - start end))) - -;;;###autoload -(defun pgg-snarf-keys () - "Import public keys in the current buffer." - (interactive "") - (pgg-snarf-keys-region (point-min) (point-max))) - -(defun pgg-lookup-key (string &optional type) - (pgg-invoke "lookup-key" (or pgg-scheme pgg-default-scheme) string type)) - -(defvar pgg-insert-url-function (function pgg-insert-url-with-w3)) - -(defun pgg-insert-url-with-w3 (url) - (ignore-errors - (require 'url) - (let (buffer-file-name) - (url-insert-file-contents url)))) - -(defvar pgg-insert-url-extra-arguments nil) -(defvar pgg-insert-url-program nil) - -(defun pgg-insert-url-with-program (url) - (let ((args (copy-sequence pgg-insert-url-extra-arguments)) - process) - (insert - (with-temp-buffer - (setq process - (apply #'start-process " *PGG url*" (current-buffer) - pgg-insert-url-program (nconc args (list url)))) - (set-process-sentinel process #'ignore) - (while (eq 'run (process-status process)) - (accept-process-output process 5)) - (delete-process process) - (if (and process (eq 'run (process-status process))) - (interrupt-process process)) - (buffer-string))))) - -(defun pgg-fetch-key (keyserver key) - "Attempt to fetch a KEY from KEYSERVER for addition to PGP or GnuPG keyring." - (with-current-buffer (get-buffer-create pgg-output-buffer) - (buffer-disable-undo) - (erase-buffer) - (let ((proto (if (string-match "^[a-zA-Z\\+\\.\\\\-]+:" keyserver) - (substring keyserver 0 (1- (match-end 0)))))) - (save-excursion - (funcall pgg-insert-url-function - (if proto keyserver - (format "http://%s:11371/pks/lookup?op=get&search=%s" - keyserver key)))) - (when (re-search-forward "^-+BEGIN" nil 'last) - (delete-region (point-min) (match-beginning 0)) - (when (re-search-forward "^-+END" nil t) - (delete-region (progn (end-of-line) (point)) - (point-max))) - (insert "\n") - (with-temp-buffer - (insert-buffer-substring pgg-output-buffer) - (pgg-snarf-keys-region (point-min)(point-max))))))) - - -(provide 'pgg) - -;;; pgg.el ends here diff --git a/texi/ChangeLog b/texi/ChangeLog index 3372b2c75..82f6e36a4 100644 --- a/texi/ChangeLog +++ b/texi/ChangeLog @@ -1,3 +1,11 @@ +2012-04-11 Katsumi Yamaoka + + * epa.texi: New file imported from Emacs. + + * pgg.texi: Remove. + + * Makefile.in: Replace pgg.* with epa.*. + 2012-04-05 Teodor Zlatanov * auth.texi (Secret Service API): Edit further and give examples. diff --git a/texi/Makefile.in b/texi/Makefile.in index 5120271a0..6dddacc8e 100644 --- a/texi/Makefile.in +++ b/texi/Makefile.in @@ -19,7 +19,7 @@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ SHELL = /bin/sh PAPERTYPE=a4 -INFO_DEPS=gnus message emacs-mime sieve pgg auth sasl +INFO_DEPS=gnus message emacs-mime sieve epa auth sasl REFCARD=gnus-refcard LOGO=gnus-logo @@ -49,9 +49,9 @@ GNUS-NEWS: gnus-news.texi gnus-news.el $(EMACSCOMP) -l $(srcdir)/gnus-news.el -f batch-gnus-news $< $@ mv $@ ../$@ -dvi: gnus.dvi message.dvi $(REFCARD).dvi emacs-mime.dvi sieve.dvi pgg.dvi auth.dvi sasl.dvi +dvi: gnus.dvi message.dvi $(REFCARD).dvi emacs-mime.dvi sieve.dvi epa.dvi auth.dvi sasl.dvi -pdf: gnus.pdf message.pdf $(REFCARD).pdf emacs-mime.pdf sieve.pdf pgg.pdf auth.pdf sasl.pdf +pdf: gnus.pdf message.pdf $(REFCARD).pdf emacs-mime.pdf sieve.pdf epa.pdf auth.pdf sasl.pdf .texi.dvi : sed -e '/@iflatex/,/@end iflatex/d' $< > gnustmp.texi @@ -111,9 +111,9 @@ makeinfo: texi2latex.elc: texi2latex.el srcdir=$(srcdir)/../lisp $(EMACSCOMP) -l $(srcdir)/../lisp/dgnushack.el --eval '(byte-compile-file "$(srcdir)/texi2latex.el")' -latex: gnus.latexi gnus-faq.latexi message.latexi emacs-mime.latexi sieve.latexi pgg.latexi auth.latexi sasl.latexi gnus-news.latexi +latex: gnus.latexi gnus-faq.latexi message.latexi emacs-mime.latexi sieve.latexi epa.latexi auth.latexi sasl.latexi gnus-news.latexi -gnus.latexi gnus-faq.latexi message.latexi emacs-mime.latexi sieve.latexi pgg.latexi auth.latexi sasl.latexi gnus-news.latexi: $(srcdir)/gnus.texi $(srcdir)/gnus-faq.texi $(srcdir)/message.texi $(srcdir)/emacs-mime.texi $(srcdir)/sieve.texi $(srcdir)/pgg.texi $(srcdir)/sasl.texi $(srcdir)/gnus-news.texi texi2latex.elc +gnus.latexi gnus-faq.latexi message.latexi emacs-mime.latexi sieve.latexi epa.latexi auth.latexi sasl.latexi gnus-news.latexi: $(srcdir)/gnus.texi $(srcdir)/gnus-faq.texi $(srcdir)/message.texi $(srcdir)/emacs-mime.texi $(srcdir)/sieve.texi $(srcdir)/epa.texi $(srcdir)/sasl.texi $(srcdir)/gnus-news.texi texi2latex.elc srcdir=$(srcdir) $(EMACSCOMP) -l ./texi2latex.elc -f latexi-translate .latexi.dvi-x: diff --git a/texi/epa.texi b/texi/epa.texi new file mode 100644 index 000000000..c729333ac --- /dev/null +++ b/texi/epa.texi @@ -0,0 +1,498 @@ +\input texinfo @c -*- mode: texinfo -*- +@c %**start of header +@setfilename epa +@settitle EasyPG Assistant User's Manual +@c %**end of header + +@set VERSION 1.0.0 + +@copying +This file describes EasyPG Assistant @value{VERSION}. + +Copyright @copyright{} 2007-2012 Free Software Foundation, Inc. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, with the Front-Cover texts being ``A GNU Manual,'' +and with the Back-Cover Texts as in (a) below. A copy of the license +is included in the section entitled ``GNU Free Documentation License'' +in the Emacs manual. + +(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and +modify this GNU manual. Buying copies from the FSF supports it in +developing GNU and promoting software freedom.'' + +This document is part of a collection distributed under the GNU Free +Documentation License. If you want to distribute this document +separately from the collection, you can do so by adding a copy of the +license to the document, as described in section 6 of the license. +@end quotation +@end copying + +@dircategory Emacs misc features +@direntry +* EasyPG Assistant: (epa). An Emacs user interface to GNU Privacy Guard. +@end direntry + +@titlepage +@title EasyPG Assistant + +@author by Daiki Ueno +@page + +@vskip 0pt plus 1filll +@insertcopying +@end titlepage + +@contents + +@node Top +@top EasyPG Assistant user's manual + +EasyPG Assistant is an Emacs user interface to GNU Privacy Guard +(GnuPG, @pxref{Top, , Top, gnupg, Using the GNU Privacy Guard}). + +EasyPG Assistant is a part of the package called EasyPG, an all-in-one +GnuPG interface for Emacs. EasyPG also contains the library interface +called EasyPG Library. + +@ifnottex +@insertcopying +@end ifnottex + +@menu +* Overview:: +* Quick start:: +* Commands:: +* Caching Passphrases:: +* Bug Reports:: +@end menu + +@node Overview +@chapter Overview + +EasyPG Assistant provides the following features. + +@itemize @bullet +@item Key management. +@item Cryptographic operations on regions. +@item Cryptographic operations on files. +@item Dired integration. +@item Mail-mode integration. +@item Automatic encryption/decryption of *.gpg files. +@end itemize + +@node Quick start +@chapter Quick start + +EasyPG Assistant commands are prefixed by @samp{epa-}. For example, + +@itemize @bullet +@item To browse your keyring, type @kbd{M-x epa-list-keys} + +@item To create a cleartext signature of the region, type @kbd{M-x epa-sign-region} + +@item To encrypt a file, type @kbd{M-x epa-encrypt-file} +@end itemize + +EasyPG Assistant provides several cryptographic features which can be +integrated into other Emacs functionalities. For example, automatic +encryption/decryption of @samp{*.gpg} files. + +@node Commands +@chapter Commands + +This chapter introduces various commands for typical use cases. + +@menu +* Key management:: +* Cryptographic operations on regions:: +* Cryptographic operations on files:: +* Dired integration:: +* Mail-mode integration:: +* Encrypting/decrypting *.gpg files:: +@end menu + +@node Key management +@section Key management +Probably the first step of using EasyPG Assistant is to browse your +keyring. @kbd{M-x epa-list-keys} is corresponding to @samp{gpg +--list-keys} from the command line. + +@deffn Command epa-list-keys name mode +Show all keys matched with @var{name} from the public keyring. +@end deffn + +@noindent +The output looks as follows. + +@example + u A5B6B2D4B15813FE Daiki Ueno +@end example + +@noindent +A character on the leftmost column indicates the trust level of the +key. If it is @samp{u}, the key is marked as ultimately trusted. The +second column is the key ID, and the rest is the user ID. + +You can move over entries by @key{TAB}. If you type @key{RET} or +click button1 on an entry, you will see more detailed information +about the key you selected. + +@example + u Daiki Ueno + u A5B6B2D4B15813FE 1024bits DSA + Created: 2001-10-09 + Expires: 2007-09-04 + Capabilities: sign certify + Fingerprint: 8003 7CD0 0F1A 9400 03CA 50AA A5B6 B2D4 B158 13FE + u 4447461B2A9BEA2D 2048bits ELGAMAL_E + Created: 2001-10-09 + Expires: 2007-09-04 + Capabilities: encrypt + Fingerprint: 9003 D76B 73B7 4A8A E588 10AF 4447 461B 2A9B EA2D +@end example + +@noindent +To browse your private keyring, use @kbd{M-x epa-list-secret-keys}. + +@deffn Command epa-list-secret-keys name +Show all keys matched with @var{name} from the private keyring. +@end deffn + +@noindent +In @samp{*Keys*} buffer, several commands are available. The common +use case is to export some keys to a file. To do that, type @kbd{m} +to select keys, type @kbd{o}, and then supply the filename. + +Below are other commands related to key management. Some of them take +a file as input/output, and others take the current region. + +@deffn Command epa-insert-keys keys +Insert selected @var{keys} after the point. It will let you select +keys before insertion. By default, it will encode keys in the OpenPGP +armor format. +@end deffn + +@deffn Command epa-import-keys file +Import keys from @var{file} to your keyring. +@end deffn + +@deffn Command epa-import-keys-region start end +Import keys from the current region between @var{start} and @var{end} +to your keyring. +@end deffn + +@deffn Command epa-import-armor-in-region start end +Import keys in the OpenPGP armor format in the current region between +@var{start} and @var{end}. The difference from +@code{epa-import-keys-region} is that +@code{epa-import-armor-in-region} searches armors in the region and +applies @code{epa-import-keys-region} to each of them. +@end deffn + +@deffn Command epa-delete-keys allow-secret +Delete selected keys. If @var{allow-secret} is non-@code{nil}, it +also delete the secret keys. +@end deffn + +@node Cryptographic operations on regions +@section Cryptographic operations on regions + +@deffn Command epa-decrypt-region start end +Decrypt the current region between @var{start} and @var{end}. It +replaces the region with the decrypted text. +@end deffn + +@deffn Command epa-decrypt-armor-in-region start end +Decrypt OpenPGP armors in the current region between @var{start} and +@var{end}. The difference from @code{epa-decrypt-region} is that +@code{epa-decrypt-armor-in-region} searches armors in the region +and applies @code{epa-decrypt-region} to each of them. That is, this +command does not alter the original text around armors. +@end deffn + +@deffn Command epa-verify-region start end +Verify the current region between @var{start} and @var{end}. It sends +the verification result to the minibuffer or a popup window. It +replaces the region with the signed text. +@end deffn + +@deffn Command epa-verify-cleartext-in-region +Verify OpenPGP cleartext blocks in the current region between +@var{start} and @var{end}. The difference from +@code{epa-verify-region} is that @code{epa-verify-cleartext-in-region} +searches OpenPGP cleartext blocks in the region and applies +@code{epa-verify-region} to each of them. That is, this command does +not alter the original text around OpenPGP cleartext blocks. +@end deffn + +@deffn Command epa-sign-region start end signers type +Sign the current region between @var{start} and @var{end}. By +default, it creates a cleartext signature. If a prefix argument is +given, it will let you select signing keys, and then a signature +type. +@end deffn + +@deffn Command epa-encrypt-region start end recipients sign signers +Encrypt the current region between @var{start} and @var{end}. It will +let you select recipients. If a prefix argument is given, it will +also ask you whether or not to sign the text before encryption and if +you answered yes, it will let you select the signing keys. +@end deffn + +@node Cryptographic operations on files +@section Cryptographic operations on files + +@deffn Command epa-decrypt-file file +Decrypt @var{file}. +@end deffn + +@deffn Command epa-verify-file file +Verify @var{file}. +@end deffn + +@deffn Command epa-sign-file file signers type +Sign @var{file}. If a prefix argument is given, it will let you +select signing keys, and then a signature type. +@end deffn + +@deffn Command epa-encrypt-file file recipients +Encrypt @var{file}. It will let you select recipients. +@end deffn + +@node Dired integration +@section Dired integration + +EasyPG Assistant extends Dired Mode for GNU Emacs to allow users to +easily do cryptographic operations on files. For example, + +@example +M-x dired +(mark some files) +: e (or M-x epa-dired-do-encrypt) +(select recipients by 'm' and click [OK]) +@end example + +@noindent +The following keys are assigned. + +@table @kbd +@item : d +@kindex @kbd{: d} +@findex epa-dired-do-decrypt +Decrypt marked files. + +@item : v +@kindex @kbd{: v} +@findex epa-dired-do-verify +Verify marked files. + +@item : s +@kindex @kbd{: s} +@findex epa-dired-do-sign +Sign marked files. + +@item : e +@kindex @kbd{: e} +@findex epa-dired-do-encrypt +Encrypt marked files. + +@end table + +@node Mail-mode integration +@section Mail-mode integration + +EasyPG Assistant provides a minor mode @code{epa-mail-mode} to help +user compose inline OpenPGP messages. Inline OpenPGP is a traditional +style of sending signed/encrypted emails by embedding raw OpenPGP +blobs inside a message body, not using modern MIME format. + +NOTE: Inline OpenPGP is not recommended and you should consider to use +PGP/MIME. See +@uref{http://josefsson.org/inline-openpgp-considered-harmful.html, +Inline OpenPGP in E-mail is bad@comma{} Mm'kay?}. + +@noindent +Once @code{epa-mail-mode} is enabled, the following keys are assigned. +You can do it by @kbd{C-u 1 M-x epa-mail-mode} or through the Customize +interface. Try @kbd{M-x customize-variable epa-global-mail-mode}. + +@table @kbd +@item C-c C-e C-d and C-c C-e d +@kindex @kbd{C-c C-e C-d} +@kindex @kbd{C-c C-e d} +@findex epa-mail-decrypt +Decrypt OpenPGP armors in the current buffer. + +@item C-c C-e C-v and C-c C-e v +@kindex @kbd{C-c C-e C-v} +@kindex @kbd{C-c C-e v} +@findex epa-mail-verify +Verify OpenPGP cleartext signed messages in the current buffer. + +@item C-c C-e C-s and C-c C-e s +@kindex @kbd{C-c C-e C-s} +@kindex @kbd{C-c C-e s} +@findex epa-mail-sign +Compose a signed message from the current buffer. + +@item C-c C-e C-e and C-c C-e e +@kindex @kbd{C-c C-e C-e} +@kindex @kbd{C-c C-e e} +@findex epa-mail-encrypt +Compose an encrypted message from the current buffer. +By default it tries to build the recipient list from @samp{to}, +@samp{cc}, and @samp{bcc} fields of the mail header. To include your +key in the recipient list, use @samp{encrypt-to} option in +@file{~/.gnupg/gpg.conf}. + +@end table + +@node Encrypting/decrypting *.gpg files +@section Encrypting/decrypting *.gpg files +By default, every file whose name ends with @samp{.gpg} will be +treated as encrypted. That is, when you open such a file, the +decrypted text is inserted in the buffer rather than encrypted one. +Similarly, when you save the buffer to a @samp{foo.gpg} file, +encrypted data is written. + +The file name pattern for encrypted files can be controlled by +@var{epa-file-name-regexp}. + +@defvar epa-file-name-regexp +Regexp which matches filenames treated as encrypted. +@end defvar + +You can disable this behavior with @kbd{M-x epa-file-disable}, and +then get it back with @kbd{M-x epa-file-enable}. + +@deffn Command epa-file-disable +Disable automatic encryption/decryption of *.gpg files. +@end deffn + +@deffn Command epa-file-enable +Enable automatic encryption/decryption of *.gpg files. +@end deffn + +@noindent +By default, @code{epa-file} will try to use symmetric encryption, aka +password-based encryption. If you want to use public key encryption +instead, do @kbd{M-x epa-file-select-keys}, which will pops up the key +selection dialog. + +@deffn Command epa-file-select-keys +Select recipient keys to encrypt the currently visiting file with +public key encryption. +@end deffn + +You can also change the default behavior with the variable +@var{epa-file-select-keys}. + +@defvar epa-file-select-keys +Control whether or not to pop up the key selection dialog. +@end defvar + +For frequently visited files, it might be a good idea to tell Emacs +which encryption method should be used through @xref{File Variables, , +, emacs, the Emacs Manual}. Use the @code{epa-file-encrypt-to} local +variable for this. +@vindex epa-file-encrypt-to + +For example, if you want an Elisp file should be encrypted with a +public key associated with an email address @samp{ueno@@unixuser.org}, +add the following line to the beginning of the file. + +@cartouche +@lisp +;; -*- epa-file-encrypt-to: ("ueno@@unixuser.org") -*- +@end lisp +@end cartouche + +Instead, if you want the file always (regardless of the value of the +@code{epa-file-select-keys} variable) encrypted with symmetric +encryption, change the line as follows. + +@cartouche +@lisp +;; -*- epa-file-encrypt-to: nil -*- +@end lisp +@end cartouche + +Other variables which control the automatic encryption/decryption +behavior are below. + +@defvar epa-file-cache-passphrase-for-symmetric-encryption +If non-@code{nil}, cache passphrase for symmetric encryption. The +default value is @code{nil}. +@end defvar + +@defvar epa-file-inhibit-auto-save +If non-@code{nil}, disable auto-saving when opening an encrypted file. +The default value is @code{t}. +@end defvar + +@node Caching Passphrases +@chapter Caching Passphrases + +Typing passphrases is an irritating task if you frequently open and +close the same file. GnuPG and EasyPG Assistant provide mechanisms to +remember your passphrases. However, the configuration is a bit +confusing since it depends on your GnuPG installation (GnuPG version 1 or +GnuPG version 2), encryption method (symmetric or public key), and whether or +not you want to use gpg-agent. Here are some questions: + +@enumerate +@item Do you use GnuPG version 2 instead of GnuPG version 1? +@item Do you use symmetric encryption rather than public key encryption? +@item Do you want to use gpg-agent? +@end enumerate + +Here are configurations depending on your answers: + +@multitable {111} {222} {333} {configuration configuration configuration} +@item @b{1} @tab @b{2} @tab @b{3} @tab Configuration +@item Yes @tab Yes @tab Yes @tab Set up gpg-agent. +@item Yes @tab Yes @tab No @tab You can't, without gpg-agent. +@item Yes @tab No @tab Yes @tab Set up gpg-agent. +@item Yes @tab No @tab No @tab You can't, without gpg-agent. +@item No @tab Yes @tab Yes @tab Set up elisp passphrase cache. +@item No @tab Yes @tab No @tab Set up elisp passphrase cache. +@item No @tab No @tab Yes @tab Set up gpg-agent. +@item No @tab No @tab No @tab You can't, without gpg-agent. +@end multitable + +To set up gpg-agent, follow the instruction in GnuPG manual. +@pxref{Invoking GPG-AGENT, , Invoking GPG-AGENT, gnupg}. + +To set up elisp passphrase cache, set +@code{epa-file-cache-passphrase-for-symmetric-encryption}. +@xref{Encrypting/decrypting *.gpg files}. + +@node Bug Reports +@chapter Bug Reports + +Bugs and problems with EasyPG Assistant are actively worked on by the +Emacs development team. Feature requests and suggestions are also +more than welcome. Use @kbd{M-x report-emacs-bug}, @pxref{Bugs, , +Bugs, emacs, Reporting Bugs}. + +When submitting a bug report, please try to describe in excruciating +detail the steps required to reproduce the problem. Also try to +collect necessary information to fix the bug, such as: + +@itemize @bullet +@item the GnuPG version. Send the output of @samp{gpg --version}. +@item the GnuPG configuration. Send the contents of @file{~/.gnupg/gpg.conf}. +@end itemize + +Before reporting the bug, you should set @code{epg-debug} in the +@file{~/.emacs} file and repeat the bug. Then, include the contents +of the @samp{ *epg-debug*} buffer. Note that the first letter of the +buffer name is a whitespace. + +@bye + +@c End: diff --git a/texi/pgg.texi b/texi/pgg.texi deleted file mode 100644 index e19aec257..000000000 --- a/texi/pgg.texi +++ /dev/null @@ -1,506 +0,0 @@ -\input texinfo @c -*-texinfo-*- - -@include gnus-overrides.texi - -@setfilename pgg -@settitle PGG @value{VERSION} - -@set VERSION 0.1 - -@copying -This file describes PGG @value{VERSION}, an Emacs interface to various -PGP implementations. - -Copyright @copyright{} 2001, 2003-2012 Free Software Foundation, Inc. - -@quotation -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.3 or -any later version published by the Free Software Foundation; with no -Invariant Sections, with the Front-Cover texts being ``A GNU Manual,'' -and with the Back-Cover Texts as in (a) below. A copy of the license -is included in the section entitled ``GNU Free Documentation License.'' - -(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and -modify this GNU manual. Buying copies from the FSF supports it in -developing GNU and promoting software freedom.'' -@end quotation -@end copying - -@dircategory Emacs network features -@direntry -* PGG: (pgg). Emacs interface to various PGP implementations. -@end direntry - -@titlepage -@ifset WEBHACKDEVEL -@title PGG (DEVELOPMENT VERSION) -@end ifset -@ifclear WEBHACKDEVEL -@title PGG -@end ifclear - -@author by Daiki Ueno -@page - -@vskip 0pt plus 1filll -@insertcopying -@end titlepage - -@contents - -@node Top -@top PGG - -PGG is an interface library between Emacs -and various tools for secure communication. PGG also provides a simple -user interface to encrypt, decrypt, sign, and verify MIME messages. - -@ifnottex -@insertcopying -@end ifnottex - -@menu -* Overview:: What PGG is. -* Prerequisites:: Complicated stuff you may have to do. -* How to use:: Getting started quickly. -* Architecture:: -* Parsing OpenPGP packets:: -* GNU Free Documentation License:: The license for this documentation. -* Function Index:: -* Variable Index:: -@end menu - -@node Overview -@chapter Overview - -PGG is an interface library between Emacs and various tools for secure -communication. Even though Mailcrypt has similar feature, it does not -deal with detached PGP messages, normally used in PGP/MIME -infrastructure. This was the main reason why I wrote the new library. - -PGP/MIME is an application of MIME Object Security Services (RFC1848). -The standard is documented in RFC2015. - -@node Prerequisites -@chapter Prerequisites - -PGG requires at least one implementation of privacy guard system. -This document assumes that you have already obtained and installed them -and that you are familiar with its basic functions. - -By default, PGG uses GnuPG. If you are new to such a system, I -recommend that you should look over the GNU Privacy Handbook (GPH) -which is available at @uref{http://www.gnupg.org/documentation/}. - -When using GnuPG, we recommend the use of the @code{gpg-agent} -program, which is distributed with versions 2.0 and later of GnuPG. -This is a daemon to manage private keys independently from any -protocol, and provides the most secure way to input and cache your -passphrases (@pxref{Caching passphrase}). By default, PGG will -attempt to use @code{gpg-agent} if it is running. @xref{Invoking -GPG-AGENT,,,gnupg,Using the GNU Privacy Guard}. - -PGG also supports Pretty Good Privacy version 2 or version 5. - -@node How to use -@chapter How to use - -The toplevel interface of this library is quite simple, and only -intended to use with public-key cryptographic operation. - -To use PGG, evaluate following expression at the beginning of your -application program. - -@lisp -(require 'pgg) -@end lisp - -If you want to check existence of pgg.el at runtime, instead you can -list autoload setting for desired functions as follows. - -@lisp -(autoload 'pgg-encrypt-region "pgg" - "Encrypt the current region." t) -(autoload 'pgg-encrypt-symmetric-region "pgg" - "Encrypt the current region with symmetric algorithm." t) -(autoload 'pgg-decrypt-region "pgg" - "Decrypt the current region." t) -(autoload 'pgg-sign-region "pgg" - "Sign the current region." t) -(autoload 'pgg-verify-region "pgg" - "Verify the current region." t) -(autoload 'pgg-insert-key "pgg" - "Insert the ASCII armored public key." t) -(autoload 'pgg-snarf-keys-region "pgg" - "Import public keys in the current region." t) -@end lisp - -@menu -* User Commands:: -* Selecting an implementation:: -* Caching passphrase:: -* Default user identity:: -@end menu - -@node User Commands -@section User Commands - -At this time you can use some cryptographic commands. The behavior of -these commands relies on a fashion of invocation because they are also -intended to be used as library functions. In case you don't have the -signer's public key, for example, the function @code{pgg-verify-region} -fails immediately, but if the function had been called interactively, it -would ask you to retrieve the signer's public key from the server. - -@deffn Command pgg-encrypt-region start end recipients &optional sign passphrase -Encrypt the current region between @var{start} and @var{end} for -@var{recipients}. When the function were called interactively, you -would be asked about the recipients. - -If encryption is successful, it replaces the current region contents (in -the accessible portion) with the resulting data. - -If optional argument @var{sign} is non-@code{nil}, the function is -request to do a combined sign and encrypt. This currently is -confirmed to work with GnuPG, but might not work with PGP or PGP5. - -If optional @var{passphrase} is @code{nil}, the passphrase will be -obtained from the passphrase cache or user. -@end deffn - -@deffn Command pgg-encrypt-symmetric-region &optional start end passphrase -Encrypt the current region between @var{start} and @var{end} using a -symmetric cipher. After invocation you are asked for a passphrase. - -If optional @var{passphrase} is @code{nil}, the passphrase will be -obtained from the passphrase cache or user. - -symmetric-cipher encryption is currently only implemented for GnuPG. -@end deffn - -@deffn Command pgg-decrypt-region start end &optional passphrase -Decrypt the current region between @var{start} and @var{end}. If -decryption is successful, it replaces the current region contents (in -the accessible portion) with the resulting data. - -If optional @var{passphrase} is @code{nil}, the passphrase will be -obtained from the passphrase cache or user. -@end deffn - -@deffn Command pgg-sign-region start end &optional cleartext passphrase -Make the signature from text between @var{start} and @var{end}. If the -optional third argument @var{cleartext} is non-@code{nil}, or the -function is called interactively, it does not create a detached -signature. In such a case, it replaces the current region contents (in -the accessible portion) with the resulting data. - -If optional @var{passphrase} is @code{nil}, the passphrase will be -obtained from the passphrase cache or user. -@end deffn - -@deffn Command pgg-verify-region start end &optional signature fetch -Verify the current region between @var{start} and @var{end}. If the -optional third argument @var{signature} is non-@code{nil}, it is treated -as the detached signature file of the current region. - -If the optional 4th argument @var{fetch} is non-@code{nil}, or the -function is called interactively, we attempt to fetch the signer's -public key from the key server. -@end deffn - -@deffn Command pgg-insert-key -Retrieve the user's public key and insert it as ASCII-armored format. -@end deffn - -@deffn Command pgg-snarf-keys-region start end -Collect public keys in the current region between @var{start} and -@var{end}, and add them into the user's keyring. -@end deffn - -@node Selecting an implementation -@section Selecting an implementation - -Since PGP has a long history and there are a number of PGP -implementations available today, the function which each one has differs -considerably. For example, if you are using GnuPG, you know you can -select cipher algorithm from 3DES, CAST5, BLOWFISH, and so on, but on -the other hand the version 2 of PGP only supports IDEA. - -Which implementation is used is controlled by the @code{pgg-scheme} -variable. If it is @code{nil} (the default), the value of the -@code{pgg-default-scheme} variable will be used instead. - -@defvar pgg-scheme -Force specify the scheme of PGP implementation. The value can be set to -@code{gpg}, @code{pgp}, and @code{pgp5}. The default is @code{nil}. -@end defvar - -@defvar pgg-default-scheme -The default scheme of PGP implementation. The value should be one of -@code{gpg}, @code{pgp}, and @code{pgp5}. The default is @code{gpg}. -@end defvar - -@node Caching passphrase -@section Caching passphrase - -When using GnuPG (gpg) as the PGP scheme, we recommend using a program -called @code{gpg-agent} for entering and caching -passphrases@footnote{Actually, @code{gpg-agent} does not cache -passphrases but private keys. On the other hand, from a user's point -of view, this technical difference isn't visible.}. - -@defvar pgg-gpg-use-agent -If non-@code{nil}, attempt to use @code{gpg-agent} whenever possible. -The default is @code{t}. If @code{gpg-agent} is not running, or GnuPG -is not the current PGP scheme, PGG's own passphrase-caching mechanism -is used (see below). -@end defvar - -To use @code{gpg-agent} with PGG, you must first ensure that -@code{gpg-agent} is running. For example, if you are running in the X -Window System, you can do this by putting the following line in your -@file{.xsession} file: - -@smallexample -eval "$(gpg-agent --daemon)" -@end smallexample - -For more details on invoking @code{gpg-agent}, @xref{Invoking -GPG-AGENT,,,gnupg,Using the GNU Privacy Guard}. - -Whenever you perform a PGG operation that requires a GnuPG passphrase, -GnuPG will contact @code{gpg-agent}, which prompts you for the -passphrase. Furthermore, @code{gpg-agent} ``caches'' the result, so -that subsequent uses will not require you to enter the passphrase -again. (This cache usually expires after a certain time has passed; -you can change this using the @code{--default-cache-ttl} option when -invoking @code{gpg-agent}.) - -If you are running in a X Window System environment, @code{gpg-agent} -prompts for a passphrase by opening a graphical window. However, if -you are running Emacs on a text terminal, @code{gpg-agent} has trouble -receiving input from the terminal, since it is being sent to Emacs. -One workaround for this problem is to run @code{gpg-agent} on a -different terminal from Emacs, with the @code{--keep-tty} option; this -tells @code{gpg-agent} use its own terminal to prompt for passphrases. - -When @code{gpg-agent} is not being used, PGG prompts for a passphrase -through Emacs. It also has its own passphrase caching mechanism, -which is controlled by the variable @code{pgg-cache-passphrase} (see -below). - -There is a security risk in handling passphrases through PGG rather -than @code{gpg-agent}. When you enter your passphrase into an Emacs -prompt, it is temporarily stored as a cleartext string in the memory -of the Emacs executable. If the executable memory is swapped to disk, -the root user can, in theory, extract the passphrase from the -swapfile. Furthermore, the swapfile containing the cleartext -passphrase might remain on the disk after the system is discarded or -stolen. @code{gpg-agent} avoids this problem by using certain tricks, -such as memory locking, which have not been implemented in Emacs. - -@defvar pgg-cache-passphrase -If non-@code{nil}, store passphrases. The default value of this -variable is @code{t}. If you are worried about security issues, -however, you could stop the caching of passphrases by setting this -variable to @code{nil}. -@end defvar - -@defvar pgg-passphrase-cache-expiry -Elapsed time for expiration in seconds. -@end defvar - -If your passphrase contains non-ASCII characters, you might need to -specify the coding system to be used to encode your passphrases, since -GnuPG treats them as a byte sequence, not as a character sequence. - -@defvar pgg-passphrase-coding-system -Coding system used to encode passphrase. -@end defvar - -@node Default user identity -@section Default user identity - -The PGP implementation is usually able to select the proper key to use -for signing and decryption, but if you have more than one key, you may -need to specify the key id to use. - -@defvar pgg-default-user-id -User ID of your default identity. It defaults to the value returned -by @samp{(user-login-name)}. You can customize this variable. -@end defvar - -@defvar pgg-gpg-user-id -User ID of the GnuPG default identity. It defaults to @samp{nil}. -This overrides @samp{pgg-default-user-id}. You can customize this -variable. -@end defvar - -@defvar pgg-pgp-user-id -User ID of the PGP 2.x/6.x default identity. It defaults to -@samp{nil}. This overrides @samp{pgg-default-user-id}. You can -customize this variable. -@end defvar - -@defvar pgg-pgp5-user-id -User ID of the PGP 5.x default identity. It defaults to @samp{nil}. -This overrides @samp{pgg-default-user-id}. You can customize this -variable. -@end defvar - -@node Architecture -@chapter Architecture - -PGG introduces the notion of a "scheme of PGP implementation" (used -interchangeably with "scheme" in this document). This term refers to a -singleton object wrapped with the luna object system. - -Since PGG was designed for accessing and developing PGP functionality, -the architecture had to be designed not just for interoperability but -also for extensibility. In this chapter we explore the architecture -while finding out how to write the PGG back end. - -@menu -* Initializing:: -* Back end methods:: -* Getting output:: -@end menu - -@node Initializing -@section Initializing - -A scheme must be initialized before it is used. -It had better guarantee to keep only one instance of a scheme. - -The following code is snipped out of @file{pgg-gpg.el}. Once an -instance of @code{pgg-gpg} scheme is initialized, it's stored to the -variable @code{pgg-scheme-gpg-instance} and will be reused from now on. - -@lisp -(defvar pgg-scheme-gpg-instance nil) - -(defun pgg-make-scheme-gpg () - (or pgg-scheme-gpg-instance - (setq pgg-scheme-gpg-instance - (luna-make-entity 'pgg-scheme-gpg)))) -@end lisp - -The name of the function must follow the -regulation---@code{pgg-make-scheme-} follows the back end name. - -@node Back end methods -@section Back end methods - -In each back end, these methods must be present. The output of these -methods is stored in special buffers (@ref{Getting output}), so that -these methods must tell the status of the execution. - -@deffn Method pgg-scheme-lookup-key scheme string &optional type -Return keys associated with @var{string}. If the optional third -argument @var{type} is non-@code{nil}, it searches from the secret -keyrings. -@end deffn - -@deffn Method pgg-scheme-encrypt-region scheme start end recipients &optional sign passphrase -Encrypt the current region between @var{start} and @var{end} for -@var{recipients}. If @var{sign} is non-@code{nil}, do a combined sign -and encrypt. If encryption is successful, it returns @code{t}, -otherwise @code{nil}. -@end deffn - -@deffn Method pgg-scheme-encrypt-symmetric-region scheme start end &optional passphrase -Encrypt the current region between @var{start} and @var{end} using a -symmetric cipher and a passphrases. If encryption is successful, it -returns @code{t}, otherwise @code{nil}. This function is currently only -implemented for GnuPG. -@end deffn - -@deffn Method pgg-scheme-decrypt-region scheme start end &optional passphrase -Decrypt the current region between @var{start} and @var{end}. If -decryption is successful, it returns @code{t}, otherwise @code{nil}. -@end deffn - -@deffn Method pgg-scheme-sign-region scheme start end &optional cleartext passphrase -Make the signature from text between @var{start} and @var{end}. If the -optional third argument @var{cleartext} is non-@code{nil}, it does not -create a detached signature. If signing is successful, it returns -@code{t}, otherwise @code{nil}. -@end deffn - -@deffn Method pgg-scheme-verify-region scheme start end &optional signature -Verify the current region between @var{start} and @var{end}. If the -optional third argument @var{signature} is non-@code{nil}, it is treated -as the detached signature of the current region. If the signature is -successfully verified, it returns @code{t}, otherwise @code{nil}. -@end deffn - -@deffn Method pgg-scheme-insert-key scheme -Retrieve the user's public key and insert it as ASCII-armored format. -On success, it returns @code{t}, otherwise @code{nil}. -@end deffn - -@deffn Method pgg-scheme-snarf-keys-region scheme start end -Collect public keys in the current region between @var{start} and -@var{end}, and add them into the user's keyring. -On success, it returns @code{t}, otherwise @code{nil}. -@end deffn - -@node Getting output -@section Getting output - -The output of the back end methods (@ref{Back end methods}) is stored in -special buffers, so that these methods must tell the status of the -execution. - -@defvar pgg-errors-buffer -The standard error output of the execution of the PGP command is stored -here. -@end defvar - -@defvar pgg-output-buffer -The standard output of the execution of the PGP command is stored here. -@end defvar - -@defvar pgg-status-buffer -The rest of status information of the execution of the PGP command is -stored here. -@end defvar - -@node Parsing OpenPGP packets -@chapter Parsing OpenPGP packets - -The format of OpenPGP messages is maintained in order to publish all -necessary information needed to develop interoperable applications. -The standard is documented in RFC 2440. - -PGG has its own parser for the OpenPGP packets. - -@defun pgg-parse-armor string -List the sequence of packets in @var{string}. -@end defun - -@defun pgg-parse-armor-region start end -List the sequence of packets in the current region between @var{start} -and @var{end}. -@end defun - -@defvar pgg-ignore-packet-checksum -If non-@code{nil}, don't check the checksum of the packets. -@end defvar - -@node GNU Free Documentation License -@appendix GNU Free Documentation License -@include doclicense.texi - -@node Function Index -@unnumbered Function Index -@printindex fn - -@node Variable Index -@unnumbered Variable Index -@printindex vr - -@bye - -@c End: -- 2.25.1