]> git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/compiler/back-ends/tag-util.c
Security-54.1.7.tar.gz
[apple/security.git] / SecuritySNACCRuntime / compiler / back-ends / tag-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 /*
20 * compiler/back_ends/c_gen/tag_util.c - utilities for dealing with tags
21 *
22 * MS 92
23 * Copyright (C) 1991, 1992 Michael Sample
24 * and the University of British Columbia
25 *
26 * This program is free software; you can redistribute it and/or modify
27 * it under the terms of the GNU General Public License as published by
28 * the Free Software Foundation; either version 2 of the License, or
29 * (at your option) any later version.
30 *
31 * INSERT_VDA_COMMENTS
32 *
33 * $Header: /cvs/root/Security/SecuritySNACCRuntime/compiler/back-ends/Attic/tag-util.c,v 1.1.1.1 2001/05/18 23:14:08 mb Exp $
34 * $Log: tag-util.c,v $
35 * Revision 1.1.1.1 2001/05/18 23:14:08 mb
36 * Move from private repository to open source repository
37 *
38 * Revision 1.2 2001/05/05 00:59:27 rmurphy
39 * Adding darwin license headers
40 *
41 * Revision 1.1.1.1 1999/03/16 18:06:39 aram
42 * Originals from SMIME Free Library.
43 *
44 * Revision 1.3 1995/07/25 18:15:28 rj
45 * changed `_' to `-' in file names.
46 *
47 * Revision 1.2 1994/09/01 00:26:07 rj
48 * snacc_config.h and other superfluous .h files removed.
49 *
50 * Revision 1.1 1994/08/28 09:48:39 rj
51 * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
52 *
53 */
54
55 #include <stdio.h>
56
57 #include "asn-incl.h"
58 #include "asn1module.h"
59 #include "mem.h"
60 #include "define.h"
61 #include "lib-types.h"
62 #include "c-gen/rules.h"
63 #include "c-gen/type-info.h"
64 #include "str-util.h"
65 #include "snacc-util.h"
66 #include "c-gen/util.h"
67 #include "tag-util.h"
68
69
70
71 /*
72 * returns the tags for the given type (stops at next type definition).
73 * if no tags have been grabbed yet and an untagged CHOICE is encountered,
74 * all of the CHOICE's top level tags are returned and the stoleChoiceTags
75 * flag is set. If the type has no tags an empty list is returned, not
76 * NULL.
77 *
78 * ASSUMES: tag list's and implicit flags have been adjusted according
79 * to module level IMPLICIT/EXPLICIT-TAGS and type level
80 * IMPLICIT/EXPLICIT tagging.
81 *
82 * EXAMPLE:
83 *
84 * typeX ::= SEQUENCE SomeChoice ::= CHOICE
85 * { {
86 * foo [0] INTEGER, [0] INTEGER,
87 * bar SomeChoice, [1] BOOLEAN,
88 * bell [1] IMPLICIT BOOLEAN, [2] IA5String
89 * gumby [2] SomeChoice, }
90 poki SomeOtherChoice
91 * }
92 *
93 * SomeOtherChoice ::= [APPLICATION 99] CHOICE { ....}
94 *
95 * GetTags (foo's type) --> CNTX 0, UNIV INTEGER_TAG_CODE stoleChoiceTags = FALSE
96 * GetTags (bar) --> CNTX 0, CNTX 1, CNTX 2 (SomeChoice Elmt's first Tags)
97 * stoleChoiceTags = TRUE
98 * GetTags (bell) --> CNTX 1 stoleChoiceTags = FALSE
99 * GetTags (gumby) --> CNTX 2 stoleChoiceTags = FALSE
100 * GetTags (poki) --> APPLICATION 99 stoleChoiceTags = FALSE
101 *
102 * MS 92/03/04 Added tag form information
103 */
104 TagList*
105 GetTags PARAMS ((t, stoleChoiceTags),
106 Type *t _AND_
107 int *stoleChoiceTags)
108 {
109 Tag *tag;
110 TagList *tl;
111 TagList *retVal;
112 Tag *last;
113 Tag *tagCopy;
114 Tag **tagHndl;
115 int implicitRef;
116 int stoleChoicesAgain;
117 NamedType *e;
118
119 tl = t->tags;
120 if (tl != NULL)
121 AsnListFirst (tl);
122
123 retVal = (TagList*) AsnListNew (sizeof (void*));
124 implicitRef = FALSE;
125 *stoleChoiceTags = FALSE;
126
127 for (;;)
128 {
129 /*
130 * go through tag list local to this type if any
131 */
132
133 FOR_REST_LIST_ELMT (tag, tl)
134 {
135 tagCopy = (Tag*)Malloc (sizeof (Tag));
136 memcpy (tagCopy, tag, sizeof (Tag));
137 tagHndl = (Tag**)AsnListAppend (retVal);
138 *tagHndl = tagCopy;
139
140 }
141
142 /*
143 * follow tags of referenced types
144 */
145
146 if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
147 (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
148 {
149 if (!implicitRef)
150 implicitRef = t->implicit;
151
152
153 if (t->basicType->a.localTypeRef->link == NULL)
154 {
155 fprintf (stderr,"ERROR - unresolved type ref, cannot get tags for decoding>\n");
156 break;
157 }
158 t = t->basicType->a.localTypeRef->link->type;
159 tl = t->tags;
160
161 if (tl != NULL)
162 {
163 AsnListFirst (tl); /* set curr ptr to first node */
164 if ((!LIST_EMPTY (tl)) && implicitRef)
165 {
166 AsnListNext (tl);
167 implicitRef = FALSE;
168 }
169 }
170
171 }
172
173 /*
174 * if untagged choice and no tags found yet
175 */
176 else if ((t->basicType->choiceId == BASICTYPE_CHOICE) && (LIST_EMPTY (retVal)))
177 {
178 /*
179 * Return list of top level tags from this choice
180 * and set "stoleChoiceTags" bool param
181 */
182 if (implicitRef)
183 fprintf (stderr,"ERROR - IMPLICITLY Tagged CHOICE\n");
184
185 *stoleChoiceTags = TRUE;
186
187 FOR_EACH_LIST_ELMT (e, t->basicType->a.choice)
188 {
189 stoleChoicesAgain = FALSE;
190 tl = GetTags (e->type, &stoleChoicesAgain);
191
192 if (tl == NULL)
193 break;
194
195 AsnListFirst (tl);
196 if (stoleChoicesAgain)
197 {
198 FOR_EACH_LIST_ELMT (tag, tl)
199 {
200 tagCopy = (Tag*)Malloc (sizeof (Tag));
201 memcpy (tagCopy, tag, sizeof (Tag));
202 tagHndl = (Tag**)AsnListAppend (retVal);
203 *tagHndl = tagCopy;
204
205 }
206 }
207 else
208 {
209 tag = (Tag*)FIRST_LIST_ELMT (tl);
210 tagCopy = (Tag*)Malloc (sizeof (Tag));
211 memcpy (tagCopy, tag, sizeof (Tag));
212 tagHndl = (Tag**)AsnListAppend (retVal);
213 *tagHndl = tagCopy;
214 }
215 FreeTags (tl);
216 }
217
218 break; /* exit for loop */
219 }
220
221 else
222 break; /* exit for loop */
223 }
224
225
226 if (!*stoleChoiceTags && (retVal != NULL) && !LIST_EMPTY (retVal))
227 {
228 last = (Tag*)LAST_LIST_ELMT (retVal);
229 FOR_EACH_LIST_ELMT (tag, retVal)
230 {
231 tag->form = CONS;
232 }
233 last->form = LIBTYPE_GET_TAG_FORM (GetBuiltinType (t));
234 }
235
236 AsnListFirst (retVal);
237 return retVal;
238
239 } /* GetTags */
240
241
242 void
243 FreeTags PARAMS ((tl),
244 TagList *tl)
245 {
246 Tag *tag;
247 AsnListNode *listNode;
248 AsnListNode *ln;
249
250 /* free tags */
251 FOR_EACH_LIST_ELMT (tag, tl)
252 {
253 Free (tag);
254 }
255
256 /* free list nodes */
257 for (ln = FIRST_LIST_NODE (tl); ln != NULL; )
258 {
259 listNode = ln;
260 ln = ln->next;
261 Free (listNode);
262 }
263
264 /* free list head */
265 Free (tl);
266
267 } /* FreeTags */
268
269 /*
270 * Returns the number of tags that GetTags would return for
271 * the same type.
272 */
273 int
274 CountTags PARAMS ((t),
275 Type *t)
276 {
277 int tagCount;
278 Tag *tag;
279 TagList *tl;
280 int implicitRef;
281 int stoleChoicesAgain;
282 NamedType *e;
283
284 tl = t->tags;
285 if (tl != NULL)
286 AsnListFirst (tl);
287
288 tagCount = 0;
289 implicitRef = FALSE;
290
291 for (;;)
292 {
293 /*
294 * go through tag list local to this type if any
295 */
296
297 FOR_REST_LIST_ELMT (tag, tl)
298 {
299 tagCount++;
300 }
301
302 /*
303 * follow tags of referenced types
304 */
305
306 if ((t->basicType->choiceId == BASICTYPE_LOCALTYPEREF) ||
307 (t->basicType->choiceId == BASICTYPE_IMPORTTYPEREF))
308 {
309 if (!implicitRef)
310 implicitRef = t->implicit;
311
312
313 if (t->basicType->a.localTypeRef->link == NULL)
314 {
315 fprintf (stderr,"ERROR - unresolved type ref, cannot get tags for decoding>\n");
316 break;
317 }
318 t = t->basicType->a.localTypeRef->link->type;
319 tl = t->tags;
320
321 if (tl != NULL)
322 {
323 AsnListFirst (tl); /* set curr ptr to first node */
324 if ((!LIST_EMPTY (tl)) && implicitRef)
325 {
326 AsnListNext (tl);
327 implicitRef = FALSE;
328 }
329 }
330
331 }
332 else
333 break;
334 }
335
336 return tagCount;
337
338 } /* CountTags */
339
340
341 unsigned long int
342 TagByteLen PARAMS ((tagCode),
343 unsigned long int tagCode)
344 {
345 unsigned long int tagLen;
346
347 if (tagCode < 31)
348 tagLen = 1;
349 else if (tagCode < 128)
350 tagLen = 2;
351 else if (tagCode < 16384)
352 tagLen = 3;
353 else if (tagCode < 2097152)
354 tagLen = 4;
355 else
356 tagLen = 5;
357
358 return tagLen;
359 } /* TagByteLen */
360
361
362
363 char*
364 Class2ClassStr PARAMS ((class),
365 int class)
366 {
367 switch (class)
368 {
369 case UNIV:
370 return "UNIV";
371 break;
372
373 case APPL:
374 return "APPL";
375 break;
376
377 case CNTX:
378 return "CNTX";
379 break;
380
381 case PRIV:
382 return "PRIV";
383 break;
384
385 default:
386 return "UNKNOWN";
387 break;
388 }
389 } /* Class2ClassStr */
390
391
392
393 char*
394 Form2FormStr PARAMS ((form),
395 BER_FORM form)
396 {
397 switch (form)
398 {
399 case PRIM:
400 return "PRIM";
401 break;
402
403 case CONS:
404 return "CONS";
405 break;
406
407 default:
408 return "UNKNOWN";
409 break;
410 }
411 } /* Form2FormStr */
412
413
414
415 char*
416 Code2UnivCodeStr PARAMS ((code),
417 BER_UNIV_CODE code)
418 {
419 switch (code)
420 {
421 case BOOLEAN_TAG_CODE:
422 return "BOOLEAN_TAG_CODE";
423 break;
424
425 case INTEGER_TAG_CODE:
426 return "INTEGER_TAG_CODE";
427 break;
428
429 case BITSTRING_TAG_CODE:
430 return "BITSTRING_TAG_CODE";
431 break;
432
433 case OCTETSTRING_TAG_CODE:
434 return "OCTETSTRING_TAG_CODE";
435 break;
436
437 case NULLTYPE_TAG_CODE:
438 return "NULLTYPE_TAG_CODE";
439 break;
440
441 case OID_TAG_CODE:
442 return "OID_TAG_CODE";
443 break;
444
445 case OD_TAG_CODE:
446 return "OD_TAG_CODE";
447 break;
448
449 case EXTERNAL_TAG_CODE:
450 return "EXTERNAL_TAG_CODE";
451 break;
452
453 case REAL_TAG_CODE:
454 return "REAL_TAG_CODE";
455 break;
456
457 case ENUM_TAG_CODE:
458 return "ENUM_TAG_CODE";
459 break;
460
461 case SEQ_TAG_CODE:
462 return "SEQ_TAG_CODE";
463 break;
464
465 case SET_TAG_CODE:
466 return "SET_TAG_CODE";
467 break;
468
469 case NUMERICSTRING_TAG_CODE:
470 return "NUMERICSTRING_TAG_CODE";
471 break;
472
473 case PRINTABLESTRING_TAG_CODE:
474 return "PRINTABLESTRING_TAG_CODE";
475 break;
476
477 case TELETEXSTRING_TAG_CODE:
478 return "TELETEXSTRING_TAG_CODE";
479 break;
480
481 case VIDEOTEXSTRING_TAG_CODE:
482 return "VIDEOTEXSTRING_TAG_CODE";
483 break;
484
485 case IA5STRING_TAG_CODE:
486 return "IA5STRING_TAG_CODE";
487 break;
488
489 case UTCTIME_TAG_CODE:
490 return "UTCTIME_TAG_CODE";
491 break;
492
493 case GENERALIZEDTIME_TAG_CODE:
494 return "GENERALIZEDTIME_TAG_CODE";
495 break;
496
497 case GRAPHICSTRING_TAG_CODE:
498 return "GRAPHICSTRING_TAG_CODE";
499 break;
500
501 case VISIBLESTRING_TAG_CODE:
502 return "VISIBLESTRING_TAG_CODE";
503 break;
504
505 case GENERALSTRING_TAG_CODE:
506 return "GENERALSTRING_TAG_CODE";
507 break;
508
509 #ifdef VDADER_RULES
510
511 case UNIVERSALSTRING_TAG_CODE:
512 return "UNIVERSALSTRING_TAG_CODE";
513 break;
514
515 case BMPSTRING_TAG_CODE:
516 return "BMPSTRING_TAG_CODE";
517 break;
518
519 default:
520 {
521 /* if the universal type is not known then just return the
522 * unvisersal tag code. This is useful for defining new types
523 * in local modules w/o having to modify the compiler.
524 */
525 static char retstring[3];
526 sprintf(retstring, "%d", code);
527 return retstring;
528 }
529 #else
530
531 default:
532 return "UNKNOWN";
533 #endif
534
535 }
536 } /* TagId2FormStr */