gsasl  2.2.2
test-parser.c
Go to the documentation of this file.
1 /* test-parser.c --- Self tests of DIGEST-MD5 parser & printer.
2  * Copyright (C) 2004-2025 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, see
18  * <https://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #include <config.h>
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 
28 #include "free.h"
29 #include "parser.h"
30 #include "printer.h"
31 #include "digesthmac.h"
32 
33 #include "gc.h"
34 
35 int
36 main (void)
37 {
41  char buf32[33];
42  char buf16[16];
43  int rc;
44  char *tmp;
45 
46  {
47  const char *token = "nonce=4711, foo=bar, algorithm=md5-sess";
48 
49  printf ("challenge `%s': ", token);
50  rc = digest_md5_parse_challenge (token, 0, &c);
51  if (rc != 0)
52  abort ();
53  printf ("nonce `%s': %s", c.nonce,
54  strcmp ("4711", c.nonce) == 0 ? "PASS" : "FAILURE");
55  printf ("\n");
56  tmp = digest_md5_print_challenge (&c);
57  if (!tmp)
58  abort ();
59  printf ("printed `%s' PASS\n", tmp);
60  free (tmp);
62  }
63 
64  {
65  const char *token =
66  "qop=\"auth, auth-conf\", nonce=42, algorithm=md5-sess";
67 
68  printf ("challenge `%s': ", token);
69  rc = digest_md5_parse_challenge (token, 0, &c);
70  if (rc == 0)
71  abort ();
73  printf ("PASS\n");
74  }
75 
76  {
77  const char *token = "cipher=\"des\", nonce=42, algorithm=md5-sess";
78 
79  printf ("challenge `%s': ", token);
80  rc = digest_md5_parse_challenge (token, 0, &c);
81  if (rc == 0)
82  abort ();
84  printf ("PASS\n");
85  }
86 
87  {
88  const char *token = "qop=\"auth, auth-conf\", nonce=42, "
89  "algorithm=md5-sess, cipher=\"des\"";
90 
91  printf ("challenge `%s': ", token);
92  rc = digest_md5_parse_challenge (token, 0, &c);
93  if (rc != 0)
94  abort ();
95  printf ("qop %02x ciphers %02x: %s\n",
96  (unsigned) c.qops, (unsigned) c.ciphers,
97  (c.qops == 5 && c.ciphers == 1) ? "PASS" : "FAILURE");
98  tmp = digest_md5_print_challenge (&c);
99  if (!tmp)
100  abort ();
101  printf ("printed `%s' PASS\n", tmp);
102  free (tmp);
104  }
105 
106  {
107  const char *token = "bar=foo, foo=bar";
108 
109  printf ("challenge `%s': ", token);
110  rc = digest_md5_parse_challenge (token, 0, &c);
111  if (rc == 0)
112  abort ();
113  printf ("PASS\n");
114  }
115 
116  {
117  const char *token = "realm=foo, realm=bar, nonce=42, algorithm=md5-sess";
118 
119  printf ("challenge `%s': ", token);
120  rc = digest_md5_parse_challenge (token, 0, &c);
121  if (rc != 0)
122  abort ();
123  if (c.nrealms != 2)
124  abort ();
125  printf ("realms `%s', `%s': PASS\n", c.realms[0], c.realms[1]);
126  tmp = digest_md5_print_challenge (&c);
127  if (!tmp)
128  abort ();
129  printf ("printed `%s' PASS\n", tmp);
130  free (tmp);
132  }
133 
134  /* Response */
135 
136  {
137  const char *token = "bar=foo, foo=bar";
138 
139  printf ("response `%s': ", token);
140  rc = digest_md5_parse_response (token, 0, &r);
141  if (rc == 0)
142  abort ();
143  printf ("PASS\n");
145  }
146 
147  {
148  const char *token = "username=jas, nonce=42, cnonce=4711, nc=00000001, "
149  "digest-uri=foo, response=01234567890123456789012345678901";
150 
151  printf ("response `%s': ", token);
152  rc = digest_md5_parse_response (token, 0, &r);
153  if (rc != 0)
154  abort ();
155  printf ("username `%s', nonce `%s', cnonce `%s',"
156  " nc %08lx, digest-uri `%s', response `%s': PASS\n",
157  r.username, r.nonce, r.cnonce, r.nc, r.digesturi, r.response);
158  tmp = digest_md5_print_response (&r);
159  if (!tmp)
160  abort ();
161  printf ("printed `%s' PASS\n", tmp);
162  free (tmp);
164  }
165 
166  /* Auth-response, finish. */
167 
168  {
169  const char *token = "rspauth=\"6a204da26b9888ee40bb3052ff056a67\"";
170 
171  printf ("finish `%s': ", token);
172  rc = digest_md5_parse_finish (token, 0, &f);
173  if (rc != 0)
174  abort ();
175  printf ("`%s'? %s\n", f.rspauth,
176  strcmp ("6a204da26b9888ee40bb3052ff056a67", f.rspauth) == 0
177  ? "ok" : "FAILURE");
179  }
180 
181  {
182  const char *token = "bar=foo, foo=bar";
183 
184  printf ("finish `%s': ", token);
185  rc = digest_md5_parse_finish (token, 0, &f);
186  if (rc == 0)
187  abort ();
188  printf ("invalid? PASS\n");
190  }
191 
192  rc = gc_init ();
193  if (rc != 0)
194  {
195  printf ("gc_init error %d\n", rc);
196  abort ();
197  }
198 
199  memset (buf16, 'Q', 16);
200 
201  rc = digest_md5_hmac (buf32, buf16, "nonce", 1, "cnonce",
202  DIGEST_MD5_QOP_AUTH, "authzid", "digesturi",
203  1, 0, NULL, NULL, NULL, NULL);
204  if (rc != 0)
205  abort ();
206  buf32[32] = '\0';
207  if (strcmp (buf32, "6a204da26b9888ee40bb3052ff056a67") != 0)
208  abort ();
209  printf ("digest: `%s': PASS\n", buf32);
210 
211  rc = digest_md5_hmac (buf32, buf16, "nonce", 1, "cnonce",
212  DIGEST_MD5_QOP_AUTH, "authzid", "digesturi", 0, 0,
213  NULL, NULL, NULL, NULL);
214  if (rc != 0)
215  abort ();
216  buf32[32] = '\0';
217  if (strcmp (buf32, "6c1f58bfa46e9c225b93745c84204efd") != 0)
218  abort ();
219  printf ("digest: `%s': PASS\n", buf32);
220 
221  return 0;
222 }
void digest_md5_free_finish(digest_md5_finish *f)
void digest_md5_free_response(digest_md5_response *r)
void digest_md5_free_challenge(digest_md5_challenge *c)
int digest_md5_parse_challenge(const char *challenge, size_t len, digest_md5_challenge *out)
int digest_md5_parse_response(const char *response, size_t len, digest_md5_response *out)
int digest_md5_parse_finish(const char *finish, size_t len, digest_md5_finish *out)
char * digest_md5_print_challenge(digest_md5_challenge *c)
char * digest_md5_print_response(digest_md5_response *r)
@ DIGEST_MD5_QOP_AUTH
int digest_md5_hmac(char *output, char secret[MD5LEN], const char *nonce, unsigned long nc, const char *cnonce, digest_md5_qop qop, const char *authzid, const char *digesturi, int rspauth, digest_md5_cipher cipher, char *kic, char *kis, char *kcc, char *kcs)
Definition: digesthmac.c:76
int rc
Definition: error.c:36
char rspauth[DIGEST_MD5_RESPONSE_LENGTH+1]
char response[DIGEST_MD5_RESPONSE_LENGTH+1]
int main(void)
Definition: test-parser.c:36