aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaiki Ueno2011-08-04 15:55:53 +0900
committerDaiki Ueno2011-08-04 15:55:53 +0900
commiteeec79cbfa7d7a45b1436942878ef5ad627a5a31 (patch)
tree08f494b08df4543ef044bd89a45fe09a7dd15047
parentc74e9d8682a27211336db9745f7b4d6399929b37 (diff)
downloademacs-eeec79cbfa7d7a45b1436942878ef5ad627a5a31.tar.gz
emacs-eeec79cbfa7d7a45b1436942878ef5ad627a5a31.zip
Make sure GPG keys are usable when composing non-MIME messages (bug#8955).
* mml1991.el (mml1991-epg-find-usable-key) (mml1991-epg-find-usable-secret-key): New function. (mml1991-epg-sign): Check if signing key is usable. (mml1991-epg-encrypt): Check if encrypting key is usable (bug#8955).
-rw-r--r--lisp/gnus/ChangeLog7
-rw-r--r--lisp/gnus/mml1991.el94
2 files changed, 82 insertions, 19 deletions
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index 9029ab8e6fd..b361760f511 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,10 @@
12011-08-04 Daiki Ueno <ueno@unixuser.org>
2
3 * mml1991.el (mml1991-epg-find-usable-key)
4 (mml1991-epg-find-usable-secret-key): New function.
5 (mml1991-epg-sign): Check if signing key is usable.
6 (mml1991-epg-encrypt): Check if encrypting key is usable (bug#8955).
7
12011-08-03 Andrew Cohen <cohen@andy.bu.edu> 82011-08-03 Andrew Cohen <cohen@andy.bu.edu>
2 9
3 * nnir.el (nnir-read-server-parm): Add an argument to restrict to 10 * nnir.el (nnir-read-server-parm): Add an argument to restrict to
diff --git a/lisp/gnus/mml1991.el b/lisp/gnus/mml1991.el
index a5d778845c1..ad9f95796fe 100644
--- a/lisp/gnus/mml1991.el
+++ b/lisp/gnus/mml1991.el
@@ -247,6 +247,10 @@ Whether the passphrase is cached at all is controlled by
247(autoload 'epg-context-set-textmode "epg") 247(autoload 'epg-context-set-textmode "epg")
248(autoload 'epg-context-set-signers "epg") 248(autoload 'epg-context-set-signers "epg")
249(autoload 'epg-context-set-passphrase-callback "epg") 249(autoload 'epg-context-set-passphrase-callback "epg")
250(autoload 'epg-key-sub-key-list "epg")
251(autoload 'epg-sub-key-capability "epg")
252(autoload 'epg-sub-key-validity "epg")
253(autoload 'epg-sub-key-fingerprint "epg")
250(autoload 'epg-sign-string "epg") 254(autoload 'epg-sign-string "epg")
251(autoload 'epg-encrypt-string "epg") 255(autoload 'epg-encrypt-string "epg")
252(autoload 'epg-configuration "epg-config") 256(autoload 'epg-configuration "epg-config")
@@ -274,17 +278,59 @@ Whether the passphrase is cached at all is controlled by
274 (cons key-id mml1991-epg-secret-key-id-list)) 278 (cons key-id mml1991-epg-secret-key-id-list))
275 (copy-sequence passphrase))))) 279 (copy-sequence passphrase)))))
276 280
281(defun mml1991-epg-find-usable-key (keys usage)
282 (catch 'found
283 (while keys
284 (let ((pointer (epg-key-sub-key-list (car keys))))
285 (while pointer
286 (if (and (memq usage (epg-sub-key-capability (car pointer)))
287 (not (memq 'disabled (epg-sub-key-capability (car pointer))))
288 (not (memq (epg-sub-key-validity (car pointer))
289 '(revoked expired))))
290 (throw 'found (car keys)))
291 (setq pointer (cdr pointer))))
292 (setq keys (cdr keys)))))
293
294;; XXX: since gpg --list-secret-keys does not return validity of each
295;; key, `mml1991-epg-find-usable-key' defined above is not enough for
296;; secret keys. The function `mml1991-epg-find-usable-secret-key'
297;; below looks at appropriate public keys to check usability.
298(defun mml1991-epg-find-usable-secret-key (context name usage)
299 (let ((secret-keys (epg-list-keys context name t))
300 secret-key)
301 (while (and (not secret-key) secret-keys)
302 (if (mml1991-epg-find-usable-key
303 (epg-list-keys context (epg-sub-key-fingerprint
304 (car (epg-key-sub-key-list
305 (car secret-keys)))))
306 usage)
307 (setq secret-key (car secret-keys)
308 secret-keys nil)
309 (setq secret-keys (cdr secret-keys))))
310 secret-key))
311
277(defun mml1991-epg-sign (cont) 312(defun mml1991-epg-sign (cont)
278 (let ((context (epg-make-context)) 313 (let ((context (epg-make-context))
279 headers cte signers signature) 314 headers cte signer-key signers signature)
280 (if (eq mm-sign-option 'guided) 315 (if (eq mm-sign-option 'guided)
281 (setq signers (epa-select-keys context "Select keys for signing. 316 (setq signers (epa-select-keys context "Select keys for signing.
282If no one is selected, default secret key is used. " 317If no one is selected, default secret key is used. "
283 mml1991-signers t)) 318 mml1991-signers t))
284 (if mml1991-signers 319 (if mml1991-signers
285 (setq signers (mapcar (lambda (name) 320 (setq signers (delq nil
286 (car (epg-list-keys context name t))) 321 (mapcar
287 mml1991-signers)))) 322 (lambda (name)
323 (setq signer-key
324 (mml1991-epg-find-usable-secret-key
325 context name 'sign))
326 (unless (or signer-key
327 (y-or-n-p
328 (format
329 "No secret key for %s; skip it? "
330 name)))
331 (error "No secret key for %s" name))
332 signer-key)
333 mml1991-signers)))))
288 (epg-context-set-armor context t) 334 (epg-context-set-armor context t)
289 (epg-context-set-textmode context t) 335 (epg-context-set-textmode context t)
290 (epg-context-set-signers context signers) 336 (epg-context-set-signers context signers)
@@ -344,7 +390,11 @@ If no one is selected, default secret key is used. "
344 (split-string 390 (split-string
345 (message-options-get 'message-recipients) 391 (message-options-get 'message-recipients)
346 "[ \f\t\n\r\v,]+"))) 392 "[ \f\t\n\r\v,]+")))
347 cipher signers config) 393 recipient-key signer-key cipher signers config)
394 (when mml1991-encrypt-to-self
395 (unless mml1991-signers
396 (error "mml1991-signers is not set"))
397 (setq recipients (nconc recipients mml1991-signers)))
348 ;; We should remove this check if epg-0.0.6 is released. 398 ;; We should remove this check if epg-0.0.6 is released.
349 (if (and (condition-case nil 399 (if (and (condition-case nil
350 (require 'epg-config) 400 (require 'epg-config)
@@ -363,26 +413,32 @@ If no one is selected, default secret key is used. "
363If no one is selected, symmetric encryption will be performed. " 413If no one is selected, symmetric encryption will be performed. "
364 recipients)) 414 recipients))
365 (setq recipients 415 (setq recipients
366 (delq nil (mapcar (lambda (name) 416 (delq nil (mapcar
367 (car (epg-list-keys context name))) 417 (lambda (name)
368 recipients)))) 418 (setq recipient-key (mml1991-epg-find-usable-key
369 (if mml1991-encrypt-to-self 419 (epg-list-keys context name)
370 (if mml1991-signers 420 'encrypt))
371 (setq recipients 421 (unless (or recipient-key
372 (nconc recipients 422 (y-or-n-p
373 (mapcar (lambda (name) 423 (format "No public key for %s; skip it? "
374 (car (epg-list-keys context name))) 424 name)))
375 mml1991-signers))) 425 (error "No public key for %s" name))
376 (error "mml1991-signers not set"))) 426 recipient-key)
427 recipients)))
428 (unless recipients
429 (error "No recipient specified")))
377 (when sign 430 (when sign
378 (if (eq mm-sign-option 'guided) 431 (if (eq mm-sign-option 'guided)
379 (setq signers (epa-select-keys context "Select keys for signing. 432 (setq signers (epa-select-keys context "Select keys for signing.
380If no one is selected, default secret key is used. " 433If no one is selected, default secret key is used. "
381 mml1991-signers t)) 434 mml1991-signers t))
382 (if mml1991-signers 435 (if mml1991-signers
383 (setq signers (mapcar (lambda (name) 436 (setq signers (delq nil
384 (car (epg-list-keys context name t))) 437 (mapcar
385 mml1991-signers)))) 438 (lambda (name)
439 (mml1991-epg-find-usable-secret-key
440 context name 'sign))
441 mml1991-signers)))))
386 (epg-context-set-signers context signers)) 442 (epg-context-set-signers context signers))
387 (epg-context-set-armor context t) 443 (epg-context-set-armor context t)
388 (epg-context-set-textmode context t) 444 (epg-context-set-textmode context t)