1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-02 11:21:42 +00:00

- replace pgg with epg/epa - working version, with no calls to pgg.

- remove passphrase verifier and hinting.

(allout-passphrase-verifier-handling), (allout-passphrase-hint-handling):
No longer used, delete.
(allout-epg-protocol): Never used and unnecessary, delete.

(allout-mode): Adjust docstring to describe changed encryption provisions.

(allout-toggle-current-subtree-encryption): Adjust docstring to describe
changed encryption provisions.  Change fetch-pass to keymode-cue, for
simpler universal argument interpretation.

(allout-toggle-subtree-encryption):  Adjust docstring to describe
changed encryption provisions.  Change fetch-pass to keymode-cue, for
simpler universal argument interpretation.  Remove provisions for handling
key type and identity - they'll all be within allout-encrypt-string or
epg/epg or even contained all the way in gpg.

(allout-encrypt-string): Include keypair-mode argument, for requesting
keypair encryption.  Require epa, for recipients handling.  Change how
regexp filtering elements are named.

(allout-obtain-passphrase), (allout-epg-passphrase-callback-function),
(allout-make-passphrase-state), (allout-passphrase-state-passphrase):
Remove, we're not providing passphrase verification and hinting because:
- gpg v1 is required for epg passphrase callback operation, on which
  verification and hinting depends
- doing that handling exposes the passphrase to emacs code, which is much
  much less secure than leaving all passphrase handling in gpg
- leaving all passphrase handling to gpg removes a lot of complexity from
  allout code
- gpg v2 connection to gpg-agent requires no user provisions, so is simpler
  and provides some convenience that makes up for the lack of hinting and
  verification

(allout-encrypted-key-info), (allout-update-passphrase-mnemonic-aids),
(allout-get-encryption-passphrase-verifier), (allout-verify-passphrase):
Obsolete.
This commit is contained in:
Ken Manheimer 2010-12-10 17:09:57 -05:00
parent ff3e8c8e20
commit 29fac3fec1

View File

