security/nss/lib/util/secasn1t.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial