--- smime.el +++ smime.el @@ -152,9 +152,10 @@ The file is assumed to be in PEM format. You can also associate additional certificates to be sent with every message to each address." :type '(repeat (list (string :tag "Mail address") + (boolean :tag "Private key encrypted" :value t) (file :tag "File name") (repeat :tag "Additional certificate files" - (file :tag "File name")))) + (file :tag "File name")))) :group 'smime) (defcustom smime-CA-directory nil @@ -292,7 +296,7 @@ ;; Sign+encrypt region -(defun smime-sign-region (b e keyfile) +(defun smime-sign-region (b e keyfile &optional clearkey) "Sign region with certified key in KEYFILE. If signing fails, the buffer is not modified. Region is assumed to have proper MIME tags. KEYFILE is expected to contain a PEM encoded @@ -304,7 +308,8 @@ (let* ((certfiles (and (cdr-safe keyfile) (cadr keyfile))) (keyfile (or (car-safe keyfile) keyfile)) (buffer (generate-new-buffer " *smime*")) - (passphrase (smime-ask-passphrase (expand-file-name keyfile))) + (passphrase (if clearkey nil + (smime-ask-passphrase (expand-file-name keyfile)))) (tmpfile (smime-make-temp-file "smime"))) (if passphrase (setenv "GNUS_SMIME_PASSPHRASE" passphrase)) @@ -332,7 +337,7 @@ (insert-buffer-substring buffer)) (kill-buffer buffer)))) -(defun smime-encrypt-region (b e certfiles) +(defun smime-encrypt-region (b e certfiles &optional clearkey) "Encrypt region for recipients specified in CERTFILES. If encryption fails, the buffer is not modified. Region is assumed to have proper MIME tags. CERTFILES is a list of filenames, each file @@ -365,19 +370,24 @@ "S/MIME sign BUFFER with key in KEYFILE. KEYFILE should contain a PEM encoded key and certificate." (interactive) - (with-current-buffer (or buffer (current-buffer)) - (unless (smime-sign-region - (point-min) (point-max) - (if keyfile - keyfile - (smime-get-key-with-certs-by-email - (completing-read - (concat "Sign using key" - (if smime-keys - (concat " (default " (caar smime-keys) "): ") - ": ")) - smime-keys nil nil (car-safe (car-safe smime-keys)))))) - (error "Signing failed")))) + (let (keycerts email) + (if keyfile + (setq keycerts keyfile) + (setq email + (completing-read + (concat "Sign using key" + (if smime-keys + (concat " (default " (caar smime-keys) "): ") + ": ")) + smime-keys nil nil (car-safe (car-safe smime-keys)))) + (setq keycerts (smime-get-key-with-certs-by-email email))) + (with-current-buffer (or buffer (current-buffer)) + (unless (smime-sign-region + (point-min) (point-max) + keycerts + (unless keyfile + (smime-get-key-is-clear-by-email email))) + (error "Signing failed"))))) (defun smime-encrypt-buffer (&optional certfiles buffer) "S/MIME encrypt BUFFER for recipients specified in CERTFILES. @@ -431,14 +441,15 @@ (defvar from) -(defun smime-decrypt-region (b e keyfile) +(defun smime-decrypt-region (b e keyfile &optional clearkey) "Decrypt S/MIME message in region between B and E with key in KEYFILE. On success, replaces region with decrypted data and return non-nil. Any details (stderr on success, stdout and stderr on error) are left in the buffer specified by `smime-details-buffer'." (smime-new-details-buffer) (let ((buffer (generate-new-buffer " *smime*")) - CAs (passphrase (smime-ask-passphrase (expand-file-name keyfile))) + CAs (passphrase (if clearkey nil + (smime-ask-passphrase (expand-file-name keyfile)))) (tmpfile (smime-make-temp-file "smime"))) (if passphrase (setenv "GNUS_SMIME_PASSPHRASE" passphrase)) @@ -496,18 +507,24 @@ Any details (stderr on success, stdout and stderr on error) are left in the buffer specified by `smime-details-buffer'." (interactive) - (with-current-buffer (or buffer (current-buffer)) - (smime-decrypt-region - (point-min) (point-max) - (expand-file-name - (or keyfile - (smime-get-key-by-email - (completing-read - (concat "Decipher using key" - (if smime-keys (concat " (default " (caar smime-keys) "): ") - ": ")) - smime-keys nil nil (car-safe (car-safe smime-keys))))))))) - + (let (key email) + (if keyfile + (setq key keyfile) + (setq email + (completing-read + (concat "Decipher using key" + (if smime-keys + (concat " (default " (caar smime-keys) "): ") + ": ")) + smime-keys nil nil (car-safe (car-safe smime-keys)))) + (setq key (smime-get-key-by-email email))) + (with-current-buffer (or buffer (current-buffer)) + (smime-decrypt-region + (point-min) (point-max) + key + (unless keyfile + (smime-get-key-is-clear-by-email email)))))) + ;; Various operations (defun smime-new-details-buffer () @@ -722,10 +739,13 @@ ;; Other functions (defun smime-get-key-by-email (email) - (cadr (assoc email smime-keys))) + (nth 2 (assoc email smime-keys))) (defun smime-get-key-with-certs-by-email (email) - (cdr (assoc email smime-keys))) + (cddr (assoc email smime-keys))) + +(defun smime-get-key-is-clear-by-email (email) + (not (cadr (assoc email smime-keys)))) (provide 'smime)