75efcaa133012f63222945ea77ddbb585271ac80
[sxemacs] / tests / automated / openssl-tests.el
1 ;;;  openssl-tests.el -- Regression Tests for OpenSSL
2 ;; Copyright (C) 2005 Sebastian Freundt
3 ;;
4 ;; Author: Sebastian Freundt <hroptatyr@sxemacs.org>
5 ;; Keywords: tests
6 ;;
7 ;; This file is part of SXEmacs.
8 ;;
9 ;; SXEmacs is free software: you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published by the
11 ;; Free Software Foundation, either version 3 of the License, or (at your
12 ;; option) any later version.
13
14 ;; SXEmacs is distributed in the hope that it will be
15 ;; useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 ;; General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 ;;
22 ;;; Synched up with: Not in FSF.
23 ;;
24 ;;; Commentary:
25 ;; - test for cryptographical facilities
26 ;; See test-harness.el for instructions on how to run these tests.
27
28 (eval-when-compile
29   (condition-case nil
30       (require 'test-harness)
31     (file-error
32      (push "." load-path)
33      (when (and (boundp 'load-file-name) (stringp load-file-name))
34        (push (file-name-directory load-file-name) load-path))
35      (require 'test-harness))))
36
37 \f
38 (when (featurep 'openssl)
39   ;; this is not a real failure, but without digests OpenSSL is useless
40   (Assert (< 0 (length (ossl-available-digests))))
41   ;; this is not a real failure, but without ciphers OpenSSL is useless
42   (Assert (< 0 (length (ossl-available-ciphers))))
43
44   ;;-----------------------------------------------------
45   ;; Testing base64, base16 converters
46   ;;-----------------------------------------------------
47   (Assert (string-equal (base16-encode-string "AbCdEfG") "41624364456647"))
48   (Assert (string-equal (base16-decode-string "61426344") "aBcD"))
49   (Assert (string-equal (base16-decode-string "6142634") "aBc"))
50
51   ;;-----------------------------------------------------
52   ;; Testing digests
53   ;;-----------------------------------------------------
54   (let ((pre-comp-hashes
55          `(("a test string to digest"
56             (MD2 . "92ff6a34139fe7c8a4fc8910ab04cfb5")
57             (MD4 . "ce1d60a3d1a5f11a24dd5546eb1d26a9")
58             (MD5 . "68e2515ecffedbcf8ec5384070f17bd8")
59             (SHA . "e03994bcae4cf46d3d3bafa21ac9a80882fd10d0")
60             (SHA1 . "620d4122c2efe326e83d9e255976642c1799ae52")
61             (SHA256
62              . "f344f3c6e0e7d48b01104f71663e25a19554946c36ddf94eaa9ff98055a54220")
63             (SHA512
64              . "8020970e4beb48c07f1076552b34af378e08e9433254e3d24364bdbe77de8b6a82a1ab1045f95702a31f3db05948e8bd05d5765461551e40fb9919209e6a05b4")
65             (RIPEMD160 . "e7ed46ec351da9c23ab99971174e3be1a1e1c9c5")
66             (SHA224 . "5448e12607746b71a5bd97d99cc5896293acef755bb079c46ad95578")
67             (MDC2 . "612611f81794892a71f5bc108cfe1b29"))
68            (,(base16-decode-string "0408040021214150")
69             (MD2 . "0e3bac1631d3ec6a6142742a80deece9")
70             (MD4 . "1e74a3a5f55cd154b138585225fdfd24")
71             (MD5 . "a32f0ed6ac3412c6a492ffe33426f6a8")
72             (SHA . "1fe879ebe32795b1e05346743bb84343e25d94a9")
73             (SHA1 . "da23c727ec421df3810bfb2bd8180de81c7cbd0c")
74             (SHA256
75              . "642bf481623f86a12ddce32271a4a391c93c163a4f44091787f5e6529c985672")
76             (SHA512
77              . "1a267c78623654ac9e3c4c5831ac63c87cafbb14313b05b75ed3143285211d59bb04b70dae2c53c0a02ac60d30dcc474668ba4a8f6d96f7ae723bf09f07b2bb9")
78             (RIPEMD160 . "65d2b6018dd5b86ef63250d615f407f7c1608959")
79             (SHA224 . "17af47acac6b8c42f0ec8d22e09d2961e0c9b6f02e8d564e5c6844c7")
80             (MDC2 . "f8ec01ad32b21c6357c0e498cc52ae68"))
81            (""
82             ;; I am not sure if they change it in the future :|
83             (MD2 . "8350e5a3e24c153df2275c9f80692773")
84             (MD4 . "31d6cfe0d16ae931b73c59d7e0c089c0")
85             (MD5 . "d41d8cd98f00b204e9800998ecf8427e")
86             (SHA . "f96cea198ad1dd5617ac084a3d92c6107708c0ef")
87             (SHA1 . "da39a3ee5e6b4b0d3255bfef95601890afd80709")
88             (SHA256
89              . "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
90             (SHA512
91              . "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
92             (RIPEMD160 . "9c1185a5c5e9fc54612808977ee8f548b2258d31")
93             (SHA224 . "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f")
94             (MDC2 . "52525252525252522525252525252525"))))
95         (mydigests (ossl-available-digests)))
96     (mapc #'(lambda (hash)
97               (let ((str (car hash))
98                     (pchashes (cdr hash)))
99                 (mapc #'(lambda (alg+dgst)
100                           (when (member (car alg+dgst) mydigests)
101                             (eval `(Assert (string-equal
102                                             (base16-encode-string
103                                              (ossl-digest ',(car alg+dgst) ,str))
104                                             ,(cdr alg+dgst))))))
105                       pchashes)))
106           pre-comp-hashes))
107
108   ;; testing the lengths of digests
109   (let ((dgst-lens
110          '((MD2 . 16)
111            (MD4 . 16)
112            (MD5 . 16)
113            (SHA . 20)
114            (SHA1 . 20)
115            (SHA224 . 28)
116            (SHA256 . 32)
117            (SHA512 . 64)
118            (MDC2 . 16)
119            (RIPEMD160 . 20)))
120         (mydigests (ossl-available-digests)))
121     (mapc #'(lambda (algo+len)
122               (when (member (car algo+len) mydigests)
123                 (let (randstrs)
124                   (dotimes (i 10)
125                     (setq randstrs
126                           (cons (ossl-rand-bytes (random 40))
127                                 randstrs)))
128                   (setq randstrs
129                         (append '("" " " "\n")  randstrs))
130                   (mapc #'(lambda (randstr)
131                             (eval `(Assert (= (length
132                                                (ossl-digest ',(car algo+len)
133                                                             ,randstr))
134                                               ,(cdr algo+len)))))
135                         randstrs))))
136           dgst-lens))
137
138   ;;-----------------------------------------------------
139   ;; Testing HMACs
140   ;;-----------------------------------------------------
141   (let ((pre-comp-macs
142          `(("a test string to digest"
143             (MD2 . "28f832a5088e6153c5d7342bdd27f133")
144             (MD4 . "1b5fb31ce2e5467e472e4790d77310e1")
145             (MD5 . "15337877e5bc8c7f1dbc3f1c5955ef48")
146             (SHA . "ec3905d4aba1ace1f739494478f1c8fcb61f34ea")
147             (SHA1 . "0180ce61c72849c605ca1e6b1fc790574e8e94f3")
148             (SHA256
149              . "8c6e66238cae2fb7b51469b9a56b07d79ca8b95577a08ef88f71811a80bffacf")
150             (SHA512
151              . "f7d15205cfc10c710ee1547bf02cbc665cafea34244e0daa4707f3eb888dd0d7f27ebdc9bc1237b9a566c52b0185d73f3f03f54e387d87a3b350f1048ed31977")
152             (RIPEMD160 . "8afeab4e091a27b2e6a6cab8adf813c18e22c9f5")
153             (SHA224 . "bdd7013afbd17fede079cdff796b9ad41ae4701e40da605629fca5c6")
154             (MDC2 . "da8db2984052b945db36eb5967b854c6"))
155            (,(base16-decode-string "0408040021214150")
156             (MD2 . "773807b9c622cf7e4720bfdbea2d00a0")
157             (MD4 . "157a3019d5d06ab6861e60985c3f6802")
158             (MD5 . "2e86cfb9cf4e9fe4fde6a484a5ae161d")
159             (SHA . "8acd0238da00c91fdd16a63601a36d60e85b8a3f")
160             (SHA1 . "03a6bd81b30ac05e3a74c5f0434e53660e2ad826")
161             (SHA256
162              . "2d7e1cbba92433c22eb4bf2e5a6670783fa0960b0b2799b16f9d2ec09a8ef634")
163             (SHA512
164              . "e700e1696971d156391cf554e0d521dc92ce3ec1b50837b82854567695a414724390c8882575ece15fa1b0fd4dea25dd4ec1bd98084114167d40d664704c0d1b")
165             (RIPEMD160 . "9fd14450a6a9bab2e0d209ca08012710185b5b4b")
166             (SHA224 . "89a4fadeababc107e1d34cec6d57509015398e21a7f85052ad8f34c0")
167             (MDC2 . "9b038620f59f0f98f0223aa4270aee47"))
168            (""
169             ;; I am not sure if they change it in the future :|
170             (MD2 . "34315994b98b7e46ecc8e92e0968e34e")
171             (MD4 . "ad728e8db14adecc49a3fc361b30b715")
172             (MD5 . "23d466834f70a1d657561a5ec2c51ea0")
173             (SHA . "c1ae479310f17ba8923eb94ddb7d1079f69ec56c")
174             (SHA1 . "f1ccdb92a929f5149ed40c5d0f3f2fbbe7809521")
175             (SHA256
176              . "e56a207acd1e6714735487c199c6f095844b7cc8e5971d86c003a7b6f36ef51e")
177             (SHA512
178              . "ded1bda29058c02f011c01087e12543684821c54d42ac2a9924a1a0ee10830b5a2028a90febc0cda5188517bc79aecdbd720b00895181571496e8688c57ddfa0")
179             (RIPEMD160 . "03ea2ae5c6875de5ec79ce4a9a7b37837660794e")
180             (SHA224 . "bf8cc8d94e30e99fa36e0b66ce4220c8a653b830e3d9fb46d25be803")
181             (MDC2 . "bab8504dfe0337da87a79d85567fbf53"))))
182         (mydigests (ossl-available-digests)))
183     (mapc #'(lambda (mac)
184               (let ((str (car mac))
185                     (pchashes (cdr mac)))
186                 (mapc #'(lambda (alg+dgst)
187                           (when (member (car alg+dgst) mydigests)
188                             (eval `(Assert (string-equal
189                                             (base16-encode-string
190                                              (ossl-hmac ',(car alg+dgst) ,str
191                                                         "password"))
192                                             ,(cdr alg+dgst))))))
193                       pchashes)))
194           pre-comp-macs))
195
196   ;; we expect at least md5, sha1 and ripemd160 in available digests
197   ;; otherwise OpenSSL must be considered useless!
198   (Assert (member 'MD5 (ossl-available-digests)))
199   (Assert (member 'SHA1 (ossl-available-digests)))
200   (Assert (member 'RIPEMD160 (ossl-available-digests)))
201
202   ;; for non-existing digests we expect an error
203   (Check-Error-Message error "no such digest" (ossl-digest 'FOO "bar"))
204
205
206   ;;-----------------------------------------------------
207   ;; Testing ciphers
208   ;;-----------------------------------------------------
209
210   ;; we expect at least DES (in the modes ECB, CFB and CBC)
211   ;; also AES (with 192 and 256 bits) would be nice
212   (Assert (member 'DES-ECB (ossl-available-ciphers)))
213   (Assert (member 'DES-CFB (ossl-available-ciphers)))
214   (Assert (member 'DES-CBC (ossl-available-ciphers)))
215   (Assert (member 'AES-128-CBC (ossl-available-ciphers)))
216   (Assert (member 'AES-128-ECB (ossl-available-ciphers)))
217   (Assert (member 'AES-128-CFB (ossl-available-ciphers)))
218   (Assert (member 'AES-128-OFB (ossl-available-ciphers)))
219   (Assert (member 'AES-192-CBC (ossl-available-ciphers)))
220   (Assert (member 'AES-192-ECB (ossl-available-ciphers)))
221   (Assert (member 'AES-192-CFB (ossl-available-ciphers)))
222   (Assert (member 'AES-192-OFB (ossl-available-ciphers)))
223
224   ;; first we check the key generator
225   (let ((encstrs
226          (list "foo string test bar"
227                (base16-decode-string "080004084803526444")
228                "\n"))
229         (salts
230          (list nil "salt" "" "toomuchsalt"))
231         ;; Ciphers
232         (ciphers
233          ;; We seem to have issues with the following ciphers.  Not
234          ;; sure yet if it is SXEmacs bug, or OpenSSL bug.  But perhaps
235          ;; we should prevent them from being used at all with our ssl
236          ;; code instead of just conveniently ignoring them in the
237          ;; testsuite? --SY.
238          (let ((bad-ciphers '(id-smime-alg-CMS3DESwrap
239                               id-aes128-wrap id-aes192-wrap id-aes256-wrap
240                               id-aes128-GCM id-aes128-CCM id-aes192-GCM
241                               id-aes192-CCM id-aes256-GCM id-aes256-CCM
242                               AES-128-XTS AES-256-XTS))
243                ciphers)
244            (mapc-internal
245             #'(lambda (cipher)
246                 (let ((ciphmode (substring (symbol-name cipher) -2)))
247                   ;; Never use CFB1 and CFB8 modes.
248                   ;; Both modes tend to mangle the result strings which
249                   ;; yields an assertion error.
250                   ;; Bug in openssl?
251                   ;; -hroptatyr
252                   ;; Shouldn't we prevent their use outside the testsuite
253                   ;; as well? --SY.
254                   (unless (or ;(< (ossl-cipher-bits cipher) 128)
255                            (string= "B1" ciphmode)
256                            (string= "B8" ciphmode)
257                            (member cipher bad-ciphers))
258                     (setq ciphers
259                           (cons cipher ciphers)))))
260             (ossl-available-ciphers))
261            ciphers))
262         ;; Digests
263         ;; Sebastian had initially only used digests that didn't have
264         ;; a dash in their name, I'm not sure what his reasoning was,
265         ;; perhaps just to speed up running the testsuite, I dunno.
266         ;; But I say we should test them ALL. :-) --SY.
267         (digests (ossl-available-digests))
268         ;; (digests
269         ;;  (let (digests)
270         ;;    (mapc-internal
271         ;;     #'(lambda (digest)
272         ;;      (let ((digestname (symbol-name digest)))
273         ;;        ;; only use digests without a dash in their names
274         ;;        (unless (string-match "-" digestname)
275         ;;          (setq digests
276         ;;                (cons digest digests)))))
277         ;;     (ossl-available-digests))
278         ;;    digests))
279         key iv
280         enc dec)
281
282     (mapc-internal
283      #'(lambda (salt)
284          (mapc-internal
285           #'(lambda (digest)
286               (mapc-internal
287                #'(lambda (cipher)
288                    (mapc-internal
289                     #'(lambda (str)
290                         (setq key ;; a key and initialisation vector
291                               (ossl-bytes-to-key cipher digest salt
292                                                  "password" 1)
293                               iv (get key 'iv))
294
295                         ;; let's see if we always generate the same key/iv pair
296                         (eval `(Assert (and (string-equal
297                                              (ossl-bytes-to-key
298                                               ',cipher ',digest ,salt
299                                               "password" 1)
300                                              ,key)
301                                             (string-equal
302                                              (get (ossl-bytes-to-key
303                                                    ',cipher ',digest ,salt
304                                                    "password" 1) 'iv)
305                                              ,iv))))
306
307                         ;; let's encrypt something, decrypt it and compare
308                         (setq enc (ossl-encrypt cipher str key iv))
309                         (setq dec (ossl-decrypt cipher enc key iv))
310                         (eval `(Assert (string-equal ,dec ,str)))
311
312                         ;; this should even work if the key+iv is regenerated
313                         (setq key ;; a new key and initialisation vector
314                               (ossl-bytes-to-key cipher digest salt "password" 1)
315                               iv (get key 'iv))
316                         (setq dec ;; the encrypted text
317                               (ossl-decrypt cipher enc key iv))
318                         (eval `(Assert (string-equal ,dec ,str)))
319
320                         ;; let's doubly-encrypt something
321                         (let (enc2 dec2)
322                           (setq enc (ossl-encrypt cipher str key iv))
323                           (setq enc2 (ossl-encrypt cipher enc key iv))
324                           (setq dec (ossl-decrypt cipher enc2 key iv))
325                           (eval `(Assert (string-equal ,dec ,enc)))
326                           (setq dec2 (ossl-decrypt cipher dec key iv))
327                           (eval `(Assert (string-equal ,dec2 ,str)))))
328                     encstrs))
329                ciphers))
330           digests))
331      salts))
332   )
333
334
335 ;;; openssl-tests.el ends here