/*-
 * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
 * Redistribution and modifications are permitted subject to BSD license.
 */
#include <asn_internal.h>
#include <INTEGER.h>
#include <OBJECT_IDENTIFIER.h>
#include <OCTET_STRING.h>
#include <limits.h>	/* for CHAR_BIT */
#include <errno.h>

/*
 * OBJECT IDENTIFIER basic type description.
 */
static const ber_tlv_tag_t asn_DEF_OBJECT_IDENTIFIER_tags[] = {
	(ASN_TAG_CLASS_UNIVERSAL | (6 << 2))
};
asn_TYPE_operation_t asn_OP_OBJECT_IDENTIFIER = {
	ASN__PRIMITIVE_TYPE_free,
	OBJECT_IDENTIFIER_print,
	OCTET_STRING_compare,   /* Implemented in terms of a string comparison */
	ber_decode_primitive,
	der_encode_primitive,
	OBJECT_IDENTIFIER_decode_xer,
	OBJECT_IDENTIFIER_encode_xer,
#ifdef	ASN_DISABLE_OER_SUPPORT
	0,
	0,
#else
	OBJECT_IDENTIFIER_decode_oer,
	OBJECT_IDENTIFIER_encode_oer,
#endif  /* ASN_DISABLE_OER_SUPPORT */
#ifdef	ASN_DISABLE_PER_SUPPORT
	0,
	0,
#else
	OCTET_STRING_decode_uper,
	OCTET_STRING_encode_uper,
#endif	/* ASN_DISABLE_PER_SUPPORT */
	OBJECT_IDENTIFIER_random_fill,
	0	/* Use generic outmost tag fetcher */
};
asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {
	"OBJECT IDENTIFIER",
	"OBJECT_IDENTIFIER",
	&asn_OP_OBJECT_IDENTIFIER,
	asn_DEF_OBJECT_IDENTIFIER_tags,
	sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
	    / sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
	asn_DEF_OBJECT_IDENTIFIER_tags,	/* Same as above */
	sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
	    / sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]),
	{ 0, 0, OBJECT_IDENTIFIER_constraint },
	0, 0,	/* No members */
	0	/* No specifics */
};

int
OBJECT_IDENTIFIER_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
		asn_app_constraint_failed_f *ctfailcb, void *app_key) {
	const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;

	if(st && st->buf) {
		if(st->size < 1) {
			ASN__CTFAIL(app_key, td, sptr,
				"%s: at least one numerical value "
				"expected (%s:%d)",
				td->name, __FILE__, __LINE__);
			return -1;
		}
	} else {
		ASN__CTFAIL(app_key, td, sptr,
			"%s: value not given (%s:%d)",
			td->name, __FILE__, __LINE__);
		return -1;
	}

	return 0;
}

static ssize_t
OBJECT_IDENTIFIER_get_first_arcs(const uint8_t *arcbuf, size_t arcbuf_len,
                                 asn_oid_arc_t *arc0, asn_oid_arc_t *arc1) {
    asn_oid_arc_t value;

    ssize_t rd = OBJECT_IDENTIFIER_get_single_arc(arcbuf, arcbuf_len, &value);
    if(rd <= 0) return rd;

    if(value >= 80) {
        *arc0 = 2;
        *arc1 = value - 80;
    } else if(value >= 40) {
        *arc0 = 1;
        *arc1 = value - 40;
    } else {
        *arc0 = 0;
        *arc1 = value;
    }

    return rd;
}

ssize_t
OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf, size_t arcbuf_len,
                                 asn_oid_arc_t *ret_value) {
    const uint8_t *b = arcbuf;
    const uint8_t *arcend = arcbuf + arcbuf_len; /* End of arc */

    if(arcbuf == arcend) {
        return 0;
    } else {
        asn_oid_arc_t accum;
        /* Gather all bits into the accumulator */
        for(accum = 0; b < arcend; b++) {
            accum = (accum << 7) | (*b & ~0x80);
            if((*b & 0x80) == 0) {
                if(accum <= ASN_OID_ARC_MAX) {
                    *ret_value = accum;
                    return 1 + (b - arcbuf);
                } else {
                    errno = ERANGE; /* Overflow */
                    return -1;
                }
            }
        }
        errno = EINVAL;
        return -1;
    }

}

