OLD | NEW |
| (Empty) |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 | |
5 /* | |
6 * Utility routines to complement the ASN.1 encoding and decoding functions. | |
7 * | |
8 * $Id: secasn1u.c,v 1.6 2012/04/25 14:50:16 gerv%gerv.net Exp $ | |
9 */ | |
10 | |
11 #include "secasn1.h" | |
12 | |
13 | |
14 /* | |
15 * We have a length that needs to be encoded; how many bytes will the | |
16 * encoding take? | |
17 * | |
18 * The rules are that 0 - 0x7f takes one byte (the length itself is the | |
19 * entire encoding); everything else takes one plus the number of bytes | |
20 * in the length. | |
21 */ | |
22 int | |
23 SEC_ASN1LengthLength (unsigned long len) | |
24 { | |
25 int lenlen = 1; | |
26 | |
27 if (len > 0x7f) { | |
28 do { | |
29 lenlen++; | |
30 len >>= 8; | |
31 } while (len); | |
32 } | |
33 | |
34 return lenlen; | |
35 } | |
36 | |
37 | |
38 /* | |
39 * XXX Move over (and rewrite as appropriate) the rest of the | |
40 * stuff in dersubr.c! | |
41 */ | |
42 | |
43 | |
44 /* | |
45 * Find the appropriate subtemplate for the given template. | |
46 * This may involve calling a "chooser" function, or it may just | |
47 * be right there. In either case, it is expected to *have* a | |
48 * subtemplate; this is asserted in debug builds (in non-debug | |
49 * builds, NULL will be returned). | |
50 * | |
51 * "thing" is a pointer to the structure being encoded/decoded | |
52 * "encoding", when true, means that we are in the process of encoding | |
53 * (as opposed to in the process of decoding) | |
54 */ | |
55 const SEC_ASN1Template * | |
56 SEC_ASN1GetSubtemplate (const SEC_ASN1Template *theTemplate, void *thing, | |
57 PRBool encoding) | |
58 { | |
59 const SEC_ASN1Template *subt = NULL; | |
60 | |
61 PORT_Assert (theTemplate->sub != NULL); | |
62 if (theTemplate->sub != NULL) { | |
63 if (theTemplate->kind & SEC_ASN1_DYNAMIC) { | |
64 SEC_ASN1TemplateChooserPtr chooserp; | |
65 | |
66 chooserp = *(SEC_ASN1TemplateChooserPtr *) theTemplate->sub; | |
67 if (chooserp) { | |
68 if (thing != NULL) | |
69 thing = (char *)thing - theTemplate->offset; | |
70 subt = (* chooserp)(thing, encoding); | |
71 } | |
72 } else { | |
73 subt = (SEC_ASN1Template*)theTemplate->sub; | |
74 } | |
75 } | |
76 return subt; | |
77 } | |
78 | |
79 PRBool SEC_ASN1IsTemplateSimple(const SEC_ASN1Template *theTemplate) | |
80 { | |
81 if (!theTemplate) { | |
82 return PR_TRUE; /* it doesn't get any simpler than NULL */ | |
83 } | |
84 /* only templates made of one primitive type or a choice of primitive | |
85 types are considered simple */ | |
86 if (! (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK))) { | |
87 return PR_TRUE; /* primitive type */ | |
88 } | |
89 if (!(theTemplate->kind & SEC_ASN1_CHOICE)) { | |
90 return PR_FALSE; /* no choice means not simple */ | |
91 } | |
92 while (++theTemplate && theTemplate->kind) { | |
93 if (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK)) { | |
94 return PR_FALSE; /* complex type */ | |
95 } | |
96 } | |
97 return PR_TRUE; /* choice of primitive types */ | |
98 } | |
99 | |
OLD | NEW |