1 /* verify.c: The opieverify() library function.
4 This software is Copyright 1996-2001 by Craig Metz, All Rights Reserved.
5 The Inner Net License Version 3 applies to this software.
6 You should have received a copy of the license with this software. If
7 you didn't get a copy, you may request one from <license@inner.net>.
11 Modified by cmetz for OPIE 2.4. Use struct opie_otpkey for keys.
12 Check that seed and sequence number are valid.
13 Modified by cmetz for OPIE 2.32. Renamed _opieparsechallenge() to
14 __opieparsechallenge() and handle new argument. Fixed init
16 Modified by cmetz for OPIE 2.31. Renamed "init" to "init-hex".
17 Modified by cmetz for OPIE 2.31. Renamed "init" and "RESPONSE_INIT"
18 to "init-hex" and "RESPONSE_INIT_HEX". Removed active attack
20 Created by cmetz for OPIE 2.3 using the old verify.c as a guide.
26 #endif /* HAVE_STRING_H */
29 #define RESPONSE_STANDARD 0
30 #define RESPONSE_WORD 1
31 #define RESPONSE_HEX 2
32 #define RESPONSE_INIT_HEX 3
33 #define RESPONSE_INIT_WORD 4
34 #define RESPONSE_UNKNOWN 5
41 static struct _rtrans rtrans[] = {
42 { RESPONSE_WORD, "word" },
43 { RESPONSE_HEX, "hex" },
44 { RESPONSE_INIT_HEX, "init-hex" },
45 { RESPONSE_INIT_WORD, "init-word" },
46 { RESPONSE_STANDARD, "" },
47 { RESPONSE_UNKNOWN, NULL }
50 static char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" };
52 static int changed FUNCTION((opie), struct opie *opie)
56 memset(&opie2, 0, sizeof(struct opie));
57 opie2.opie_principal = opie->opie_principal;
58 if (__opiereadrec(&opie2))
61 if ((opie2.opie_n != opie->opie_n) || strcmp(opie2.opie_val, opie->opie_val) || strcmp(opie2.opie_seed, opie->opie_seed))
64 memset(&opie2, 0, sizeof(struct opie));
68 int opieverify FUNCTION((opie, response), struct opie *opie AND char *response)
72 struct opie_otpkey key, fkey, lastkey;
75 if (!opie || !response)
78 if (!opie->opie_principal)
85 if (!opieatob8(&lastkey, opie->opie_val))
88 for (c = opie->opie_seed; *c; c++)
92 if (opie->opie_n <= 0)
95 if (c = strchr(response, ':')) {
99 for (r = rtrans; r->name && strcmp(r->name, response); r++);
103 i = RESPONSE_STANDARD;
106 case RESPONSE_STANDARD:
109 if (opieetob(&key, response) == 1) {
110 memcpy(&fkey, &key, sizeof(struct opie_otpkey));
111 opiehash(&fkey, MDX);
112 i = memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey));
114 if (i && opieatob8(&key, response)) {
115 memcpy(&fkey, &key, sizeof(struct opie_otpkey));
116 opiehash(&fkey, MDX);
117 i = memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey));
123 if (opieetob(&key, c) == 1) {
124 memcpy(&fkey, &key, sizeof(struct opie_otpkey));
125 opiehash(&fkey, MDX);
126 i = memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey));
132 if (opieatob8(&key, c)) {
133 memcpy(&fkey, &key, sizeof(struct opie_otpkey));
134 opiehash(&fkey, MDX);
135 i = memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey));
138 case RESPONSE_INIT_HEX:
139 case RESPONSE_INIT_WORD:
143 if (!(c2 = strchr(c, ':')))
148 if (i == RESPONSE_INIT_HEX) {
149 if (!opieatob8(&key, c))
152 if (opieetob(&key, c) != 1)
156 memcpy(&fkey, &key, sizeof(struct opie_otpkey));
157 opiehash(&fkey, MDX);
159 if (memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey)))
167 if (!opiebtoa8(opie->opie_val, &key))
170 if (__opiewriterec(opie))
173 if (!(c2 = strchr(c = c2, ':')))
181 if (__opieparsechallenge(c, &j, &(opie->opie_n), &(opie->opie_seed), &k) || (j != MDX) || k)
185 if (i == RESPONSE_INIT_HEX) {
186 if (!opieatob8(&key, c2))
189 if (opieetob(&key, c2) != 1)
194 case RESPONSE_UNKNOWN:
213 if (!opiebtoa8(opie->opie_val, &key))
215 rval = __opiewriterec(opie);
219 memset(opie, 0, sizeof(struct opie));