static ssize_t
OBJECT_IDENTIFIER__dump_body(const OBJECT_IDENTIFIER_t *st,
                             asn_app_consume_bytes_f *cb, void *app_key) {
    char scratch[32];
    asn_oid_arc_t arc0, arc1;
    size_t produced = 0;
    size_t off = 0;
    ssize_t rd;
    int ret;

    rd = OBJECT_IDENTIFIER_get_first_arcs(st->buf, st->size, &arc0, &arc1);
    if(rd <= 0) {
        return -1;
    }

    ret = snprintf(scratch, sizeof(scratch), "%"PRIu32".%"PRIu32, arc0, arc1);
    if(ret >= (ssize_t)sizeof(scratch)) {
        return -1;
    }
    produced += ret;
    if(cb(scratch, ret, app_key) < 0)
        return -1;

    for(off = rd; ; ) {
        asn_oid_arc_t arc;
        rd = OBJECT_IDENTIFIER_get_single_arc(st->buf + off, st->size - off,
                                              &arc);
        if(rd < 0) {
            return -1;
        } else if(rd == 0) {
            /* No more arcs. */
            break;
        } else {
            off += rd;
            assert(off <= st->size);
            ret = snprintf(scratch, sizeof(scratch), ".%" PRIu32, arc);
            if(ret >= (ssize_t)sizeof(scratch)) {
                return -1;
            }
            produced += ret;
            if(cb(scratch, ret, app_key) < 0) return -1;
        }
    }

    if(off != st->size) {
        ASN_DEBUG("Could not scan to the end of Object Identifier");
        return -1;
    }

	return produced;
}

static enum xer_pbd_rval
OBJECT_IDENTIFIER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {
	OBJECT_IDENTIFIER_t *st = (OBJECT_IDENTIFIER_t *)sptr;
	const char *chunk_end = (const char *)chunk_buf + chunk_size;
	const char *endptr;
	asn_oid_arc_t s_arcs[10];
	asn_oid_arc_t *arcs = s_arcs;
	ssize_t num_arcs;
	ssize_t ret;

	(void)td;

    num_arcs = OBJECT_IDENTIFIER_parse_arcs(
        (const char *)chunk_buf, chunk_size, arcs,
        sizeof(s_arcs) / sizeof(s_arcs[0]), &endptr);
    if(num_arcs < 0) {
		/* Expecting more than zero arcs */
		return XPBD_BROKEN_ENCODING;
	} else if(num_arcs == 0) {
		return XPBD_NOT_BODY_IGNORE;
	}
	assert(endptr == chunk_end);

	if((size_t)num_arcs > sizeof(s_arcs)/sizeof(s_arcs[0])) {
		arcs = (asn_oid_arc_t *)MALLOC(num_arcs * sizeof(asn_oid_arc_t));
		if(!arcs) return XPBD_SYSTEM_FAILURE;
        ret = OBJECT_IDENTIFIER_parse_arcs((const char *)chunk_buf, chunk_size,
                                           arcs, num_arcs, &endptr);
        if(ret != num_arcs)
			return XPBD_SYSTEM_FAILURE;	/* assert?.. */
	}

	/*
	 * Convert arcs into BER representation.
	 */
	ret = OBJECT_IDENTIFIER_set_arcs(st, arcs, num_arcs);
	if(arcs != s_arcs) FREEMEM(arcs);

	return ret ? XPBD_SYSTEM_FAILURE : XPBD_BODY_CONSUMED;
}

asn_dec_rval_t
OBJECT_IDENTIFIER_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
	asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
		const void *buf_ptr, size_t size) {

	return xer_decode_primitive(opt_codec_ctx, td,
		sptr, sizeof(OBJECT_IDENTIFIER_t), opt_mname,
			buf_ptr, size, OBJECT_IDENTIFIER__xer_body_decode);
}

