1 ;;; digest-md5.el --- Compute DIGEST-MD5.
3 ;; Copyright (C) 1999 Kenichi OKADA
5 ;; Author: Kenichi OKADA <okada@opaopa.org>
6 ;; Daiki Ueno <ueno@ueda.info.waseda.ac.jp>
7 ;; Keywords: DIGEST-MD5, HMAC-MD5, SASL, IMAP, POP, ACAP
9 ;; This file is part of FLIM (Faithful Library about Internet Message).
11 ;; This program is free software; you can redistribute it and/or
12 ;; modify it under the terms of the GNU General Public License as
13 ;; published by the Free Software Foundation; either version 2, or
14 ;; (at your option) any later version.
16 ;; This program is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with this program; see the file COPYING. If not, write to
23 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
30 ;; This program is implemented from draft-leach-digest-sasl-05.txt.
32 ;; It is caller's responsibility to base64-decode challenges and
33 ;; base64-encode responses in IMAP4 AUTHENTICATE command.
35 ;; Passphrase should be longer than 16 bytes. (See RFC 2195)
39 ;; (digest-md5-parse-digest-challenge
40 ;; "realm=\"elwood.innosoft.com\",nonce=\"OA6MG9tEQGm2hh\",qop=\"auth\",algorithm=md5-sess,charset=utf-8")
41 ;; => (realm "elwood.innosoft.com" nonce "OA6MG9tEQGm2hh" qop "auth" algorithm md5-sess charset utf-8)
43 ;; (digest-md5-build-response-value
44 ;; "chris" "secret" "OA6MHXh6VqTrRk" "imap/elwood.innosoft.com")
45 ;; => "d388dad90d4bbd760a152321f2143af7"
52 (defvar digest-md5-challenge nil)
53 (defvar digest-md5-nonce-count 1)
55 (defvar digest-md5-parse-digest-challenge-syntax-table
56 (let ((table (make-syntax-table)))
57 (modify-syntax-entry ?= "." table)
58 (modify-syntax-entry ?, "." table)
60 "A syntax table for parsing digest-challenge attributes.")
63 (defun digest-md5-parse-digest-challenge (digest-challenge)
64 ;; return a property list of
65 ;; (realm nonce qop-options stale maxbuf charset
66 ;; algorithm cipher-opts auth-param).
68 (set-syntax-table digest-md5-parse-digest-challenge-syntax-table)
69 (insert digest-challenge)
70 (goto-char (point-min))
72 (while (progn (forward-sexp) (not (eobp)))
77 (setplist 'digest-md5-challenge (read (point-min-marker)))
79 (error "Parse error in digest-challenge.")))))
81 (defun digest-md5-digest-uri (serv-type host &optional serv-name)
82 (concat serv-type "/" host
84 (null (string= host serv-name)))
85 (concat "/" serv-name))))
87 (defun digest-md5-cnonce ()
88 ;; It is RECOMMENDED that it
89 ;; contain at least 64 bits of entropy.
90 (concat (unique-id-m "") (unique-id-m "")))
92 (defmacro digest-md5-challenge (prop)
93 (list 'get ''digest-md5-challenge prop))
95 (defmacro digest-md5-build-response-value (username passwd cnonce digest-uri)
100 (md5-binary (concat (md5-binary
102 ":" (digest-md5-challenge 'realm)
104 ":" (digest-md5-challenge 'nonce)
106 (let ((authzid (digest-md5-challenge 'authzid)))
107 (if authzid (concat ":" authzid) nil)))))
108 ":" (digest-md5-challenge 'nonce)
109 ":" (format "%08x" digest-md5-nonce-count) ":" ,cnonce
110 ":" (digest-md5-challenge 'qop) ":"
113 (concat "AUTHENTICATE:" ,digest-uri
114 (if (member "auth" (split-string
115 (digest-md5-challenge 'qop)
118 ":00000000000000000000000000000000"))))))))
121 (defun digest-md5-digest-response (username passwd digest-uri)
122 (let ((cnonce (digest-md5-cnonce)))
124 "username=\"" username "\","
125 "realm=\"" (digest-md5-challenge 'realm) "\","
126 "nonce=\"" (digest-md5-challenge 'nonce) "\","
127 (format "nc=%08x," digest-md5-nonce-count)
128 "cnonce=\"" cnonce "\","
129 "digest-uri=\"" digest-uri "\","
131 (digest-md5-build-response-value username passwd cnonce digest-uri)
136 (mapcar (lambda (prop)
137 (if (digest-md5-challenge prop)
139 prop (digest-md5-challenge prop))))
140 '(charset qop maxbuf cipher authzid)))
143 (provide 'digest-md5)
145 ;;; digest-md5.el ends here