asn_enc_rval_t BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr, int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) { asn_enc_rval_t erval; BOOLEAN_t *st = (BOOLEAN_t *)sptr; erval.encoded = der_write_tags(td, 1, tag_mode, 0, tag, cb, app_key); if(erval.encoded == -1) { erval.failed_type = td; erval.structure_ptr = sptr; return erval; } if(cb) { uint8_t bool_value; bool_value = *st ? 0xff : 0; /* 0xff mandated by DER */ if(cb(&bool_value, 1, app_key) < 0) { erval.encoded = -1; erval.failed_type = td; erval.structure_ptr = sptr; return erval; } } erval.encoded += 1; ASN__ENCODED_OK(erval); }
asn_enc_rval_t NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics; asn_enc_rval_t er; const long *native = (const long *)sptr; const asn_INTEGER_enum_map_t *el; (void)ilevel; (void)flags; if(!native) ASN__ENCODE_FAILED; el = INTEGER_map_value2enum(specs, *native); if(el) { size_t srcsize = el->enum_len + 5; char *src = (char *)alloca(srcsize); er.encoded = snprintf(src, srcsize, "<%s/>", el->enum_name); assert(er.encoded > 0 && (size_t)er.encoded < srcsize); if(cb(src, er.encoded, app_key) < 0) ASN__ENCODE_FAILED; ASN__ENCODED_OK(er); } else { ASN_DEBUG("ASN.1 forbids dealing with " "unknown value of ENUMERATED type"); ASN__ENCODE_FAILED; } }
asn_enc_rval_t oer_encode_primitive(const asn_TYPE_descriptor_t *td, const asn_oer_constraints_t *constraints, const void *sptr, asn_app_consume_bytes_f *cb, void *app_key) { const ASN__PRIMITIVE_TYPE_t *st = (const ASN__PRIMITIVE_TYPE_t *)sptr; asn_enc_rval_t er = {0, 0, 0}; ssize_t ret; (void)constraints; if(!st) ASN__ENCODE_FAILED; ASN_DEBUG("Encoding %s (%" ASN_PRI_SIZE " bytes)", td ? td->name : "", st->size); /* * X.696 (08/2015) #27.2 */ ret = oer_serialize_length(st->size, cb, app_key); if(ret < 0) { ASN__ENCODE_FAILED; } er.encoded += ret; er.encoded += st->size; if(cb(st->buf, st->size, app_key) < 0) { ASN__ENCODE_FAILED; } else { ASN__ENCODED_OK(er); } }
/* * Encode an always-primitive type using DER. */ asn_enc_rval_t der_encode_primitive(asn_TYPE_descriptor_t *td, void *sptr, int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) { asn_enc_rval_t erval; ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)sptr; ASN_DEBUG("%s %s as a primitive type (tm=%d)", cb?"Encoding":"Estimating", td->name, tag_mode); erval.encoded = der_write_tags(td, st->size, tag_mode, 0, tag, cb, app_key); ASN_DEBUG("%s wrote tags %d", td->name, (int)erval.encoded); if(erval.encoded == -1) { erval.failed_type = td; erval.structure_ptr = sptr; return erval; } if(cb && st->buf) { if(cb(st->buf, st->size, app_key) < 0) { erval.encoded = -1; erval.failed_type = td; erval.structure_ptr = sptr; return erval; } } else { assert(st->buf || st->size == 0); } erval.encoded += st->size; ASN__ENCODED_OK(erval); }
/* * The XER encoder of any type. May be invoked by the application. */ asn_enc_rval_t xer_encode(asn_TYPE_descriptor_t *td, void *sptr, enum xer_encoder_flags_e xer_flags, asn_app_consume_bytes_f *cb, void *app_key) { asn_enc_rval_t er, tmper; const char *mname; size_t mlen; int xcan = (xer_flags & XER_F_CANONICAL) ? 1 : 2; if(!td || !sptr) goto cb_failed; mname = td->xml_tag; mlen = strlen(mname); ASN__CALLBACK3("<", 1, mname, mlen, ">", 1); tmper = td->xer_encoder(td, sptr, 1, xer_flags, cb, app_key); if(tmper.encoded == -1) return tmper; ASN__CALLBACK3("</", 2, mname, mlen, ">\n", xcan); er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded; ASN__ENCODED_OK(er); cb_failed: ASN__ENCODE_FAILED; }
asn_enc_rval_t BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { asn_enc_rval_t er; char scratch[128]; char *p = scratch; char *scend = scratch + (sizeof(scratch) - 10); const BIT_STRING_t *st = (const BIT_STRING_t *)sptr; int xcan = (flags & XER_F_CANONICAL); uint8_t *buf; uint8_t *end; if(!st || !st->buf) ASN__ENCODE_FAILED; er.encoded = 0; buf = st->buf; end = buf + st->size - 1; /* Last byte is special */ /* * Binary dump */ for(; buf < end; buf++) { int v = *buf; int nline = xcan?0:(((buf - st->buf) % 8) == 0); if(p >= scend || nline) { er.encoded += p - scratch; ASN__CALLBACK(scratch, p - scratch); p = scratch; if(nline) ASN__TEXT_INDENT(1, ilevel); } memcpy(p + 0, _bit_pattern[v >> 4], 4); memcpy(p + 4, _bit_pattern[v & 0x0f], 4); p += 8; } if(!xcan && ((buf - st->buf) % 8) == 0) ASN__TEXT_INDENT(1, ilevel); er.encoded += p - scratch; ASN__CALLBACK(scratch, p - scratch); p = scratch; if(buf == end) { int v = *buf; int ubits = st->bits_unused; int i; for(i = 7; i >= ubits; i--) *p++ = (v & (1 << i)) ? 0x31 : 0x30; er.encoded += p - scratch; ASN__CALLBACK(scratch, p - scratch); } if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1); ASN__ENCODED_OK(er); cb_failed: ASN__ENCODE_FAILED; }
asn_enc_rval_t CHOICE_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { const asn_CHOICE_specifics_t *specs = (const asn_CHOICE_specifics_t *)td->specifics; asn_enc_rval_t er; unsigned present; if(!sptr) ASN__ENCODE_FAILED; /* * Figure out which CHOICE element is encoded. */ present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size); if(present == 0 || present > td->elements_count) { ASN__ENCODE_FAILED; } else { asn_enc_rval_t tmper; asn_TYPE_member_t *elm = &td->elements[present-1]; const void *memb_ptr; const char *mname = elm->name; unsigned int mlen = strlen(mname); if(elm->flags & ATF_POINTER) { memb_ptr = *(const void *const *)((const char *)sptr + elm->memb_offset); if(!memb_ptr) ASN__ENCODE_FAILED; } else { memb_ptr = (const void *)((const char *)sptr + elm->memb_offset); } er.encoded = 0; if(!(flags & XER_F_CANONICAL)) ASN__TEXT_INDENT(1, ilevel); ASN__CALLBACK3("<", 1, mname, mlen, ">", 1); tmper = elm->type->op->xer_encoder(elm->type, memb_ptr, ilevel + 1, flags, cb, app_key); if(tmper.encoded == -1) return tmper; er.encoded += tmper.encoded; ASN__CALLBACK3("</", 2, mname, mlen, ">", 1); } if(!(flags & XER_F_CANONICAL)) ASN__TEXT_INDENT(1, ilevel - 1); ASN__ENCODED_OK(er); cb_failed: ASN__ENCODE_FAILED; }
asn_enc_rval_t BOOLEAN_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { const BOOLEAN_t *st = (const BOOLEAN_t *)sptr; asn_enc_rval_t er = { 0, 0, 0 }; (void)constraints; if(!st) ASN__ENCODE_FAILED; if(per_put_few_bits(po, *st ? 1 : 0, 1)) ASN__ENCODE_FAILED; ASN__ENCODED_OK(er); }
asn_enc_rval_t NativeReal_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { const double *Dbl = (const double *)sptr; asn_enc_rval_t er; (void)ilevel; if(!Dbl) ASN__ENCODE_FAILED; er.encoded = REAL__dump(*Dbl, flags & XER_F_CANONICAL, cb, app_key); if(er.encoded < 0) ASN__ENCODE_FAILED; ASN__ENCODED_OK(er); }
asn_enc_rval_t SET_OF_encode_aper( struct asn_TYPE_descriptor_s *type_descriptor, asn_per_constraints_t *constraints, void *struct_ptr, asn_per_outp_t *per_output) { asn_enc_rval_t erval; (void)type_descriptor; /* Unused argument */ (void)constraints; /* Unused argument */ (void)struct_ptr; /* Unused argument */ (void)per_output; /* Unused argument */ erval.encoded = -1; ASN__ENCODED_OK(erval); }
asn_enc_rval_t INTEGER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { const INTEGER_t *st = (const INTEGER_t *)sptr; asn_enc_rval_t er; (void)ilevel; (void)flags; if(!st || !st->buf) ASN__ENCODE_FAILED; er.encoded = INTEGER__dump(td, st, cb, app_key, 1); if(er.encoded < 0) ASN__ENCODE_FAILED; ASN__ENCODED_OK(er); }
asn_enc_rval_t BOOLEAN_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { const BOOLEAN_t *st = (const BOOLEAN_t *)sptr; asn_enc_rval_t er; (void)ilevel; (void)flags; if(!st) ASN__ENCODE_FAILED; if(*st) { ASN__CALLBACK("<true/>", 7); er.encoded = 7; } else { ASN__CALLBACK("<false/>", 8); er.encoded = 8; } ASN__ENCODED_OK(er); cb_failed: ASN__ENCODE_FAILED; }
asn_enc_rval_t SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) { asn_enc_rval_t er; asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics; asn_TYPE_member_t *elm = td->elements; asn_anonymous_set_ *list = _A_SET_FROM_VOID(sptr); const char *mname = specs->as_XMLValueList ? 0 : ((*elm->name) ? elm->name : elm->type->xml_tag); size_t mlen = mname ? strlen(mname) : 0; int xcan = (flags & XER_F_CANONICAL); xer_tmp_enc_t *encs = 0; size_t encs_count = 0; void *original_app_key = app_key; asn_app_consume_bytes_f *original_cb = cb; int i; if(!sptr) ASN__ENCODE_FAILED; if(xcan) { encs = (xer_tmp_enc_t *)MALLOC(list->count * sizeof(encs[0])); if(!encs) ASN__ENCODE_FAILED; cb = SET_OF_encode_xer_callback; } er.encoded = 0; for(i = 0; i < list->count; i++) { asn_enc_rval_t tmper; void *memb_ptr = list->array[i]; if(!memb_ptr) continue; if(encs) { memset(&encs[encs_count], 0, sizeof(encs[0])); app_key = &encs[encs_count]; encs_count++; } if(mname) { if(!xcan) ASN__TEXT_INDENT(1, ilevel); ASN__CALLBACK3("<", 1, mname, mlen, ">", 1); } if(!xcan && specs->as_XMLValueList == 1) ASN__TEXT_INDENT(1, ilevel + 1); tmper = elm->type->xer_encoder(elm->type, memb_ptr, ilevel + (specs->as_XMLValueList != 2), flags, cb, app_key); if(tmper.encoded == -1) { td = tmper.failed_type; sptr = tmper.structure_ptr; goto cb_failed; } if(tmper.encoded == 0 && specs->as_XMLValueList) { const char *name = elm->type->xml_tag; size_t len = strlen(name); ASN__CALLBACK3("<", 1, name, len, "/>", 2); } if(mname) { ASN__CALLBACK3("</", 2, mname, mlen, ">", 1); er.encoded += 5; } er.encoded += (2 * mlen) + tmper.encoded; } if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1); if(encs) { xer_tmp_enc_t *enc = encs; xer_tmp_enc_t *end = encs + encs_count; ssize_t control_size = 0; cb = original_cb; app_key = original_app_key; qsort(encs, encs_count, sizeof(encs[0]), SET_OF_xer_order); for(; enc < end; enc++) { ASN__CALLBACK(enc->buffer, enc->offset); FREEMEM(enc->buffer); enc->buffer = 0; control_size += enc->offset; } assert(control_size == er.encoded); } goto cleanup; cb_failed: er.encoded = -1; er.failed_type = td; er.structure_ptr = sptr; cleanup: if(encs) { while(encs_count-- > 0) { if(encs[encs_count].buffer) FREEMEM(encs[encs_count].buffer); } FREEMEM(encs); } ASN__ENCODED_OK(er); }
/* * The DER encoder of the SET OF type. */ asn_enc_rval_t SET_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr, int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) { asn_TYPE_member_t *elm = td->elements; asn_TYPE_descriptor_t *elm_type = elm->type; der_type_encoder_f *der_encoder = elm_type->der_encoder; asn_anonymous_set_ *list = _A_SET_FROM_VOID(ptr); size_t computed_size = 0; ssize_t encoding_size = 0; struct _el_buffer *encoded_els; ssize_t eels_count = 0; size_t max_encoded_len = 1; asn_enc_rval_t erval; int ret; int edx; ASN_DEBUG("Estimating size for SET OF %s", td->name); /* * Gather the length of the underlying members sequence. */ for(edx = 0; edx < list->count; edx++) { void *memb_ptr = list->array[edx]; if(!memb_ptr) continue; erval = der_encoder(elm_type, memb_ptr, 0, elm->tag, 0, 0); if(erval.encoded == -1) return erval; computed_size += erval.encoded; /* Compute maximum encoding's size */ if(max_encoded_len < (size_t)erval.encoded) max_encoded_len = erval.encoded; } /* * Encode the TLV for the sequence itself. */ encoding_size = der_write_tags(td, computed_size, tag_mode, 1, tag, cb, app_key); if(encoding_size == -1) { erval.encoded = -1; erval.failed_type = td; erval.structure_ptr = ptr; return erval; } computed_size += encoding_size; if(!cb || list->count == 0) { erval.encoded = computed_size; ASN__ENCODED_OK(erval); } /* * DER mandates dynamic sorting of the SET OF elements * according to their encodings. Build an array of the * encoded elements. */ encoded_els = (struct _el_buffer *)MALLOC( list->count * sizeof(encoded_els[0])); if(encoded_els == NULL) { erval.encoded = -1; erval.failed_type = td; erval.structure_ptr = ptr; return erval; } ASN_DEBUG("Encoding members of %s SET OF", td->name); /* * Encode all members. */ for(edx = 0; edx < list->count; edx++) { void *memb_ptr = list->array[edx]; struct _el_buffer *encoded_el = &encoded_els[eels_count]; if(!memb_ptr) continue; /* * Prepare space for encoding. */ encoded_el->buf = (uint8_t *)MALLOC(max_encoded_len); if(encoded_el->buf) { encoded_el->length = 0; encoded_el->size = max_encoded_len; } else { for(edx--; edx >= 0; edx--) FREEMEM(encoded_els[edx].buf); FREEMEM(encoded_els); erval.encoded = -1; erval.failed_type = td; erval.structure_ptr = ptr; return erval; } /* * Encode the member into the prepared space. */ erval = der_encoder(elm_type, memb_ptr, 0, elm->tag, _el_addbytes, encoded_el); if(erval.encoded == -1) { for(; edx >= 0; edx--) FREEMEM(encoded_els[edx].buf); FREEMEM(encoded_els); return erval; } encoding_size += erval.encoded; eels_count++; } /* * Sort the encoded elements according to their encoding. */ qsort(encoded_els, eels_count, sizeof(encoded_els[0]), _el_buf_cmp); /* * Report encoded elements to the application. * Dispose of temporary sorted members table. */ ret = 0; for(edx = 0; edx < eels_count; edx++) { struct _el_buffer *encoded_el = &encoded_els[edx]; /* Report encoded chunks to the application */ if(ret == 0 && cb(encoded_el->buf, encoded_el->length, app_key) < 0) ret = -1; FREEMEM(encoded_el->buf); } FREEMEM(encoded_els); if(ret || computed_size != (size_t)encoding_size) { /* * Standard callback failed, or * encoded size is not equal to the computed size. */ erval.encoded = -1; erval.failed_type = td; erval.structure_ptr = ptr; } else { erval.encoded = computed_size; } ASN__ENCODED_OK(erval); }
/* * Encode OCTET STRING type using DER. */ asn_enc_rval_t OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr, int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) { asn_enc_rval_t er; asn_OCTET_STRING_specifics_t *specs = td->specifics ? (asn_OCTET_STRING_specifics_t *)td->specifics : &asn_DEF_OCTET_STRING_specs; BIT_STRING_t *st = (BIT_STRING_t *)sptr; enum asn_OS_Subvariant type_variant = specs->subvariant; int fix_last_byte = 0; ASN_DEBUG("%s %s as OCTET STRING", cb?"Estimating":"Encoding", td->name); /* * Write tags. */ if(type_variant != ASN_OSUBV_ANY || tag_mode == 1) { er.encoded = der_write_tags(td, (type_variant == ASN_OSUBV_BIT) + st->size, tag_mode, type_variant == ASN_OSUBV_ANY, tag, cb, app_key); if(er.encoded == -1) { er.failed_type = td; er.structure_ptr = sptr; return er; } } else { /* Disallow: [<tag>] IMPLICIT ANY */ assert(type_variant != ASN_OSUBV_ANY || tag_mode != -1); er.encoded = 0; } if(!cb) { er.encoded += (type_variant == ASN_OSUBV_BIT) + st->size; ASN__ENCODED_OK(er); } /* * Prepare to deal with the last octet of BIT STRING. */ if(type_variant == ASN_OSUBV_BIT) { uint8_t b = st->bits_unused & 0x07; if(b && st->size) fix_last_byte = 1; ASN__CALLBACK(&b, 1); er.encoded++; } /* Invoke callback for the main part of the buffer */ ASN__CALLBACK(st->buf, st->size - fix_last_byte); /* The last octet should be stripped off the unused bits */ if(fix_last_byte) { uint8_t b = st->buf[st->size-1] & (0xff << st->bits_unused); ASN__CALLBACK(&b, 1); } er.encoded += st->size; ASN__ENCODED_OK(er); cb_failed: ASN__ENCODE_FAILED; }
asn_enc_rval_t CHOICE_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; asn_TYPE_member_t *elm; /* CHOICE's element */ asn_per_constraint_t *ct; void *memb_ptr; int present; int present_enc; if(!sptr) ASN__ENCODE_FAILED; ASN_DEBUG("Encoding %s as CHOICE", td->name); if(constraints) ct = &constraints->value; else if(td->per_constraints) ct = &td->per_constraints->value; else ct = 0; present = _fetch_present_idx(sptr, specs->pres_offset, specs->pres_size); /* * If the structure was not initialized properly, it cannot be encoded: * can't deduce what to encode in the choice type. */ if(present <= 0 || present > td->elements_count) ASN__ENCODE_FAILED; else present--; ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present); /* Adjust if canonical order is different from natural order */ if(specs->canonical_order) present_enc = specs->canonical_order[present]; else present_enc = present; if(ct && ct->range_bits >= 0) { if(present_enc < ct->lower_bound || present_enc > ct->upper_bound) { if(ct->flags & APC_EXTENSIBLE) { if(per_put_few_bits(po, 1, 1)) ASN__ENCODE_FAILED; } else { ASN__ENCODE_FAILED; } ct = 0; } } if(ct && ct->flags & APC_EXTENSIBLE) if(per_put_few_bits(po, 0, 1)) ASN__ENCODE_FAILED; elm = &td->elements[present]; if(elm->flags & ATF_POINTER) { /* Member is a pointer to another structure */ memb_ptr = *(void **)((char *)sptr + elm->memb_offset); if(!memb_ptr) ASN__ENCODE_FAILED; } else { memb_ptr = (char *)sptr + elm->memb_offset; } if(ct && ct->range_bits >= 0) { if(per_put_few_bits(po, present_enc, ct->range_bits)) ASN__ENCODE_FAILED; return elm->type->uper_encoder(elm->type, elm->per_constraints, memb_ptr, po); } else { asn_enc_rval_t rval; if(specs->ext_start == -1) ASN__ENCODE_FAILED; if(uper_put_nsnnwn(po, present_enc - specs->ext_start)) ASN__ENCODE_FAILED; if(uper_open_type_put(elm->type, elm->per_constraints, memb_ptr, po)) ASN__ENCODE_FAILED; rval.encoded = 0; ASN__ENCODED_OK(rval); } }
asn_enc_rval_t CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr, int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) { asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; asn_TYPE_member_t *elm; /* CHOICE element */ asn_enc_rval_t erval; void *memb_ptr; size_t computed_size = 0; int present; if(!sptr) ASN__ENCODE_FAILED; ASN_DEBUG("%s %s as CHOICE", cb?"Encoding":"Estimating", td->name); present = _fetch_present_idx(sptr, specs->pres_offset, specs->pres_size); /* * If the structure was not initialized, it cannot be encoded: * can't deduce what to encode in the choice type. */ if(present <= 0 || present > td->elements_count) { if(present == 0 && td->elements_count == 0) { /* The CHOICE is empty?! */ erval.encoded = 0; ASN__ENCODED_OK(erval); } ASN__ENCODE_FAILED; } /* * Seek over the present member of the structure. */ elm = &td->elements[present-1]; if(elm->flags & ATF_POINTER) { memb_ptr = *(void **)((char *)sptr + elm->memb_offset); if(memb_ptr == 0) { if(elm->optional) { erval.encoded = 0; ASN__ENCODED_OK(erval); } /* Mandatory element absent */ ASN__ENCODE_FAILED; } } else { memb_ptr = (void *)((char *)sptr + elm->memb_offset); } /* * If the CHOICE itself is tagged EXPLICIT: * T ::= [2] EXPLICIT CHOICE { ... } * Then emit the appropriate tags. */ if(tag_mode == 1 || td->tags_count) { /* * For this, we need to pre-compute the member. */ ssize_t ret; /* Encode member with its tag */ erval = elm->type->der_encoder(elm->type, memb_ptr, elm->tag_mode, elm->tag, 0, 0); if(erval.encoded == -1) return erval; /* Encode CHOICE with parent or my own tag */ ret = der_write_tags(td, erval.encoded, tag_mode, 1, tag, cb, app_key); if(ret == -1) ASN__ENCODE_FAILED; computed_size += ret; } /* * Encode the single underlying member. */ erval = elm->type->der_encoder(elm->type, memb_ptr, elm->tag_mode, elm->tag, cb, app_key); if(erval.encoded == -1) return erval; ASN_DEBUG("Encoded CHOICE member in %ld bytes (+%ld)", (long)erval.encoded, (long)computed_size); erval.encoded += computed_size; return erval; }
asn_enc_rval_t NativeEnumerated_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) { asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics; asn_enc_rval_t er; long native, value; asn_per_constraint_t *ct; int inext = 0; asn_INTEGER_enum_map_t key; const asn_INTEGER_enum_map_t *kf; if(!sptr) ASN__ENCODE_FAILED; if(!specs) ASN__ENCODE_FAILED; if(constraints) ct = &constraints->value; else if(td->per_constraints) ct = &td->per_constraints->value; else ASN__ENCODE_FAILED; /* Mandatory! */ ASN_DEBUG("Encoding %s as NativeEnumerated", td->name); er.encoded = 0; native = *(long *)sptr; if(native < 0) ASN__ENCODE_FAILED; key.nat_value = native; kf = bsearch(&key, specs->value2enum, specs->map_count, sizeof(key), NativeEnumerated__compar_value2enum); if(!kf) { ASN_DEBUG("No element corresponds to %ld", native); ASN__ENCODE_FAILED; } value = kf - specs->value2enum; if(ct->range_bits >= 0) { int cmpWith = specs->extension ? specs->extension - 1 : specs->map_count; if(value >= cmpWith) inext = 1; } if(ct->flags & APC_EXTENSIBLE) { if(per_put_few_bits(po, inext, 1)) ASN__ENCODE_FAILED; if(inext) ct = 0; } else if(inext) { ASN__ENCODE_FAILED; } if(ct && ct->range_bits >= 0) { if(per_put_few_bits(po, value, ct->range_bits)) ASN__ENCODE_FAILED; ASN__ENCODED_OK(er); } if(!specs->extension) ASN__ENCODE_FAILED; /* * X.691, #10.6: normally small non-negative whole number; */ ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld", value, specs->extension, inext, value - (inext ? (specs->extension - 1) : 0)); if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0))) ASN__ENCODE_FAILED; ASN__ENCODED_OK(er); }
/* * The DER encoder of the SET OF type. */ asn_enc_rval_t SET_OF_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr, int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) { const asn_TYPE_member_t *elm = td->elements; const asn_anonymous_set_ *list = _A_CSET_FROM_VOID(sptr); size_t computed_size = 0; ssize_t encoding_size = 0; struct _el_buffer *encoded_els; int edx; ASN_DEBUG("Estimating size for SET OF %s", td->name); /* * Gather the length of the underlying members sequence. */ for(edx = 0; edx < list->count; edx++) { void *memb_ptr = list->array[edx]; asn_enc_rval_t erval; if(!memb_ptr) ASN__ENCODE_FAILED; erval = elm->type->op->der_encoder(elm->type, memb_ptr, 0, elm->tag, 0, 0); if(erval.encoded == -1) return erval; computed_size += erval.encoded; } /* * Encode the TLV for the sequence itself. */ encoding_size = der_write_tags(td, computed_size, tag_mode, 1, tag, cb, app_key); if(encoding_size < 0) { ASN__ENCODE_FAILED; } computed_size += encoding_size; if(!cb || list->count == 0) { asn_enc_rval_t erval; erval.encoded = computed_size; ASN__ENCODED_OK(erval); } ASN_DEBUG("Encoding members of %s SET OF", td->name); /* * DER mandates dynamic sorting of the SET OF elements * according to their encodings. Build an array of the * encoded elements. */ encoded_els = SET_OF__encode_sorted(elm, list, SOES_DER); /* * Report encoded elements to the application. * Dispose of temporary sorted members table. */ for(edx = 0; edx < list->count; edx++) { struct _el_buffer *encoded_el = &encoded_els[edx]; /* Report encoded chunks to the application */ if(cb(encoded_el->buf, encoded_el->length, app_key) < 0) { break; } else { encoding_size += encoded_el->length; } } SET_OF__encode_sorted_free(encoded_els, list->count); if(edx == list->count) { asn_enc_rval_t erval; assert(computed_size == (size_t)encoding_size); erval.encoded = computed_size; ASN__ENCODED_OK(erval); } else { ASN__ENCODE_FAILED; } }
asn_enc_rval_t SET_OF_encode_uper(const asn_TYPE_descriptor_t *td, const asn_per_constraints_t *constraints, const void *sptr, asn_per_outp_t *po) { const asn_anonymous_set_ *list; const asn_per_constraint_t *ct; const asn_TYPE_member_t *elm = td->elements; struct _el_buffer *encoded_els; asn_enc_rval_t er; size_t encoded_edx; if(!sptr) ASN__ENCODE_FAILED; list = _A_CSET_FROM_VOID(sptr); er.encoded = 0; ASN_DEBUG("Encoding %s as SEQUENCE OF (%d)", td->name, list->count); if(constraints) ct = &constraints->size; else if(td->encoding_constraints.per_constraints) ct = &td->encoding_constraints.per_constraints->size; else ct = 0; /* If extensible constraint, check if size is in root */ if(ct) { int not_in_root = (list->count < ct->lower_bound || list->count > ct->upper_bound); ASN_DEBUG("lb %ld ub %ld %s", ct->lower_bound, ct->upper_bound, ct->flags & APC_EXTENSIBLE ? "ext" : "fix"); if(ct->flags & APC_EXTENSIBLE) { /* Declare whether size is in extension root */ if(per_put_few_bits(po, not_in_root, 1)) ASN__ENCODE_FAILED; if(not_in_root) ct = 0; } else if(not_in_root && ct->effective_bits >= 0) { ASN__ENCODE_FAILED; } } if(ct && ct->effective_bits >= 0) { /* X.691, #19.5: No length determinant */ if(per_put_few_bits(po, list->count - ct->lower_bound, ct->effective_bits)) ASN__ENCODE_FAILED; } else if(list->count == 0) { /* When the list is empty add only the length determinant * X.691, #20.6 and #11.9.4.1 */ if (uper_put_length(po, 0, 0)) { ASN__ENCODE_FAILED; } ASN__ENCODED_OK(er); } /* * Canonical UPER #22.1 mandates dynamic sorting of the SET OF elements * according to their encodings. Build an array of the encoded elements. */ encoded_els = SET_OF__encode_sorted(elm, list, SOES_CUPER); for(encoded_edx = 0; (ssize_t)encoded_edx < list->count;) { ssize_t may_encode; size_t edx; int need_eom = 0; if(ct && ct->effective_bits >= 0) { may_encode = list->count; } else { may_encode = uper_put_length(po, list->count - encoded_edx, &need_eom); if(may_encode < 0) ASN__ENCODE_FAILED; } for(edx = encoded_edx; edx < encoded_edx + may_encode; edx++) { const struct _el_buffer *el = &encoded_els[edx]; if(asn_put_many_bits(po, el->buf, (8 * el->length) - el->bits_unused) < 0) { break; } } if(need_eom && uper_put_length(po, 0, 0)) ASN__ENCODE_FAILED; /* End of Message length */ encoded_edx += may_encode; } SET_OF__encode_sorted_free(encoded_els, list->count); if((ssize_t)encoded_edx == list->count) { ASN__ENCODED_OK(er); } else { ASN__ENCODE_FAILED; } }