Пример #1
0
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);
}
Пример #2
0
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;
	}
}
Пример #3
0
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);
    }
}
Пример #4
0
/*
 * 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);
}
Пример #5
0
/*
 * 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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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);
}
Пример #9
0
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);
}
Пример #10
0
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);
}
Пример #11
0
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);
}
Пример #12
0
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;
}
Пример #13
0
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);
}
Пример #14
0
/*
 * 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);
}
Пример #15
0
/*
 * 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;
}
Пример #16
0
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);
	}
}
Пример #17
0
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;
}
Пример #18
0
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);
}
Пример #19
0
/*
 * 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;
    }
}
Пример #20
0
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;
    }
}