2 * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 #ifndef __TEMPLATE_H__
39 #define __TEMPLATE_H__
44 * - For OER also encode number of optional/default/extension elements into
45 * header entry's ptr field, not just the number of entries that follow it
47 * - For JER/GSER/whatver, and probably for not-C-coded template interpreters,
48 * we'll need to have an entry type for the names of structures and their
51 * - For auto open types we need a new opcode, let's call it
52 * A1_OP_OPENTYPE_OBJSET, and we need to encode into its entry:
53 * a) the index of the template entry for the type ID field, and
54 * b) the index of the template entry for the open type field,
55 * c) 1 bit to indicate whether the object set is sorted by type ID value,
56 * d) a pointer to the object set's template.
57 * With that we can then find the struct offsets of those, and also their
58 * types (since we can find their template entries).
59 * The object set entries should be encoded into two template entries each:
60 * one pointing to the value of the type ID field for that object (unless
61 * the value is an integer, in which case the ptr should be the integer
62 * value directly), and the other pointing to the template for the type
63 * identified by the type ID. These will need an opcode each...
64 * A1_OP_OPENTYPE_ID and A1_OP_OPENTYPE.
65 * We should also end the object set with an A1_OP_OPENTYPE_OBJSET entry so
66 * that iterating backwards can be fast. Unless... unless we don't inline
67 * the object set and its objects but point to the object set's template.
68 * Also, for extensible object sets we can point to the object set's name,
69 * and we can then have a function to get an object set template by name,
70 * one to release that, and one to add an object to the object set (there's
71 * no need to remove objects from object sets, which helps with thread-
72 * safety). And then we don't need (c) either.
73 * The decoder will then not see these entries until after decoding the type
74 * ID and open type field (as its outer type, so OCTET STRING, BIT STRING,
75 * or HEIM_ANY) and so it will be able to find those values in the struct at
76 * their respective offsets.
77 * The encoder and decoder both need to identify the relevant object in the
78 * object set, either by linear search or binary search if they are sorted
79 * by type ID value, then interpret the template for the identified type.
80 * The encoder needs to place the encoding into the normal location for it
81 * in the struct, then it can execute the normal template entry for it.
85 * HF flags if not a BIT STRING type
86 * HBF flags if a BIT STRING type
88 * ptr is count of elements
89 * offset is size of struct
99 * ptr points to template for tagged type
100 * offset is offset of struct field
113 /* defval: (next template entry is defaulted)
115 * DV flags (ptr is or points to defval)
117 * ptr is default value or pointer to default value
121 /* name: first one is the name of the SET/SEQUENCE/CHOICE type
122 * subsequent ones are the name of the nth field
125 * 24..27 flags A1_NM_*
128 * ptr is const char * pointer to the name as C string
129 * offset is all zeros
133 * 0..9 open type ID entry index
134 * 10..19 open type entry index
136 * 24..27 flags A1_OS_*
139 * ptr points to object set template
140 * offset is the offset of the choice struct
143 /* opentypeid: offset is zero
144 * ptr points to value if it is not an integer
145 * ptr is the value if it is an integer
147 * 24..27 flags A1_OTI_*
151 /* opentype: offset is sizeof C type for this open type choice
152 * ptr points to template for type choice
158 #define A1_OP_MASK (0xf0000000)
159 #define A1_OP_TYPE (0x10000000)
160 #define A1_OP_TYPE_EXTERN (0x20000000)
161 #define A1_OP_TAG (0x30000000)
162 #define A1_OP_PARSE (0x40000000)
163 #define A1_OP_SEQOF (0x50000000)
164 #define A1_OP_SETOF (0x60000000)
165 #define A1_OP_BMEMBER (0x70000000)
166 #define A1_OP_CHOICE (0x80000000)
167 #define A1_OP_DEFVAL (0x90000000)
168 #define A1_OP_OPENTYPE_OBJSET (0xa0000000)
169 #define A1_OP_OPENTYPE_ID (0xb0000000)
170 #define A1_OP_OPENTYPE (0xc0000000)
171 #define A1_OP_NAME (0xd0000000)
172 #define A1_OP_TYPE_DECORATE (0xe0000000)
174 #define A1_FLAG_MASK (0x0f000000)
175 #define A1_FLAG_OPTIONAL (0x01000000)
176 #define A1_FLAG_IMPLICIT (0x02000000)
177 #define A1_FLAG_DEFAULT (0x04000000)
179 #define A1_TAG_T(CLASS,TYPE,TAG) ((A1_OP_TAG) | (((CLASS) << 22) | ((TYPE) << 21) | (TAG)))
180 #define A1_TAG_CLASS(x) (((x) >> 22) & 0x3)
181 #define A1_TAG_TYPE(x) (((x) >> 21) & 0x1)
182 #define A1_TAG_TAG(x) ((x) & 0x1fffff)
184 #define A1_TAG_LEN(t) ((uintptr_t)(t)->ptr)
185 #define A1_HEADER_LEN(t) ((uintptr_t)(t)->ptr)
187 #define A1_PARSE_T(type) ((A1_OP_PARSE) | (type))
188 #define A1_PARSE_TYPE_MASK 0xfff
189 #define A1_PARSE_TYPE(x) (A1_PARSE_TYPE_MASK & (x))
191 #define A1_PF_INDEFINTE 0x1
192 #define A1_PF_ALLOW_BER 0x2
194 #define A1_HF_PRESERVE 0x1
195 #define A1_HF_ELLIPSIS 0x2
197 #define A1_HBF_RFC1510 0x1
199 #define A1_DV_BOOLEAN 0x01
200 #define A1_DV_INTEGER 0x02
201 #define A1_DV_INTEGER32 0x04
202 #define A1_DV_INTEGER64 0x08
203 #define A1_DV_UTF8STRING 0x10
205 #define A1_OS_IS_SORTED (0x01000000)
206 #define A1_OS_OT_IS_ARRAY (0x02000000)
207 #define A1_OTI_IS_INTEGER (0x04000000)
210 struct asn1_template {
216 typedef int (ASN1CALL *asn1_type_decode)(const unsigned char *, size_t, void *, size_t *);
217 typedef int (ASN1CALL *asn1_type_encode)(unsigned char *, size_t, const void *, size_t *);
218 typedef size_t (ASN1CALL *asn1_type_length)(const void *);
219 typedef void (ASN1CALL *asn1_type_release)(void *);
220 typedef int (ASN1CALL *asn1_type_copy)(const void *, void *);
221 typedef char * (ASN1CALL *asn1_type_print)(const void *, int);
223 struct asn1_type_func {
224 asn1_type_encode encode;
225 asn1_type_decode decode;
226 asn1_type_length length;
228 asn1_type_release release;
229 asn1_type_print print;
238 enum template_types {
247 A1T_OCTET_STRING_BER,
250 A1T_UNIVERSAL_STRING,
251 A1T_PRINTABLE_STRING,
254 A1T_GENERALIZED_TIME,
263 extern struct asn1_type_func asn1_template_prim[A1T_NUM_ENTRY];
265 #define ABORT_ON_ERROR() abort()
267 #define DPOC(data,offset) ((const void *)(((const unsigned char *)data) + offset))
268 #define DPO(data,offset) ((void *)(((unsigned char *)data) + offset))
271 * These functions are needed by the generated template stubs and are
272 * really internal functions. Since they are part of der-private.h
273 * that contains extra prototypes that really a private we included a
279 const struct asn1_template * /*t*/,
280 const void * /*from*/,
284 _asn1_free_top(const struct asn1_template *, void *);
287 _asn1_print_top(const struct asn1_template *, int, const void *);
291 const struct asn1_template * /*t*/,
293 const unsigned char * /*p*/,
300 const struct asn1_template * /*t*/,
301 unsigned char * /*p*/,
303 const void * /*data*/,
307 _asn1_encode_fuzzer (
308 const struct asn1_template * /*t*/,
309 unsigned char * /*p*/,
311 const void * /*data*/,
316 const struct asn1_template * /*t*/,
321 const struct asn1_template * /*t*/,
322 const void * /*data*/);
325 _asn1_length_fuzzer (
326 const struct asn1_template * /*t*/,
327 const void * /*data*/);