+;;; It is based on RFC 2015 (PGP/MIME) and
+;;; draft-yamamoto-openpgp-mime-00.txt (OpenPGP/MIME).
+
+(defcustom mime-pgp-command-alist '((gpg . "gpg")
+ (pgp50 . "pgp")
+ (pgp . "pgp"))
+ "Alist of the schemes and the name of the commands. Valid SCHEMEs are:
+
+ gpg - GnuPG.
+ pgp50 - PGP version 5.0i.
+ pgp - PGP version 2.6.
+
+COMMAND for `pgp50' must *NOT* have a suffix, like neither \"pgpe\", \"pgpk\",
+\"pgps\" nor \"pgpv\"."
+ :group 'mime-pgp
+ :type '(repeat (cons :format "%v"
+ (choice (choice-item :tag "GnuPG" gpg)
+ (choice-item :tag "PGP 5.0i" pgp50)
+ (choice-item :tag "PGP 2.6" pgp))
+ (string :tag "Command"))))
+
+(defcustom mime-pgp-default-language-alist '((gpg . nil)
+ (pgp50 . us)
+ (pgp . en))
+ "Alist of the schemes and the symbol of languages. It should be ISO 639
+2 letter language code such as en, ja, ... Each element looks like
+\(SCHEME . SYMBOL). See also `mime-pgp-command-alist' for valid SCHEMEs."
+ :group 'mime-pgp
+ :type '(repeat (cons :format "%v"
+ (choice (choice-item :tag "GnuPG" gpg)
+ (choice-item :tag "PGP 5.0i" pgp50)
+ (choice-item :tag "PGP 2.6" pgp))
+ (symbol :tag "Language"))))
+
+(defcustom mime-pgp-good-signature-regexp-alist
+ '((gpg
+ (nil "Good signature from.*$" nil)
+ )
+ (pgp50
+ (us "Good signature made .* by key:$"
+ mime-pgp-good-signature-post-function-pgp50-us)
+ )
+ (pgp
+ (en "Good signature from user.*$" nil)
+ ))
+ "Alist of the schemes and alist of the languages and the regexps for
+detecting ``Good signature''. The optional symbol of the post processing
+function for arranging the output message can be specified in each element.
+It will be called just after re-search is done successfully, and it is
+expected that the function returns a string for messaging."
+ :group 'mime-pgp
+ :type '(repeat (cons :format "%v"
+ (choice (choice-item :tag "GnuPG" gpg)
+ (choice-item :tag "PGP 5.0i" pgp50)
+ (choice-item :tag "PGP 2.6" pgp))
+ (repeat (list :format "%v"
+ (symbol :tag "Language")
+ (regexp :tag "Regexp")
+ (function :tag "Post Function"))))))
+
+(defcustom mime-pgp-bad-signature-regexp-alist
+ '((gpg
+ (nil "BAD signature from.*$" nil)
+ )
+ (pgp50
+ (us "BAD signature made .* by key:$"
+ mime-pgp-bad-signature-post-function-pgp50-us)
+ )
+ (pgp
+ (en "Bad signature from user.*$" nil)
+ ))
+ "Alist of the schemes and alist of the languages and the regexps for
+detecting ``BAD signature''. The optional symbol of the post processing
+function for arranging the output message can be specified in each element.
+It will be called just after re-search is done successfully, and it is
+expected that the function returns a string for messaging."
+ :group 'mime-pgp
+ :type '(repeat (cons :format "%v"
+ (choice (choice-item :tag "GnuPG" gpg)
+ (choice-item :tag "PGP 5.0i" pgp50)
+ (choice-item :tag "PGP 2.6" pgp))
+ (repeat (list :format "%v"
+ (symbol :tag "Language")
+ (regexp :tag "Regexp")
+ (function :tag "Post Function"))))))
+
+(defcustom mime-pgp-key-expected-regexp-alist
+ '((gpg
+ (nil
+ .
+ "key ID \\(\\S +\\)\ngpg: Can't check signature: public key not found")
+ )
+ (pgp50
+ (us . "Signature by unknown keyid: 0x\\(\\S +\\)")
+ )
+ (pgp
+ (en . "Key matching expected Key ID \\(\\S +\\) not found")
+ ))
+ "Alist of the schemes and alist of the languages and regexps for detecting
+``Key expected''."
+ :group 'mime-pgp
+ :type '(repeat (cons :format "%v"
+ (choice (choice-item :tag "GnuPG" gpg)
+ (choice-item :tag "PGP 5.0i" pgp50)
+ (choice-item :tag "PGP 2.6" pgp))
+ (repeat (cons :format "%v"
+ (symbol :tag "Language")
+ (regexp :tag "Regexp"))))))
+
+(defmacro mime-pgp-command (&optional suffix)
+ "Return a suitable command. SUFFIX should be either \"e\", \"k\", \"s\"
+or \"v\" for choosing a command of PGP 5.0i."
+ (` (let ((command (cdr (assq pgp-version mime-pgp-command-alist))))
+ (if (and command
+ (progn
+ (if (eq 'pgp50 pgp-version)
+ (setq command (format "%s%s" command (, suffix))))
+ (exec-installed-p command)))
+ command
+ (error "Please specify the valid command name for `%s'."
+ (or pgp-version 'pgp-version))))))
+
+(defmacro mime-pgp-default-language ()
+ "Return a symbol of language."
+ '(cond ((eq 'gpg pgp-version)
+ nil)
+ ((eq 'pgp50 pgp-version)
+ (or (cdr (assq pgp-version mime-pgp-default-language-alist)) 'us)
+ )
+ (t
+ (or (cdr (assq pgp-version mime-pgp-default-language-alist)) 'en)
+ )))
+
+(defmacro mime-pgp-good-signature-regexp ()
+ "Return a regexp to detect ``Good signature''."
+ '(nth 1
+ (assq
+ (mime-pgp-default-language)
+ (cdr (assq pgp-version mime-pgp-good-signature-regexp-alist))
+ )))
+
+(defmacro mime-pgp-good-signature-post-function ()
+ "Return a post processing function for arranging the message for
+``Good signature''."
+ '(nth 2
+ (assq
+ (mime-pgp-default-language)
+ (cdr (assq pgp-version mime-pgp-good-signature-regexp-alist))
+ )))
+
+(defmacro mime-pgp-bad-signature-regexp ()
+ "Return a regexp to detect ``BAD signature''."
+ '(nth 1
+ (assq
+ (mime-pgp-default-language)
+ (cdr (assq pgp-version mime-pgp-bad-signature-regexp-alist))
+ )))
+
+(defmacro mime-pgp-bad-signature-post-function ()
+ "Return a post processing function for arranging the message for
+``BAD signature''."
+ '(nth 2
+ (assq
+ (mime-pgp-default-language)
+ (cdr (assq pgp-version mime-pgp-bad-signature-regexp-alist))
+ )))
+
+(defmacro mime-pgp-key-expected-regexp ()
+ "Return a regexp to detect ``Key expected''."
+ '(cdr (assq (mime-pgp-default-language)
+ (cdr (assq pgp-version mime-pgp-key-expected-regexp-alist))
+ )))
+
+(defun mime-pgp-detect-version ()
+ "Detect PGP version in the buffer. The buffer is expected to be narrowed
+to just an ascii armor. However, a few leading garbage lines are allowed."
+ (let ((version (save-restriction
+ (goto-char (point-min))
+ (if (re-search-forward "^-+BEGIN PGP " nil t)
+ (progn
+ (forward-line 1)
+ (narrow-to-region (point) (point-max))
+ (std11-narrow-to-header)
+ (std11-fetch-field "Version")
+ )))))
+ (cond ((not version)
+ pgp-version)
+ ((string-match "GnuPG" version)
+ 'gpg)
+ ((string-match "5\\.0i" version)
+ 'pgp50)
+ ((string-match "2\\.6" version)
+ 'pgp)
+ (t
+ pgp-version))))
+
+(defun mime-entity-detect-pgp-version (entity)
+ "Detect PGP version from entity content."
+ (with-temp-buffer
+ (mime-insert-entity-content entity)
+ (mime-pgp-detect-version)
+ ))