("Signature by unknown keyid: " .
"UNKNOWN_SIGNATURE")))
-(defvar epg-pgp50i-status nil)
-
(defun epg-pgp50i--start (context program args)
(let ((args (append '("--headers" "--language=us")
(if (epg-context-armor context) '("--armor"))
(with-current-buffer buffer
(make-local-variable 'epg-read-point)
(setq epg-read-point (point-min))
+ (make-local-variable 'epg-process-filter-running)
+ (setq epg-process-filter-running nil)
(make-local-variable 'epg-pending-status-list)
(setq epg-pending-status-list nil)
(make-local-variable 'epg-key-id)
(setq epg-key-id nil)
(make-local-variable 'epg-context)
- (setq epg-context context)
- (make-local-variable 'epg-pgp50i-status)
- (setq epg-pgp50i-status nil))
+ (setq epg-context context))
(unwind-protect
(progn
(set-default-file-modes 448)
(set-buffer (process-buffer process))
(goto-char (point-max))
(insert input)
- (unless epg-pgp50i-status
- (goto-char epg-read-point)
- (while (not (eobp))
- (save-excursion
- (if (looking-at
- "\\(PRI\\|INF\\|QRY\\|STA\\|WRN\\|ERR\\): \\(.*\\)")
- (let ((message (match-string 2))
- (pointer epg-pgp50i-message-alist)
- status symbol)
- (while pointer
- (if (string-match (car (car pointer)) message)
- (setq status (cdr (car pointer))
- pointer nil))
- (setq pointer (cdr pointer)))
- (when status
- (unless (looking-at ".*\n")
- (end-of-line)
- (insert "\n"))
- (if (member status epg-pending-status-list)
- (setq epg-pending-status-list nil))
- (setq symbol (intern-soft (concat "epg-pgp50i--status-"
- status)))
- (if (and symbol
- (fboundp symbol))
- (unwind-protect
- (progn
- (setq epg-pgp50i-status status)
- (funcall symbol epg-context message))
- (setq epg-pgp50i-status nil)))))))
- (forward-line)
- (setq epg-read-point (point)))))))
-
-(defun epg-pgp50i--wait-for-line (context)
+ (unless epg-process-filter-running
+ (unwind-protect
+ (progn
+ (setq epg-process-filter-running t)
+ (goto-char epg-read-point)
+ (while (not (eobp))
+ (if (looking-at
+ "^\\(PRI\\|INF\\|QRY\\|STA\\|WRN\\|ERR\\): \\(.*\\)")
+ (let ((message (match-string 2))
+ (pointer epg-pgp50i-message-alist)
+ status symbol)
+ (while pointer
+ (if (string-match (car (car pointer)) message)
+ (setq status (cdr (car pointer))
+ pointer nil))
+ (setq pointer (cdr pointer)))
+ (when status
+ (unless (looking-at ".*\n")
+ (end-of-line)
+ (insert "\n"))
+ (if (member status epg-pending-status-list)
+ (setq epg-pending-status-list nil))
+ (setq symbol (intern-soft (concat
+ "epg-pgp50i--status-"
+ status)))
+ (if (and symbol
+ (fboundp symbol))
+ (funcall symbol epg-context message)))))
+ (forward-line)
+ (setq epg-read-point (point))))
+ (setq epg-process-filter-running nil))))))
+
+(defun epg-pgp50i--read-line (context)
(if (eq (process-status (epg-context-process context)) 'run)
(save-excursion
(set-buffer (process-buffer (epg-context-process context)))
+ (forward-line)
(goto-char epg-read-point)
- (beginning-of-line 2)
- (while (and (eq (process-status (epg-context-process context)) 'run)
- (not (if (looking-at ".*\n")
- (setq epg-read-point (point)))))
- (accept-process-output (epg-context-process context) 1))
- (buffer-substring (point) (progn (end-of-line) (point))))))
+ (if (looking-at ".*\n")
+ (buffer-substring (point) (progn (end-of-line) (point)))))))
(defun epg-pgp50i--status-ENTER_PASSPHRASE (context message)
(epg--status-GET_HIDDEN context "passphrase."))
(defun epg-pgp50i--read-key (context)
- (let ((line (epg-pgp50i--wait-for-line context))
+ (let ((line (epg-pgp50i--read-line context))
key-id user-id-list)
(when (and line
(string-match "[ 0-9]+ bits, Key ID \\([0-9A-F]+\\)" line))
(setq key-id (match-string 1 line))
- (when (and (setq line (epg-pgp50i--wait-for-line context))
- (string-match "\"\\([^\"]+\\)\"" line))
+ (while (and (setq line (epg-pgp50i--read-line context))
+ (string-match "\"\\([^\"]+\\)\"" line))
(setq user-id-list (cons (match-string 1 line) user-id-list)))
(cons key-id user-id-list))))
epg-user-id-alist)))
(setq epg-key-id (car key))))
+(defun epg-pgp50i--status-CANNOT_DECRYPT (context message)
+ (epg-context-set-result-for
+ context 'error
+ (cons (cons 'decryption-failed
+ (epg-pgp50i--read-key context))
+ (epg-context-result-for context 'error))))
+
+(defun epg-pgp50i--parse-time (string)
+ (if (string-match "\\`\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\) \
+\\([0-9][0-9]\\):\\([0-9][0-9]\\) GMT\\'" string)
+ (encode-time 0
+ (string-to-number (match-string 5 string))
+ (string-to-number (match-string 4 string))
+ (string-to-number (match-string 3 string))
+ (string-to-number (match-string 2 string))
+ (string-to-number (match-string 1 string))
+ 0)))
+
(defun epg-pgp50i--status-GOOD_SIGNATURE (context message)
- (let ((key (epg-pgp50i--read-key context)))
- (epg--status-*SIG context 'good (concat (car key) " " (car (cdr key))))))
+ (if (string-match "Good signature made \\(.*\\) by key:" message)
+ (let ((time (epg-pgp50i--parse-time (match-string 1 message)))
+ (key (epg-pgp50i--read-key context)))
+ (epg--status-*SIG context 'good (concat (car key) " " (car (cdr key))))
+ (epg-signature-set-creation-time
+ (car (epg-context-result-for context 'verify))
+ time))))
+
+(defun epg-pgp50i--status-BAD_SIGNATURE (context message)
+ (if (string-match "BAD signature made \\(.*\\) by key:" message)
+ (let ((time (epg-pgp50i--parse-time (match-string 1 message)))
+ (key (epg-pgp50i--read-key context)))
+ (epg--status-*SIG context 'good (concat (car key) " " (car (cdr key))))
+ (epg-signature-set-creation-time
+ (car (epg-context-result-for context 'verify))
+ time))))
(defadvice epg-start-decrypt
(around epg-pgp50i activate)
(around epg-pgp50i activate)
(if (eq (epg-context-protocol (ad-get-arg 0)) 'CMS)
ad-do-it
- (error "Not implemented yet")))
+ (let ((context (ad-get-arg 0))
+ (plain (ad-get-arg 1))
+ (mode (ad-get-arg 2)))
+ (epg-context-set-operation context 'sign)
+ (epg-context-set-result context nil)
+ (unless (memq mode '(t detached nil normal))
+ (epg-context-set-armor context t))
+ (epg-pgp50i--start context
+ epg-pgp50i-pgps-program
+ (append (list (if (memq mode '(t detached))
+ "-b"))
+ (apply #'nconc
+ (mapcar
+ (lambda (signer)
+ (list "-u"
+ (epg-sub-key-id
+ (car (epg-key-sub-key-list signer)))))
+ (epg-context-signers context)))
+ (if (epg-data-file plain)
+ (list (epg-data-file plain)))))
+ ;; `gpgsm' does not read passphrase from stdin, so waiting is not needed.
+ (unless (eq (epg-context-protocol context) 'CMS)
+ (epg-wait-for-status context '("BEGIN_SIGNING")))
+ (when (epg-data-string plain)
+ (if (eq (process-status (epg-context-process context)) 'run)
+ (process-send-string (epg-context-process context)
+ (epg-data-string plain)))
+ (if (eq (process-status (epg-context-process context)) 'run)
+ (process-send-eof (epg-context-process context)))))
+ ))
(defadvice epg-start-encrypt
(around epg-pgp50i activate)