asn_enc_rval_t
OBJECT_IDENTIFIER_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 OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;
	asn_enc_rval_t er;

    (void)ilevel;
    (void)flags;

    if(!st || !st->buf) {
        ASN__ENCODE_FAILED;
    }

    er.encoded = OBJECT_IDENTIFIER__dump_body(st, cb, app_key);
    if(er.encoded < 0) ASN__ENCODE_FAILED;

    ASN__ENCODED_OK(er);
}

int
OBJECT_IDENTIFIER_print(asn_TYPE_descriptor_t *td, const void *sptr,
	int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
	const OBJECT_IDENTIFIER_t *st = (const OBJECT_IDENTIFIER_t *)sptr;

	(void)td;	/* Unused argument */
	(void)ilevel;	/* Unused argument */

	if(!st || !st->buf)
		return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;

	/* Dump preamble */
	if(cb("{ ", 2, app_key) < 0)
		return -1;

    if(OBJECT_IDENTIFIER__dump_body(st, cb, app_key) < 0) {
        return -1;
    }

    return (cb(" }", 2, app_key) < 0) ? -1 : 0;
}

ssize_t
OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *st, asn_oid_arc_t *arcs,
                           size_t arc_slots) {
    asn_oid_arc_t arc0, arc1;
    size_t num_arcs = 0;
    size_t off;
    ssize_t rd;

    if(!st || !st->buf) {
        errno = EINVAL;
        return -1;
    }

    rd = OBJECT_IDENTIFIER_get_first_arcs(st->buf, st->size, &arc0, &arc1);
    if(rd <= 0) {
        return -1;
    }
    num_arcs = 2;
    switch(arc_slots) {
    default:
    case 2:
        arcs[1] = arc1;
        /* Fall through */
    case 1:
        arcs[0] = arc0;
        /* Fall through */
    case 0:
        break;
    }

    for(off = rd; ; ) {
        asn_oid_arc_t arc;
        rd = OBJECT_IDENTIFIER_get_single_arc(st->buf + off, st->size - off,
                                              &arc);
        if(rd < 0) {
            return -1;
        } else if(rd == 0) {
            /* No more arcs. */
            break;
        } else {
            off += rd;
            if(num_arcs < arc_slots) {
                arcs[num_arcs] = arc;
            }
            num_arcs++;
        }
    }

    if(off != st->size) {
        return -1;
    }

    return num_arcs;
}


/*
 * Save the single value as an object identifier arc.
 */
ssize_t
OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf, size_t arcbuf_len,
                                 asn_oid_arc_t value) {
    /*
	 * The following conditions must hold:
	 * assert(arcbuf);
	 */
    uint8_t scratch[((sizeof(value) * CHAR_BIT + 6) / 7)];
    uint8_t *scratch_end = &scratch[sizeof(scratch)-1];
    uint8_t *b;
    size_t result_len;
    uint8_t mask;

    for(b = scratch_end, mask = 0; ; mask = 0x80, b--) {
        *b = mask | (value & 0x7f);
        value >>= 7;
        if(!value) {
            break;
        }
    }

    result_len = (scratch_end - b) + 1;

    if(result_len > arcbuf_len) {
        return -1;
    }

    memcpy(arcbuf, b, result_len);

	return result_len;
}