@ -85,6 +85,7 @@
(eval-when-compile
;; Most of the requires here are for stuff covered by autoloads, which
;; byte-compiling doesn't trigger.
(require 'epg)
(require 'epa)
(require 'overlay)
;; `cl' is required for `assert'. `assert' is not covered by a standard
@ -812,32 +813,6 @@ formatted copy."
:type '(choice (const nil) string)
:version "22.1"
:group 'allout-encryption)
;;;_ = allout-passphrase-verifier-handling
(defcustom allout-passphrase-verifier-handling t
"Enable use of symmetric encryption passphrase verifier if non-nil.
See the docstring for the `allout-enable-file-variable-adjustment'
variable for details about allout ajustment of file variables."
:type 'boolean
:version "22.1"
:group 'allout-encryption)
(make-variable-buffer-local 'allout-passphrase-verifier-handling)
;;;_ = allout-passphrase-hint-handling
(defcustom allout-passphrase-hint-handling 'always
"Dictate outline encryption passphrase reminder handling:
always -- always show reminder when prompting
needed -- show reminder on passphrase entry failure
disabled -- never present or adjust reminder
See the docstring for the `allout-enable-file-variable-adjustment'
variable for details about allout ajustment of file variables."
:type '(choice (const always)
(const needed)
(const disabled))
:version "22.1"
:group 'allout-encryption)
(make-variable-buffer-local 'allout-passphrase-hint-handling)
;;;_ = allout-encrypt-unencrypted-on-saves
(defcustom allout-encrypt-unencrypted-on-saves t
"When saving, should topics pending encryption be encrypted?
@ -1533,12 +1508,6 @@ wrapped within allout's automatic fill-prefix setting.")
"Horrible hack used to prevent invalid multiple triggering of outline
mode from prop-line file-var activation. Used by `allout-mode' function
to track repeats.")
;;;_ = allout-epg-protocol
(defvar allout-epg-protocol 'OpenPGP
"*The default protocol.
The value can be either 'OpenPGP or 'CMS.
You should bind this variable with `let', but do not set it globally.")
;;;_ = allout-passphrase-verifier-string
(defvar allout-passphrase-verifier-string nil
"Setting used to test solicited encryption passphrases against the one
@ -1554,6 +1523,8 @@ The verifier string is retained as an Emacs file variable, as well as in
the Emacs buffer state, if file variable adjustments are enabled. See
`allout-enable-file-variable-adjustment' for details about that.")
(make-variable-buffer-local 'allout-passphrase-verifier-string)
(make-obsolete 'allout-passphrase-verifier-string
'allout-passphrase-verifier-string "23.3")
;;;###autoload
(put 'allout-passphrase-verifier-string 'safe-local-variable 'stringp)
;;;_ = allout-passphrase-hint-string
@ -1568,6 +1539,8 @@ state, if file variable adjustments are enabled. See
`allout-enable-file-variable-adjustment' for details about that.")
(make-variable-buffer-local 'allout-passphrase-hint-string)
(setq-default allout-passphrase-hint-string "")
(make-obsolete 'allout-passphrase-hint-string
'allout-passphrase-hint-string "23.3")
;;;###autoload
(put 'allout-passphrase-hint-string 'safe-local-variable 'stringp)
;;;_ = allout-after-save-decrypt
@ -1937,19 +1910,14 @@ M-x outlineify-sticky Activate outline mode for current buffer,
Topic Encryption
Outline mode supports gpg encryption of topics, with support for
symmetric and key-pair modes, passphrase timeout, passphrase
consistency checking, user-provided hinting for symmetric key
mode, and auto-encryption of topics pending encryption on save.
symmetric and key-pair modes, and auto-encryption of topics
pending encryption on save.
Topics pending encryption are, by default, automatically
encrypted during file saves. If the contents of the topic
containing the cursor was encrypted for a save, it is
automatically decrypted for continued editing.
The aim of these measures is reliable topic privacy while
preventing accidents like neglected encryption before saves,
forgetting which passphrase was used, and other practical
pitfalls.
encrypted during file saves, including checkpoint saves, to avoid
exposing the plain text of encrypted topics in the file system.
If the content of the topic containing the cursor was encrypted
for a save, it is automatically decrypted for continued editing.
See `allout-toggle-current-subtree-encryption' function docstring
and `allout-encrypt-unencrypted-on-saves' customization variable
@ -5999,29 +5967,27 @@ With repeat count, copy the exposed portions of entire buffer."
(goto-char start-pt)))
;;;_ #8 Encryption
;;;_ > allout-toggle-current-subtree-encryption (&optional fetch-pass)
(defun allout-toggle-current-subtree-encryption (&optional fetch-pass)
"Encrypt clear or decrypt encoded text of visibly-containing topic's contents.
;;;_ > allout-toggle-current-subtree-encryption (&optional keymode-cue)
(defun allout-toggle-current-subtree-encryption (&optional keymode-cue)
"Encrypt clear or decrypt encoded topic text.
Optional FETCH-PASS universal argument provokes key-pair encryption with
single universal argument. With doubled universal argument (value = 16),
it forces prompting for the passphrase regardless of availability from the
passphrase cache. With no universal argument, the appropriate passphrase
is obtained from the cache, if available, else from the user.
Allout uses emacs 'epg' libary to perform encryption. Symmetric
and keypair encryption are supported. All encryption is ascii
armored.
Allout uses emacs 'epg' libary to perform encryption. Allout
encrypts with ascii armoring.
When encrypting, optional KEYMODE-CUE universal argument greater
than 1 causes prompting for recipients for public-key keypair
encryption. Otherwise a symmetric mode is assumed for
encryption.
Both symmetric-key and key-pair encryption is implemented. Symmetric is
the default, use a single (x4) universal argument for keypair mode.
Encrypted topic's bullet is set to a `~' to signal that the contents of the
topic (body and subtopics, but not heading) is pending encryption or
encrypted. `*' asterisk immediately after the bullet signals that the body
is encrypted, its' absence means the topic is meant to be encrypted but is
not. When a file with topics pending encryption is saved, topics pending
encryption are encrypted. See allout-encrypt-unencrypted-on-saves for
auto-encryption specifics.
Encrypted topic's bullets are set to a `~' to signal that the
contents of the topic (body and subtopics, but not heading) is
pending encryption or encrypted. `*' asterisk immediately after
the bullet signals that the body is encrypted, its absence means
the topic is meant to be encrypted but is not currently. When a
file with topics pending encryption is saved, topics pending
encryption are encrypted. See allout-encrypt-unencrypted-on-saves
for auto-encryption specifics.
\*NOTE WELL* that automatic encryption that happens during saves will
default to symmetric encryption -- you must deliberately (re)encrypt key-pair
@ -6029,55 +5995,22 @@ encrypted topics if you want them to continue to use the key-pair cipher.
Level-one topics, with prefix consisting solely of an `*' asterisk, cannot be
encrypted. If you want to encrypt the contents of a top-level topic, use
\\[allout-shift-in] to increase its depth.
Passphrase Caching
The encryption passphrase is solicited if not currently available in the
passphrase cache from a recent encryption action.
Symmetric Passphrase Hinting and Verification
If the file previously had no associated passphrase, or had a different
passphrase than specified, the user is prompted to repeat the new one for
corroboration. A random string encrypted by the new passphrase is set on
the buffer-specific variable `allout-passphrase-verifier-string', for
confirmation of the passphrase when next obtained, before encrypting or
decrypting anything with it. This helps avoid mistakenly shifting between
keys.
If allout customization var `allout-passphrase-verifier-handling' is
non-nil, an entry for `allout-passphrase-verifier-string' and its value is
added to an Emacs 'local variables' section at the end of the file, which
is created if necessary. That setting is for retention of the passphrase
verifier across Emacs sessions.
Similarly, `allout-passphrase-hint-string' stores a user-provided reminder
about their passphrase, and `allout-passphrase-hint-handling' specifies
when the hint is presented, or if passphrase hints are disabled. If
enabled (see the `allout-passphrase-hint-handling' docstring for details),
the hint string is stored in the local-variables section of the file, and
solicited whenever the passphrase is changed."
\\[allout-shift-in] to increase its depth."
(interactive "P")
(save-excursion
(allout-back-to-current-heading)
(allout-toggle-subtree-encryption fetch-pass)
)
)
;;;_ > allout-toggle-subtree-encryption (&optional fetch-pass)
(defun allout-toggle-subtree-encryption (&optional fetch-pass)
(allout-toggle-subtree-encryption keymode-cue)))
;;;_ > allout-toggle-subtree-encryption (&optional keymode-cue)
(defun allout-toggle-subtree-encryption (&optional keymode-cue)
"Encrypt clear text or decrypt encoded topic contents (body and subtopics.)
Optional FETCH-PASS universal argument provokes key-pair encryption with
single universal argument. With doubled universal argument (value = 16),
it forces prompting for the passphrase regardless of availability from the
passphrase cache. With no universal argument, the appropriate passphrase
is obtained from the cache, if available, else from the user.
When encrypting, optional KEYMODE-CUE universal argument greater than
1 provokes prompting for recipients for public-key keypair
encryption, otherwise a symmetric-mode passphrase is solicited.
Currently only GnuPG encryption is supported, and integration
with gpg-agent is not yet implemented.
Encryption depends on the emacs epg library.
NOTE that the encrypted text will be ascii-armored.
Encrypted text will be ascii-armored.
See `allout-toggle-current-subtree-encryption' for more details."
@ -6097,6 +6030,7 @@ See `allout-toggle-current-subtree-encryption' for more details."
(progn (if (= (point-max) after-bullet-pos)
(error "no body to encrypt"))
(allout-encrypted-topic-p)))
(keypair-mode (> (prefix-numeric-value keymode-cue) 1))
(was-collapsed (if (not (search-forward "\n" nil t))
nil
(backward-char 1)
@ -6115,17 +6049,6 @@ See `allout-toggle-current-subtree-encryption' for more details."
(if was-encrypted "de" "en"))
nil))
;; Assess key parameters:
;;PGG rework key-info!
(key-info (or
;; detect the type by which it is already encrypted
(and was-encrypted
(allout-encrypted-key-info subject-text))
(and (member fetch-pass '(4 (4)))
'(keypair nil))
'(symmetric nil)))
(for-key-type (car key-info))
(for-key-identity (cadr key-info))
(fetch-pass (and fetch-pass (member fetch-pass '(16 (16)))))
(was-coding-system buffer-file-coding-system))
(when (not was-encrypted)
@ -6151,9 +6074,7 @@ See `allout-toggle-current-subtree-encryption' for more details."
(setq result-text
(allout-encrypt-string subject-text was-encrypted
(current-buffer)
for-key-type for-key-identity
))
(current-buffer) keypair-mode))
;; Replace the subtree with the processed product.
(allout-unprotected
@ -6184,8 +6105,10 @@ See `allout-toggle-current-subtree-encryption' for more details."
(insert "*"))))
(run-hook-with-args 'allout-structure-added-hook
bullet-pos subtree-end))))
;;;_ > allout-encrypt-string (text decrypt allout-buffer)
(defun allout-encrypt-string (text decrypt allout-buffer &optional rejected)
;;;_ > allout-encrypt-string (text decrypt allout-buffer keypair-mode
;;; &optional rejected)
(defun allout-encrypt-string (text decrypt allout-buffer keypair-mode
&optional rejected)
"Encrypt or decrypt message TEXT.
Returns the resulting string, or nil if the transformation fails.
@ -6194,31 +6117,40 @@ If DECRYPT is true (default false), then decrypt instead of encrypt.
ALLOUT-BUFFER identifies the buffer containing the text.
Optional REJECTED is for internal use -- conveys the number of
If KEYPAIR-MODE is non-nil, encryption involves prompting for
keypair recipients.
Optional REJECTED is for internal use, to convey the number of
rejections due to matches against
`allout-encryption-ciphertext-rejection-regexps', as limited by
`allout-encryption-ciphertext-rejection-ceiling'.
"
`allout-encryption-ciphertext-rejection-ceiling'."
(require 'epg)
(require 'epa)
(let* ((epg-context (epg-make-context epa-protocol t))
(let* ((epg-context (epg-make-context nil t))
(encoding (with-current-buffer allout-buffer
buffer-file-coding-system))
(multibyte (with-current-buffer allout-buffer
enable-multibyte-characters))
(strip-plaintext-regexps
(if (not decrypt)
(allout-get-configvar-values
'allout-encryption-plaintext-sanitization-regexps)))
(reject-ciphertext-regexps
(if (not decrypt)
(allout-get-configvar-values
'allout-encryption-ciphertext-rejection-regexps)))
;; "sanitization" avoids encryption results that are outline structure.
(sani-regexps 'allout-encryption-plaintext-sanitization-regexps)
(strip-plaintext-regexps (if (not decrypt)
(allout-get-configvar-values
sani-regexps)))
(rejection-regexps 'allout-encryption-ciphertext-rejection-regexps)
(reject-ciphertext-regexps (if (not decrypt)
(allout-get-configvar-values
rejection-regexps)))
(rejected (or rejected 0))
(rejections-left (- allout-encryption-ciphertext-rejection-ceiling
rejected))
massaged-text result-text
(keypair-message (concat "Select encryption recipients.\n Not"
" selecting any causes"
" symmetric encryption. "))
recipients
massaged-text
result-text
)
;; Massage the subject text for encoding and filtering.
@ -6243,284 +6175,49 @@ rejections due to matches against
(setq massaged-text (buffer-substring-no-properties (point-min)
(point-max))))
(setq result-text
(if decrypt
(epg-decrypt-string epg-context
(encode-coding-string massaged-text
(or encoding 'utf-8)))
(if (equal key-type 'symmetric)
;; establish the passphrase callback. it will only be used
;; with gpgv1, but then it will handle hinting and verification.
(allout-set-epg-passphrase-callback epg-context allout-buffer))
(epg-encrypt-string epg-context
(encode-coding-string massaged-text
(or encoding 'utf-8))
nil)))
(and keypair-mode
(epa-select-keys epg-context
keypair-message)))))
;; validate result -- non-empty
(if (not result-text)
(error "%scryption failed." (if decrypt "De" "En"))
(cond
((not result-text)
(error "%scryption failed." (if decrypt "De" "En")))
;; Retry (within limit) if ciphertext contains rejections:
((and (not decrypt)
;; Check for disqualification of this ciphertext:
(let ((regexps reject-ciphertext-regexps)
reject-it)
(while (and regexps (not reject-it))
(setq reject-it (string-match (car regexps) result-text))
(pop regexps))
reject-it))
(setq rejections-left (1- rejections-left))
(if (<= rejections-left 0)
(error (concat "Ciphertext rejected too many times"
" (%s), per `%s'")
allout-encryption-ciphertext-rejection-ceiling
'allout-encryption-ciphertext-rejection-regexps)
;; try again:
;; XXX alas, we depend on external caching for the passphrase.
(allout-encrypt-string text decrypt allout-buffer
(1+ rejected))))
;; Retry (within limit) if ciphertext contains rejections:
((and (not decrypt)
;; Check for disqualification of this ciphertext:
(let ((regexps reject-ciphertext-regexps)
reject-it)
(while (and regexps (not reject-it))
(setq reject-it (string-match (car regexps) result-text))
(pop regexps))
reject-it))
(setq rejections-left (1- rejections-left))
(if (<= rejections-left 0)
(error (concat "Ciphertext rejected too many times"
" (%s), per `%s'")
allout-encryption-ciphertext-rejection-ceiling
'allout-encryption-ciphertext-rejection-regexps)
;; try again (gpg-agent may have the key cached):
(allout-encrypt-string text decrypt allout-buffer keypair-mode
(1+ rejected))))
;; Barf if encryption yields extraordinary control chars:
((and (not decrypt)
(string-match "[\C-a\C-k\C-o-\C-z\C-@]"
result-text))
(error (concat "Encryption produced non-armored text, which"
"conflicts with allout mode -- reconfigure!")))
;; Barf if encryption yields extraordinary control chars:
((and (not decrypt)
(string-match "[\C-a\C-k\C-o-\C-z\C-@]"
result-text))
(error (concat "Encryption produced non-armored text, which"
"conflicts with allout mode -- reconfigure!")))
(t result-text)
)
)
)
;;;_ . epg passphrase callback handling (epg uses only for GnuPG v1)
;;;_ > allout-epg-passphrase-callback-function (context key-id state)
(defun allout-epg-passphrase-callback-function (context key-id state)
"Handle allout passphrase prompting when used with the emacs epg library.
Note that epg's passphrase callback provision only works when
operating with GnuPG v1. Check your GnuPG version using 'gpg
--version' from the command line.
CONTEXT is an epg context object, per 'epg-make-context'.
KEY-ID is apparently either 'SYM, for symmetric passphrase, or
something else for a key pair, per 'epg-passphrase-callback-function'.
STATE is an allout passphrase state construct, per
'allout-make-passphrase-state'."
(message "allout-passphrase-callback-function: in")(sit-for 1)
(let* ((allout-buffer (allout-passphrase-state-buffer state))
(provided (allout-passphrase-state-buffer state)))
(if (eq key-id 'SYM)
(if provided
provided
(let*
((hint-string
(with-current-buffer allout-buffer
(if (and (not (string= allout-passphrase-hint-string
""))
(or (equal allout-passphrase-hint-handling 'always)
(and (equal allout-passphrase-hint-handling
'needed)
retried)))
(format " [%s]" allout-passphrase-hint-string)
"")))
(verifier-string (allout-get-encryption-passphrase-verifier))
(passphrase (read-passwd
(format "Passphrase for %s symmetric encryption%s: "
(buffer-name allout-buffer) hint-string))))
(if allout-passphrase-verifier-handling
(if verifier-string
;; try verifying against existing verifier.
;; - successful: return the passphrase.
;; - unsuccessful: offer to change the verifier
;; - if change accepted, change verifier and continue
;; - if change refused, raise an encryption error.
(if (condition-case err
(epg-decrypt-string
(allout-context-epg-passphrase-callback
epg-context allout-buffer passphrase)
verifier-string)
(error nil))
;;(allout-update-passphrase-mnemonic-aids for-key passphrase
;; allout-buffer)
)
(read-passwd
(if (eq key-id 'PIN)
"Passphrase for PIN: "
(let ((entry (assoc key-id epg-user-id-alist)))
(if entry
(format "Passphrase for %s %s: " key-id (cdr entry))
(format "Passphrase for %s: " key-id)))))))
;;;_ > allout-context-epg-passphrase-callback (epg-context buffer
;;; &optional passphrase)
(defun allout-context-epg-passphrase-callback (epg-context buffer
&optional passphrase)
"Return an epg-context which uses allout's passphrase callback with state.
NOTE that epg's passphrase callback provision only works when
operating with GnuPG v1. Check your GnuPG version using 'gpg
--version' from the command line.
A deep copy of the specified EPG-CONTEXT, per 'epg-make-context',
is used as a template.
BUFFER is the allout outline buffer containing the target text.
Optional PASSPHRASE is an already obtained passphrase to be used for
multiple decryptions, eg when verifying symmetric passphrases."
(let ((new-epg-context (copy-tree epg-context)))
(epg-context-set-passphrase-callback
new-epg-context
(cons #'allout-epg-passphrase-callback-function
(allout-make-passphrase-state buffer passphrase)))
new-epg-context))
;;;_ > allout-make-passphrase-state (buffer &optional passphrase)
(defun allout-make-passphrase-state (buffer &optional passphrase)
"Return an allout passphrase state construct.
BUFFER is the allout outline buffer.
Optional PASSPHRASE is used when decrypting to convey an already
obtained passphrase for doing multiple decryptions, eg when doing
verification as part of symmetric passphrse decryption."
(cons buffer passphrase))
;;;_ > allout-passphrase-state-buffer (state)
(defun allout-passphrase-state-buffer (state)
"Given an allout passphrase STATE construct, return the buffer."
(car state))
;;;_ > allout-passphrase-state-passphrase (state)
(defun allout-passphrase-state-passphrase (state)
"Given an allout passphrase STATE construct, return the passphrase or nil."
(cdr state))
;;;_ > ;;PGG allout-obtain-passphrase (for-key ;;PGG cache-id
;;; prompt-id key-type allout-buffer retried
;;; ;;PGG fetch-pass)
(defun allout-obtain-passphrase (for-key ;;PGG cache-id
prompt-id key-type allout-buffer retried
;;fetch-pass
)
"Obtain passphrase for a key from the user.
When obtaining from the user, symmetric-cipher passphrases are verified
against either, if available and enabled, a random string that was
encrypted against the passphrase, or else against repeated entry by the
user for corroboration.
FOR-KEY is the key for which the passphrase is being obtained.
;;PGG CACHE-ID is the cache id of the key for the passphrase.
PROMPT-ID is the id for use when prompting the user.
KEY-TYPE is either `symmetric' or `keypair'.
ALLOUT-BUFFER is the buffer containing the entry being en/decrypted.
RETRIED is the number of this attempt to obtain this passphrase.
;;PGG FETCH-PASS causes the passphrase to be solicited from the user, regardless
;;PGG of the availability of a cached copy.
"
(if (not (equal key-type 'symmetric))
;; do regular passphrase read on non-symmetric passphrase:
(pgg-read-passphrase (format "%s passphrase%s: "
(upcase (format "%s" (or pgg-scheme
pgg-default-scheme
"GPG")))
(if prompt-id
(format " for %s" prompt-id)
""))
for-key ;;PGG cache-id
t)
;; Symmetric hereon:
(with-current-buffer allout-buffer
(let* ((hint (if (and (not (string= allout-passphrase-hint-string ""))
(or (equal allout-passphrase-hint-handling 'always)
(and (equal allout-passphrase-hint-handling
'needed)
retried)))
(format " [%s]" allout-passphrase-hint-string)
""))
(retry-message (if retried (format " (%s retry)" retried) ""))
(prompt-sans-hint (format "'%s' symmetric passphrase%s: "
prompt-id retry-message))
(full-prompt (format "'%s' symmetric passphrase%s%s: "
prompt-id hint retry-message))
(prompt full-prompt)
(verifier-string (allout-get-encryption-passphrase-verifier))
;;PGG (cached (and (not fetch-pass)
;;PGG (pgg-read-passphrase-from-cache cache-id t)))
(got-pass ;;PGG (or cached
(pgg-read-passphrase full-prompt ;;PGG cache-id
for-key t))
;;PGG )
confirmation)
(if (not got-pass)
nil
;; Duplicate our handle on the passphrase so it's not clobbered by
;; deactivate-passwd memory clearing:
(setq got-pass (copy-sequence got-pass))
(cond (verifier-string
(save-window-excursion
(if (allout-encrypt-string verifier-string 'decrypt
allout-buffer 'symmetric for-key
;;PGG nil
0 0 'verifying
(copy-sequence got-pass))
(setq confirmation (format "%s" got-pass))))
(if (and (not confirmation)
(if (yes-or-no-p
(concat "Passphrase differs from established"
" -- use new one instead? "))
;; deactivate password for subsequent
;; confirmation:
(progn
;;PGG (pgg-remove-passphrase-from-cache cache-id t)
(setq prompt prompt-sans-hint)
nil)
t))
;;PGG (progn (pgg-remove-passphrase-from-cache cache-id t)
(error "Wrong passphrase")))
;;PGG)
;; No verifier string -- force confirmation by repetition of
;; (new) passphrase:
;;PGG ((or fetch-pass (not cached))
;;PGG (pgg-remove-passphrase-from-cache cache-id t)))
)
;; confirmation vs new input -- doing pgg-read-passphrase will do the
;; right thing, in either case:
(if (not confirmation)
(setq confirmation
(pgg-read-passphrase (concat prompt
" ... confirm spelling: ")
;;PGG cache-id
for-key t)))
(prog1
(if (equal got-pass confirmation)
confirmation
(if (yes-or-no-p (concat "spelling of original and"
" confirmation differ -- retry? "))
(progn (setq retried (if retried (1+ retried) 1))
;;PGG (pgg-remove-passphrase-from-cache cache-id
for-key t)
;; recurse to this routine:
(pgg-read-passphrase prompt-sans-hint ;;PGG cache-id
for-key t))
;;PGG (pgg-remove-passphrase-from-cache cache-id t)
(error "Confirmation failed"))))))))
(t result-text))))
;;;_ > allout-encrypted-topic-p ()
(defun allout-encrypted-topic-p ()
"True if the current topic is encryptable and encrypted."
@ -6531,130 +6228,6 @@ RETRIED is the number of this attempt to obtain this passphrase.
(save-match-data (looking-at "\\*")))
)
)
;;;_ > ;;PGG allout-encrypted-key-info (text)
;; XXX gpg-specific, alas
(defun allout-encrypted-key-info (text)
"Return a pair of the key type and identity of a recipient's secret key.
The key type is one of `symmetric' or `keypair'.
If `keypair', and some of the user's secret keys are among those for which
the message was encoded, return the identity of the first. Otherwise,
return nil for the second item of the pair.
An error is raised if the text is not encrypted."
(require 'pgg-parse)
(save-excursion
(with-temp-buffer
(insert text)
(let* ((parsed-armor (pgg-parse-armor-region (point-min) (point-max)))
(type (if (assq 'symmetric-key-algorithm (car (cdr parsed-armor)))
'symmetric
'keypair))
secret-keys first-secret-key for-key-owner)
(if (equal type 'keypair)
(setq secret-keys (pgg-gpg-lookup-all-secret-keys)
first-secret-key (pgg-gpg-select-matching-key parsed-armor
secret-keys)
for-key-owner (and first-secret-key
(pgg-gpg-lookup-key-owner
first-secret-key))))
(list type (pgg-gpg-key-id-from-key-owner for-key-owner))
)
)
)
)
;;;_ > allout-create-encryption-passphrase-verifier (passphrase)
(defun allout-create-encryption-passphrase-verifier (passphrase)
"Encrypt random message for later validation of symmetric key's passphrase."
;; use 20 random ascii characters, across the entire ascii range.
(random t)
(let ((spew (make-string 20 ?\0)))
(dotimes (i (length spew))
(aset spew i (1+ (random 254))))
(allout-encrypt-string spew nil (current-buffer) 'symmetric nil
;;PGG nil
nil 0 0 passphrase))
)
;;;_ > allout-update-passphrase-mnemonic-aids (for-key passphrase
;;; outline-buffer)
(defun allout-update-passphrase-mnemonic-aids (for-key passphrase
outline-buffer)
"Update passphrase verifier and hint strings if necessary.
See `allout-passphrase-verifier-string' and `allout-passphrase-hint-string'
settings.
PASSPHRASE is the passphrase being mnemonicized.
OUTLINE-BUFFER is the buffer of the outline being adjusted.
These are used to help the user keep track of the passphrase they use for
symmetric encryption in the file.
Behavior is governed by `allout-passphrase-verifier-handling',
`allout-passphrase-hint-handling', and also, controlling whether the values
are preserved on Emacs local file variables,
`allout-enable-file-variable-adjustment'."
;; If passphrase doesn't agree with current verifier:
;; - adjust the verifier
;; - if passphrase hint handling is enabled, adjust the passphrase hint
;; - if file var settings are enabled, adjust the file vars
(let* ((new-verifier-needed (not (allout-verify-passphrase
for-key passphrase outline-buffer)))
(new-verifier-string
(if new-verifier-needed
;; Collapse to a single line and enclose in string quotes:
(subst-char-in-string
?\n ?\C-a (allout-create-encryption-passphrase-verifier
passphrase))))
new-hint)
(when new-verifier-string
;; do the passphrase hint first, since it's interactive
(when (and allout-passphrase-hint-handling
(not (equal allout-passphrase-hint-handling 'disabled)))
(setq new-hint
(read-from-minibuffer "Passphrase hint to jog your memory: "
allout-passphrase-hint-string))
(when (not (string= new-hint allout-passphrase-hint-string))
(setq allout-passphrase-hint-string new-hint)
(allout-adjust-file-variable "allout-passphrase-hint-string"
allout-passphrase-hint-string)))
(when allout-passphrase-verifier-handling
(setq allout-passphrase-verifier-string new-verifier-string)
(allout-adjust-file-variable "allout-passphrase-verifier-string"
allout-passphrase-verifier-string))
)
)
)
;;;_ > allout-get-encryption-passphrase-verifier ()
(defun allout-get-encryption-passphrase-verifier ()
"Return text of the encrypt passphrase verifier, unmassaged, or nil if none.
Derived from value of `allout-passphrase-verifier-string'."
(let ((verifier-string (and (boundp 'allout-passphrase-verifier-string)
allout-passphrase-verifier-string)))
(if verifier-string
;; Return it uncollapsed
(subst-char-in-string ?\C-a ?\n verifier-string))
)
)
;;;_ > allout-verify-passphrase (key passphrase allout-buffer)
(defun allout-verify-passphrase (key passphrase allout-buffer)
"True if passphrase successfully decrypts verifier, nil otherwise.
\"Otherwise\" includes absence of passphrase verifier."
(with-current-buffer allout-buffer
(and (boundp 'allout-passphrase-verifier-string)
allout-passphrase-verifier-string
(allout-encrypt-string (allout-get-encryption-passphrase-verifier)
'decrypt allout-buffer 'symmetric key
;;PGG nil
0 0 'verifying passphrase)
t)))
;;;_ > allout-next-topic-pending-encryption (&optional except-mark)
(defun allout-next-topic-pending-encryption (&optional except-mark)
"Return the point of the next topic pending encryption, or nil if none.