Exemple #1
0
static size_t decode_len(const uint8_t **ptr, const uint8_t *end)
{
	const uint8_t *tmp = *ptr;
	size_t ret;

	if ( ber_len_form_short(*tmp) ) {
		ret = ber_len_short(*tmp);
		tmp++;
	}else{
		size_t i, l;

		l = ber_len_short(*tmp);
		if ( l > 4 || tmp + l > end ) {
			*ptr = end;
			return 1;
		}

		tmp++;
		for(ret = i = 0; i < l; i++, tmp++) {
			ret <<= 8;
			ret |= *tmp;
		}

	}

	*ptr = tmp;
	return ret;
}
Exemple #2
0
static const uint8_t *do_decode_tag(struct gber_tag *tag,
				const uint8_t *ptr, size_t len)
{
	const uint8_t *end = ptr + len;

	if ( len  < 2 ) {
		printf("block too small\n");
		return NULL;
	}

	tag->ber_id = *(ptr++);
	tag->ber_tag = tag->ber_id;
	if ( (tag->ber_id & 0x1f) == 0x1f ) {
		if ( (*ptr & 0x80) ) {
			printf("bad id\n");
			return NULL;
		}
		tag->ber_tag <<= 8;
		tag->ber_tag |= *(ptr++);
		if ( ptr >= end ) {
			printf("tag too big\n");
			return NULL;
		}
	}

	if ( ber_len_form_short(*ptr) ) {
		tag->ber_len = ber_len_short(*ptr);
		ptr++;
	}else{
		unsigned int i;
		uint8_t ll;

		ll = ber_len_short(*(ptr++));
		if ( ptr + ll > end || ll > 4 ) {
			printf("tag past end\n");
			return NULL;
		}

		for(tag->ber_len = 0, i = 0; i < ll; i++, ptr++) {
			tag->ber_len <<= 8;
			tag->ber_len |= *ptr;
		}
	}

	return ptr;
}
Exemple #3
0
static const uint8_t *do_decode_tag(struct gber_tag *tag,
				const uint8_t *ptr, size_t len)
{
	const uint8_t *end = ptr + len;

	if ( len < 2 )
		return NULL;

	tag->ber_id = *(ptr++);
	tag->ber_tag = tag->ber_id;
	if ( (tag->ber_id & 0x1f) == 0x1f ) {
		if ( (*ptr & 0x80) )
			return NULL;
		tag->ber_tag <<= 8;
		tag->ber_tag |= *(ptr++);
		if ( ptr >= end )
			return NULL;
	}

	if ( ber_len_form_short(*ptr) ) {
		tag->ber_len = ber_len_short(*ptr);
		ptr++;
	}else{
		unsigned int i;
		uint8_t ll;

		ll = ber_len_short(*(ptr++));
		if ( ptr + ll > end || ll > 4 )
			return NULL;

		for(tag->ber_len = 0, i = 0; i < ll; i++, ptr++) {
			tag->ber_len <<= 8;
			tag->ber_len |= *ptr;
		}
	}

	return ptr;
}
Exemple #4
0
void ber_dump(const uint8_t *buf, size_t len, unsigned int depth)
{
	const uint8_t *end = buf + len;
	uint32_t clen, num, i;
	uint8_t idb;
#if 0
	const char * const clsname[]={
		"universal",
		"application",
		"context-specific",
		"private",
	};
#endif
again:
	if ( buf >= end )
		return;

	idb = *buf;
	num = ber_id_octet_tag(*buf);
	buf++;

	/* FIXME: if ( tag == 0x1f ) get rest of type... */
	if ( num >= 0x1f ) {
		for(num = 0, i = 0; buf < end; i++) {
			num <<= 7;
			num |= *buf & 0x7f;
			buf++;
			if ( !(*buf & 0x80) )
				break;
		}
	}

	printf("%*c.tag = %u (0x%x)\n", depth, ' ', num, num);

	if ( buf >= end )
		return;

	if ( ber_len_form_short(*buf) ) {
		clen = ber_len_short(*buf);
		buf++;
	}else{
		uint32_t l;

		l = ber_len_short(*buf);
		if ( l > 4 || buf + l > end )
			return;
		buf++;
		for(clen = i = 0; i < l; i++, buf++) {
			clen <<= 8;
			clen |= *buf;
		}

	}

	if ( buf + clen > end )
		return;

	printf("%*c.len = %zu (0x%zx)",
		depth, ' ', len, len);

	if ( ber_id_octet_constructed(idb) ) {
		printf(" {\n");
		ber_dump(buf, clen, depth + 2);
		printf("%*c}\n", depth, ' ');
	}else{
		printf("\n");
		hex_dump(buf, clen, 16, depth);
	}

	buf += clen;
	goto again;
}