]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/opie/libopie/verify.c
Add libbearssl
[FreeBSD/FreeBSD.git] / contrib / opie / libopie / verify.c
1 /* verify.c: The opieverify() library function.
2
3 %%% copyright-cmetz-96
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>.
8
9         History:
10
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
15                 response parsing bug.
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
19                 protection support.
20         Created by cmetz for OPIE 2.3 using the old verify.c as a guide.
21 */
22
23 #include "opie_cfg.h"
24 #ifdef HAVE_STRING_H
25 #include <string.h>
26 #endif /* HAVE_STRING_H */
27 #include <ctype.h>
28 #include "opie.h"
29
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
36
37 struct _rtrans {
38   int type;
39   char *name;
40 };
41
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 }
49 };
50
51 static char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" };
52
53 static int changed FUNCTION((opie), struct opie *opie)
54 {
55   struct opie opie2;
56
57   memset(&opie2, 0, sizeof(struct opie));
58   opie2.opie_principal = opie->opie_principal;
59   if (__opiereadrec(&opie2))
60     return 1;
61
62   if ((opie2.opie_n != opie->opie_n) || strcmp(opie2.opie_val, opie->opie_val) || strcmp(opie2.opie_seed, opie->opie_seed))
63     return 1;
64
65   memset(&opie2, 0, sizeof(struct opie));
66   return 0;
67 }
68
69 int opieverify FUNCTION((opie, response), struct opie *opie AND char *response)
70 {
71   int i, rval = -1;
72   char *c;
73   struct opie_otpkey key, fkey, lastkey;
74   struct opie nopie;
75
76   if (!opie || !response)
77     goto verret;
78
79   if (!opie->opie_principal)
80 #if DEBUG
81     abort();
82 #else /* DEBUG */
83     goto verret;
84 #endif /* DEBUG */
85
86   if (!opieatob8(&lastkey, opie->opie_val))
87     goto verret;
88
89   for (c = opie->opie_seed; *c; c++)
90     if (!isalnum(*c))
91       goto verret;
92
93   if (opie->opie_n <= 0)
94     goto verret;
95
96   if (c = strchr(response, ':')) {
97     *(c++) = 0;
98     {
99       struct _rtrans *r;
100       for (r = rtrans; r->name && strcmp(r->name, response); r++);
101       i = r->type;
102     }
103   } else
104     i = RESPONSE_STANDARD;
105
106   switch(i) {
107   case RESPONSE_STANDARD:
108     i = 1;
109     
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));
114     }
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));
119     }
120     break;
121   case RESPONSE_WORD:
122     i = 1;
123
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));
128     }
129     break;
130   case RESPONSE_HEX:
131     i = 1;
132
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));
137     }
138     break;
139   case RESPONSE_INIT_HEX:
140   case RESPONSE_INIT_WORD:
141     {
142       char *c2;
143
144       if (!(c2 = strchr(c, ':')))
145         goto verret;
146
147       *(c2++) = 0;
148
149       if (i == RESPONSE_INIT_HEX) {
150         if (!opieatob8(&key, c))
151           goto verret;
152       } else {
153         if (opieetob(&key, c) != 1)
154           goto verret;
155       }
156
157       memcpy(&fkey, &key, sizeof(struct opie_otpkey));
158       opiehash(&fkey, MDX);
159
160       if (memcmp(&fkey, &lastkey, sizeof(struct opie_otpkey)))
161         goto verret;
162
163       if (changed(opie))
164         goto verret;
165       
166       opie->opie_n--;
167
168       if (!opiebtoa8(opie->opie_val, &key))
169         goto verret;
170
171       if (__opiewriterec(opie))
172         goto verret;
173
174       if (!(c2 = strchr(c = c2, ':')))
175         goto verret;
176
177       *(c2++) = 0;
178
179       {
180         int j, k;
181
182         if (__opieparsechallenge(c, &j, &(opie->opie_n), &(opie->opie_seed), &k) || (j != MDX) || k)
183           goto verret;
184       }
185
186       if (i == RESPONSE_INIT_HEX) {
187         if (!opieatob8(&key, c2))
188           goto verret;
189       } else {
190         if (opieetob(&key, c2) != 1)
191           goto verret;
192       }
193     }
194     goto verwrt;
195   case RESPONSE_UNKNOWN:
196     rval = 1;
197     goto verret;
198   default:
199     rval = -1;
200     goto verret;
201   }
202
203   if (i) {
204     rval = 1;
205     goto verret;
206   }
207
208   if (changed(opie))
209     goto verret;
210   
211   opie->opie_n--;
212
213 verwrt:
214   if (!opiebtoa8(opie->opie_val, &key))
215     goto verret;
216   rval = __opiewriterec(opie);
217
218 verret:
219   opieunlock();
220   memset(opie, 0, sizeof(struct opie));
221   return rval;
222 }