X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=epg.el;h=356ad57cee75f5b042f8ba51e2b14403208affbc;hb=621763839b0561549af819bdfd77799fd23cfdf4;hp=79a03c6126797a44d0f135e32615da1c5f283426;hpb=332a8eb58f0f53054bb2b00c4ccba8e2f5a3b1b6;p=elisp%2Fepg.git diff --git a/epg.el b/epg.el index 79a03c6..356ad57 100644 --- a/epg.el +++ b/epg.el @@ -1061,7 +1061,9 @@ This function is for internal use only." (let* ((args (append (list "--no-tty" "--status-fd" "1" "--yes") - (if (string-match ":" (or (getenv "GPG_AGENT_INFO") "")) + (if (and (not (eq (epg-context-protocol context) 'CMS)) + (string-match ":" (or (getenv "GPG_AGENT_INFO") + ""))) '("--use-agent")) (if (and (not (eq (epg-context-protocol context) 'CMS)) (epg-context-progress-callback context)) @@ -1076,6 +1078,7 @@ This function is for internal use only." (list "--output" (epg-context-output-file context))) args)) (coding-system-for-write 'binary) + (coding-system-for-read 'binary) process-connection-type (orig-mode (default-file-modes)) (buffer (generate-new-buffer " *epg*")) @@ -1092,6 +1095,8 @@ This function is for internal use only." epg-gpg-program) (mapconcat #'identity args " "))))) (with-current-buffer buffer + (if (fboundp 'set-buffer-multibyte) + (set-buffer-multibyte nil)) (make-local-variable 'epg-last-status) (setq epg-last-status nil) (make-local-variable 'epg-read-point) @@ -1193,6 +1198,11 @@ This function is for internal use only." (let* ((key-id (match-string 1 string)) (user-id (match-string 2 string)) (entry (assoc key-id epg-user-id-alist))) + (condition-case nil + (setq user-id (epg--decode-coding-string + (epg--decode-percent-escape user-id) + 'utf-8)) + (error)) (if entry (setcdr entry user-id) (setq epg-user-id-alist (cons (cons key-id user-id) @@ -1265,11 +1275,10 @@ This function is for internal use only." (y-or-n-p (if entry (cdr entry) (concat string "? "))))) (defun epg--prompt-GET_BOOL-untrusted_key.override (context string) - (if (and (equal (car epg-last-status) "USERID_HINT") - (string-match "\\`\\([^ ]+\\) \\(.*\\)" (cdr epg-last-status))) - (y-or-n-p (format "Untrusted key %s %s. Trust this key anyway? " - (match-string 1 string) - (match-string 2 string))))) + (y-or-n-p (if (equal (car epg-last-status) "USERID_HINT") + (format "Untrusted key %s. Use anyway? " + (cdr epg-last-status)) + "Use untrusted key anyway? "))) (defun epg--status-GET_BOOL (context string) (let (inhibit-quit) @@ -1313,10 +1322,13 @@ This function is for internal use only." 'verify (cons (epg-make-signature status key-id) (epg-context-result-for context 'verify))) - (if (eq (epg-context-protocol context) 'CMS) - (condition-case nil + (condition-case nil + (if (eq (epg-context-protocol context) 'CMS) (setq user-id (epg-dn-from-string user-id)) - (error))) + (setq user-id (epg--decode-coding-string + (epg--decode-percent-escape user-id) + 'utf-8))) + (error)) (if entry (setcdr entry user-id) (setq epg-user-id-alist @@ -1575,6 +1587,11 @@ This function is for internal use only." (let* ((key-id (match-string 1 string)) (user-id (match-string 2 string)) (entry (assoc key-id epg-user-id-alist))) + (condition-case nil + (setq user-id (epg--decode-coding-string + (epg--decode-percent-escape user-id) + 'utf-8)) + (error)) (if entry (setcdr entry user-id) (setq epg-user-id-alist (cons (cons key-id user-id) @@ -1645,18 +1662,23 @@ This function is for internal use only." (defun epg--list-keys-1 (context name mode) (let ((args (append (if epg-gpg-home-directory (list "--homedir" epg-gpg-home-directory)) - (list "--with-colons" "--no-greeting" "--batch" - "--with-fingerprint" + '("--with-colons" "--no-greeting" "--batch" "--with-fingerprint" - (if (memq mode '(t secret)) - "--list-secret-keys" - (if (memq mode '(nil public)) - "--list-keys" - "--list-sigs"))) + "--with-fingerprint") (unless (eq (epg-context-protocol context) 'CMS) - '("--fixed-list-mode")) - (if name (list name)))) + '("--fixed-list-mode")))) + (list-keys-option (if (memq mode '(t secret)) + "--list-secret-keys" + (if (memq mode '(nil public)) + "--list-keys" + "--list-sigs"))) + (coding-system-for-read 'binary) keys string field index) + (unless (listp name) + (setq name (list name))) + (while name + (setq args (append args (list list-keys-option (car name))) + name (cdr name))) (with-temp-buffer (apply #'call-process (if (eq (epg-context-protocol context) 'CMS) @@ -1697,9 +1719,10 @@ This function is for internal use only." If MODE is nil or 'public, only public keyring should be searched. If MODE is t or 'secret, only secret keyring should be searched. Otherwise, only public keyring should be searched and the key -signatures should be included." +signatures should be included. +NAME is either a string or a list of strings." (let ((lines (epg--list-keys-1 context name mode)) - keys cert pointer pointer-1) + keys cert pointer pointer-1 index string) (while lines (cond ((member (aref (car lines) 0) '("pub" "sec" "crt" "crs")) @@ -1719,6 +1742,19 @@ signatures should be included." (cons (epg--make-sub-key-1 (car lines)) (epg-key-sub-key-list (car keys))))) ((equal (aref (car lines) 0) "uid") + ;; Decode the UID name as a backslash escaped UTF-8 string, + ;; generated by GnuPG/GpgSM. + (setq string (copy-sequence (aref (car lines) 9)) + index 0) + (while (string-match "\"" string index) + (setq string (replace-match "\\\"" t t string) + index (1+ (match-end 0)))) + (condition-case nil + (setq string (epg--decode-coding-string + (car (read-from-string (concat "\"" string "\""))) + 'utf-8)) + (error + (setq string (aref (car lines) 9)))) (epg-key-set-user-id-list (car keys) (cons (epg-make-user-id @@ -1727,9 +1763,9 @@ signatures should be included." epg-key-validity-alist))) (if cert (condition-case nil - (epg-dn-from-string (aref (car lines) 9)) - (error (aref (car lines) 9))) - (aref (car lines) 9))) + (epg-dn-from-string string) + (error string)) + string)) (epg-key-user-id-list (car keys))))) ((equal (aref (car lines) 0) "fpr") (epg-sub-key-set-fingerprint (car (epg-key-sub-key-list (car keys))) @@ -1832,6 +1868,10 @@ You can then use `write-region' to write new data into the file." (defalias 'epg--encode-coding-string 'encode-coding-string) (defalias 'epg--encode-coding-string 'identity)) +(if (fboundp 'decode-coding-string) + (defalias 'epg--decode-coding-string 'decode-coding-string) + (defalias 'epg--decode-coding-string 'identity)) + (defun epg--args-from-sig-notations (notations) (apply #'nconc (mapcar @@ -2496,27 +2536,42 @@ PARAMETERS is a string which tells how to create the key." (epg-context-result-for context 'error)))) (epg-reset context))) +(defun epg--decode-percent-escape (string) + (let ((index 0)) + (while (string-match "%\\(\\(%\\)\\|\\([0-9A-Fa-f][0-9A-Fa-f]\\)\\)" + string index) + (if (match-beginning 2) + (setq string (replace-match "%" t t string) + index (1- (match-end 0))) + (setq string (replace-match + (string (string-to-number (match-string 3 string) 16)) + t t string) + index (- (match-end 0) 2)))) + string)) + (defun epg--decode-hexstring (string) (let ((index 0)) (while (eq index (string-match "[0-9A-Fa-f][0-9A-Fa-f]" string index)) - (setq string (replace-match "\\\\x\\&" t nil string) - index (+ index 4))) - (car (read-from-string (concat "\"" string "\""))))) + (setq string (replace-match (string (string-to-number + (match-string 0 string) 16)) + t t string) + index (1- (match-end 0)))) + string)) (defun epg--decode-quotedstring (string) (let ((index 0)) (while (string-match "\\\\\\(\\([,=+<>#;\\\"]\\)\\|\ -\\([0-9A-Fa-f][0-9A-Fa-f]\\)\\|\\(.\\)\\)" +\\([0-9A-Fa-f][0-9A-Fa-f]\\)\\)" string index) (if (match-beginning 2) (setq string (replace-match "\\2" t nil string) - index (1+ index)) + index (1- (match-end 0))) (if (match-beginning 3) - (setq string (replace-match "\\\\x\\3" t nil string) - index (+ index 4)) - (setq string (replace-match "\\\\\\\\\\4" t nil string) - index (+ index 3))))) - (car (read-from-string (concat "\"" string "\""))))) + (setq string (replace-match (string (string-to-number + (match-string 0 string) 16)) + t t string) + index (- (match-end 0) 2))))) + string)) (defun epg-dn-from-string (string) "Parse STRING as LADPv3 Distinguished Names (RFC2253).