1/* test-parser.c --- Self tests of DIGEST-MD5 parser & printer.
2 * Copyright (C) 2004-2012 Simon Josefsson
3 *
4 * This file is part of GNU SASL Library.
5 *
6 * GNU SASL Library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * GNU SASL Library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with GNU SASL Library; if not, write to the Free
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27#include "parser.h"
28#include "printer.h"
29#include "digesthmac.h"
30
31#include "gc.h"
32
33int
34main (int argc, char *argv[])
35{
36 digest_md5_challenge c;
37 digest_md5_response r;
38 digest_md5_finish f;
39 char buf32[33];
40 char buf16[16];
41 int rc;
42 char *tmp;
43
44 {
45 const char *token = "nonce=4711, foo=bar, algorithm=md5-sess";
46
47 printf ("challenge `%s': ", token);
48 rc = digest_md5_parse_challenge (token, 0, &c);
49 if (rc != 0)
50 abort ();
51 printf ("nonce `%s': %s", c.nonce,
52 strcmp ("4711", c.nonce) == 0 ? "PASS" : "FAILURE");
53 printf ("\n");
54 tmp = digest_md5_print_challenge (&c);
55 if (!tmp)
56 abort ();
57 printf ("printed `%s' PASS\n", tmp);
58 free (tmp);
59 }
60
61 {
62 const char *token =
63 "qop=\"auth, auth-conf\", nonce=42, algorithm=md5-sess";
64
65 printf ("challenge `%s': ", token);
66 rc = digest_md5_parse_challenge (token, 0, &c);
67 if (rc == 0)
68 abort ();
69 printf ("PASS\n");
70 }
71
72 {
73 const char *token = "cipher=\"des\", nonce=42, algorithm=md5-sess";
74
75 printf ("challenge `%s': ", token);
76 rc = digest_md5_parse_challenge (token, 0, &c);
77 if (rc == 0)
78 abort ();
79 printf ("PASS\n");
80 }
81
82 {
83 const char *token = "qop=\"auth, auth-conf\", nonce=42, "
84 "algorithm=md5-sess, cipher=\"des\"";
85
86 printf ("challenge `%s': ", token);
87 rc = digest_md5_parse_challenge (token, 0, &c);
88 if (rc != 0)
89 abort ();
90 printf ("qop %02x ciphers %02x: %s\n", c.qops, c.ciphers,
91 (c.qops == 5 && c.ciphers == 1) ? "PASS" : "FAILURE");
92 tmp = digest_md5_print_challenge (&c);
93 if (!tmp)
94 abort ();
95 printf ("printed `%s' PASS\n", tmp);
96 free (tmp);
97 }
98
99 {
100 const char *token = "bar=foo, foo=bar";
101
102 printf ("challenge `%s': ", token);
103 rc = digest_md5_parse_challenge (token, 0, &c);
104 if (rc == 0)
105 abort ();
106 printf ("PASS\n");
107 }
108
109 {
110 const char *token = "realm=foo, realm=bar, nonce=42, algorithm=md5-sess";
111
112 printf ("challenge `%s': ", token);
113 rc = digest_md5_parse_challenge (token, 0, &c);
114 if (rc != 0)
115 abort ();
116 if (c.nrealms != 2)
117 abort ();
118 printf ("realms `%s', `%s': PASS\n", c.realms[0], c.realms[1]);
119 tmp = digest_md5_print_challenge (&c);
120 if (!tmp)
121 abort ();
122 printf ("printed `%s' PASS\n", tmp);
123 free (tmp);
124 }
125
126 /* Response */
127
128 {
129 const char *token = "bar=foo, foo=bar";
130
131 printf ("response `%s': ", token);
132 rc = digest_md5_parse_response (token, 0, &r);
133 if (rc == 0)
134 abort ();
135 printf ("PASS\n");
136 }
137
138 {
139 const char *token = "username=jas, nonce=42, cnonce=4711, nc=00000001, "
140 "digest-uri=foo, response=01234567890123456789012345678901";
141
142 printf ("response `%s': ", token);
143 rc = digest_md5_parse_response (token, 0, &r);
144 if (rc != 0)
145 abort ();
146 printf ("username `%s', nonce `%s', cnonce `%s',"
147 " nc %08lx, digest-uri `%s', response `%s': PASS\n",
148 r.username, r.nonce, r.cnonce, r.nc, r.digesturi, r.response);
149 tmp = digest_md5_print_response (&r);
150 if (!tmp)
151 abort ();
152 printf ("printed `%s' PASS\n", tmp);
153 free (tmp);
154 }
155
156 /* Auth-response, finish. */
157
158 {
159 const char *token = "rspauth=\"6a204da26b9888ee40bb3052ff056a67\"";
160
161 printf ("finish `%s': ", token);
162 rc = digest_md5_parse_finish (token, 0, &f);
163 if (rc != 0)
164 abort ();
165 printf ("`%s'? %s\n", f.rspauth,
166 strcmp ("6a204da26b9888ee40bb3052ff056a67", f.rspauth) == 0
167 ? "ok" : "FAILURE");
168 }
169
170 {
171 const char *token = "bar=foo, foo=bar";
172
173 printf ("finish `%s': ", token);
174 rc = digest_md5_parse_finish (token, 0, &f);
175 if (rc == 0)
176 abort ();
177 printf ("invalid? PASS\n");
178 }
179
180 rc = gc_init ();
181 if (rc != 0)
182 {
183 printf ("gc_init error %d\n", rc);
184 abort ();
185 }
186
187 memset (buf16, 'Q', 16);
188
189 rc = digest_md5_hmac (buf32, buf16, "nonce", 1, "cnonce",
190 DIGEST_MD5_QOP_AUTH, "authzid", "digesturi",
191 1, 0, NULL, NULL, NULL, NULL);
192 if (rc != 0)
193 abort ();
194 buf32[32] = '\0';
195 if (strcmp (buf32, "6a204da26b9888ee40bb3052ff056a67") != 0)
196 abort ();
197 printf ("digest: `%s': PASS\n", buf32);
198
199 rc = digest_md5_hmac (buf32, buf16, "nonce", 1, "cnonce",
200 DIGEST_MD5_QOP_AUTH, "authzid", "digesturi", 0, 0,
201 NULL, NULL, NULL, NULL);
202 if (rc != 0)
203 abort ();
204 buf32[32] = '\0';
205 if (strcmp (buf32, "6c1f58bfa46e9c225b93745c84204efd") != 0)
206 abort ();
207 printf ("digest: `%s': PASS\n", buf32);
208
209 return 0;
210}
211