OBJECT IDENTIFIER and RELATIVE-OID OER encoding and randomized testing
diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c
index 039a973..86fee46 100644
--- a/skeletons/OBJECT_IDENTIFIER.c
+++ b/skeletons/OBJECT_IDENTIFIER.c
@@ -27,8 +27,8 @@
0,
0,
#else
- 0,
- 0,
+ OBJECT_IDENTIFIER_decode_oer,
+ OBJECT_IDENTIFIER_encode_oer,
#endif /* ASN_DISABLE_OER_SUPPORT */
#ifdef ASN_DISABLE_PER_SUPPORT
0,
@@ -784,17 +784,23 @@
* value up to the upper limit.
*/
static uint32_t
-OBJECT_IDENTIFIER__biased_random_arc(int32_t upper_bound) {
+OBJECT_IDENTIFIER__biased_random_arc(uint32_t upper_bound) {
static const uint16_t values[] = {0, 1, 127, 128, 129, 254, 255, 256};
+ size_t idx;
- size_t idx = asn_random_between(0, 2 * sizeof(values)/sizeof(values[0]));
- if(idx < sizeof(values) / sizeof(values[0])) {
+ 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;
}
-
- return asn_random_between(0, upper_bound);
}
asn_random_fill_result_t
@@ -821,9 +827,9 @@
arcs[0] = asn_random_between(0, 2);
arcs[1] =
- OBJECT_IDENTIFIER__biased_random_arc(arcs[0] <= 1 ? 39 : INT32_MAX);
+ OBJECT_IDENTIFIER__biased_random_arc(arcs[0] <= 1 ? 39 : UINT_MAX);
for(i = 2; i < arcs_len; i++) {
- arcs[i] = OBJECT_IDENTIFIER__biased_random_arc(INT32_MAX);
+ arcs[i] = OBJECT_IDENTIFIER__biased_random_arc(UINT_MAX);
}
if(OBJECT_IDENTIFIER_set_arcs(st, arcs, sizeof(arcs[0]), arcs_len)) {
diff --git a/skeletons/OBJECT_IDENTIFIER.h b/skeletons/OBJECT_IDENTIFIER.h
index 02dde9c..d160e43 100644
--- a/skeletons/OBJECT_IDENTIFIER.h
+++ b/skeletons/OBJECT_IDENTIFIER.h
@@ -30,6 +30,8 @@
#define OBJECT_IDENTIFIER_compare OCTET_STRING_compare
#define OBJECT_IDENTIFIER_decode_ber ber_decode_primitive
#define OBJECT_IDENTIFIER_encode_der der_encode_primitive
+#define OBJECT_IDENTIFIER_decode_oer oer_decode_primitive
+#define OBJECT_IDENTIFIER_encode_oer oer_encode_primitive
#define OBJECT_IDENTIFIER_decode_uper OCTET_STRING_decode_uper
#define OBJECT_IDENTIFIER_encode_uper OCTET_STRING_encode_uper
diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c
index 6edecfa..33bfd4a 100644
--- a/skeletons/RELATIVE-OID.c
+++ b/skeletons/RELATIVE-OID.c
@@ -28,8 +28,8 @@
0,
0,
#else
- 0,
- 0,
+ RELATIVE_OID_decode_oer,
+ RELATIVE_OID_encode_oer,
#endif /* ASN_DISABLE_OER_SUPPORT */
#ifdef ASN_DISABLE_PER_SUPPORT
0,
@@ -262,12 +262,16 @@
RELATIVE_OID__biased_random_arc() {
static const uint16_t values[] = {0, 1, 127, 128, 129, 254, 255, 256};
- size_t idx = asn_random_between(0, 2 * sizeof(values)/sizeof(values[0]));
- if(idx < sizeof(values) / sizeof(values[0])) {
- return values[idx];
+ switch(asn_random_between(0, 2)) {
+ case 0:
+ return values[asn_random_between(
+ 0, sizeof(values) / sizeof(values[0]) - 1)];
+ case 1:
+ return asn_random_between(0, UINT_MAX);
+ case 2:
+ default:
+ return UINT_MAX;
}
-
- return asn_random_between(0, INT32_MAX);
}
asn_random_fill_result_t
@@ -278,8 +282,9 @@
asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
RELATIVE_OID_t *st;
+ const int min_arcs = 1; /* A minimum of 1 arc is required */
+ size_t arcs_len = asn_random_between(min_arcs, 3);
uint32_t arcs[3];
- size_t arcs_len = asn_random_between(0, 3);
size_t i;
(void)constraints;
diff --git a/skeletons/RELATIVE-OID.h b/skeletons/RELATIVE-OID.h
index f24c392..1eaf559 100644
--- a/skeletons/RELATIVE-OID.h
+++ b/skeletons/RELATIVE-OID.h
@@ -27,6 +27,8 @@
#define RELATIVE_OID_constraint asn_generic_no_constraint
#define RELATIVE_OID_decode_ber ber_decode_primitive
#define RELATIVE_OID_encode_der der_encode_primitive
+#define RELATIVE_OID_decode_oer oer_decode_primitive
+#define RELATIVE_OID_encode_oer oer_encode_primitive
#define RELATIVE_OID_decode_uper OCTET_STRING_decode_uper
#define RELATIVE_OID_encode_uper OCTET_STRING_encode_uper
diff --git a/skeletons/oer_decoder.c b/skeletons/oer_decoder.c
index e803ad2..386e846 100644
--- a/skeletons/oer_decoder.c
+++ b/skeletons/oer_decoder.c
@@ -3,6 +3,7 @@
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
+#include <asn_codecs_prim.h>
/*
* The OER decoder of any type.
@@ -91,3 +92,58 @@
}
}
+
+asn_dec_rval_t
+oer_decode_primitive(const asn_codec_ctx_t *opt_codec_ctx,
+ asn_TYPE_descriptor_t *td,
+ const asn_oer_constraints_t *constraints, void **sptr,
+ const void *ptr, size_t size) {
+ ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr;
+ asn_dec_rval_t rval = {RC_OK, 0};
+ size_t expected_length = 0;
+ ssize_t len_len;
+
+ (void)opt_codec_ctx;
+ (void)constraints;
+
+ if(!st) {
+ st = (ASN__PRIMITIVE_TYPE_t *)(*sptr = CALLOC(
+ 1, sizeof(ASN__PRIMITIVE_TYPE_t)));
+ if(!st) ASN__DECODE_FAILED;
+ }
+
+
+ /*
+ * X.696 (08/2015) #27.2
+ * Encode length determinant as _number of octets_, but only
+ * if upper bound is not equal to lower bound.
+ */
+ len_len = oer_fetch_length(ptr, size, &expected_length);
+ if(len_len > 0) {
+ rval.consumed = len_len;
+ ptr = (const char *)ptr + len_len;
+ size -= len_len;
+ } else if(len_len == 0) {
+ ASN__DECODE_STARVED;
+ } else if(len_len < 0) {
+ ASN__DECODE_FAILED;
+ }
+
+ if(size < expected_length) {
+ ASN__DECODE_STARVED;
+ } else {
+ uint8_t *buf = MALLOC(expected_length + 1);
+ if(buf == NULL) {
+ ASN__DECODE_FAILED;
+ } else {
+ memcpy(buf, ptr, expected_length);
+ buf[expected_length] = '\0';
+ }
+ FREEMEM(st->buf);
+ st->buf = buf;
+ st->size = expected_length;
+
+ rval.consumed += expected_length;
+ return rval;
+ }
+}
diff --git a/skeletons/oer_decoder.h b/skeletons/oer_decoder.h
index bf4bc08..c5e9744 100644
--- a/skeletons/oer_decoder.h
+++ b/skeletons/oer_decoder.h
@@ -59,6 +59,11 @@
const asn_oer_constraints_t *constraints,
void **struct_ptr, const void *bufptr, size_t size);
+/*
+ * Length-prefixed buffer decoding for primitive types.
+ */
+oer_type_decoder_f oer_decode_primitive;
+
#ifdef __cplusplus
}
diff --git a/skeletons/oer_encoder.c b/skeletons/oer_encoder.c
index af3c7d1..a6f7a78 100644
--- a/skeletons/oer_encoder.c
+++ b/skeletons/oer_encoder.c
@@ -3,6 +3,7 @@
* Redistribution and modifications are permitted subject to BSD license.
*/
#include <asn_internal.h>
+#include <asn_codecs_prim.h>
/*
* The OER encoder of any type.
@@ -76,3 +77,35 @@
}
return ec;
}
+
+asn_enc_rval_t
+oer_encode_primitive(asn_TYPE_descriptor_t *td,
+ const asn_oer_constraints_t *constraints, 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 (%zu 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);
+ }
+}
+
diff --git a/skeletons/oer_encoder.h b/skeletons/oer_encoder.h
index f474a7b..3150b5c 100644
--- a/skeletons/oer_encoder.h
+++ b/skeletons/oer_encoder.h
@@ -46,6 +46,11 @@
);
+/*
+ * Length-prefixed buffer encoding for primitive types.
+ */
+oer_type_encoder_f oer_encode_primitive;
+
#ifdef __cplusplus
}
#endif
diff --git a/tests/tests-randomized/Makefile.am b/tests/tests-randomized/Makefile.am
index 1547da0..a02982b 100644
--- a/tests/tests-randomized/Makefile.am
+++ b/tests/tests-randomized/Makefile.am
@@ -31,6 +31,8 @@
TESTS += bundles/05-BIT-STRING-bundle.txt
TESTS += bundles/06-OCTET-STRING-bundle.txt
TESTS += bundles/07-VisibleString-bundle.txt
+TESTS += bundles/08-OBJECT-IDENTIFIER-bundle.txt
+TESTS += bundles/09-RELATIVE-OID-bundle.txt
EXTRA_DIST = \
random-test-driver.c \