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 */
30 #define RESPONSE_STANDARD 0
31 #define RESPONSE_WORD 1
32 #define RESPONSE_HEX 2
33 #define RESPONSE_INIT_HEX 3
34 #define RESPONSE_INIT_WORD 4
35 #define RESPONSE_UNKNOWN 5
42 static struct _rtrans rtrans[] = {
43 { RESPONSE_WORD, "word" },
44 { RESPONSE_HEX, "hex" },
45 { RESPONSE_INIT_HEX, "init-hex" },
46 { RESPONSE_INIT_WORD, "init-word" },
47 { RESPONSE_STANDARD, "" },
48 { RESPONSE_UNKNOWN, NULL }
51 static char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" };
53 static int changed FUNCTION((opie), struct opie *opie)
57 memset(&opie2, 0, sizeof(struct opie));
58 opie2.opie_principal = opie->opie_principal;
59 if (__opiereadrec(&opie2))
62 if ((opie2.opie_n != opie->opie_n) || strcmp(opie2.opie_val, opie->opie_val) || strcmp(opie2.opie_seed, opie->opie_seed))
65 memset(&opie2, 0, sizeof(struct opie));
69 int opieverify FUNCTION((opie, response), struct opie *opie AND char *response)
73 struct opie_otpkey key, fkey, lastkey;
76 if (!opie || !response)
79 if (!opie->opie_principal)
86 if (!opieatob8(&lastkey, opie->opie_val))
89 for (c = opie->opie_seed; *c; c++)
93 if (opie->opie_n <= 0)
96 if (c = strchr(response, ':')) {
100 for (r = rtrans; r->name && strcmp(r->name, response); r++);
104 i = RESPONSE_STANDARD;
107 case RESPONSE_STANDARD:
110 if (opieetob(&key, response) == 1) {
111 memcpy(&fkey, &key, sizeof(struct opie_otpkey));
112 opiehash(&fkey, MDX);
113 i = memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey));
115 if (i && opieatob8(&key, response)) {
116 memcpy(&fkey, &key, sizeof(struct opie_otpkey));
117 opiehash(&fkey, MDX);
118 i = memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey));
124 if (opieetob(&key, c) == 1) {
125 memcpy(&fkey, &key, sizeof(struct opie_otpkey));
126 opiehash(&fkey, MDX);
127 i = memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey));
133 if (opieatob8(&key, c)) {
134 memcpy(&fkey, &key, sizeof(struct opie_otpkey));
135 opiehash(&fkey, MDX);
136 i = memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey));
139 case RESPONSE_INIT_HEX:
140 case RESPONSE_INIT_WORD:
144 if (!(c2 = strchr(c, ':')))
149 if (i == RESPONSE_INIT_HEX) {
150 if (!opieatob8(&key, c))
153 if (opieetob(&key, c) != 1)
157 memcpy(&fkey, &key, sizeof(struct opie_otpkey));
158 opiehash(&fkey, MDX);
160 if (memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey)))
168 if (!opiebtoa8(opie->opie_val, &key))
171 if (__opiewriterec(opie))
174 if (!(c2 = strchr(c = c2, ':')))
182 if (__opieparsechallenge(c, &j, &(opie->opie_n), &(opie->opie_seed), &k) || (j != MDX) || k)
186 if (i == RESPONSE_INIT_HEX) {
187 if (!opieatob8(&key, c2))
190 if (opieetob(&key, c2) != 1)
195 case RESPONSE_UNKNOWN:
214 if (!opiebtoa8(opie->opie_val, &key))
216 rval = __opiewriterec(opie);
220 memset(opie, 0, sizeof(struct opie));