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