1 /*
2 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
3 * All rights reserved.
4 * Redistribution and modifications are permitted subject to BSD license.
5 */
6 #ifndef ASN_DISABLE_OER_SUPPORT
7
8 #include "asn1/asn1c/asn_internal.h"
9 #include "asn1/asn1c/constr_SEQUENCE.h"
10 #include "asn1/asn1c/OPEN_TYPE.h"
11 #include <errno.h>
12
13 /*
14 * This macro "eats" the part of the buffer which is definitely "consumed",
15 * i.e. was correctly converted into local representation or rightfully skipped.
16 */
17 #undef ADVANCE
18 #define ADVANCE(num_bytes) \
19 do { \
20 size_t num = num_bytes; \
21 ptr = ((const char *)ptr) + num; \
22 size -= num; \
23 consumed_myself += num; \
24 } while(0)
25
26 /*
27 * Switch to the next phase of parsing.
28 */
29 #undef NEXT_PHASE
30 #undef PHASE_OUT
31 #define NEXT_PHASE(ctx) \
32 do { \
33 ctx->phase++; \
34 ctx->step = 0; \
35 } while(0)
36
37 /*
38 * Check whether we are inside the extensions group.
39 */
40 #define IN_EXTENSION_GROUP(specs, memb_idx) \
41 ((specs)->first_extension >= 0 \
42 && (unsigned)(specs)->first_extension <= (memb_idx))
43
44 #define IN_ROOT_GROUP_PRED(edx) \
45 edx < (specs->first_extension < 0 ? td->elements_count \
46 : (size_t)specs->first_extension)
47
48 #define FOR_IN_ROOT_GROUP(edx) for(edx = 0; IN_ROOT_GROUP_PRED(edx); edx++)
49
50 /*
51 * Return a standardized complex structure.
52 */
53 #undef RETURN
54 #define RETURN(_code) do { \
55 rval.code = _code; \
56 rval.consumed = consumed_myself;\
57 return rval; \
58 } while(0)
59
60 /*
61 * Return pointer to a member.
62 */
63 static void **
element_ptrptr(void * struct_ptr,asn_TYPE_member_t * elm,void ** tmp_save_ptr)64 element_ptrptr(void *struct_ptr, asn_TYPE_member_t *elm, void **tmp_save_ptr) {
65 if(elm->flags & ATF_POINTER) {
66 /* Member is a pointer to another structure */
67 return (void **)((char *)struct_ptr + elm->memb_offset);
68 } else {
69 assert(tmp_save_ptr);
70 *tmp_save_ptr = (void *)((char *)struct_ptr + elm->memb_offset);
71 return tmp_save_ptr;
72 }
73 }
74
75 static const void *
element_ptr(const void * struct_ptr,const asn_TYPE_member_t * elm)76 element_ptr(const void *struct_ptr, const asn_TYPE_member_t *elm) {
77 if(elm->flags & ATF_POINTER) {
78 /* Member is a pointer to another structure */
79 return *(const void *const *)((const char *)struct_ptr
80 + elm->memb_offset);
81 } else {
82 return (const void *)((const char *)struct_ptr + elm->memb_offset);
83 }
84 }
85
86 asn_dec_rval_t
SEQUENCE_decode_oer(const asn_codec_ctx_t * opt_codec_ctx,const asn_TYPE_descriptor_t * td,const asn_oer_constraints_t * constraints,void ** struct_ptr,const void * ptr,size_t size)87 SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
88 const asn_TYPE_descriptor_t *td,
89 const asn_oer_constraints_t *constraints, void **struct_ptr,
90 const void *ptr, size_t size) {
91 const asn_SEQUENCE_specifics_t *specs =
92 (const asn_SEQUENCE_specifics_t *)td->specifics;
93 asn_dec_rval_t rval = {RC_OK, 0};
94 void *st = *struct_ptr; /* Target structure */
95 asn_struct_ctx_t *ctx; /* Decoder context */
96 size_t consumed_myself = 0; /* Consumed bytes from ptr. */
97
98 (void)constraints;
99
100 if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
101 ASN__DECODE_FAILED;
102
103 /*
104 * Create the target structure if it is not present already.
105 */
106 if(st == 0) {
107 st = *struct_ptr = CALLOC(1, specs->struct_size);
108 if(st == 0) {
109 RETURN(RC_FAIL);
110 }
111 }
112
113 /*
114 * Restore parsing context.
115 */
116 ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
117
118 /*
119 * Start to parse where left previously.
120 */
121 switch(ctx->phase) {
122 case 0: {
123 /*
124 * Fetch preamble.
125 */
126 asn_bit_data_t *preamble;
127 int has_extensions_bit = (specs->first_extension >= 0);
128 size_t preamble_bits = (has_extensions_bit + specs->roms_count);
129 size_t preamble_bytes = ((7 + preamble_bits) >> 3);
130
131 ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 0", td->name);
132
133 ASN_DEBUG(
134 "Expecting preamble bits %" ASN_PRI_SIZE " for %s (including %d extension bits)",
135 preamble_bits, td->name, has_extensions_bit);
136
137 if(preamble_bytes > size) {
138 ASN__DECODE_STARVED;
139 }
140
141 preamble = asn_bit_data_new_contiguous(ptr, preamble_bits);
142 if(!preamble) {
143 RETURN(RC_FAIL);
144 }
145 preamble->nboff = has_extensions_bit;
146 ctx->ptr = preamble;
147 ADVANCE(preamble_bytes);
148 }
149 NEXT_PHASE(ctx);
150 /* FALL THROUGH */
151 case 1: {
152 /* Decode components of the extension root */
153 asn_bit_data_t *preamble = ctx->ptr;
154 size_t edx;
155
156 ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 1 (Root)", td->name);
157
158 assert(preamble);
159
160 for(edx = (ctx->step >> 1); IN_ROOT_GROUP_PRED(edx);
161 edx++, ctx->step = (ctx->step & ~1) + 2) {
162 asn_TYPE_member_t *elm = &td->elements[edx];
163
164 ASN_DEBUG("Decoding %s->%s", td->name, elm->name);
165
166 assert(!IN_EXTENSION_GROUP(specs, edx));
167
168 if(ctx->step & 1) {
169 goto microphase2_decode_continues;
170 }
171
172
173 if(elm->optional) {
174 int32_t present = asn_get_few_bits(preamble, 1);
175 if(present < 0) {
176 ASN_DEBUG("Presence map ended prematurely: %d", present);
177 RETURN(RC_FAIL);
178 } else if(present == 0) {
179 if(elm->default_value_set) {
180 /* Fill-in DEFAULT */
181 void *tmp;
182 if(elm->default_value_set(
183 element_ptrptr(st, elm, &tmp))) {
184 RETURN(RC_FAIL);
185 }
186 }
187 /* The member is not present. */
188 continue;
189 }
190 /* Present OPTIONAL or DEFAULT component. */
191 }
192
193 /*
194 * MICROPHASE 2: Invoke the member-specific decoder.
195 */
196 ctx->step |= 1; /* Confirm entering next microphase */
197 microphase2_decode_continues:
198 if(elm->flags & ATF_OPEN_TYPE) {
199 rval = OPEN_TYPE_oer_get(opt_codec_ctx, td, st, elm, ptr, size);
200 } else {
201 void *save_memb_ptr; /* Temporary reference. */
202 void **memb_ptr2; /* Pointer to a pointer to a memmber */
203
204 memb_ptr2 = element_ptrptr(st, elm, &save_memb_ptr);
205
206 rval = elm->type->op->oer_decoder(
207 opt_codec_ctx, elm->type,
208 elm->encoding_constraints.oer_constraints, memb_ptr2, ptr,
209 size);
210 }
211 switch(rval.code) {
212 case RC_OK:
213 ADVANCE(rval.consumed);
214 break;
215 case RC_WMORE:
216 ASN_DEBUG("More bytes needed at element %s \"%s\"", td->name,
217 elm->name);
218 ADVANCE(rval.consumed);
219 RETURN(RC_WMORE);
220 case RC_FAIL:
221 ASN_DEBUG("Decoding failed at element %s \"%s\"", td->name,
222 elm->name);
223 RETURN(RC_FAIL);
224 }
225 } /* for(all root members) */
226
227 }
228 NEXT_PHASE(ctx);
229 /* FALL THROUGH */
230 case 2:
231 assert(ctx->ptr);
232 {
233 /* Cleanup preamble. */
234 asn_bit_data_t *preamble = ctx->ptr;
235 asn_bit_data_t *extadds;
236 int has_extensions_bit = (specs->first_extension >= 0);
237 int extensions_present =
238 has_extensions_bit
239 && (preamble->buffer == NULL
240 || (((const uint8_t *)preamble->buffer)[0] & 0x80));
241 uint8_t unused_bits;
242 size_t len = 0;
243 ssize_t len_len;
244
245 ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 2", td->name);
246
247 preamble->buffer = 0; /* Will do extensions_present==1 next time. */
248
249 if(!extensions_present) {
250 ctx->phase = 10;
251 RETURN(RC_OK);
252 }
253
254 /*
255 * X.696 (08/2015) #16.1 (c), #16.4
256 * Read in the extension addition presence bitmap.
257 */
258
259 len_len = oer_fetch_length(ptr, size, &len);
260 if(len_len > 0) {
261 ADVANCE(len_len);
262 } else if(len_len < 0) {
263 RETURN(RC_FAIL);
264 } else {
265 RETURN(RC_WMORE);
266 }
267
268 if(len == 0) {
269 /* 16.4.1-2 */
270 RETURN(RC_FAIL);
271 } else if(len > size) {
272 RETURN(RC_WMORE);
273 }
274
275 /* Account for unused bits */
276 unused_bits = 0x7 & *(const uint8_t *)ptr;
277 ADVANCE(1);
278 len--;
279 if(unused_bits && len == 0) {
280 RETURN(RC_FAIL);
281 }
282
283 /* Get the extensions map */
284 extadds = asn_bit_data_new_contiguous(ptr, len * 8 - unused_bits);
285 if(!extadds) {
286 RETURN(RC_FAIL);
287 }
288 FREEMEM(preamble);
289 ctx->ptr = extadds;
290 ADVANCE(len);
291 }
292 NEXT_PHASE(ctx);
293 ctx->step =
294 (specs->first_extension < 0 ? td->elements_count
295 : (size_t)specs->first_extension);
296 /* Fall through */
297 case 3:
298 ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 3 (Extensions)", td->name);
299 for(; ctx->step < (signed)td->elements_count; ctx->step++) {
300 asn_bit_data_t *extadds = ctx->ptr;
301 size_t edx = ctx->step;
302 asn_TYPE_member_t *elm = &td->elements[edx];
303 void *tmp_memb_ptr;
304 void **memb_ptr2 = element_ptrptr(st, elm, &tmp_memb_ptr);
305
306 switch(asn_get_few_bits(extadds, 1)) {
307 case -1:
308 /*
309 * Not every one of our extensions is known to the remote side.
310 * Continue filling in their defaults though.
311 */
312 /* Fall through */
313 case 0:
314 /* Fill-in DEFAULT */
315 if(elm->default_value_set
316 && elm->default_value_set(memb_ptr2)) {
317 RETURN(RC_FAIL);
318 }
319 continue;
320 case 1: {
321 /* Read OER open type */
322 ssize_t ot_size =
323 oer_open_type_get(opt_codec_ctx, elm->type,
324 elm->encoding_constraints.oer_constraints,
325 memb_ptr2, ptr, size);
326 assert(ot_size <= (ssize_t)size);
327 if(ot_size > 0) {
328 ADVANCE(ot_size);
329 } else if(ot_size < 0) {
330 RETURN(RC_FAIL);
331 } else {
332 /* Roll back open type parsing */
333 asn_get_undo(extadds, 1);
334 RETURN(RC_WMORE);
335 }
336 break;
337 }
338 default:
339 RETURN(RC_FAIL);
340 }
341 }
342
343 NEXT_PHASE(ctx);
344 /* Fall through */
345 case 4:
346 ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 4", td->name);
347 /* Read in the rest of Open Types while ignoring them */
348 for(;;) {
349 asn_bit_data_t *extadds = ctx->ptr;
350 switch(asn_get_few_bits(extadds, 1)) {
351 case 0:
352 continue;
353 case 1: {
354 ssize_t skipped = oer_open_type_skip(ptr, size);
355 if(skipped > 0) {
356 ADVANCE(skipped);
357 } else if(skipped < 0) {
358 RETURN(RC_FAIL);
359 } else {
360 asn_get_undo(extadds, 1);
361 RETURN(RC_WMORE);
362 }
363 continue;
364 }
365 case -1:
366 /* No more Open Type encoded components */
367 break;
368 default:
369 RETURN(RC_FAIL);
370 }
371 break;
372 }
373 }
374
375 RETURN(RC_OK);
376 }
377
378 /*
379 * Encode as Canonical OER.
380 */
381 asn_enc_rval_t
SEQUENCE_encode_oer(const asn_TYPE_descriptor_t * td,const asn_oer_constraints_t * constraints,const void * sptr,asn_app_consume_bytes_f * cb,void * app_key)382 SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td,
383 const asn_oer_constraints_t *constraints, const void *sptr,
384 asn_app_consume_bytes_f *cb, void *app_key) {
385 const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
386 size_t computed_size = 0;
387 int has_extensions_bit = (specs->first_extension >= 0);
388 size_t preamble_bits = (has_extensions_bit + specs->roms_count);
389 uint32_t has_extensions = 0;
390 size_t edx;
391 int ret;
392
393 (void)constraints;
394
395 if(preamble_bits) {
396 asn_bit_outp_t preamble;
397
398 memset(&preamble, 0, sizeof(preamble));
399 preamble.output = cb;
400 preamble.op_key = app_key;
401
402 if(has_extensions_bit) {
403 for(edx = specs->first_extension; edx < td->elements_count; edx++) {
404 asn_TYPE_member_t *elm = &td->elements[edx];
405 const void *memb_ptr = element_ptr(sptr, elm);
406 if(memb_ptr) {
407 if(elm->default_value_cmp
408 && elm->default_value_cmp(memb_ptr) == 0) {
409 /* Do not encode default values in extensions */
410 } else {
411 has_extensions = 1;
412 break;
413 }
414 }
415 }
416 ret = asn_put_few_bits(&preamble, has_extensions, 1);
417 assert(ret == 0);
418 if(ret < 0) {
419 ASN__ENCODE_FAILED;
420 }
421 }
422
423 /*
424 * Encode optional components bitmap.
425 */
426 if(specs->roms_count) {
427 FOR_IN_ROOT_GROUP(edx) {
428 asn_TYPE_member_t *elm = &td->elements[edx];
429
430 if(IN_EXTENSION_GROUP(specs, edx)) break;
431
432 if(elm->optional) {
433 const void *memb_ptr = element_ptr(sptr, elm);
434 uint32_t has_component = memb_ptr != NULL;
435 if(has_component && elm->default_value_cmp
436 && elm->default_value_cmp(memb_ptr) == 0) {
437 has_component = 0;
438 }
439 ret = asn_put_few_bits(&preamble, has_component, 1);
440 if(ret < 0) {
441 ASN__ENCODE_FAILED;
442 }
443 }
444 }
445 }
446
447 asn_put_aligned_flush(&preamble);
448 computed_size += preamble.flushed_bytes;
449 } /* if(preamble_bits) */
450
451 /*
452 * Put root components and extensions root.
453 */
454 for(edx = 0; edx < td->elements_count; edx++) {
455 asn_TYPE_member_t *elm = &td->elements[edx];
456 asn_enc_rval_t er;
457 const void *memb_ptr;
458
459 if(IN_EXTENSION_GROUP(specs, edx)) break;
460
461 memb_ptr = element_ptr(sptr, elm);
462 if(memb_ptr) {
463 if(elm->default_value_cmp
464 && elm->default_value_cmp(memb_ptr) == 0) {
465 /* Skip default values in encoding */
466 continue;
467 }
468 } else {
469 if(elm->optional) continue;
470 /* Mandatory element is missing */
471 ASN__ENCODE_FAILED;
472 }
473 if(!elm->type->op->oer_encoder) {
474 ASN_DEBUG("OER encoder is not defined for type %s", elm->type->name);
475 ASN__ENCODE_FAILED;
476 }
477 er = elm->type->op->oer_encoder(
478 elm->type, elm->encoding_constraints.oer_constraints, memb_ptr, cb,
479 app_key);
480 if(er.encoded == -1) {
481 ASN_DEBUG("... while encoding %s member \"%s\"\n", td->name,
482 elm->name);
483 return er;
484 }
485 computed_size += er.encoded;
486 }
487
488 /*
489 * Before encode extensions, encode extensions additions presense bitmap
490 # X.696 (08/2015) #16.4.
491 */
492 if(has_extensions) {
493 asn_bit_outp_t extadds;
494
495 /* Special case allowing us to use exactly one byte for #8.6 */
496 size_t aoms_length_bits = specs->aoms_count;
497 size_t aoms_length_bytes = (7 + aoms_length_bits) >> 3;
498 uint8_t unused_bits = 0x07 & (8 - (aoms_length_bits & 0x07));
499
500 assert(1 + aoms_length_bytes <= 127);
501
502 memset(&extadds, 0, sizeof(extadds));
503 extadds.output = cb;
504 extadds.op_key = app_key;
505
506 /* #8.6 length determinant */
507 ret = asn_put_few_bits(&extadds, (1 + aoms_length_bytes), 8);
508 if(ret < 0) ASN__ENCODE_FAILED;
509
510 /* Number of unused bytes, #16.4.2 */
511 ret = asn_put_few_bits(&extadds, unused_bits, 8);
512 if(ret < 0) ASN__ENCODE_FAILED;
513
514 /* Encode presence bitmap #16.4.3 */
515 for(edx = specs->first_extension; edx < td->elements_count; edx++) {
516 asn_TYPE_member_t *elm = &td->elements[edx];
517 const void *memb_ptr = element_ptr(sptr, elm);
518 if(memb_ptr && elm->default_value_cmp
519 && elm->default_value_cmp(memb_ptr) == 0) {
520 memb_ptr = 0; /* Do not encode default value. */
521 }
522 ret |= asn_put_few_bits(&extadds, memb_ptr ? 1 : 0, 1);
523 }
524 if(ret < 0) ASN__ENCODE_FAILED;
525
526 asn_put_aligned_flush(&extadds);
527 computed_size += extadds.flushed_bytes;
528
529 /* Now, encode extensions */
530 for(edx = specs->first_extension; edx < td->elements_count; edx++) {
531 asn_TYPE_member_t *elm = &td->elements[edx];
532 const void *memb_ptr = element_ptr(sptr, elm);
533
534 if(memb_ptr) {
535 if(elm->default_value_cmp
536 && elm->default_value_cmp(memb_ptr) == 0) {
537 /* Do not encode default value. */
538 } else {
539 ssize_t wrote = oer_open_type_put(
540 elm->type, elm->encoding_constraints.oer_constraints,
541 memb_ptr, cb, app_key);
542 if(wrote == -1) {
543 ASN__ENCODE_FAILED;
544 }
545 computed_size += wrote;
546 }
547 } else if(!elm->optional) {
548 ASN__ENCODE_FAILED;
549 }
550 }
551 } /* if(has_extensions) */
552
553
554 {
555 asn_enc_rval_t er = {0, 0, 0};
556 er.encoded = computed_size;
557 ASN__ENCODED_OK(er);
558 }
559 }
560
561 #endif /* ASN_DISABLE_OER_SUPPORT */
562