| 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 | |
| 33 | int |
| 34 | main (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 | |