| 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 |