int
OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *st, const asn_oid_arc_t *arcs,
                           size_t arc_slots) {
    uint8_t *buf;
    uint8_t *bp;
    size_t wrote;
    asn_oid_arc_t arc0;
    asn_oid_arc_t arc1;
    size_t size;
    size_t i;

    if(!st || !arcs || arc_slots < 2) {
        errno = EINVAL;
		return -1;
	}

    arc0 = arcs[0];
    arc1 = arcs[1];

	if(arc0 <= 1) {
		if(arc1 >= 40) {
			/* 8.19.4: At most 39 subsequent values (including 0) */
			errno = ERANGE;
			return -1;
		}
    } else if(arc0 == 2) {
        if(arc1 > ASN_OID_ARC_MAX - 80) {
            errno = ERANGE;
            return -1;
        }
    } else if(arc0 > 2) {
        /* 8.19.4: Only three values are allocated from the root node */
        errno = ERANGE;
        return -1;
    }

    /*
	 * After above tests it is known that the value of arc0 is completely
	 * trustworthy (0..2). However, the arc1's value is still meaningless.
	 */

    /*
     * Roughly estimate the maximum size necessary to encode these arcs.
     * This estimation implicitly takes in account the following facts,
     * that cancel each other:
     * 	* the first two arcs are encoded in a single value.
     * 	* the first value may require more space (+1 byte)
     * 	* the value of the first arc which is in range (0..2)
     */
    size = ((sizeof(asn_oid_arc_t) * CHAR_BIT + 6) / 7) * arc_slots;
    bp = buf = (uint8_t *)MALLOC(size + 1);
    if(!buf) {
        /* ENOMEM */
        return -1;
    }

    wrote = OBJECT_IDENTIFIER_set_single_arc(bp, size, arc0 * 40 + arc1);
    if(wrote <= 0) {
        FREEMEM(buf);
        return -1;
    }
    assert(wrote <= size);
    bp += wrote;
    size -= wrote;

    for(i = 2; i < arc_slots; i++) {
		wrote = OBJECT_IDENTIFIER_set_single_arc(bp, size, arcs[i]);
        if(wrote <= 0) {
            FREEMEM(buf);
            return -1;
        }
        assert(wrote <= size);
        bp += wrote;
        size -= wrote;
        assert(wrote <= size);
    }

    assert(size >= 0);

    /*
	 * Replace buffer.
	 */
	st->size = bp - buf;
	bp = st->buf;
	st->buf = buf;
	st->buf[st->size] = '\0';
	if(bp) FREEMEM(bp);

	return 0;
}

ssize_t
OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
                             asn_oid_arc_t *arcs, size_t arcs_count,
                             const char **opt_oid_text_end) {
    size_t num_arcs = 0;
    const char *oid_end;
	enum {
		ST_LEADSPACE,
		ST_TAILSPACE,
		ST_AFTERVALUE,	/* Next character ought to be '.' or a space */
		ST_WAITDIGITS 	/* Next character is expected to be a digit */
	} state = ST_LEADSPACE;

	if(!oid_text || oid_txt_length < -1 || (arcs_count && !arcs)) {
		if(opt_oid_text_end) *opt_oid_text_end = oid_text;
		errno = EINVAL;
		return -1;
	}

	if(oid_txt_length == -1)
		oid_txt_length = strlen(oid_text);

#define _OID_CAPTURE_ARC(oid_text, oid_end)                       \
    do {                                                          \
        const char *endp = oid_end;                               \
        unsigned long value;                                      \
        switch(asn_strtoul_lim(oid_text, &endp, &value)) {        \
        case ASN_STRTOX_EXTRA_DATA:                               \
        case ASN_STRTOX_OK:                                       \
            if(value <= ASN_OID_ARC_MAX) {                        \
                if(num_arcs < arcs_count) arcs[num_arcs] = value; \
                num_arcs++;                                       \
                oid_text = endp - 1;                              \
                break;                                            \
            }                                                     \
            /* Fall through */                                    \
        case ASN_STRTOX_ERROR_RANGE:                              \
            if(opt_oid_text_end) *opt_oid_text_end = oid_text;    \
            errno = ERANGE;                                       \
            return -1;                                            \
        case ASN_STRTOX_ERROR_INVAL:                              \
        case ASN_STRTOX_EXPECT_MORE:                              \
            if(opt_oid_text_end) *opt_oid_text_end = oid_text;    \
            errno = EINVAL;                                       \
            return -1;                                            \
        }                                                         \
    } while(0)

    for(oid_end = oid_text + oid_txt_length; oid_text<oid_end; oid_text++) {
	    switch(*oid_text) {
	    case 0x09: case 0x0a: case 0x0d: case 0x20:	/* whitespace */
		switch(state) {
		case ST_LEADSPACE:
		case ST_TAILSPACE:
			continue;
		case ST_AFTERVALUE:
			state = ST_TAILSPACE;
			continue;
		case ST_WAITDIGITS:
			break;	/* Digits expected after ".", got whitespace */
		}
		break;
	    case 0x2e:	/* '.' */
		switch(state) {
		case ST_LEADSPACE:
		case ST_TAILSPACE:
		case ST_WAITDIGITS:
			if(opt_oid_text_end)
				*opt_oid_text_end = oid_text;
			errno = EINVAL;	/* Broken OID */
			return -1;
			break;
		case ST_AFTERVALUE:
			state = ST_WAITDIGITS;
			continue;
		}
		break;
	    case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
	    case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
		switch(state) {
		case ST_TAILSPACE:
		case ST_AFTERVALUE:
			if(opt_oid_text_end)
				*opt_oid_text_end = oid_text;
			errno = EINVAL;	/* "1. 1" => broken OID */
			return -1;
		case ST_LEADSPACE:
		case ST_WAITDIGITS:
			_OID_CAPTURE_ARC(oid_text, oid_end);
			state = ST_AFTERVALUE;
			continue;
		}
		break;
	    default:
		/* Unexpected symbols */
		state = ST_WAITDIGITS;
		break;
	    } /* switch() */
	    break;
	} /* for() */


	if(opt_oid_text_end) *opt_oid_text_end = oid_text;

	/* Finalize last arc */
	switch(state) {
	case ST_LEADSPACE:
		return 0; /* No OID found in input data */
	case ST_WAITDIGITS:
		errno = EINVAL;	/* Broken OID */
		return -1;
	case ST_AFTERVALUE:
	case ST_TAILSPACE:
		return num_arcs;
	}

	errno = EINVAL;	/* Broken OID */
	return -1;
}

