1 |
|
|
/* $OpenBSD: parse_assertion.c,v 1.16 2015/12/14 03:25:59 mmcc Exp $ */ |
2 |
|
|
/* |
3 |
|
|
* The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu) |
4 |
|
|
* |
5 |
|
|
* This code was written by Angelos D. Keromytis in Philadelphia, PA, USA, |
6 |
|
|
* in April-May 1998 |
7 |
|
|
* |
8 |
|
|
* Copyright (C) 1998, 1999 by Angelos D. Keromytis. |
9 |
|
|
* |
10 |
|
|
* Permission to use, copy, and modify this software with or without fee |
11 |
|
|
* is hereby granted, provided that this entire notice is included in |
12 |
|
|
* all copies of any software which is or includes a copy or |
13 |
|
|
* modification of this software. |
14 |
|
|
* |
15 |
|
|
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR |
16 |
|
|
* IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO |
17 |
|
|
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE |
18 |
|
|
* MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR |
19 |
|
|
* PURPOSE. |
20 |
|
|
*/ |
21 |
|
|
|
22 |
|
|
#include <sys/types.h> |
23 |
|
|
|
24 |
|
|
#include <ctype.h> |
25 |
|
|
#include <limits.h> |
26 |
|
|
#include <regex.h> |
27 |
|
|
#include <stdio.h> |
28 |
|
|
#include <stdlib.h> |
29 |
|
|
#include <string.h> |
30 |
|
|
|
31 |
|
|
#include "keynote.h" |
32 |
|
|
#include "assertion.h" |
33 |
|
|
#include "signature.h" |
34 |
|
|
|
35 |
|
|
/* |
36 |
|
|
* Recurse on graph discovery. |
37 |
|
|
*/ |
38 |
|
|
static int |
39 |
|
|
rec_evaluate_query(struct assertion *as) |
40 |
|
|
{ |
41 |
|
|
struct assertion *ast; |
42 |
|
|
struct keylist *kl; |
43 |
|
|
int i, s; |
44 |
|
|
|
45 |
|
|
as->as_kresult = KRESULT_IN_PROGRESS; |
46 |
|
|
|
47 |
|
|
/* |
48 |
|
|
* If we get the minimum result or an error from evaluating this |
49 |
|
|
* assertion, we don't need to recurse. |
50 |
|
|
*/ |
51 |
|
|
keynote_evaluate_assertion(as); |
52 |
|
|
if (keynote_errno != 0) |
53 |
|
|
{ |
54 |
|
|
as->as_kresult = KRESULT_DONE; |
55 |
|
|
if (keynote_errno) |
56 |
|
|
as->as_error = keynote_errno; |
57 |
|
|
if (keynote_errno == ERROR_MEMORY) |
58 |
|
|
return -1; |
59 |
|
|
else |
60 |
|
|
{ |
61 |
|
|
keynote_errno = 0; /* Ignore syntax errors for now */ |
62 |
|
|
return 0; |
63 |
|
|
} |
64 |
|
|
} |
65 |
|
|
|
66 |
|
|
if (as->as_result == 0) |
67 |
|
|
{ |
68 |
|
|
as->as_kresult = KRESULT_DONE; |
69 |
|
|
return as->as_result; |
70 |
|
|
} |
71 |
|
|
|
72 |
|
|
for (kl = as->as_keylist; |
73 |
|
|
kl != NULL; |
74 |
|
|
kl = kl->key_next) |
75 |
|
|
{ |
76 |
|
|
switch (keynote_in_action_authorizers(kl->key_key, kl->key_alg)) |
77 |
|
|
{ |
78 |
|
|
case -1: |
79 |
|
|
as->as_kresult = KRESULT_DONE; |
80 |
|
|
if (keynote_errno == ERROR_MEMORY) |
81 |
|
|
{ |
82 |
|
|
as->as_error = ERROR_MEMORY; |
83 |
|
|
return -1; |
84 |
|
|
} |
85 |
|
|
else |
86 |
|
|
{ |
87 |
|
|
keynote_errno = 0; /* Reset */ |
88 |
|
|
continue; |
89 |
|
|
} |
90 |
|
|
|
91 |
|
|
case RESULT_FALSE: /* Not there, check for assertions instead */ |
92 |
|
|
break; |
93 |
|
|
|
94 |
|
|
case RESULT_TRUE: /* Ok, don't bother with assertions */ |
95 |
|
|
keynote_current_assertion = NULL; |
96 |
|
|
continue; |
97 |
|
|
} |
98 |
|
|
|
99 |
|
|
for (i = 0;; i++) |
100 |
|
|
{ |
101 |
|
|
ast = keynote_find_assertion(kl->key_key, i, kl->key_alg); |
102 |
|
|
if (ast == NULL) |
103 |
|
|
break; |
104 |
|
|
|
105 |
|
|
if (ast->as_kresult == KRESULT_IN_PROGRESS) /* Cycle detected */ |
106 |
|
|
continue; |
107 |
|
|
|
108 |
|
|
if (ast->as_kresult == KRESULT_UNTOUCHED) /* Recurse if needed */ |
109 |
|
|
rec_evaluate_query(ast); |
110 |
|
|
|
111 |
|
|
/* Check for errors */ |
112 |
|
|
if (keynote_errno == ERROR_MEMORY) |
113 |
|
|
{ |
114 |
|
|
as->as_error = ERROR_MEMORY; |
115 |
|
|
as->as_kresult = KRESULT_DONE; |
116 |
|
|
return -1; |
117 |
|
|
} |
118 |
|
|
else |
119 |
|
|
keynote_errno = 0; /* Reset */ |
120 |
|
|
} |
121 |
|
|
} |
122 |
|
|
|
123 |
|
|
keynote_current_assertion = as; |
124 |
|
|
s = keynote_parse_keypred(as, 0); |
125 |
|
|
keynote_current_assertion = NULL; |
126 |
|
|
|
127 |
|
|
if (keynote_errno == ERROR_MEMORY) |
128 |
|
|
{ |
129 |
|
|
as->as_error = ERROR_MEMORY; |
130 |
|
|
as->as_kresult = KRESULT_DONE; |
131 |
|
|
return -1; |
132 |
|
|
} |
133 |
|
|
else |
134 |
|
|
if (keynote_errno) |
135 |
|
|
{ |
136 |
|
|
keynote_errno = 0; |
137 |
|
|
s = 0; |
138 |
|
|
} |
139 |
|
|
|
140 |
|
|
/* Keep lower of two */ |
141 |
|
|
as->as_result = (as->as_result < s ? as->as_result : s); |
142 |
|
|
|
143 |
|
|
/* Check the signature now if we haven't done so already */ |
144 |
|
|
if (as->as_sigresult == SIGRESULT_UNTOUCHED) |
145 |
|
|
{ |
146 |
|
|
if (!(as->as_flags & ASSERT_FLAG_LOCAL)) |
147 |
|
|
as->as_sigresult = keynote_sigverify_assertion(as); |
148 |
|
|
else |
149 |
|
|
as->as_sigresult = SIGRESULT_TRUE; /* Trusted assertion */ |
150 |
|
|
} |
151 |
|
|
|
152 |
|
|
if (as->as_sigresult != SIGRESULT_TRUE) |
153 |
|
|
{ |
154 |
|
|
as->as_result = 0; |
155 |
|
|
as->as_sigresult = SIGRESULT_FALSE; |
156 |
|
|
if (keynote_errno != ERROR_MEMORY) |
157 |
|
|
keynote_errno = 0; /* Reset */ |
158 |
|
|
else |
159 |
|
|
{ |
160 |
|
|
as->as_error = ERROR_MEMORY; |
161 |
|
|
as->as_kresult = KRESULT_DONE; |
162 |
|
|
return -1; |
163 |
|
|
} |
164 |
|
|
} |
165 |
|
|
|
166 |
|
|
as->as_kresult = KRESULT_DONE; |
167 |
|
|
return as->as_result; |
168 |
|
|
} |
169 |
|
|
|
170 |
|
|
/* |
171 |
|
|
* Fix the Authorizer/Licencees/Signature fields. If the first argument is |
172 |
|
|
* empty, fix all assertions. The second argument specifies whether the |
173 |
|
|
* Signature field should be parsed or not. |
174 |
|
|
*/ |
175 |
|
|
static int |
176 |
|
|
keynote_fix_fields(struct assertion *ast, int sigfield) |
177 |
|
|
{ |
178 |
|
|
struct assertion *as; |
179 |
|
|
int i; |
180 |
|
|
|
181 |
|
|
/* Signature generation/verification handling, no need to eval Licensees */ |
182 |
|
|
if (ast != NULL) |
183 |
|
|
{ |
184 |
|
|
/* Authorizer */ |
185 |
|
|
if (keynote_evaluate_authorizer(ast, 1) != RESULT_TRUE) |
186 |
|
|
return -1; |
187 |
|
|
|
188 |
|
|
/* Signature */ |
189 |
|
|
if ((sigfield) && (ast->as_signature_string_s != NULL)) |
190 |
|
|
if (keynote_evaluate_authorizer(ast, 0) != RESULT_TRUE) |
191 |
|
|
return -1; |
192 |
|
|
|
193 |
|
|
return RESULT_TRUE; |
194 |
|
|
} |
195 |
|
|
|
196 |
|
|
for (i = 0; i < HASHTABLESIZE; i++) |
197 |
|
|
for (as = keynote_current_session->ks_assertion_table[i]; |
198 |
|
|
as != NULL; |
199 |
|
|
as = as->as_next) |
200 |
|
|
{ |
201 |
|
|
if (!(as->as_internalflags & ASSERT_IFLAG_NEEDPROC) && |
202 |
|
|
!(as->as_internalflags & ASSERT_IFLAG_WEIRDLICS) && |
203 |
|
|
!(as->as_internalflags & ASSERT_IFLAG_WEIRDAUTH) && |
204 |
|
|
!(as->as_internalflags & ASSERT_IFLAG_WEIRDSIG)) |
205 |
|
|
continue; |
206 |
|
|
|
207 |
|
|
/* Parse the Signature field */ |
208 |
|
|
if (((as->as_internalflags & ASSERT_IFLAG_WEIRDSIG) || |
209 |
|
|
(as->as_internalflags & ASSERT_IFLAG_NEEDPROC)) && |
210 |
|
|
(as->as_signature_string_s != NULL)) |
211 |
|
|
if (keynote_evaluate_authorizer(as, 0) == -1) |
212 |
|
|
{ |
213 |
|
|
if (keynote_errno) |
214 |
|
|
as->as_error = keynote_errno; |
215 |
|
|
if (keynote_errno == ERROR_MEMORY) |
216 |
|
|
return -1; |
217 |
|
|
else |
218 |
|
|
keynote_errno = 0; |
219 |
|
|
} |
220 |
|
|
|
221 |
|
|
/* Parse the Licensees field */ |
222 |
|
|
if ((as->as_internalflags & ASSERT_IFLAG_WEIRDLICS) || |
223 |
|
|
(as->as_internalflags & ASSERT_IFLAG_NEEDPROC)) |
224 |
|
|
if (keynote_parse_keypred(as, 1) == -1) |
225 |
|
|
{ |
226 |
|
|
if (keynote_errno) |
227 |
|
|
as->as_error = keynote_errno; |
228 |
|
|
if (keynote_errno == ERROR_MEMORY) |
229 |
|
|
return -1; |
230 |
|
|
else |
231 |
|
|
keynote_errno = 0; |
232 |
|
|
} |
233 |
|
|
|
234 |
|
|
/* Parse the Authorizer field */ |
235 |
|
|
if ((as->as_internalflags & ASSERT_IFLAG_WEIRDAUTH) || |
236 |
|
|
(as->as_internalflags & ASSERT_IFLAG_NEEDPROC)) |
237 |
|
|
if (keynote_evaluate_authorizer(as, 1) == -1) |
238 |
|
|
{ |
239 |
|
|
if (keynote_errno) |
240 |
|
|
as->as_error = keynote_errno; |
241 |
|
|
if (keynote_errno == ERROR_MEMORY) |
242 |
|
|
return -1; |
243 |
|
|
else |
244 |
|
|
keynote_errno = 0; |
245 |
|
|
} |
246 |
|
|
} |
247 |
|
|
|
248 |
|
|
/* Reposition if necessary */ |
249 |
|
|
for (i = 0; i < HASHTABLESIZE; i++) |
250 |
|
|
for (as = keynote_current_session->ks_assertion_table[i]; |
251 |
|
|
as != NULL; |
252 |
|
|
as = as->as_next) |
253 |
|
|
if (((as->as_internalflags & ASSERT_IFLAG_WEIRDAUTH) && |
254 |
|
|
!(as->as_internalflags & ASSERT_IFLAG_PROCESSED)) || |
255 |
|
|
(as->as_internalflags & ASSERT_IFLAG_NEEDPROC)) |
256 |
|
|
{ |
257 |
|
|
as->as_internalflags &= ~ASSERT_IFLAG_NEEDPROC; |
258 |
|
|
as->as_internalflags |= ASSERT_IFLAG_PROCESSED; |
259 |
|
|
keynote_sremove_assertion(keynote_current_session->ks_id, |
260 |
|
|
as->as_id); |
261 |
|
|
|
262 |
|
|
if (keynote_add_htable(as, 1) != RESULT_TRUE) |
263 |
|
|
return -1; |
264 |
|
|
|
265 |
|
|
/* Point to beginning of the previous list. */ |
266 |
|
|
i--; |
267 |
|
|
break; |
268 |
|
|
} |
269 |
|
|
|
270 |
|
|
return RESULT_TRUE; |
271 |
|
|
} |
272 |
|
|
|
273 |
|
|
/* |
274 |
|
|
* Find the trust graph. This is a depth-first search, starting at |
275 |
|
|
* POLICY assertions. |
276 |
|
|
*/ |
277 |
|
|
int |
278 |
|
|
keynote_evaluate_query(void) |
279 |
|
|
{ |
280 |
|
|
struct assertion *as; |
281 |
|
|
int p, prev; |
282 |
|
|
int i; |
283 |
|
|
|
284 |
|
|
/* Fix the authorizer/licensees/signature fields */ |
285 |
|
|
if (keynote_fix_fields(NULL, 0) != RESULT_TRUE) |
286 |
|
|
return -1; |
287 |
|
|
|
288 |
|
|
/* Find POLICY assertions and try to evaluate the query. */ |
289 |
|
|
for (i = 0, prev = 0; i < HASHTABLESIZE; i++) |
290 |
|
|
for (as = keynote_current_session->ks_assertion_table[i]; |
291 |
|
|
as != NULL; |
292 |
|
|
as = as->as_next) |
293 |
|
|
if ((as->as_authorizer != NULL) && /* Paranoid */ |
294 |
|
|
(as->as_signeralgorithm == KEYNOTE_ALGORITHM_NONE)) |
295 |
|
|
if ((!strcmp("POLICY", as->as_authorizer)) && |
296 |
|
|
(as->as_flags & ASSERT_FLAG_LOCAL)) |
297 |
|
|
{ |
298 |
|
|
if ((p = rec_evaluate_query(as)) == -1) |
299 |
|
|
{ |
300 |
|
|
if (keynote_errno) |
301 |
|
|
as->as_error = keynote_errno; |
302 |
|
|
if (keynote_errno == ERROR_MEMORY) |
303 |
|
|
return -1; |
304 |
|
|
else |
305 |
|
|
{ |
306 |
|
|
keynote_errno = 0; |
307 |
|
|
continue; |
308 |
|
|
} |
309 |
|
|
} |
310 |
|
|
|
311 |
|
|
if (p > prev) |
312 |
|
|
prev = p; |
313 |
|
|
|
314 |
|
|
/* If we get the highest possible return value, just return */ |
315 |
|
|
if (prev == (keynote_current_session->ks_values_num - 1)) |
316 |
|
|
return prev; |
317 |
|
|
} |
318 |
|
|
|
319 |
|
|
return prev; |
320 |
|
|
} |
321 |
|
|
|
322 |
|
|
/* |
323 |
|
|
* Return keyword type. |
324 |
|
|
*/ |
325 |
|
|
static int |
326 |
|
|
whichkeyword(char *start, char *end) |
327 |
|
|
{ |
328 |
|
|
int len = (end - start); |
329 |
|
|
|
330 |
|
|
if (len <= 0) |
331 |
|
|
{ |
332 |
|
|
keynote_errno = ERROR_MEMORY; |
333 |
|
|
return -1; |
334 |
|
|
} |
335 |
|
|
|
336 |
|
|
if (!strncasecmp("keynote-version:", start, len)) |
337 |
|
|
return KEYWORD_VERSION; |
338 |
|
|
|
339 |
|
|
if (!strncasecmp("local-constants:", start, len)) |
340 |
|
|
return KEYWORD_LOCALINIT; |
341 |
|
|
|
342 |
|
|
if (!strncasecmp("authorizer:", start, len)) |
343 |
|
|
return KEYWORD_AUTHORIZER; |
344 |
|
|
|
345 |
|
|
if (!strncasecmp("licensees:", start, len)) |
346 |
|
|
return KEYWORD_LICENSEES; |
347 |
|
|
|
348 |
|
|
if (!strncasecmp("conditions:", start, len)) |
349 |
|
|
return KEYWORD_CONDITIONS; |
350 |
|
|
|
351 |
|
|
if (!strncasecmp("signature:", start, len)) |
352 |
|
|
return KEYWORD_SIGNATURE; |
353 |
|
|
|
354 |
|
|
if (!strncasecmp("comment:", start, len)) |
355 |
|
|
return KEYWORD_COMMENT; |
356 |
|
|
|
357 |
|
|
keynote_errno = ERROR_SYNTAX; |
358 |
|
|
return -1; |
359 |
|
|
} |
360 |
|
|
|
361 |
|
|
/* |
362 |
|
|
* Parse an assertion. Set keynote_errno to ERROR_SYNTAX if parsing |
363 |
|
|
* failed due to certificate badness, and ERROR_MEMORY if memory |
364 |
|
|
* problem. If more than one assertions have been passed in the |
365 |
|
|
* buffer, they will be linked. |
366 |
|
|
*/ |
367 |
|
|
struct assertion * |
368 |
|
|
keynote_parse_assertion(char *buf, int len, int assertion_flags) |
369 |
|
|
{ |
370 |
|
|
int k, i, j, seen_field = 0, ver = 0, end_of_assertion = 0; |
371 |
|
|
char *ks, *ke, *ts, *te = NULL; |
372 |
|
|
struct assertion *as; |
373 |
|
|
|
374 |
|
|
/* Allocate memory for assertion */ |
375 |
|
|
as = calloc(1, sizeof(struct assertion)); |
376 |
|
|
if (as == NULL) |
377 |
|
|
{ |
378 |
|
|
keynote_errno = ERROR_MEMORY; |
379 |
|
|
return NULL; |
380 |
|
|
} |
381 |
|
|
|
382 |
|
|
/* Keep a copy of the assertion around */ |
383 |
|
|
as->as_buf = strdup(buf); |
384 |
|
|
if (as->as_buf == NULL) |
385 |
|
|
{ |
386 |
|
|
keynote_errno = ERROR_MEMORY; |
387 |
|
|
keynote_free_assertion(as); |
388 |
|
|
return NULL; |
389 |
|
|
} |
390 |
|
|
|
391 |
|
|
as->as_flags = assertion_flags & ~(ASSERT_FLAG_SIGGEN | |
392 |
|
|
ASSERT_FLAG_SIGVER); |
393 |
|
|
|
394 |
|
|
/* Skip any leading whitespace */ |
395 |
|
|
for (i = 0, j = len; i < j && isspace((unsigned char)as->as_buf[i]); i++) |
396 |
|
|
; |
397 |
|
|
|
398 |
|
|
/* Keyword must start at begining of buffer or line */ |
399 |
|
|
if ((i >= j) || ((i != 0) && (as->as_buf[i - 1] != '\n'))) |
400 |
|
|
{ |
401 |
|
|
keynote_free_assertion(as); |
402 |
|
|
keynote_errno = ERROR_SYNTAX; |
403 |
|
|
return NULL; |
404 |
|
|
} |
405 |
|
|
|
406 |
|
|
while (i < j) /* Decomposition loop */ |
407 |
|
|
{ |
408 |
|
|
ks = as->as_buf + i; |
409 |
|
|
|
410 |
|
|
/* Mark begining of assertion for signature purposes */ |
411 |
|
|
if (as->as_startofsignature == NULL) |
412 |
|
|
as->as_startofsignature = ks; |
413 |
|
|
|
414 |
|
|
/* This catches comments at the begining of an assertion only */ |
415 |
|
|
if (as->as_buf[i] == '#') /* Comment */ |
416 |
|
|
{ |
417 |
|
|
seen_field = 1; |
418 |
|
|
|
419 |
|
|
/* Skip until the end of line */ |
420 |
|
|
while ((i< j) && as->as_buf[++i] != '\n') |
421 |
|
|
; |
422 |
|
|
|
423 |
|
|
i++; |
424 |
|
|
continue; /* Loop */ |
425 |
|
|
} |
426 |
|
|
|
427 |
|
|
/* Advance until we find a keyword separator */ |
428 |
|
|
for (; (as->as_buf[i] != ':') && (i < j); i++) |
429 |
|
|
; |
430 |
|
|
|
431 |
|
|
if (i + 1 > j) |
432 |
|
|
{ |
433 |
|
|
keynote_free_assertion(as); |
434 |
|
|
keynote_errno = ERROR_SYNTAX; |
435 |
|
|
return NULL; |
436 |
|
|
} |
437 |
|
|
|
438 |
|
|
/* ks points at begining of keyword, ke points at end */ |
439 |
|
|
ke = as->as_buf + i; |
440 |
|
|
|
441 |
|
|
/* ts points at begining of value field */ |
442 |
|
|
ts = as->as_buf + i + 1; /* Skip ':' */ |
443 |
|
|
|
444 |
|
|
/* |
445 |
|
|
* Find the end of the field -- means end of buffer, |
446 |
|
|
* a newline followed by a non-whitespace character, |
447 |
|
|
* or two newlines. |
448 |
|
|
*/ |
449 |
|
|
while (++i <= j) |
450 |
|
|
{ |
451 |
|
|
/* If end of buffer, we're at the end of the field */ |
452 |
|
|
if (i == j) |
453 |
|
|
{ |
454 |
|
|
end_of_assertion = 1; |
455 |
|
|
te = as->as_buf + i; |
456 |
|
|
break; |
457 |
|
|
} |
458 |
|
|
|
459 |
|
|
/* If two newlines, end of assertion */ |
460 |
|
|
if ((as->as_buf[i] == '\n') && (i + 1 < j) && |
461 |
|
|
(as->as_buf[i + 1] == '\n')) |
462 |
|
|
{ |
463 |
|
|
end_of_assertion = 1; |
464 |
|
|
te = as->as_buf + i; |
465 |
|
|
break; |
466 |
|
|
} |
467 |
|
|
|
468 |
|
|
/* If newline followed by non-whitespace or comment character */ |
469 |
|
|
if ((as->as_buf[i] == '\n') && |
470 |
|
|
(!isspace((unsigned char)as->as_buf[i + 1])) && |
471 |
|
|
(as->as_buf[i + 1] != '#')) |
472 |
|
|
{ |
473 |
|
|
te = as->as_buf + i; |
474 |
|
|
break; |
475 |
|
|
} |
476 |
|
|
} |
477 |
|
|
|
478 |
|
|
i++; |
479 |
|
|
|
480 |
|
|
/* |
481 |
|
|
* On each of the cases (except the first), we check that: |
482 |
|
|
* - we've already seen a keynote-version field (and that |
483 |
|
|
* it's the first one that appears in the assertion) |
484 |
|
|
* - the signature field, if present, is the last one |
485 |
|
|
* - no field appears more than once |
486 |
|
|
*/ |
487 |
|
|
switch (whichkeyword(ks, ke)) |
488 |
|
|
{ |
489 |
|
|
case -1: |
490 |
|
|
keynote_free_assertion(as); |
491 |
|
|
return NULL; |
492 |
|
|
|
493 |
|
|
case KEYWORD_VERSION: |
494 |
|
|
if ((ver == 1) || (seen_field == 1)) |
495 |
|
|
{ |
496 |
|
|
keynote_free_assertion(as); |
497 |
|
|
keynote_errno = ERROR_SYNTAX; |
498 |
|
|
return NULL; |
499 |
|
|
} |
500 |
|
|
|
501 |
|
|
/* Test for version correctness */ |
502 |
|
|
keynote_get_envlist(ts, te, 1); |
503 |
|
|
if (keynote_errno != 0) |
504 |
|
|
{ |
505 |
|
|
keynote_free_assertion(as); |
506 |
|
|
return NULL; |
507 |
|
|
} |
508 |
|
|
|
509 |
|
|
ver = 1; |
510 |
|
|
break; |
511 |
|
|
|
512 |
|
|
case KEYWORD_LOCALINIT: |
513 |
|
|
if (as->as_env != NULL) |
514 |
|
|
{ |
515 |
|
|
keynote_free_assertion(as); |
516 |
|
|
keynote_errno = ERROR_SYNTAX; |
517 |
|
|
return NULL; |
518 |
|
|
} |
519 |
|
|
|
520 |
|
|
as->as_env = keynote_get_envlist(ts, te, 0); |
521 |
|
|
if (keynote_errno != 0) |
522 |
|
|
{ |
523 |
|
|
keynote_free_assertion(as); |
524 |
|
|
return NULL; |
525 |
|
|
} |
526 |
|
|
break; |
527 |
|
|
|
528 |
|
|
case KEYWORD_AUTHORIZER: |
529 |
|
|
if (as->as_authorizer_string_s != NULL) |
530 |
|
|
{ |
531 |
|
|
keynote_free_assertion(as); |
532 |
|
|
keynote_errno = ERROR_SYNTAX; |
533 |
|
|
return NULL; |
534 |
|
|
} |
535 |
|
|
|
536 |
|
|
as->as_authorizer_string_s = ts; |
537 |
|
|
as->as_authorizer_string_e = te; |
538 |
|
|
break; |
539 |
|
|
|
540 |
|
|
case KEYWORD_LICENSEES: |
541 |
|
|
if (as->as_keypred_s != NULL) |
542 |
|
|
{ |
543 |
|
|
keynote_free_assertion(as); |
544 |
|
|
keynote_errno = ERROR_SYNTAX; |
545 |
|
|
return NULL; |
546 |
|
|
} |
547 |
|
|
|
548 |
|
|
as->as_keypred_s = ts; |
549 |
|
|
as->as_keypred_e = te; |
550 |
|
|
break; |
551 |
|
|
|
552 |
|
|
case KEYWORD_CONDITIONS: |
553 |
|
|
if (as->as_conditions_s != NULL) |
554 |
|
|
{ |
555 |
|
|
keynote_free_assertion(as); |
556 |
|
|
keynote_errno = ERROR_SYNTAX; |
557 |
|
|
return NULL; |
558 |
|
|
} |
559 |
|
|
|
560 |
|
|
as->as_conditions_s = ts; |
561 |
|
|
as->as_conditions_e = te; |
562 |
|
|
break; |
563 |
|
|
|
564 |
|
|
case KEYWORD_SIGNATURE: |
565 |
|
|
if (as->as_signature_string_s != NULL) |
566 |
|
|
{ |
567 |
|
|
keynote_free_assertion(as); |
568 |
|
|
keynote_errno = ERROR_SYNTAX; |
569 |
|
|
return NULL; |
570 |
|
|
} |
571 |
|
|
|
572 |
|
|
end_of_assertion = 1; |
573 |
|
|
as->as_allbutsignature = ks; |
574 |
|
|
as->as_signature_string_s = ts; |
575 |
|
|
as->as_signature_string_e = te; |
576 |
|
|
break; |
577 |
|
|
|
578 |
|
|
case KEYWORD_COMMENT: |
579 |
|
|
if (as->as_comment_s != NULL) |
580 |
|
|
{ |
581 |
|
|
keynote_free_assertion(as); |
582 |
|
|
keynote_errno = ERROR_SYNTAX; |
583 |
|
|
return NULL; |
584 |
|
|
} |
585 |
|
|
|
586 |
|
|
as->as_comment_s = ts; |
587 |
|
|
as->as_comment_e = te; |
588 |
|
|
break; |
589 |
|
|
} |
590 |
|
|
|
591 |
|
|
seen_field = 1; |
592 |
|
|
if (end_of_assertion == 1) |
593 |
|
|
{ |
594 |
|
|
/* End of buffer, good termination */ |
595 |
|
|
if ((te == as->as_buf + len) || (te + 1 == as->as_buf + len) || |
596 |
|
|
(*(te) == '\0') || (*(te + 1) == '\0')) |
597 |
|
|
break; |
598 |
|
|
|
599 |
|
|
/* Check whether there's something else following */ |
600 |
|
|
for (k = 1; te + k < as->as_buf + len && *(te + k) != '\n'; k++) |
601 |
|
|
if (!isspace((unsigned char)*(te + k))) |
602 |
|
|
{ |
603 |
|
|
keynote_free_assertion(as); |
604 |
|
|
keynote_errno = ERROR_SYNTAX; |
605 |
|
|
return NULL; |
606 |
|
|
} |
607 |
|
|
|
608 |
|
|
break; /* Assertion is "properly" terminated */ |
609 |
|
|
} |
610 |
|
|
} |
611 |
|
|
|
612 |
|
|
/* Check that the basic fields are there */ |
613 |
|
|
if (as->as_authorizer_string_s == NULL) |
614 |
|
|
{ |
615 |
|
|
keynote_free_assertion(as); |
616 |
|
|
keynote_errno = ERROR_SYNTAX; |
617 |
|
|
return NULL; |
618 |
|
|
} |
619 |
|
|
|
620 |
|
|
/* Signature generation/verification handling */ |
621 |
|
|
if (assertion_flags & ASSERT_FLAG_SIGGEN) |
622 |
|
|
{ |
623 |
|
|
if (keynote_fix_fields(as, 0) != RESULT_TRUE) |
624 |
|
|
{ |
625 |
|
|
keynote_free_assertion(as); |
626 |
|
|
return NULL; |
627 |
|
|
} |
628 |
|
|
} |
629 |
|
|
else |
630 |
|
|
if (assertion_flags & ASSERT_FLAG_SIGVER) |
631 |
|
|
if (keynote_fix_fields(as, 1) != RESULT_TRUE) |
632 |
|
|
{ |
633 |
|
|
keynote_free_assertion(as); |
634 |
|
|
return NULL; |
635 |
|
|
} |
636 |
|
|
|
637 |
|
|
return as; |
638 |
|
|
} |