]> git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/c-lib/src/tbl-util.c
Security-54.1.3.tar.gz
[apple/security.git] / SecuritySNACCRuntime / c-lib / src / tbl-util.c
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 #ifdef TTBL
20
21 /*
22 * tbl_util.c - type table utilities.
23 *
24 * Copyright (C) 1993 Michael Sample
25 * and the University of British Columbia
26 *
27 * This library is free software; you can redistribute it and/or
28 * modify it provided that this copyright/license information is retained
29 * in original form.
30 *
31 * If you modify this file, you must clearly indicate your changes.
32 *
33 * This source code is distributed in the hope that it will be
34 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
35 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
36 */
37
38
39 #include <stdio.h>
40 #include "tbl-incl.h"
41 #include "sbuf.h"
42
43 /* non -exported routine protos */
44 void TblLinkIndexes PROTO ((TBL *tbl));
45 void TblLinkTypeRefs PROTO ((TBL *tbl, TBLType *tblT));
46
47 void TblFixTags PROTO ((TBL *tbl));
48 void TblFixTypeTags PROTO ((TBLType *tblT));
49 void TblSetTagForms PROTO ((TBLType *t));
50
51
52 /*
53 * opens given filename, determines its size, allocs a block
54 * of that size and reads the file into it. returns a pointer
55 * to this block. Prints an err msgs is something screwed up
56 * and returns NULL. Sets the size param to the size of the file.
57 */
58 char*
59 LoadFile PARAMS ((fileName, size),
60 char *fileName _AND_
61 unsigned long int *size)
62 {
63 FILE *f;
64 unsigned long int fsize;
65 char *fileData;
66
67 f = fopen (fileName, "r");
68
69 if (f == NULL)
70 {
71 Asn1Error("Could not open file for reading.\n");
72 return NULL;
73 }
74
75 fseek (f, 0, 2); /* seek to end */
76 fsize = ftell (f); /* get size of file */
77 fseek (f, 0, 0); /* seek to beginning */
78
79 *size = fsize;
80 fileData = (char *) malloc (fsize);
81
82 if (fileData == NULL)
83 {
84 Asn1Error("Not enough memory to read in file.\n");
85 return NULL;
86 }
87
88 if (fread (fileData, sizeof (char), fsize, f) != fsize)
89 {
90 free (fileData);
91 fileData = NULL;
92 Asn1Error("Trouble reading file.\n");
93 }
94
95 fclose (f);
96 return fileData;
97 } /* LoadFile */
98
99
100 TBL*
101 LoadTblFile PARAMS ((tblFileName),
102 char *tblFileName)
103 {
104 SBuf sb;
105 SBuf *sbPtr;
106 GenBuf gb;
107 TBL *tbl;
108 unsigned long int fsize;
109 char *fileData;
110 AsnLen decodedLen;
111 ENV_TYPE env;
112 int val;
113
114
115 fileData = LoadFile (tblFileName, &fsize);
116 if (fileData == NULL)
117 return NULL;
118
119 SBufInstallData (&sb, fileData, fsize);
120 SBufResetInReadMode (&sb);
121 PutSBufInGenBuf (&sb, &gb);
122
123 decodedLen = 0;
124
125 tbl = (TBL*)Asn1Alloc (sizeof (TBL));
126
127 if ((val = setjmp (env)) == 0)
128 BDecTBL (&gb, tbl, &decodedLen, env);
129 else
130 return NULL;
131
132 /* convert the typeDefIndexes into real pointers */
133 TblLinkIndexes (tbl);
134
135 TblFixTags (tbl);
136
137 free (fileData); /* malloc'd in LoadFile */
138
139 return tbl;
140 }
141
142
143 /*
144 * just use slow individual lookup instead of creating a table
145 * (a conversion tbl could be built during decoding)
146 */
147 void
148 TblLinkIndexes PARAMS ((tbl),
149 TBL *tbl)
150 {
151 TBLModule *tblMod;
152 TBLTypeDef *tblTd;
153
154 FOR_EACH_LIST_ELMT (tblMod, tbl->modules)
155 {
156 FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs)
157 {
158 /* go through the types looking for TBLTypeRefs */
159 TblLinkTypeRefs (tbl, tblTd->type);
160 }
161 }
162 } /* TBLLinkIndexes */
163
164
165 /*
166 * set tags forms and include encoded version to improve
167 * decoding and encoding performance.
168 */
169 void
170 TblFixTags PARAMS ((tbl),
171 TBL *tbl)
172 {
173 TBLModule *tblMod;
174 TBLTypeDef *tblTd;
175
176 FOR_EACH_LIST_ELMT (tblMod, tbl->modules)
177 {
178 FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs)
179 {
180 TblFixTypeTags (tblTd->type);
181 }
182 }
183 } /* TBLFixTags */
184
185
186
187 /*
188 * recursively descends type looking for typeDefIds in type refs
189 * to convert to the type defs actual ptr
190 *
191 * Also sets the form field for each tag. (this speeds up enc/dec).
192 * Note that the form bit is not in the encoded version of a TBLTag.
193 */
194 void
195 TblLinkTypeRefs PARAMS ((tbl, tblT),
196 TBL *tbl _AND_
197 TBLType *tblT)
198 {
199 TBLType *tblElmtT;
200 void *tmp;
201
202 switch (tblT->typeId)
203 {
204 case TBL_BOOLEAN:
205 case TBL_INTEGER:
206 case TBL_BITSTRING:
207 case TBL_OCTETSTRING:
208 case TBL_NULL:
209 case TBL_OID:
210 case TBL_REAL:
211 case TBL_ENUMERATED:
212 /* not contained type refs so return */
213 break;
214
215 case TBL_SEQUENCE:
216 case TBL_SET:
217 case TBL_SEQUENCEOF:
218 case TBL_SETOF:
219 case TBL_CHOICE:
220 /* look for contained type refs */
221 tmp = CURR_LIST_NODE (tblT->content->a.elmts);
222 FOR_EACH_LIST_ELMT (tblElmtT, tblT->content->a.elmts)
223 {
224 TblLinkTypeRefs (tbl, tblElmtT);
225 }
226 SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp);
227 break;
228
229 case TBL_TYPEREF:
230 /* convert type def index into a pointer to the type def */
231 tblT->content->a.typeRef->typeDefPtr =
232 TblFindTypeDefByIndex (tbl, tblT->content->a.typeRef->typeDef);
233 break;
234 }
235 } /* TblLinkTypeRefs */
236 void
237 TblFixTypeTags PARAMS ((tblT),
238 TBLType *tblT)
239 {
240 void *tmp;
241 TBLType *tblElmtT;
242
243 TblSetTagForms (tblT);
244 switch (tblT->typeId)
245 {
246 case TBL_SEQUENCE:
247 case TBL_SET:
248 case TBL_SEQUENCEOF:
249 case TBL_SETOF:
250 case TBL_CHOICE:
251 /* fix tags in elmt types */
252 tmp = CURR_LIST_NODE (tblT->content->a.elmts);
253 FOR_EACH_LIST_ELMT (tblElmtT, tblT->content->a.elmts)
254 {
255 TblFixTypeTags (tblElmtT);
256 }
257 SET_CURR_LIST_NODE (tblT->content->a.elmts, tmp);
258 break;
259
260 default:
261 break;
262 }
263 }
264
265 void
266 TblSetTagForms PARAMS ((tblT),
267 TBLType *tblT)
268 {
269 TBLTag *tblTag;
270 TBLType *tmpTblT;
271 int numTags;
272 TBLTypeId tid;
273 BER_FORM form;
274
275 if (tblT->tagList == NULL)
276 return;
277
278 numTags = LIST_COUNT (tblT->tagList);
279
280 /*
281 * get real type id (skip through type refs)
282 * count total number of tags too.
283 */
284 for (tmpTblT = tblT; tmpTblT->typeId == TBL_TYPEREF; tmpTblT = tmpTblT->content->a.typeRef->typeDefPtr->type)
285 {
286 if (tmpTblT->tagList)
287 numTags += LIST_COUNT (tmpTblT->tagList);
288 if (tmpTblT->content->a.typeRef->implicit)
289 numTags--;
290 }
291 tid = tmpTblT->typeId;
292
293 /* only traverse this types tags */
294 FOR_EACH_LIST_ELMT (tblTag, tblT->tagList)
295 {
296 if (numTags > 1)
297 form = tblTag->form = CONS;
298 else
299 switch (tid)
300 {
301 case TBL_SEQUENCE:
302 case TBL_SET:
303 case TBL_SEQUENCEOF:
304 case TBL_SETOF:
305 case TBL_CHOICE:
306 form = tblTag->form = CONS;
307 break;
308
309 case TBL_OCTETSTRING:
310 case TBL_BITSTRING:
311 tblTag->form = ANY_FORM;
312 form = PRIM; /* store as prim (for encoder - always prim) */
313 break;
314
315 default:
316 form = tblTag->form = PRIM;
317 break;
318 }
319
320 tblTag->encTag = MAKE_TAG_ID (TblTagClassToBer (tblTag->tclass), form, tblTag->code);
321 numTags--;
322 }
323 } /* TblSetTagForms */
324
325
326
327 TBLTypeDef*
328 TblFindTypeDef PARAMS ((tbl, modName, typeName, tblModHndl),
329 TBL *tbl _AND_
330 char *modName _AND_
331 char *typeName _AND_
332 TBLModule **tblModHndl)
333 {
334 TBLModule *tblMod;
335 TBLTypeDef *tblTd;
336 void *tmp;
337
338 /* look in named module only if given */
339 if (modName != NULL)
340 {
341 tblMod = TblFindModule (tbl, modName);
342 *tblModHndl = tblMod;
343 if (tblMod == NULL)
344 return NULL;
345
346 return TblFindTypeDefInMod (tblMod, typeName);
347 }
348 else /* look in all modules and return first instance */
349 {
350 tmp = CURR_LIST_NODE (tbl->modules);
351 FOR_EACH_LIST_ELMT (tblMod, tbl->modules)
352 {
353 tblTd = TblFindTypeDefInMod (tblMod, typeName);
354 if (tblTd != NULL)
355 {
356 *tblModHndl = tblMod;
357 SET_CURR_LIST_NODE (tbl->modules, tmp);
358 return tblTd;
359 }
360 }
361 SET_CURR_LIST_NODE (tbl->modules, tmp);
362 }
363 return NULL; /* not found */
364 } /* TblFindTypeDef */
365
366
367 TBLTypeDef*
368 TblFindTypeDefInMod PARAMS ((tblMod, typeName),
369 TBLModule *tblMod _AND_
370 char *typeName)
371 {
372 TBLTypeDef *tblTd;
373 void *tmp;
374
375 tmp = CURR_LIST_NODE (tblMod->typeDefs);
376 FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs)
377 {
378 if (strcmp (tblTd->typeName.octs, typeName) == 0)
379 {
380 SET_CURR_LIST_NODE (tblMod->typeDefs, tmp);
381 return tblTd;
382 }
383 }
384 SET_CURR_LIST_NODE (tblMod->typeDefs, tmp);
385 return NULL;
386 } /* TblFindTypeDefInMod */
387
388
389 TBLTypeDef*
390 TblFindTypeDefByIndex PARAMS ((tbl, id),
391 TBL *tbl _AND_
392 TBLTypeDefId id)
393 {
394 TBLModule *tblMod;
395 TBLTypeDef *tblTd;
396 void *tmp1;
397 void *tmp2;
398
399 /* look in all modules and return typedef with given id */
400 tmp1 = CURR_LIST_NODE (tbl->modules);
401 FOR_EACH_LIST_ELMT (tblMod, tbl->modules)
402 {
403 tmp2 = CURR_LIST_NODE (tblMod->typeDefs);
404 FOR_EACH_LIST_ELMT (tblTd, tblMod->typeDefs)
405 {
406 if (tblTd->typeDefId == id)
407 {
408 SET_CURR_LIST_NODE (tblMod->typeDefs, tmp2);
409 SET_CURR_LIST_NODE (tbl->modules, tmp1);
410 return tblTd;
411 }
412 }
413 SET_CURR_LIST_NODE (tblMod->typeDefs, tmp2);
414 }
415 SET_CURR_LIST_NODE (tbl->modules, tmp1);
416
417 return NULL;
418 } /* TblFindTypeDefByIndex */
419
420
421 TBLModule*
422 TblFindModule PARAMS ((tbl, modName),
423 TBL *tbl _AND_
424 char *modName)
425 {
426 TBLModule *tblMod;
427 void *tmp;
428
429 tmp = CURR_LIST_NODE (tbl->modules);
430 FOR_EACH_LIST_ELMT (tblMod, tbl->modules)
431 {
432 if (strcmp (tblMod->name.octs, modName) == 0)
433 {
434 SET_CURR_LIST_NODE (tbl->modules, tmp);
435 return tblMod;
436 }
437 }
438 SET_CURR_LIST_NODE (tbl->modules, tmp);
439 return NULL;
440
441 } /* TblFindModule */
442
443 #endif /* TTBL */