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
));