October 24, 2004 11:49 PM
Gnu Privacy Guard (gpg) provides powerful public key cryptography to the masses. I believe there are a number of applications that provide support for gpg within emacs. But I just wanted a quick function that will sign and encrypt a buffer with the recipient as myself. PGG1 has no easy way to do this in Emacs 21.3.1. So I wrote this function which actually is a minimal version of the actual pgp-encrypt encrypting the whole buffer with the recipient as self.

Code below updated on 2004.12.05.

;make sure pgg-gpg-user-id is set like so
;(setq pgg-gpg-user-id "Your user id")

;;; emacs-wiki-pgg settings
(defgroup emacs-wiki-pgg nil
  "Options controlling the behavior of Emacs Wiki PGG Interface."
  :group 'emacs-wiki)

(defcustom emacs-wiki-pgg-interface 'pgg-encrypt-show
  "Interfacing function to invoke pgg with.
  pgg-encrypt-show asks for recipients via the minibuffer.
  pgg-encrypt-sign-self encrypts with recipient as self and signs 
  if emacs-wiki-pgg-sign is non-nil."
  :type 'function
  :group 'emacs-wiki-pgg)

(defcustom emacs-wiki-pgg-sign nil
  "Signs the message after encrypting if emacs-wiki-pgg-interface is
pgg-encrypt-sign-self."
  :type 'boolean
  :group 'emacs-wiki-pgg)

;;; PGG Functions
(defun pgg-encrypt-sign-self (&optional start end)
  "Encrypt the current buffer for self.
Signs the message if emacs-wiki-pgg-sign is non-nil.
If optional arguments START and END are specified, only encrypt within
the region."
  (interactive "*")
  (let* ((rcpts (list pgg-gpg-user-id))
	 (start (or start (point-min)))
	 (end (or end (point-max)))
	 (status (pgg-encrypt-region start end rcpts 
				     emacs-wiki-pgg-sign)))
      (pgg-display-output-buffer start end status)
    status))


(defun pgg-encrypt-show (&optional start end)
  "Encrypt and sign the current buffer for self.
If optional arguments START and END are specified, only encrypt within
the region."
  (interactive "*")
  (let* ((start (or start (point-min)))
	 (end (or end (point-max))))
    (push-mark start t t)
    (goto-char end)
    (call-interactively 'pgg-encrypt-region)
    ))

(defun pgg-decrypt-show (&optional start end)
  "Decrypt the current buffer.
If optional arguments START and END are specified, only decrypt within
the region."
  (interactive "*")
  (let* ((start (or start (point-min)))
	 (end (or end (point-max)))
	 (status (pgg-decrypt-region start end)))
      (pgg-display-output-buffer start end status)
    status))

This function can be easily used to act just like the built-in pgg-encrypt-region function by wrapping it around another interactive function which takes point and mark as arguments.

;encrypting version
(defun pgg-encrypt-sign-self-region (start end)
  "Encrypt and sign the current region for self."
  (interactive "*r")
  (pgg-encrypt-sign-self start end t))

;decrypting version
(defun pgg-decrypt-self-region (start end)
  "Decrypt the current region."
  (interactive "*r")
  (pgg-encrypt-sign-self start end t))

These two handy functions are useful especially within emacs-wiki mode. Consider text enclosed between gpg tags in an emacs-wiki source file. While in emacs-wiki mode, pressing C-c C-S-e encrypts and signs the text between each gpg tag with the recipient as yourself2. Similarly, C-c C-S-d decrypts text between each gpg tag. A simple handler for the gpg tags in emacs-wiki causes text between gpg tags to be published just like as if they were enclosed in the example tag.

As an example, consider:

<gpg>Test data</gpg>

Press C-c C-S-e to get:

-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.2.4 (GNU/Linux)

[Imagine encrypted text]

-----END PGP MESSAGE-----

Pressing C-c C-S-d gives:

<gpg>Test data</gpg>

The elisp code to do all this is:

;;; Interactive Emacs Wiki mode Functions

(defun emacs-wiki-encrypt-gpg (&optional entirewiki)
  "Find all gpg tags and encrypt their contents.
When called with C-u prefix, encrypt entire buffer."
  (interactive "P")
  (if entirewiki
      (funcall emacs-wiki-pgg-interface)
  (let (tagbegin tagend)
    (save-excursion
      (goto-char 0)
      (while (re-search-forward "<gpg>" nil t)    
	(setq tagbegin (match-end 0))
	(re-search-forward "</gpg>" nil t)
	(setq tagend (match-beginning 0))
	(funcall emacs-wiki-pgg-interface tagbegin tagend))))))

(defun emacs-wiki-decrypt-gpg (&optional entirewiki)
  "Find all gpg tags and decrypt their contents.
When called with C-u prefix, decrypt entire buffer."
  (interactive "P")
  (if entirewiki
      (pgg-decrypt-show)
  (let (tagbegin tagend)
    (save-excursion
      (goto-char 0)
      (while (re-search-forward "<gpg>" nil t)    
	(setq tagbegin (match-end 0))
	(if (re-search-forward "</gpg>" nil t)
	    (progn
	      (setq tagend (match-beginning 0))
	      (pgg-decrypt-show tagbegin tagend))
	  (message "No closing gpg tags found")))))))

;key bindings
(define-key emacs-wiki-mode-map
  [(control ?c) (control ?E)]
  'emacs-wiki-encrypt-gpg)

(define-key emacs-wiki-mode-map
  [(control ?c) (control ?D)]
  'emacs-wiki-decrypt-gpg)

;wiki handler of gpg tag
(defun emacs-wiki-gpg-tag (beg end highlight-p)
  (if highlight-p
      (progn
        (emacs-wiki-multiline-maybe beg end)
        (goto-char end))
    (insert "<pre class=\"example\">")
    (when (< (point) end)
      (goto-char end))
    (insert "</pre>")
    (add-text-properties beg end '(rear-nonsticky (read-only)
                                                  read-only t))))

(push '("gpg" t nil t emacs-wiki-gpg-tag) emacs-wiki-markup-tags)

Another implementation of these functions is to rewrite emacs-wiki-gpg-tag function in such a way that it encrypts the data between the tags. This way, you have unencrypted data in your wiki source file and encrypted data in your published html file between gpge tags. The code to do that is:

;wiki handler of gpge tag
(defun emacs-wiki-gpg-encrypt-tag (beg end highlight-p)
  (if highlight-p
      (progn
        (emacs-wiki-multiline-maybe beg end)
        (goto-char end))
    (insert "<pre class=\"example\">")
    (pgg-encrypt-sign-self (point) end t)
    (when (< (point) end)
      (goto-char end))
    (insert "</pre>")
    (add-text-properties beg (point) '(rear-nonsticky (read-only)
                                                  read-only t))))
(push '("gpge" t nil t emacs-wiki-gpg-encrypt-tag) emacs-wiki-markup-tags)

CategoryEmacsWiki


[1] PGG is an interface library between Emacs and various tools for secure communication. PGG also provides a simple user interface to encrypt, decrypt, sign, and verify MIME messages.
[2] This, of course can be customized.

Copyright © 2004-2011 Anirudh Sasikumar. All rights reserved.
Last Updated: January 21, 2005 4:39 PM