2 ;;;; Copyright (c) 2008 Zachary Beane, All Rights Reserved
4 ;;;; Redistribution and use in source and binary forms, with or without
5 ;;;; modification, are permitted provided that the following conditions
8 ;;;; * Redistributions of source code must retain the above copyright
9 ;;;; notice, this list of conditions and the following disclaimer.
11 ;;;; * Redistributions in binary form must reproduce the above
12 ;;;; copyright notice, this list of conditions and the following
13 ;;;; disclaimer in the documentation and/or other materials
14 ;;;; provided with the distribution.
16 ;;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
17 ;;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 ;;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ;;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20 ;;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 ;;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 ;;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 ;;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 ;;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 ;;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 ;;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 (defparameter *empty-string-sha256
*
33 (ironclad:byte-array-to-hex-string
34 (ironclad:digest-sequence
:sha256
(make-array 0 :element-type
'octet
))))
45 :initarg
:signed-stream
46 :accessor signed-stream
))
48 :signed-stream
(make-string-output-stream)
49 :newline
(make-array 1 :element-type
'(unsigned-byte 8)
50 :initial-element
10)))
52 (defun make-digester (key &key
(digest-algorithm :sha1
))
53 (let ((hmac (ironclad:make-hmac
(string-octets key
) digest-algorithm
)))
54 (make-instance 'digester
57 (defgeneric add-string
(string digester
)
58 (:method
(string digester
)
59 (write-string string
(signed-stream digester
))
60 (ironclad:update-hmac
(hmac digester
) (string-octets string
))))
62 (defgeneric add-newline
(digester)
64 (terpri (signed-stream digester
))
65 (ironclad:update-hmac
(hmac digester
) (newline digester
))))
67 (defgeneric add-line
(string digester
)
68 (:method
(string digester
)
69 (add-string string digester
)
70 (add-newline digester
)))
72 (defgeneric digest64
(digester)
74 (base64:usb8-array-to-base64-string
75 (ironclad:hmac-digest
(hmac digester
)))))
77 (defun file-md5 (file)
78 (ironclad:digest-file
:md5 file
))
80 (defun file-md5/b64
(file)
81 (base64:usb8-array-to-base64-string
(file-md5 file
)))
83 (defun file-md5/hex
(file)
84 (ironclad:byte-array-to-hex-string
(file-md5 file
)))
86 (defun file-sha256 (file)
87 (ironclad:digest-file
:sha256 file
))
89 (defun file-sha256/hex
(file)
90 (ironclad:byte-array-to-hex-string
(file-sha256 file
)))
92 (defun vector-sha256 (vector)
93 (ironclad:digest-sequence
:sha256 vector
))
95 (defun vector-sha256/hex
(vector)
96 (ironclad:byte-array-to-hex-string
(vector-sha256 vector
)))
98 (defun vector-md5/b64
(vector)
99 (base64:usb8-array-to-base64-string
100 (ironclad:digest-sequence
:md5 vector
)))
102 (defun file-etag (file)
103 (format nil
"\"~A\"" (file-md5/hex file
)))
105 (defun sign-string (key string
)
106 (let ((digester (make-digester key
)))
107 (add-string string digester
)
108 (digest64 digester
)))