| 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 | * Types for encoding/decoding of ASN.1 using BER/DER (Basic/Distinguished |
| 7 | * Encoding Rules). |
| 8 | */ |
| 9 | |
| 10 | #ifndef _SECASN1T_H_ |
| 11 | #define _SECASN1T_H_ |
| 12 | |
| 13 | #include "utilrename.h" |
| 14 | |
| 15 | /* |
| 16 | ** An array of these structures defines a BER/DER encoding for an object. |
| 17 | ** |
| 18 | ** The array usually starts with a dummy entry whose kind is SEC_ASN1_SEQUENCE; |
| 19 | ** such an array is terminated with an entry where kind == 0. (An array |
| 20 | ** which consists of a single component does not require a second dummy |
| 21 | ** entry -- the array is only searched as long as previous component(s) |
| 22 | ** instruct it.) |
| 23 | */ |
| 24 | typedef struct sec_ASN1Template_struct { |
| 25 | /* |
| 26 | ** Kind of item being decoded/encoded, including tags and modifiers. |
| 27 | */ |
| 28 | unsigned long kind; |
| 29 | |
| 30 | /* |
| 31 | ** The value is the offset from the base of the structure to the |
| 32 | ** field that holds the value being decoded/encoded. |
| 33 | */ |
| 34 | unsigned long offset; |
| 35 | |
| 36 | /* |
| 37 | ** When kind suggests it (SEC_ASN1_POINTER, SEC_ASN1_GROUP, SEC_ASN1_INLINE, |
| 38 | ** or a component that is *not* a SEC_ASN1_UNIVERSAL), this points to |
| 39 | ** a sub-template for nested encoding/decoding, |
| 40 | ** OR, iff SEC_ASN1_DYNAMIC is set, then this is a pointer to a pointer |
| 41 | ** to a function which will return the appropriate template when called |
| 42 | ** at runtime. NOTE! that explicit level of indirection, which is |
| 43 | ** necessary because ANSI does not allow you to store a function |
| 44 | ** pointer directly as a "void *" so we must store it separately and |
| 45 | ** dereference it to get at the function pointer itself. |
| 46 | */ |
| 47 | const void *sub; |
| 48 | |
| 49 | /* |
| 50 | ** In the first element of a template array, the value is the size |
| 51 | ** of the structure to allocate when this template is being referenced |
| 52 | ** by another template via SEC_ASN1_POINTER or SEC_ASN1_GROUP. |
| 53 | ** In all other cases, the value is ignored. |
| 54 | */ |
| 55 | unsigned int size; |
| 56 | } SEC_ASN1Template; |
| 57 | |
| 58 | /* default size used for allocation of encoding/decoding stuff */ |
| 59 | /* XXX what is the best value here? */ |
| 60 | #define SEC_ASN1_DEFAULT_ARENA_SIZE (2048) |
| 61 | |
| 62 | /* |
| 63 | ** BER/DER values for ASN.1 identifier octets. |
| 64 | */ |
| 65 | #define SEC_ASN1_TAG_MASK 0xff |
| 66 | |
| 67 | /* |
| 68 | * BER/DER universal type tag numbers. |
| 69 | * The values are defined by the X.208 standard; do not change them! |
| 70 | * NOTE: if you add anything to this list, you must add code to secasn1d.c |
| 71 | * to accept the tag, and probably also to secasn1e.c to encode it. |
| 72 | * XXX It appears some have been added recently without being added to |
| 73 | * the code; so need to go through the list now and double-check them all. |
| 74 | * (Look especially at those added in revision 1.10.) |
| 75 | */ |
| 76 | #define SEC_ASN1_TAGNUM_MASK 0x1f |
| 77 | #define SEC_ASN1_BOOLEAN 0x01 |
| 78 | #define SEC_ASN1_INTEGER 0x02 |
| 79 | #define SEC_ASN1_BIT_STRING 0x03 |
| 80 | #define SEC_ASN1_OCTET_STRING 0x04 |
| 81 | #define SEC_ASN1_NULL 0x05 |
| 82 | #define SEC_ASN1_OBJECT_ID 0x06 |
| 83 | #define SEC_ASN1_OBJECT_DESCRIPTOR 0x07 |
| 84 | /* External type and instance-of type 0x08 */ |
| 85 | #define SEC_ASN1_REAL 0x09 |
| 86 | #define SEC_ASN1_ENUMERATED 0x0a |
| 87 | #define SEC_ASN1_EMBEDDED_PDV 0x0b |
| 88 | #define SEC_ASN1_UTF8_STRING 0x0c |
| 89 | /* 0x0d */ |
| 90 | /* 0x0e */ |
| 91 | /* 0x0f */ |
| 92 | #define SEC_ASN1_SEQUENCE 0x10 |
| 93 | #define SEC_ASN1_SET 0x11 |
| 94 | #define SEC_ASN1_NUMERIC_STRING 0x12 |
| 95 | #define SEC_ASN1_PRINTABLE_STRING 0x13 |
| 96 | #define SEC_ASN1_T61_STRING 0x14 |
| 97 | #define SEC_ASN1_VIDEOTEX_STRING 0x15 |
| 98 | #define SEC_ASN1_IA5_STRING 0x16 |
| 99 | #define SEC_ASN1_UTC_TIME 0x17 |
| 100 | #define SEC_ASN1_GENERALIZED_TIME 0x18 |
| 101 | #define SEC_ASN1_GRAPHIC_STRING 0x19 |
| 102 | #define SEC_ASN1_VISIBLE_STRING 0x1a |
| 103 | #define SEC_ASN1_GENERAL_STRING 0x1b |
| 104 | #define SEC_ASN1_UNIVERSAL_STRING 0x1c |
| 105 | /* 0x1d */ |
| 106 | #define SEC_ASN1_BMP_STRING 0x1e |
| 107 | #define SEC_ASN1_HIGH_TAG_NUMBER 0x1f |
| 108 | #define SEC_ASN1_TELETEX_STRING SEC_ASN1_T61_STRING |
| 109 | |
| 110 | /* |
| 111 | ** Modifiers to type tags. These are also specified by a/the |
| 112 | ** standard, and must not be changed. |
| 113 | */ |
| 114 | |
| 115 | #define SEC_ASN1_METHOD_MASK 0x20 |
| 116 | #define SEC_ASN1_PRIMITIVE 0x00 |
| 117 | #define SEC_ASN1_CONSTRUCTED 0x20 |
| 118 | |
| 119 | #define SEC_ASN1_CLASS_MASK 0xc0 |
| 120 | #define SEC_ASN1_UNIVERSAL 0x00 |
| 121 | #define SEC_ASN1_APPLICATION 0x40 |
| 122 | #define SEC_ASN1_CONTEXT_SPECIFIC 0x80 |
| 123 | #define SEC_ASN1_PRIVATE 0xc0 |
| 124 | |
| 125 | /* |
| 126 | ** Our additions, used for templates. |
| 127 | ** These are not defined by any standard; the values are used internally only. |
| 128 | ** Just be careful to keep them out of the low 8 bits. |
| 129 | ** XXX finish comments |
| 130 | */ |
| 131 | #define SEC_ASN1_OPTIONAL 0x00100 |
| 132 | #define SEC_ASN1_EXPLICIT 0x00200 |
| 133 | #define SEC_ASN1_ANY 0x00400 |
| 134 | #define SEC_ASN1_INLINE 0x00800 |
| 135 | #define SEC_ASN1_POINTER 0x01000 |
| 136 | #define SEC_ASN1_GROUP 0x02000 /* with SET or SEQUENCE means \ |
| 137 | * SET OF or SEQUENCE OF */ |
| 138 | #define SEC_ASN1_DYNAMIC 0x04000 /* subtemplate is found by calling \ |
| 139 | * a function at runtime */ |
| 140 | #define SEC_ASN1_SKIP 0x08000 /* skip a field; only for decoding */ |
| 141 | #define SEC_ASN1_INNER 0x10000 /* with ANY means capture the \ |
| 142 | * contents only (not the id, len, \ |
| 143 | * or eoc); only for decoding */ |
| 144 | #define SEC_ASN1_SAVE 0x20000 /* stash away the encoded bytes first; \ |
| 145 | * only for decoding */ |
| 146 | #define SEC_ASN1_MAY_STREAM 0x40000 /* field or one of its sub-fields may \ |
| 147 | * stream in and so should encode as \ |
| 148 | * indefinite-length when streaming \ |
| 149 | * has been indicated; only for \ |
| 150 | * encoding */ |
| 151 | #define SEC_ASN1_SKIP_REST 0x80000 /* skip all following fields; \ |
| 152 | only for decoding */ |
| 153 | #define SEC_ASN1_CHOICE 0x100000 /* pick one from a template */ |
| 154 | #define SEC_ASN1_NO_STREAM 0X200000 /* This entry will not stream \ |
| 155 | even if the sub-template says \ |
| 156 | streaming is possible. Helps \ |
| 157 | to solve ambiguities with potential \ |
| 158 | streaming entries that are \ |
| 159 | optional */ |
| 160 | #define SEC_ASN1_DEBUG_BREAK 0X400000 /* put this in your template and the \ |
| 161 | decoder will assert when it \ |
| 162 | processes it. Only for use with \ |
| 163 | SEC_QuickDERDecodeItem */ |
| 164 | |
| 165 | /* Shorthand/Aliases */ |
| 166 | #define SEC_ASN1_SEQUENCE_OF (SEC_ASN1_GROUP | SEC_ASN1_SEQUENCE) |
| 167 | #define SEC_ASN1_SET_OF (SEC_ASN1_GROUP | SEC_ASN1_SET) |
| 168 | #define SEC_ASN1_ANY_CONTENTS (SEC_ASN1_ANY | SEC_ASN1_INNER) |
| 169 | |
| 170 | /* Maximum depth of nested SEQUENCEs and SETs */ |
| 171 | #define SEC_ASN1D_MAX_DEPTH 32 |
| 172 | |
| 173 | /* |
| 174 | ** Function used for SEC_ASN1_DYNAMIC. |
| 175 | ** "arg" is a pointer to the structure being encoded/decoded |
| 176 | ** "enc", when true, means that we are encoding (false means decoding) |
| 177 | */ |
| 178 | typedef const SEC_ASN1Template *SEC_ASN1TemplateChooser(void *arg, PRBool enc); |
| 179 | typedef SEC_ASN1TemplateChooser *SEC_ASN1TemplateChooserPtr; |
| 180 | |
| 181 | #if defined(_WIN32) || defined(ANDROID) |
| 182 | #define SEC_ASN1_GET(x) NSS_Get_##x(NULL, PR_FALSE) |
| 183 | #define SEC_ASN1_SUB(x) &p_NSS_Get_##x |
| 184 | #define SEC_ASN1_XTRN SEC_ASN1_DYNAMIC |
| 185 | #define SEC_ASN1_MKSUB(x) \ |
| 186 | static const SEC_ASN1TemplateChooserPtr p_NSS_Get_##x = &NSS_Get_##x; |
| 187 | #else |
| 188 | #define SEC_ASN1_GET(x) x |
| 189 | #define SEC_ASN1_SUB(x) x |
| 190 | #define SEC_ASN1_XTRN 0 |
| 191 | #define SEC_ASN1_MKSUB(x) |
| 192 | #endif |
| 193 | |
| 194 | #define SEC_ASN1_CHOOSER_DECLARE(x) \ |
| 195 | extern const SEC_ASN1Template *NSS_Get_##x(void *arg, PRBool enc); |
| 196 | |
| 197 | #define SEC_ASN1_CHOOSER_IMPLEMENT(x) \ |
| 198 | const SEC_ASN1Template *NSS_Get_##x(void *arg, PRBool enc) \ |
| 199 | { \ |
| 200 | return x; \ |
| 201 | } |
| 202 | |
| 203 | /* |
| 204 | ** Opaque object used by the decoder to store state. |
| 205 | */ |
| 206 | typedef struct sec_DecoderContext_struct SEC_ASN1DecoderContext; |
| 207 | |
| 208 | /* |
| 209 | ** Opaque object used by the encoder to store state. |
| 210 | */ |
| 211 | typedef struct sec_EncoderContext_struct SEC_ASN1EncoderContext; |
| 212 | |
| 213 | /* |
| 214 | * This is used to describe to a filter function the bytes that are |
| 215 | * being passed to it. This is only useful when the filter is an "outer" |
| 216 | * one, meaning it expects to get *all* of the bytes not just the |
| 217 | * contents octets. |
| 218 | */ |
| 219 | typedef enum { |
| 220 | SEC_ASN1_Identifier = 0, |
| 221 | SEC_ASN1_Length = 1, |
| 222 | SEC_ASN1_Contents = 2, |
| 223 | SEC_ASN1_EndOfContents = 3 |
| 224 | } SEC_ASN1EncodingPart; |
| 225 | |
| 226 | /* |
| 227 | * Type of the function pointer used either for decoding or encoding, |
| 228 | * when doing anything "funny" (e.g. manipulating the data stream) |
| 229 | */ |
| 230 | typedef void (*SEC_ASN1NotifyProc)(void *arg, PRBool before, |
| 231 | void *dest, int real_depth); |
| 232 | |
| 233 | /* |
| 234 | * Type of the function pointer used for grabbing encoded bytes. |
| 235 | * This can be used during either encoding or decoding, as follows... |
| 236 | * |
| 237 | * When decoding, this can be used to filter the encoded bytes as they |
| 238 | * are parsed. This is what you would do if you wanted to process the data |
| 239 | * along the way (like to decrypt it, or to perform a hash on it in order |
| 240 | * to do a signature check later). See SEC_ASN1DecoderSetFilterProc(). |
| 241 | * When processing only part of the encoded bytes is desired, you "watch" |
| 242 | * for the field(s) you are interested in with a "notify proc" (see |
| 243 | * SEC_ASN1DecoderSetNotifyProc()) and for even finer granularity (e.g. to |
| 244 | * ignore all by the contents bytes) you pay attention to the "data_kind" |
| 245 | * parameter. |
| 246 | * |
| 247 | * When encoding, this is the specification for the output function which |
| 248 | * will receive the bytes as they are encoded. The output function can |
| 249 | * perform any postprocessing necessary (like hashing (some of) the data |
| 250 | * to create a digest that gets included at the end) as well as shoving |
| 251 | * the data off wherever it needs to go. (In order to "tune" any processing, |
| 252 | * you can set a "notify proc" as described above in the decoding case.) |
| 253 | * |
| 254 | * The parameters: |
| 255 | * - "arg" is an opaque pointer that you provided at the same time you |
| 256 | * specified a function of this type |
| 257 | * - "data" is a buffer of length "len", containing the encoded bytes |
| 258 | * - "depth" is how deep in a nested encoding we are (it is not usually |
| 259 | * valuable, but can be useful sometimes so I included it) |
| 260 | * - "data_kind" tells you if these bytes are part of the ASN.1 encoded |
| 261 | * octets for identifier, length, contents, or end-of-contents |
| 262 | */ |
| 263 | typedef void (*SEC_ASN1WriteProc)(void *arg, |
| 264 | const char *data, unsigned long len, |
| 265 | int depth, SEC_ASN1EncodingPart data_kind); |
| 266 | |
| 267 | #endif /* _SECASN1T_H_ */ |
| 268 | |