/*
 * Generate values from the list of interesting values, or just a random
 * value up to the upper limit.
 */
static asn_oid_arc_t
OBJECT_IDENTIFIER__biased_random_arc(asn_oid_arc_t upper_bound) {
    const asn_oid_arc_t values[] = {0, 1, 127, 128, 129, 254, 255, 256};
    size_t idx;

    switch(asn_random_between(0, 2)) {
    case 0:
        idx = asn_random_between(0, sizeof(values) / sizeof(values[0]) - 1);
        if(values[idx] < upper_bound) {
            return values[idx];
        }
        /* Fall through */
    case 1:
        return asn_random_between(0, upper_bound);
    case 2:
    default:
        return upper_bound;
    }
}

asn_random_fill_result_t
OBJECT_IDENTIFIER_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
                              const asn_encoding_constraints_t *constraints,
                              size_t max_length) {
    asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
    asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
    asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
    OBJECT_IDENTIFIER_t *st;
    asn_oid_arc_t arcs[5];
    size_t arcs_len = asn_random_between(2, 5);
    size_t i;

    (void)constraints;

    if(max_length < arcs_len) return result_skipped;

    if(*sptr) {
        st = *sptr;
    } else {
        st = CALLOC(1, sizeof(*st));
    }

    arcs[0] = asn_random_between(0, 2);
    arcs[1] = OBJECT_IDENTIFIER__biased_random_arc(
        arcs[0] <= 1 ? 39 : (ASN_OID_ARC_MAX - 80));
    for(i = 2; i < arcs_len; i++) {
        arcs[i] = OBJECT_IDENTIFIER__biased_random_arc(ASN_OID_ARC_MAX);
    }

    if(OBJECT_IDENTIFIER_set_arcs(st, arcs, arcs_len)) {
        if(st != *sptr) {
            ASN_STRUCT_FREE(*td, st);
        }
        return result_failed;
    }

    *sptr = st;

    result_ok.length = st->size;
    return result_ok;
}
