* epg.el (epg-start-verify): Fixed a clearsign verification bug.
[elisp/epg.git] / epg.el
diff --git a/epg.el b/epg.el
index 29f78f8..87e8c5c 100644 (file)
--- a/epg.el
+++ b/epg.el
        (vector (or protocol 'OpenPGP) armor textmode include-certs
                cipher-algorithm digest-algorithm compress-algorithm
                #'epg-passphrase-callback-function
-               #'epg-progress-callback-function
+               nil
                nil nil nil nil nil)))
 
 (defun epg-context-protocol (context)
@@ -765,7 +765,7 @@ This function is for internal use only."
    (cond ((eq (epg-new-signature-type new-signature) 'detached)
          "Detached signature ")
         ((eq (epg-new-signature-type new-signature) 'clear)
-         "Clear text signature ")
+         "Cleartext signature ")
         (t
          "Signature "))
    (cdr (assq (epg-new-signature-pubkey-algorithm new-signature)
@@ -788,6 +788,8 @@ This function is for internal use only."
   (let* ((args (append (list "--no-tty"
                             "--status-fd" "1"
                             "--yes")
+                      (if (epg-context-progress-callback context)
+                          (list "--enable-progress-filter"))
                       (if epg-gpg-home-directory
                           (list "--homedir" epg-gpg-home-directory))
                       (unless (eq (epg-context-protocol context) 'CMS)
@@ -928,53 +930,55 @@ This function is for internal use only."
   (setq epg-key-id 'PIN))
 
 (defun epg--status-GET_HIDDEN (context string)
-  (if (and epg-key-id
-          (string-match "\\`passphrase\\." string))
-      (let (inhibit-quit
-           passphrase
-           passphrase-with-new-line
-           encoded-passphrase-with-new-line)
-       (unwind-protect
-           (condition-case nil
-               (progn
-                 (setq passphrase
-                       (funcall
-                        (if (consp (epg-context-passphrase-callback context))
-                            (car (epg-context-passphrase-callback context))
-                          (epg-context-passphrase-callback context))
-                        context
-                        epg-key-id
-                        (if (consp (epg-context-passphrase-callback context))
-                            (cdr (epg-context-passphrase-callback context)))))
-                 (when passphrase
-                   (setq passphrase-with-new-line (concat passphrase "\n"))
-                   (epg--clear-string passphrase)
-                   (setq passphrase nil)
-                   (if epg-locale-coding-system
-                       (progn
-                         (setq encoded-passphrase-with-new-line
-                               (encode-coding-string
-                                passphrase-with-new-line
-                                epg-locale-coding-system))
-                         (epg--clear-string passphrase-with-new-line)
-                         (setq passphrase-with-new-line nil))
-                     (setq encoded-passphrase-with-new-line
-                           passphrase-with-new-line
-                           passphrase-with-new-line nil))
-                   (process-send-string (epg-context-process context)
-                                        encoded-passphrase-with-new-line)))
-             (quit
-              (epg-context-set-result-for
-               context 'error
-               (cons '(quit)
-                     (epg-context-result-for context 'error)))
-              (delete-process (epg-context-process context))))
-         (if passphrase
-             (epg--clear-string passphrase))
-         (if passphrase-with-new-line
-             (epg--clear-string passphrase-with-new-line))
-         (if encoded-passphrase-with-new-line
-             (epg--clear-string encoded-passphrase-with-new-line))))))
+  (when (and epg-key-id
+            (string-match "\\`passphrase\\." string))
+    (unless (epg-context-passphrase-callback context)
+      (error "passphrase-callback not set"))
+    (let (inhibit-quit
+         passphrase
+         passphrase-with-new-line
+         encoded-passphrase-with-new-line)
+      (unwind-protect
+         (condition-case nil
+             (progn
+               (setq passphrase
+                     (funcall
+                      (if (consp (epg-context-passphrase-callback context))
+                          (car (epg-context-passphrase-callback context))
+                        (epg-context-passphrase-callback context))
+                      context
+                      epg-key-id
+                      (if (consp (epg-context-passphrase-callback context))
+                          (cdr (epg-context-passphrase-callback context)))))
+               (when passphrase
+                 (setq passphrase-with-new-line (concat passphrase "\n"))
+                 (epg--clear-string passphrase)
+                 (setq passphrase nil)
+                 (if epg-passphrase-coding-system
+                     (progn
+                       (setq encoded-passphrase-with-new-line
+                             (encode-coding-string
+                              passphrase-with-new-line
+                              epg-passphrase-coding-system))
+                       (epg--clear-string passphrase-with-new-line)
+                       (setq passphrase-with-new-line nil))
+                   (setq encoded-passphrase-with-new-line
+                         passphrase-with-new-line
+                         passphrase-with-new-line nil))
+                 (process-send-string (epg-context-process context)
+                                      encoded-passphrase-with-new-line)))
+           (quit
+            (epg-context-set-result-for
+             context 'error
+             (cons '(quit)
+                   (epg-context-result-for context 'error)))
+            (delete-process (epg-context-process context))))
+       (if passphrase
+           (epg--clear-string passphrase))
+       (if passphrase-with-new-line
+           (epg--clear-string passphrase-with-new-line))
+       (if encoded-passphrase-with-new-line
+           (epg--clear-string encoded-passphrase-with-new-line))))))
 
 (defun epg--status-GET_BOOL (context string)
   (let ((entry (assoc string epg-prompt-alist))
@@ -1302,9 +1306,8 @@ This function is for internal use only."
             (format "Passphrase for %s %s: " key-id (cdr entry))
           (format "Passphrase for %s: " key-id)))))))
 
-(defun epg-progress-callback-function (context what char current total
-                                              handback)
-  (message "%s: %d%%/%d%%" what current total))
+(make-obsolete 'epg-passphrase-callback-function
+              'epa-passphrase-callback-function)
 
 (defun epg--list-keys-1 (context name mode)
   (let ((args (append (if epg-gpg-home-directory
@@ -1506,7 +1509,7 @@ You can then use `write-region' to write new data into the file."
 ;;;###autoload
 (defun epg-start-decrypt (context cipher)
   "Initiate a decrypt operation on CIPHER.
-CIPHER is a data object.
+CIPHER must be a file data object.
 
 If you use this function, you will need to wait for the completion of
 `epg-gpg-program' by using `epg-wait-for-completion' and call
@@ -1517,7 +1520,7 @@ If you are unsure, use synchronous version of this function
     (error "Not a file"))
   (epg-context-set-operation context 'decrypt)
   (epg-context-set-result context nil)
-  (epg--start context (list "--decrypt" (epg-data-file cipher)))
+  (epg--start context (list "--decrypt" "--" (epg-data-file cipher)))
   ;; `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_DECRYPTION"))))
@@ -1570,7 +1573,7 @@ If PLAIN is nil, it returns the result as a string."
 SIGNATURE and SIGNED-TEXT are a data object if they are specified.
 
 For a detached signature, both SIGNATURE and SIGNED-TEXT should be set.
-For a normal or a clear text signature, SIGNED-TEXT should be nil.
+For a normal or a cleartext signature, SIGNED-TEXT should be nil.
 
 If you use this function, you will need to wait for the completion of
 `epg-gpg-program' by using `epg-wait-for-completion' and call
@@ -1582,9 +1585,10 @@ If you are unsure, use synchronous version of this function
   (if signed-text
       ;; Detached signature.
       (if (epg-data-file signed-text)
-         (epg--start context (list "--verify" (epg-data-file signature)
+         (epg--start context (list "--verify" "--" (epg-data-file signature)
                                   (epg-data-file signed-text)))
-       (epg--start context (list "--verify" (epg-data-file signature) "-"))
+       (epg--start context (list "--verify" "--" (epg-data-file signature)
+                                 "-"))
        (if (eq (process-status (epg-context-process context)) 'run)
            (process-send-string (epg-context-process context)
                                 (epg-data-string signed-text)))
@@ -1592,8 +1596,8 @@ If you are unsure, use synchronous version of this function
            (process-send-eof (epg-context-process context))))
     ;; Normal (or cleartext) signature.
     (if (epg-data-file signature)
-       (epg--start context (list "--verify" (epg-data-file signature)))
-      (epg--start context (list "--verify"))
+       (epg--start context (list "--" (epg-data-file signature)))
+      (epg--start context '("-"))
       (if (eq (process-status (epg-context-process context)) 'run)
          (process-send-string (epg-context-process context)
                               (epg-data-string signature)))
@@ -1605,8 +1609,10 @@ If you are unsure, use synchronous version of this function
   "Verify a file SIGNATURE.
 SIGNED-TEXT and PLAIN are also a file if they are specified.
 
-For a detached signature, both SIGNATURE and SIGNED-TEXT should be string.
-For a normal or a clear text signature, SIGNED-TEXT should be nil."
+For a detached signature, both SIGNATURE and SIGNED-TEXT should be
+string.  For a normal or a cleartext signature, SIGNED-TEXT should be
+nil.  In the latter case, if PLAIN is specified, the plaintext is
+stored into the file after successful verification."
   (unwind-protect
       (progn
        (if plain
@@ -1620,9 +1626,6 @@ For a normal or a clear text signature, SIGNED-TEXT should be nil."
          (epg-start-verify context
                            (epg-make-data-from-file signature)))
        (epg-wait-for-completion context)
-;      (if (epg-context-result-for context 'error)
-;          (error "Verify failed: %S"
-;                 (epg-context-result-for context 'error)))
        (unless plain
          (epg-read-output context)))
     (unless plain
@@ -1634,8 +1637,10 @@ For a normal or a clear text signature, SIGNED-TEXT should be nil."
   "Verify a string SIGNATURE.
 SIGNED-TEXT is a string if it is specified.
 
-For a detached signature, both SIGNATURE and SIGNED-TEXT should be string.
-For a normal or a clear text signature, SIGNED-TEXT should be nil."
+For a detached signature, both SIGNATURE and SIGNED-TEXT should be
+string.  For a normal or a cleartext signature, SIGNED-TEXT should be
+nil.  In the latter case, this function returns the plaintext after
+successful verification."
   (let ((coding-system-for-write 'binary)
        input-file)
     (unwind-protect
@@ -1651,9 +1656,6 @@ For a normal or a clear text signature, SIGNED-TEXT should be nil."
                                  (epg-make-data-from-string signed-text)))
            (epg-start-verify context (epg-make-data-from-string signature)))
          (epg-wait-for-completion context)
-;        (if (epg-context-result-for context 'error)
-;            (error "Verify failed: %S"
-;                   (epg-context-result-for context 'error)))
          (epg-read-output context))
       (epg-delete-output-file context)
       (if (and input-file
@@ -1668,7 +1670,7 @@ PLAIN is a data object.
 
 If optional 3rd argument MODE is t or 'detached, it makes a detached signature.
 If it is nil or 'normal, it makes a normal signature.
-Otherwise, it makes a clear text signature.
+Otherwise, it makes a cleartext signature.
 
 If you use this function, you will need to wait for the completion of
 `epg-gpg-program' by using `epg-wait-for-completion' and call
@@ -1691,7 +1693,7 @@ If you are unsure, use synchronous version of this function
                                      (car (epg-key-sub-key-list signer)))))
                             (epg-context-signers context)))
                     (if (epg-data-file plain)
-                        (list (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")))
@@ -1708,7 +1710,7 @@ If you are unsure, use synchronous version of this function
 If SIGNATURE is nil, it returns the result as a string.
 If optional 3rd argument MODE is t or 'detached, it makes a detached signature.
 If it is nil or 'normal, it makes a normal signature.
-Otherwise, it makes a clear text signature."
+Otherwise, it makes a cleartext signature."
   (unwind-protect
       (progn
        (if signature
@@ -1733,7 +1735,7 @@ Otherwise, it makes a clear text signature."
   "Sign a string PLAIN and return the output as string.
 If optional 3rd argument MODE is t or 'detached, it makes a detached signature.
 If it is nil or 'normal, it makes a normal signature.
-Otherwise, it makes a clear text signature."
+Otherwise, it makes a cleartext signature."
   (unwind-protect
       (progn
        (epg-context-set-output-file context
@@ -1784,7 +1786,7 @@ If you are unsure, use synchronous version of this function
                                      (car (epg-key-sub-key-list recipient)))))
                             recipients))
                     (if (epg-data-file plain)
-                        (list (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)
     (if sign
@@ -1908,7 +1910,7 @@ If you are unsure, use synchronous version of this function
   (epg-context-set-operation context 'import-keys)
   (epg-context-set-result context nil)
   (epg--start context (if (epg-data-file keys)
-                         (list "--import" (epg-data-file keys))
+                         (list "--import" "--" (epg-data-file keys))
                        (list "--import")))
   (when (epg-data-string keys)
     (if (eq (process-status (epg-context-process context)) 'run)
@@ -2044,7 +2046,7 @@ If you are unsure, use synchronous version of this function
   (epg-context-set-operation context 'generate-key)
   (epg-context-set-result context nil)
   (if (epg-data-file parameters)
-      (epg--start context (list "--batch" "--genkey"
+      (epg--start context (list "--batch" "--genkey" "--"
                               (epg-data-file parameters)))
     (epg--start context '("--batch" "--genkey"))
     (if (eq (process-status (epg-context-process context)) 'run)