]>
git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/c-lib/src/tbl-dec.c
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
22 * tbl_dec.c - type table decoder.
27 * Copyright (C) 1993 Michael Sample
28 * and the University of British Columbia
30 * This library is free software; you can redistribute it and/or
31 * modify it provided that this copyright/license information is retained
34 * If you modify this file, you must clearly indicate your changes.
36 * This source code is distributed in the hope that it will be
37 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
38 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
45 int TagsMatch
PROTO ((TBLType
*tblT
, AsnTag asnTag
));
46 void TblPopTagsAndLens
PROTO ((TBLType
*tblT
, BUF_TYPE b
, int implicit
, unsigned long int *bytesDecoded
, ENV_TYPE env
));
48 void TblDecodeTagsAndLens
PROTO ((TBLType
*tblT
, BUF_TYPE b
, int implicit
, ENV_TYPE env
));
50 int CountMandatoryElmts
PROTO ((TBLType
*tblT
));
53 typedef struct TagNLen
57 unsigned int size
; /* encoded len for this tag len pair */
60 #define TL_STK_SIZE 128
61 static TagNLen tlStkG
[TL_STK_SIZE
];
62 static int nextFreeTLG
= 0;
64 #define PUSH_TL(t,l,sz, env)\
65 { if (nextFreeTLG >= TL_STK_SIZE)\
66 longjmp (env, -1000);\
67 tlStkG[nextFreeTLG].tag = t;\
68 tlStkG[nextFreeTLG].len = l;\
69 tlStkG[nextFreeTLG++].size = sz; }
74 longjmp (env, -1001);}
76 #define LAST_TAG() (tlStkG[nextFreeTLG-1].tag)
77 #define LAST_LEN() (tlStkG[nextFreeTLG-1].len)
78 #define LAST_SIZE() (tlStkG[nextFreeTLG-1].size)
83 TblDecode
PARAMS ((tbl
, modName
, typeName
, b
, bytesDecoded
),
88 unsigned long int *bytesDecoded
)
96 tblTd
= TblFindTypeDef (tbl
, modName
, typeName
, &tblMod
);
99 TblError ("TblDecode: Could not find a type definition with the given module and name");
104 if ((val
= setjmp (env
)) == 0)
106 retVal
= TblDecodeType (tblTd
->type
, b
, FALSE
, bytesDecoded
, env
);
112 fprintf (stderr
,"ack! longjmp error number: %d\n", val
);
119 TblDecodeType
PARAMS ((tblT
, b
, implicit
, bytesDecoded
, env
),
123 unsigned long int *bytesDecoded _AND_
127 unsigned long int tmpBytesDecoded
= 0;
128 unsigned int currElmt
;
129 TBLType
*listElmtType
;
130 TBLType
*structElmtType
;
131 TBLType
*choiceElmtType
;
137 int i
, mandatoryCount
, mandatoryElmts
;
142 TblDecodeTagsAndLens (tblT
, b
, implicit
, env
);
144 switch (tblT
->typeId
)
148 * carry over implicit ref if goes
149 * through typeref with no tags
151 implicitRef
= tblT
->content
->a
.typeRef
->implicit
||
153 ((tblT
->tagList
== NULL
) || LIST_EMPTY (tblT
->tagList
)));
155 retVal
= TblDecodeType (tblT
->content
->a
.typeRef
->typeDefPtr
->type
, b
, implicitRef
, &tmpBytesDecoded
, env
);
159 /* go fwd though elmt type list */
161 sVal
= (AStructVal
*) Asn1Alloc (sizeof (AVal
*)*
162 LIST_COUNT (tblT
->content
->a
.elmts
));
163 tmp
= CURR_LIST_NODE (tblT
->content
->a
.elmts
);
164 FOR_EACH_LIST_ELMT (structElmtType
, tblT
->content
->a
.elmts
)
166 if (TagsMatch (structElmtType
, PeekTag (b
,env
)))
168 sVal
[currElmt
] = TblDecodeType (structElmtType
, b
, FALSE
, &tmpBytesDecoded
, env
);
170 else if (!structElmtType
->optional
)
175 SET_CURR_LIST_NODE (tblT
->content
->a
.elmts
, tmp
);
176 retVal
= (AVal
*) sVal
;
180 sVal
= (AStructVal
*) Asn1Alloc (sizeof (AVal
*)*
181 LIST_COUNT (tblT
->content
->a
.elmts
));
183 mandatoryElmts
= CountMandatoryElmts (tblT
);
184 if (LAST_LEN() == INDEFINITE_LEN
)
187 asnTag
= PeekTag (b
,env
);
189 /* find elmt that matches the peeked tag */
190 FOR_EACH_LIST_ELMT (structElmtType
, tblT
->content
->a
.elmts
)
192 if (TagsMatch (structElmtType
, asnTag
))
197 /* didn't find a match */
198 if (currElmt
>= LIST_COUNT (tblT
->content
->a
.elmts
))
201 if (!structElmtType
->optional
)
204 sVal
[currElmt
] = TblDecodeType (structElmtType
, b
, FALSE
, &tmpBytesDecoded
, env
);
207 while (tmpBytesDecoded
< LAST_LEN())
209 asnTag
= PeekTag (b
,env
);
211 /* find elmt that matches the peeked tag */
212 FOR_EACH_LIST_ELMT (structElmtType
, tblT
->content
->a
.elmts
)
214 if (TagsMatch (structElmtType
, asnTag
))
219 if (currElmt
>= LIST_COUNT (tblT
->content
->a
.elmts
))
220 longjmp (env
, -1007);
222 if (!structElmtType
->optional
)
225 sVal
[currElmt
] = TblDecodeType (structElmtType
, b
, FALSE
, &tmpBytesDecoded
, env
);
227 if (mandatoryCount
!= mandatoryElmts
)
237 retVal
= (AsnList
*)Asn1Alloc (sizeof (AsnList
));
238 listElmtType
= FIRST_LIST_ELMT (tblT
->content
->a
.elmts
);
240 if (LAST_LEN() == INDEFINITE_LEN
)
243 elmtVPtr
= TblDecodeType (listElmtType
, b
, FALSE
, &tmpBytesDecoded
, env
);
244 tmpHndl
= AsnListAppend ((AsnList
*)retVal
);
248 while (tmpBytesDecoded
< LAST_LEN())
250 elmtVPtr
= TblDecodeType (listElmtType
, b
, FALSE
, &tmpBytesDecoded
, env
);
251 tmpHndl
= AsnListAppend ((AsnList
*)retVal
);
258 retVal
= cVal
= (AChoiceVal
*) Asn1Alloc (sizeof (AChoiceVal
));
259 asnTag
= PeekTag (b
,env
);
261 /* find elmt that matches the peeked tag */
262 tmp
= CURR_LIST_NODE (tblT
->content
->a
.elmts
);
263 FOR_EACH_LIST_ELMT (choiceElmtType
, tblT
->content
->a
.elmts
)
265 if (TagsMatch (choiceElmtType
, asnTag
))
272 SET_CURR_LIST_NODE (tblT
->content
->a
.elmts
, tmp
);
273 cVal
->val
= TblDecodeType (choiceElmtType
, b
, FALSE
, &tmpBytesDecoded
, env
);
277 retVal
= Asn1Alloc (sizeof (AsnBool
));
278 BDecAsnBoolContent (b
, LAST_TAG(), LAST_LEN(), (AsnBool
*) retVal
, &tmpBytesDecoded
, env
);
283 retVal
= Asn1Alloc (sizeof (AsnInt
));
284 BDecAsnIntContent (b
, LAST_TAG(), LAST_LEN(), (AsnInt
*) retVal
, &tmpBytesDecoded
, env
);
288 retVal
= Asn1Alloc (sizeof (AsnBits
));
289 BDecAsnBitsContent (b
, LAST_TAG(), LAST_LEN(), (AsnBits
*) retVal
, &tmpBytesDecoded
, env
);
292 case TBL_OCTETSTRING
:
293 retVal
= Asn1Alloc (sizeof (AsnOcts
));
294 BDecAsnOctsContent (b
, LAST_TAG(), LAST_LEN(), (AsnOcts
*) retVal
, &tmpBytesDecoded
, env
);
298 retVal
= Asn1Alloc (sizeof (AsnNull
));
299 BDecAsnNullContent (b
, LAST_TAG(), LAST_LEN(), (AsnNull
*) retVal
, &tmpBytesDecoded
, env
);
303 retVal
= Asn1Alloc (sizeof (AsnOid
));
304 BDecAsnOidContent (b
, LAST_TAG(), LAST_LEN(), (AsnOid
*) retVal
, &tmpBytesDecoded
, env
);
308 retVal
= Asn1Alloc (sizeof (AsnReal
));
309 BDecAsnRealContent (b
, LAST_TAG(), LAST_LEN(), (AsnReal
*) retVal
, &tmpBytesDecoded
, env
);
317 TblPopTagsAndLens (tblT
, b
, implicit
, &tmpBytesDecoded
, env
);
319 (*bytesDecoded
) += tmpBytesDecoded
;
323 } /* TblDecodeType */
327 TblDecodeTagsAndLens
PARAMS ((tblT
, b
, implicit
, env
),
338 if ((tblT
->tagList
== NULL
) || (LIST_EMPTY (tblT
->tagList
)))
341 SET_CURR_LIST_NODE (tblT
->tagList
, FIRST_LIST_NODE (tblT
->tagList
));
344 SET_CURR_LIST_NODE (tblT
->tagList
, NEXT_LIST_NODE (tblT
->tagList
));
348 FOR_REST_LIST_ELMT (tblTag
, tblT
->tagList
)
351 tag
= BDecTag (b
, &encSize
, env
);
352 len
= BDecLen (b
, &encSize
, env
);
354 if (!TagsEquiv (tag
, tblTag
))
355 longjmp (env
, -1002);
357 PUSH_TL (tag
, len
, encSize
, env
);
359 } /* TblDecodeTagsAndLens */
362 * bytesDecoded should hold the length of the content that
363 * was just decoded. This verifies the lengths as it pops
364 * them off the stack. Also decodes EOCs.
367 TblPopTagsAndLens
PARAMS ((tblT
, b
, implicit
, bytesDecoded
, env
),
371 unsigned long int *bytesDecoded _AND_
376 FOR_EACH_LIST_ELMT_RVS (tblTag
, tblT
->tagList
)
378 if (implicit
&& (tblTag
== FIRST_LIST_ELMT (tblT
->tagList
)))
381 if (LAST_LEN() == INDEFINITE_LEN
)
382 BDecEoc (b
, bytesDecoded
, env
);
383 else if (*bytesDecoded
!= LAST_LEN())
384 longjmp (env
, -1003);
386 (*bytesDecoded
) += LAST_SIZE();
389 } /* TblPopTagsAndLens */
392 int TagsMatch
PARAMS ((tblT
, asnTag
),
402 * skip through type refs until encounter first tag or
403 * untagged CHOICE (only TYPEREFs and CHOICEs can
404 * have empty tag lists).
406 for (tmpTblT
= tblT
; ((tmpTblT
->typeId
== TBL_TYPEREF
) &&
407 ((tmpTblT
->tagList
== NULL
) || LIST_EMPTY (tmpTblT
->tagList
)));
408 tmpTblT
= tmpTblT
->content
->a
.typeRef
->typeDefPtr
->type
);
412 * if untagged CHOICE must check for a match with the first tag
413 * of each component of the CHOICE
415 if ((tmpTblT
->typeId
== TBL_CHOICE
) &&
416 ((tmpTblT
->tagList
== NULL
) || LIST_EMPTY (tmpTblT
->tagList
)))
418 tmp
= CURR_LIST_NODE (tmpTblT
->content
->a
.elmts
);
419 FOR_EACH_LIST_ELMT (elmtTblT
, tmpTblT
->content
->a
.elmts
)
422 * remember the elmt type can be an untagged choice too
423 * so call TagsMatch again.
425 if (TagsMatch (elmtTblT
, asnTag
))
427 SET_CURR_LIST_NODE (tmpTblT
->content
->a
.elmts
, tmp
);
428 return TRUE
; /* match in choice */
431 SET_CURR_LIST_NODE (tmpTblT
->content
->a
.elmts
, tmp
);
432 return FALSE
; /* no match in choice */
434 else /* is type other than untagged choice or type ref */
436 tblTag
= FIRST_LIST_ELMT (tmpTblT
->tagList
);
437 return TagsEquiv (asnTag
, tblTag
);
443 CountMandatoryElmts
PARAMS ((tblT
),
448 FOR_EACH_LIST_ELMT (tblElmtT
, tblT
->content
->a
.elmts
)
450 if (!tblElmtT
->optional
)
454 } /* CountMandatoryElmts */