args)))
(set-default-file-modes orig-mode))
(set-process-filter process #'epg--process-filter)
- (set-process-sentinel process #'ignore)
(epg-context-set-process context process)))
(defun epg--process-filter (process input)
(string (match-string 2))
(symbol (intern-soft (concat "epg--status-"
status))))
- (forward-line)
- (setq epg-read-point (point))
(if (member status epg-pending-status-list)
(setq epg-pending-status-list nil))
(if (and symbol
(fboundp symbol))
(funcall symbol epg-context string))
- (goto-char epg-read-point)
- (setq epg-last-status (cons status string)))
- (forward-line)
- (setq epg-read-point (point)))))
+ (setq epg-last-status (cons status string))))
+ (forward-line)
+ (setq epg-read-point (point))))
(setq epg-process-filter-running nil))))))
(defun epg-read-output (context)
(while (eq (process-status (epg-context-process context)) 'run)
(accept-process-output (epg-context-process context) 1)))
-(defun epg-wait-for-plaintext (context length)
- "Wait data from the `epg-gpg-program' process."
- (while (and (eq (process-status (epg-context-process context)) 'run)
- (< (- (point-max) epg-read-point) length))
- (accept-process-output (epg-context-process context) 1)))
-
(defun epg-reset (context)
"Reset the CONTEXT."
(if (and (epg-context-process context)
(user-id (match-string 2 string))
(entry (assoc key-id epg-user-id-alist)))
(condition-case nil
- (setq user-id (epg--decode-coding-string user-id 'utf-8))
+ (setq user-id (epg--decode-coding-string
+ (epg--decode-percent-escape user-id)
+ 'utf-8))
(error))
(if entry
(setcdr entry user-id)
(condition-case nil
(if (eq (epg-context-protocol context) 'CMS)
(setq user-id (epg-dn-from-string user-id))
- (setq user-id (epg--decode-coding-string user-id 'utf-8)))
+ (setq user-id (epg--decode-coding-string
+ (epg--decode-percent-escape user-id)
+ 'utf-8)))
(error))
(if entry
(setcdr entry user-id)
(if (consp (epg-context-progress-callback context))
(cdr (epg-context-progress-callback context))))))
-(defun epg--status-BEGIN_DECRYPTION (context string)
- (epg-context-set-result-for context 'plaintext nil))
-
(defun epg--status-DECRYPTION_FAILED (context string)
(epg-context-set-result-for context 'decryption-failed t))
(defun epg--status-DECRYPTION_OKAY (context string)
- (epg-context-set-result-for context 'decryption-okay t)
- (epg-context-set-result-for
- context
- 'decrypted-plaintext
- (epg-context-result-for context 'plaintext)))
-
-(defun epg--status-PLAINTEXT_LENGTH (context string)
- (when (string-match "\\`\\([0-9]+\\)" string)
- (let ((length (string-to-number (match-string 1 string))))
- (epg-wait-for-plaintext context length)
- (epg-context-set-result-for
- context 'plaintext
- (buffer-substring epg-read-point
- (setq epg-read-point (+ epg-read-point length)))))))
+ (epg-context-set-result-for context 'decryption-okay t))
(defun epg--status-NODATA (context string)
(epg-context-set-result-for
(user-id (match-string 2 string))
(entry (assoc key-id epg-user-id-alist)))
(condition-case nil
- (setq user-id (epg--decode-coding-string user-id 'utf-8))
+ (setq user-id (epg--decode-coding-string
+ (epg--decode-percent-escape user-id)
+ 'utf-8))
(error))
(if entry
(setcdr entry user-id)
(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-fingerprint"
- (if (memq mode '(t secret))
- "--list-secret-keys"
- (if (memq mode '(nil public))
- "--list-keys"
- "--list-sigs")))
+ '("--with-colons" "--no-greeting" "--batch"
+ "--with-fingerprint" "--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)
+ (if name
+ (progn
+ (unless (listp name)
+ (setq name (list name)))
+ (while name
+ (setq args (append args (list list-keys-option (car name)))
+ name (cdr name))))
+ (setq args (append args (list list-keys-option))))
(with-temp-buffer
(apply #'call-process
(if (eq (epg-context-protocol context) 'CMS)
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 index string)
(while lines
(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
(if (aref (car lines) 1)
(cdr (assq (string-to-char (aref (car lines) 1))
epg-key-validity-alist)))
- (condition-case nil
- (if cert
- (epg-dn-from-string (aref (car lines) 9))
- (setq string (copy-sequence (aref (car lines) 9)))
- (while (string-match "\"" string index)
- (setq string (replace-match "\\\"" t t string)
- index (1+ (match-end 0))))
- (epg--decode-coding-string
- (car (read-from-string (concat "\"" string "\"")))
- 'utf-8))
- (error (aref (car lines) 9))))
+ (if cert
+ (condition-case nil
+ (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)))
(unwind-protect
(progn
(write-region cipher nil input-file nil 'quiet)
+ (epg-context-set-output-file context
+ (epg--make-temp-file "epg-output"))
(epg-start-decrypt context (epg-make-data-from-file input-file))
(epg-wait-for-completion context)
(epg--check-error-for-decrypt context)
- (epg-context-result-for context 'decrypted-plaintext))
+ (epg-read-output context))
+ (epg-delete-output-file context)
(if (file-exists-p input-file)
(delete-file input-file))
(epg-reset context))))
(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).