/src/nss/lib/util/secasn1u.c
Line | Count | Source (jump to first uncovered line) |
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 | | |
9 | | #include "secasn1.h" |
10 | | |
11 | | /* |
12 | | * We have a length that needs to be encoded; how many bytes will the |
13 | | * encoding take? |
14 | | * |
15 | | * The rules are that 0 - 0x7f takes one byte (the length itself is the |
16 | | * entire encoding); everything else takes one plus the number of bytes |
17 | | * in the length. |
18 | | */ |
19 | | int |
20 | | SEC_ASN1LengthLength(unsigned long len) |
21 | 287k | { |
22 | 287k | int lenlen = 1; |
23 | | |
24 | 287k | if (len > 0x7f) { |
25 | 1.49k | do { |
26 | 1.49k | lenlen++; |
27 | 1.49k | len >>= 8; |
28 | 1.49k | } while (len); |
29 | 1.49k | } |
30 | | |
31 | 287k | return lenlen; |
32 | 287k | } |
33 | | |
34 | | /* |
35 | | * XXX Move over (and rewrite as appropriate) the rest of the |
36 | | * stuff in dersubr.c! |
37 | | */ |
38 | | |
39 | | /* |
40 | | * Find the appropriate subtemplate for the given template. |
41 | | * This may involve calling a "chooser" function, or it may just |
42 | | * be right there. In either case, it is expected to *have* a |
43 | | * subtemplate; this is asserted in debug builds (in non-debug |
44 | | * builds, NULL will be returned). |
45 | | * |
46 | | * "thing" is a pointer to the structure being encoded/decoded |
47 | | * "encoding", when true, means that we are in the process of encoding |
48 | | * (as opposed to in the process of decoding) |
49 | | */ |
50 | | const SEC_ASN1Template * |
51 | | SEC_ASN1GetSubtemplate(const SEC_ASN1Template *theTemplate, void *thing, |
52 | | PRBool encoding) |
53 | 2.62M | { |
54 | 2.62M | const SEC_ASN1Template *subt = NULL; |
55 | | |
56 | 2.62M | PORT_Assert(theTemplate->sub != NULL); |
57 | 2.62M | if (theTemplate->sub != NULL) { |
58 | 2.62M | if (theTemplate->kind & SEC_ASN1_DYNAMIC) { |
59 | 5.84k | SEC_ASN1TemplateChooserPtr chooserp; |
60 | | |
61 | 5.84k | chooserp = *(SEC_ASN1TemplateChooserPtr *)theTemplate->sub; |
62 | 5.84k | if (chooserp) { |
63 | 5.84k | if (thing != NULL) |
64 | 5.84k | thing = (char *)thing - theTemplate->offset; |
65 | 5.84k | subt = (*chooserp)(thing, encoding); |
66 | 5.84k | } |
67 | 2.61M | } else { |
68 | 2.61M | subt = (SEC_ASN1Template *)theTemplate->sub; |
69 | 2.61M | } |
70 | 2.62M | } |
71 | 2.62M | return subt; |
72 | 2.62M | } |
73 | | |
74 | | PRBool |
75 | | SEC_ASN1IsTemplateSimple(const SEC_ASN1Template *theTemplate) |
76 | 0 | { |
77 | 0 | if (!theTemplate) { |
78 | 0 | return PR_TRUE; /* it doesn't get any simpler than NULL */ |
79 | 0 | } |
80 | | /* only templates made of one primitive type or a choice of primitive |
81 | | types are considered simple */ |
82 | 0 | if (!(theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK))) { |
83 | 0 | return PR_TRUE; /* primitive type */ |
84 | 0 | } |
85 | 0 | if (!(theTemplate->kind & SEC_ASN1_CHOICE)) { |
86 | 0 | return PR_FALSE; /* no choice means not simple */ |
87 | 0 | } |
88 | 0 | while (++theTemplate && theTemplate->kind) { |
89 | 0 | if (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK)) { |
90 | 0 | return PR_FALSE; /* complex type */ |
91 | 0 | } |
92 | 0 | } |
93 | 0 | return PR_TRUE; /* choice of primitive types */ |
94 | 0 | } |