diff --git a/AUTHORS b/AUTHORS index d510bcdee..e18cc19f5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1,5 @@ Lev Walkin + +MDER SUPPORT: + Santiago Carot-Nemesio + Jose Antonio Santos-Cadenas diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c index be7f059af..6aefef8e2 100644 --- a/libasn1compiler/asn1c_C.c +++ b/libasn1compiler/asn1c_C.c @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2003 Lev Walkin . + * Copyright (c) 2010 Jose Antonio Santos-Cadenas . + * Copyright (c) 2010 Santiago Carot-Nemesio . + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ + /* * Don't look into this file. First, because it's a mess, and second, because * it's a brain of the compiler, and you don't wanna mess with brains do you? ;) @@ -42,8 +50,10 @@ static int expr_as_xmlvaluelist(arg_t *arg, asn1p_expr_t *expr); static int expr_elements_count(arg_t *arg, asn1p_expr_t *expr); static int emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int juscountvalues, char *type); static int emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx); +static int emit_member_MDER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx); static int emit_member_table(arg_t *arg, asn1p_expr_t *expr); static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count, const char *opt_modifier); +static int emit_MDER_tag2member_table(arg_t *arg, tag2el_t *tag2el, int tag2el_count); static int emit_include_dependencies(arg_t *arg); static asn1p_expr_t *terminal_structable(arg_t *arg, asn1p_expr_t *expr); static int expr_defined_recursively(arg_t *arg, asn1p_expr_t *expr); @@ -924,6 +934,7 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) { int all_tags_count; enum tvm_compat tv_mode; int *cmap = 0; + int genMder; /* * Fetch every inner tag from the tag to elements map. @@ -992,6 +1003,11 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) { */ emit_tag2member_map(arg, tag2el, tag2el_count, 0); + /* + * Generate choice_ids for MDER coder/decoder + */ + genMder = emit_MDER_tag2member_table(arg, tag2el, tag2el_count); + OUT("static asn_CHOICE_specifics_t asn_SPC_%s_specs_%d = {\n", MKID(expr), expr->_type_unique_index); INDENTED( @@ -1015,8 +1031,14 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) { MKID(expr), expr->_type_unique_index); else OUT("0,\n"); if(C99_MODE) OUT(".ext_start = "); - OUT("%d\t/* Extensions start */\n", + OUT("%d,\t/* Extensions start */\n", compute_extensions_start(expr)); + if(C99_MODE) OUT(".sorted_tags = "); + if(genMder) + OUT("asn_MDER_tag2member_%s_table%d\n", + MKID(expr), expr->_type_unique_index); + else + OUT("0\t/* Invalid definition of choice type for MDER */\n"); ); OUT("};\n"); @@ -1238,6 +1260,8 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { OUT("td->print_struct = asn_DEF_%s.print_struct;\n", type_name); OUT("td->ber_decoder = asn_DEF_%s.ber_decoder;\n", type_name); OUT("td->der_encoder = asn_DEF_%s.der_encoder;\n", type_name); + OUT("td->mder_decoder = asn_DEF_%s.mder_decoder;\n", type_name); + OUT("td->mder_encoder = asn_DEF_%s.mder_encoder;\n", type_name); OUT("td->xer_decoder = asn_DEF_%s.xer_decoder;\n", type_name); OUT("td->xer_encoder = asn_DEF_%s.xer_encoder;\n", type_name); OUT("td->uper_decoder = asn_DEF_%s.uper_decoder;\n", type_name); @@ -1331,6 +1355,38 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { OUT("}\n"); OUT("\n"); + p = MKID(expr); + if(HIDE_INNER_DEFS) OUT("static "); + OUT("asn_enc_rval_t\n"); + OUT("%s", p); + if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index); + OUT("_encode_mder(asn_TYPE_descriptor_t *td,\n"); + INDENTED( + OUT("\tvoid *structure, asn_mder_contraints_t constr,\n"); + OUT("\tasn_app_consume_bytes_f *cb, void *app_key) {\n"); + OUT("%s_%d_inherit_TYPE_descriptor(td);\n", + p, expr->_type_unique_index); + OUT("return td->mder_encoder(td, structure, constr, cb, app_key);\n"); + ); + OUT("}\n"); + OUT("\n"); + + p = MKID(expr); + if(HIDE_INNER_DEFS) OUT("static "); + OUT("asn_dec_rval_t\n"); + OUT("%s", p); + if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index); + OUT("_decode_mder(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n"); + INDENTED( + OUT("\tvoid **structure, const void *bufptr, size_t size,\n"); + OUT("\tasn_mder_contraints_t constr) {\n"); + OUT("%s_%d_inherit_TYPE_descriptor(td);\n", + p, expr->_type_unique_index); + OUT("return td->mder_decoder(opt_codec_ctx, td, structure, bufptr, size, constr);\n"); + ); + OUT("}\n"); + OUT("\n"); + p = MKID(expr); if(HIDE_INNER_DEFS) OUT("static "); OUT("asn_dec_rval_t\n"); @@ -1410,6 +1466,8 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) { OUT("asn_constr_check_f %s_constraint;\n", p); OUT("ber_type_decoder_f %s_decode_ber;\n", p); OUT("der_type_encoder_f %s_encode_der;\n", p); + OUT("mder_type_decoder_f %s_decode_mder;\n", p); + OUT("mder_type_encoder_f %s_encode_mder;\n", p); OUT("xer_type_decoder_f %s_decode_xer;\n", p); OUT("xer_type_encoder_f %s_encode_xer;\n", p); if(arg->flags & A1C_GEN_PER) { @@ -1681,6 +1739,68 @@ emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count, const char * return 0; } +static int +emit_MDER_tag2member_table(arg_t *arg, tag2el_t *tag2el, int tag2el_count) { + asn1p_expr_t *expr = arg->expr; + uint16_t *stags; + int type, i; + + if(!tag2el_count) + return 0; /* No top level tags */ + + type = tag2el[0].el_tag.tag_mode; /* All tags should be equal to that */ + if (type == TM_IMPLICIT) + return 0; + + for(i = 1; i < tag2el_count; i++) + if (type != tag2el[i].el_tag.tag_mode) + return 0; /* Tags shall be explicit or implicit in MDER, not mixed */ + + stags = calloc(tag2el_count, sizeof(asn1c_integer_t)); + if (!stags) + return 0; + + for(i = 0; i < tag2el_count; i++) { + if (type != TM_EXPLICIT) { + /* Implicit tag */ + if (((tag2el[i].el_no + 1) < 0) || ((tag2el[i].el_no + 1) > 65535)) { + /* Tag can't be encoded in an uint16_t */ + free(stags); + return 0; + } + stags[tag2el[i].el_no] = (uint16_t)tag2el[i].el_no + 1; + continue; + } + /* Explicit tag */ + if ((tag2el[i].el_tag.tag_value < 0) || (tag2el[i].el_tag.tag_value > 65535)) { + /* Tag can't be encoded in an uint16_t*/ + free(stags); + return 0; + } + stags[tag2el[i].el_no] = (uint16_t)tag2el[i].el_tag.tag_value; + } + + /* Check if value of tags are assigned sequentially */ + if (type == TM_EXPLICIT) + for (i = 0; i < (tag2el_count - 1); i++) + if (stags[i] >= tag2el[i+1].el_tag.tag_value) { + /* Tags are not assigned sequentially */ + free(stags); + return 0; + } + OUT("/* MDER Tags are %s */\n", (type == TM_EXPLICIT) ? "explicit" : "implicit"); + OUT("static uint16_t asn_MDER_tag2member_%s_table%d[] = {", + MKID(expr), expr->_type_unique_index); + + for(i = 0; i < tag2el_count; i++) { + OUT("%d%s", stags[i], + (i + 1 < tag2el_count) ? "," : ""); + } + OUT("};\n"); + + free(stags); + return 1; +} static enum tvm_compat emit_tags_vectors(arg_t *arg, asn1p_expr_t *expr, int *tags_count_r, int *all_tags_count_r) { struct asn1p_type_tag_s *tags = 0; /* Effective tags */ @@ -2234,6 +2354,42 @@ try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) { return 0; } +static int +is_valid_mder_type(arg_t *arg, asn1p_expr_t *expr) +{ + asn1p_expr_type_e etype; + + etype = expr_get_type(arg, expr); + switch (etype) { + case ASN_BASIC_INTEGER: + case ASN_BASIC_BIT_STRING: + case ASN_BASIC_OCTET_STRING: + case ASN_CONSTR_SEQUENCE: + case ASN_CONSTR_SEQUENCE_OF: + case ASN_CONSTR_CHOICE: + case ASN_TYPE_ANY: + return 1; + default: + return 0; + } +} + +static int +valid_mder_constraints(arg_t *arg, asn1p_expr_t *expr) +{ + asn1p_expr_type_e etype; + + etype = expr_get_type(arg, expr); + switch (etype) { + case ASN_BASIC_INTEGER: + case ASN_BASIC_BIT_STRING: + case ASN_BASIC_OCTET_STRING: + return 1; + default: + return 0; + } +} + static int emit_member_table(arg_t *arg, asn1p_expr_t *expr) { int save_target; @@ -2358,12 +2514,24 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) { } if(C99_MODE) OUT(".name = "); if(expr->_anonymous_type && !strcmp(expr->Identifier, "Member")) { - OUT("\"\"\n"); + OUT("\"\",\n"); } else { - OUT("\"%s\"\n", expr->Identifier); + OUT("\"%s\",\n", expr->Identifier); } - OUT("},\n"); + if(C99_MODE) OUT(".mder_constraints = "); + if(expr->constraints && valid_mder_constraints(arg, expr)) + OUT("&asn_MDER_memb_%s_constr_%d\n", MKID(expr), + expr->_type_unique_index); + else + OUT("0\t/* No MDER visible constraints */\n"); + INDENT(-1); + OUT("},\n"); + + save_target = arg->target->target; + REDIR(OT_CODE); + + REDIR(save_target); if(!expr->constraints || (arg->flags & A1C_NO_CONSTRAINTS)) return 0; @@ -2393,18 +2561,100 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) { if(emit_member_PER_constraints(arg, expr, "memb")) return -1; + emit_member_MDER_constraints(arg, expr, "memb"); + REDIR(save_target); return 0; } +static int +emit_member_MDER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) { + asn1cnst_range_t *r_value; + asn1p_expr_type_e etype; + asn1p_constraint_t *ct; + char *p = MKID(expr); + + etype = expr_get_type(arg, expr); + switch (etype) { + case ASN_BASIC_INTEGER: + OUT("\n"); + OUT("static mder_restricted_int " + "asn_MDER_%s_%s_constr_%d = ", + pfx, p, expr->_type_unique_index); + if (!expr->combined_constraints) { + OUT("INT_INVALID;\n"); + break; + } + ct = expr->combined_constraints; + r_value = asn1constraint_compute_PER_range(etype, ct, ACT_EL_RANGE,0,0,0); + if (r_value->left.value == 0) { + /* Unsigned Integer */ + if (r_value->right.value == 255) + OUT("INT_U8;\n"); + else if (r_value->right.value == 65535) + OUT("INT_U16;\n"); + else if (r_value->right.value == 4294967295UL) + OUT("INT_U32;\n"); + else + OUT("INT_INVALID;\n"); + break; + } + /* Check signed integer */ + if ((r_value->left.value == -128) && (r_value->right.value == 127)) + OUT("INT_I8;\n"); + else if ((r_value->left.value == -32768) && (r_value->right.value == 32767)) + OUT("INT_I16;\n"); + else if ((r_value->left.value == (-2147483647L - 1)) && (r_value->right.value == 2147483647L)) + OUT("INT_I32;\n"); + else + OUT("INT_INVALID;\n"); + break; + case ASN_BASIC_BIT_STRING: + OUT("\n"); + OUT("static mder_restricted_bit_str " + "asn_MDER_%s_%s_constr_%d = ", + pfx, p, expr->_type_unique_index); + if (!expr->combined_constraints) { + OUT("BITS_INVALID;\n"); + break; + } + ct = expr->combined_constraints; + r_value = asn1constraint_compute_PER_range(etype, ct, ACT_CT_SIZE,0,0,0); + if (r_value->left.value == 8) + OUT("BITS_8;\n"); + else if (r_value->left.value == 16) + OUT("BITS_16;\n"); + else if (r_value->left.value == 32) + OUT("BITS_32;\n"); + else + OUT("BITS_INVALID;\n"); + break; + case ASN_BASIC_OCTET_STRING: + if (!expr->combined_constraints) + return 0; + OUT("\n"); + OUT("static mder_octet_str " + "asn_MDER_%s_%s_constr_%d = ", + pfx, p, expr->_type_unique_index); + ct = expr->combined_constraints; + r_value = asn1constraint_compute_PER_range(etype, ct, ACT_CT_SIZE,0,0,0); + OUT("%d;\n", r_value->left.value); + break; + default: + return 0; + } + OUT("\n"); + return 1; +} + /* * Generate "asn_DEF_XXX" type definition. */ static int emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_count, int all_tags_count, int elements_count, enum etd_spec spec) { asn1p_expr_t *terminal; - int using_type_name = 0; + int using_type_name = 0, mder_constr; char *p = MKID(expr); terminal = asn1f_find_terminal_type_ex(arg->asn, expr); @@ -2412,6 +2662,8 @@ emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_ if(emit_member_PER_constraints(arg, expr, "type")) return -1; + mder_constr = emit_member_MDER_constraints(arg, expr, "type"); + if(HIDE_INNER_DEFS) OUT("static /* Use -fall-defs-global to expose */\n"); OUT("asn_TYPE_descriptor_t asn_DEF_%s", p); @@ -2444,11 +2696,20 @@ emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_ OUT("_" #foo ",\n"); \ } while(0) +#define MDER_FUNCREF(foo) do { \ + if(is_valid_mder_type(arg, expr)) \ + FUNCREF(foo); \ + else \ + OUT("NON_SUP_" #foo ",\n"); \ +} while(0) + FUNCREF(free); FUNCREF(print); FUNCREF(constraint); FUNCREF(decode_ber); FUNCREF(encode_der); + MDER_FUNCREF(decode_mder); + MDER_FUNCREF(encode_mder); FUNCREF(decode_xer); FUNCREF(encode_xer); if(arg->flags & A1C_GEN_PER) { @@ -2535,12 +2796,20 @@ emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_ switch(spec) { case ETD_NO_SPECIFICS: - OUT("0\t/* No specifics */\n"); + OUT("0, \t/* No specifics */\n"); break; case ETD_HAS_SPECIFICS: - OUT("&asn_SPC_%s_specs_%d\t/* Additional specs */\n", + OUT("&asn_SPC_%s_specs_%d,\t/* Additional specs */\n", p, expr->_type_unique_index); } + + /* MDER Contraints */ + if (mder_constr) + OUT("&asn_MDER_type_%s_constr_%d\n", + p, expr->_type_unique_index); + else + OUT("0\t/* No MDER restricted type */\n"); + INDENT(-1); OUT("};\n"); OUT("\n"); @@ -2853,3 +3122,4 @@ static int compar_cameo(const void *ap, const void *bp) { return 0; } + diff --git a/skeletons/ANY.c b/skeletons/ANY.c index 0ad60d0a0..d898c837d 100644 --- a/skeletons/ANY.c +++ b/skeletons/ANY.c @@ -19,6 +19,8 @@ asn_TYPE_descriptor_t asn_DEF_ANY = { asn_generic_no_constraint, OCTET_STRING_decode_ber, OCTET_STRING_encode_der, + OCTET_STRING_decode_mder, + OCTET_STRING_encode_mder, OCTET_STRING_decode_xer_hex, ANY_encode_xer, 0, 0, @@ -27,6 +29,7 @@ asn_TYPE_descriptor_t asn_DEF_ANY = { 0, /* No PER visible constraints */ 0, 0, /* No members */ &asn_DEF_ANY_specs, + 0 /* MDER contraints (defined by asn1c compiler) */ }; diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c index 9b9827127..7ee644441 100644 --- a/skeletons/BIT_STRING.c +++ b/skeletons/BIT_STRING.c @@ -4,7 +4,6 @@ */ #include #include -#include /* * BIT STRING basic type description. @@ -25,6 +24,8 @@ asn_TYPE_descriptor_t asn_DEF_BIT_STRING = { BIT_STRING_constraint, OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */ + BIT_STRING_decode_mder, + BIT_STRING_encode_mder, OCTET_STRING_decode_xer_binary, BIT_STRING_encode_xer, OCTET_STRING_decode_uper, /* Unaligned PER decoder */ @@ -38,7 +39,8 @@ asn_TYPE_descriptor_t asn_DEF_BIT_STRING = { / sizeof(asn_DEF_BIT_STRING_tags[0]), 0, /* No PER visible constraints */ 0, 0, /* No members */ - &asn_DEF_BIT_STRING_specs + &asn_DEF_BIT_STRING_specs, + 0 /* MDER contraints (defined by asn1c compiler) */ }; /* @@ -72,6 +74,78 @@ static char *_bit_pattern[16] = { "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" }; +asn_dec_rval_t +BIT_STRING_decode_mder(asn_codec_ctx_t *opt_codec_ctx, + asn_TYPE_descriptor_t *td, void **sptr, const void *buf_ptr, + size_t size, asn_mder_contraints_t constr) { + + asn_dec_rval_t rval; + BIT_STRING_t *bs = (BIT_STRING_t *)*sptr; + mder_restricted_bit_str *rbs; + + rbs = (constr) ? (mder_restricted_bit_str *)constr : + (mder_restricted_bit_str *)td->mder_constraints; + + if (!rbs || *rbs == BITS_INVALID) + _ASN_DECODE_FAILED; + + if(bs == NULL) { + bs = (BIT_STRING_t *)(*sptr = CALLOC(1, sizeof(BIT_STRING_t))); + if(bs == NULL) + _ASN_DECODE_FAILED; + } + + bs->size = *rbs; + if ((size_t)bs->size > size) { + rval.code = RC_WMORE; + rval.consumed = 0; + return rval; + } + if (bs->buf) + free(bs->buf); + bs->buf = CALLOC(1, bs->size); + if (!memcpy(bs->buf, buf_ptr, bs->size)) + _ASN_DECODE_FAILED; + + rval.code = RC_OK; + rval.consumed = bs->size; + + return rval; +} + +asn_enc_rval_t +BIT_STRING_encode_mder(asn_TYPE_descriptor_t *td, void *sptr, + asn_mder_contraints_t constr, + asn_app_consume_bytes_f *cb, void *app_key) +{ + asn_enc_rval_t er; + BIT_STRING_t *st = (BIT_STRING_t *)sptr; + mder_restricted_bit_str *rbs; + + ASN_DEBUG("%s %s as BIT STRING", + cb?"Encoding":"Estimating", td->name); + + /* specifics constraints prevail */ + rbs = (constr) ? (mder_restricted_bit_str *)constr : + (mder_restricted_bit_str *)td->mder_constraints; + + if (!rbs || !st || (!st->buf && st->size)) + _ASN_ENCODE_FAILED; + + if (*rbs == BITS_INVALID) + _ASN_ENCODE_FAILED; + + er.encoded = (ssize_t) *rbs; + + if (cb) + /* Invoke callback for the main part of the buffer */ + _ASN_CALLBACK(st->buf, (ssize_t) *rbs); + + _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, diff --git a/skeletons/BIT_STRING.h b/skeletons/BIT_STRING.h index 732e878bc..dec7adee9 100644 --- a/skeletons/BIT_STRING.h +++ b/skeletons/BIT_STRING.h @@ -24,6 +24,8 @@ extern asn_TYPE_descriptor_t asn_DEF_BIT_STRING; asn_struct_print_f BIT_STRING_print; /* Human-readable output */ asn_constr_check_f BIT_STRING_constraint; +mder_type_encoder_f BIT_STRING_encode_mder; +mder_type_decoder_f BIT_STRING_decode_mder; xer_type_encoder_f BIT_STRING_encode_xer; #ifdef __cplusplus diff --git a/skeletons/BMPString.c b/skeletons/BMPString.c index 072bd075f..cf76b2df7 100644 --- a/skeletons/BMPString.c +++ b/skeletons/BMPString.c @@ -31,6 +31,8 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = { asn_generic_no_constraint, /* No constraint by default */ OCTET_STRING_decode_ber, OCTET_STRING_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, BMPString_decode_xer, /* Convert from UTF-8 */ BMPString_encode_xer, /* Convert to UTF-8 */ OCTET_STRING_decode_uper, diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c index 2c2bbcf2f..574e73b6e 100644 --- a/skeletons/BOOLEAN.c +++ b/skeletons/BOOLEAN.c @@ -20,6 +20,8 @@ asn_TYPE_descriptor_t asn_DEF_BOOLEAN = { asn_generic_no_constraint, BOOLEAN_decode_ber, BOOLEAN_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, BOOLEAN_decode_xer, BOOLEAN_encode_xer, BOOLEAN_decode_uper, /* Unaligned PER decoder */ diff --git a/skeletons/ENUMERATED.c b/skeletons/ENUMERATED.c index 90761a2d7..c525430e3 100644 --- a/skeletons/ENUMERATED.c +++ b/skeletons/ENUMERATED.c @@ -22,6 +22,8 @@ asn_TYPE_descriptor_t asn_DEF_ENUMERATED = { asn_generic_no_constraint, ber_decode_primitive, INTEGER_encode_der, /* Implemented in terms of INTEGER */ + NON_SUP_decode_mder, + NON_SUP_encode_mder, INTEGER_decode_xer, /* This is temporary! */ INTEGER_encode_xer, ENUMERATED_decode_uper, /* Unaligned PER decoder */ diff --git a/skeletons/GeneralString.c b/skeletons/GeneralString.c index 01b606bed..260a66caf 100644 --- a/skeletons/GeneralString.c +++ b/skeletons/GeneralString.c @@ -20,6 +20,8 @@ asn_TYPE_descriptor_t asn_DEF_GeneralString = { asn_generic_unknown_constraint, OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ diff --git a/skeletons/GeneralizedTime.c b/skeletons/GeneralizedTime.c index 9d683efe4..34bfc493b 100644 --- a/skeletons/GeneralizedTime.c +++ b/skeletons/GeneralizedTime.c @@ -163,6 +163,8 @@ asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = { GeneralizedTime_constraint, /* Check validity of time */ OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ GeneralizedTime_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, OCTET_STRING_decode_xer_utf8, GeneralizedTime_encode_xer, OCTET_STRING_decode_uper, diff --git a/skeletons/GraphicString.c b/skeletons/GraphicString.c index 7d59d5224..6cbb58f8e 100644 --- a/skeletons/GraphicString.c +++ b/skeletons/GraphicString.c @@ -20,6 +20,8 @@ asn_TYPE_descriptor_t asn_DEF_GraphicString = { asn_generic_unknown_constraint, OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, /* Can't expect it to be ASCII/UTF8 */ OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ diff --git a/skeletons/IA5String.c b/skeletons/IA5String.c index 02ecd3ee7..66ce56c7c 100644 --- a/skeletons/IA5String.c +++ b/skeletons/IA5String.c @@ -25,6 +25,8 @@ asn_TYPE_descriptor_t asn_DEF_IA5String = { IA5String_constraint, /* Constraint on the alphabet */ OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, OCTET_STRING_decode_uper, diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c index f016131a1..a1c8bdc46 100644 --- a/skeletons/INTEGER.c +++ b/skeletons/INTEGER.c @@ -22,6 +22,8 @@ asn_TYPE_descriptor_t asn_DEF_INTEGER = { asn_generic_no_constraint, ber_decode_primitive, INTEGER_encode_der, + INTEGER_decode_mder, + INTEGER_encode_mder, INTEGER_decode_xer, INTEGER_encode_xer, INTEGER_decode_uper, /* Unaligned PER decoder */ @@ -33,9 +35,98 @@ asn_TYPE_descriptor_t asn_DEF_INTEGER = { sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]), 0, /* No PER visible constraints */ 0, 0, /* No members */ - 0 /* No specifics */ + 0, /* No specifics */ + 0 /* MDER contraints (defined by asn1c compiler) */ }; + +asn_dec_rval_t +INTEGER_decode_mder(asn_codec_ctx_t *opt_codec_ctx, + asn_TYPE_descriptor_t *td, void **sptr, const void *buf_ptr, + size_t size, asn_mder_contraints_t constr) { + + INTEGER_t *integer = (INTEGER_t *)*sptr; + asn_dec_rval_t rval; + mder_restricted_int *rint; + unsigned int length; + union { + const void *constbuf; + void *nonconstbuf; + } unconst_buf; + + rint = (constr) ? (mder_restricted_int *)constr : + (mder_restricted_int *)td->mder_constraints; + if (!rint || *rint == INT_INVALID) { + rval.code = RC_FAIL; + rval.consumed = 0; + return rval; + } + + GET_INT_SIZE(*rint, length); + + if(!integer) { + integer = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*integer))); + if(integer == NULL) { + rval.code = RC_FAIL; + rval.consumed = 0; + return rval; + } + } + + if(length > size) { + rval.code = RC_WMORE; + rval.consumed = 0; + return rval; + } + unconst_buf.constbuf = buf_ptr; + integer->buf = (uint8_t *)unconst_buf.nonconstbuf; + integer->size = length; + + rval.code = RC_OK; + rval.consumed = length; + + return rval; +} + +/* + * Encode INTEGER type using MDER. + */ +asn_enc_rval_t +INTEGER_encode_mder(asn_TYPE_descriptor_t *td, void *sptr, + asn_mder_contraints_t constr, + asn_app_consume_bytes_f *cb, void *app_key) { + INTEGER_t *st = (INTEGER_t *)sptr; + mder_restricted_int *rint; + int size, shift; + + ASN_DEBUG("%s %s as INTEGER", + cb?"Encoding":"Estimating", td->name); + + /* specifics constraints prevail */ + rint = (constr) ? (mder_restricted_int *)constr : + (mder_restricted_int *)td->mder_constraints; + + if (!rint || *rint == INT_INVALID) + _ASN_ENCODE_FAILED; + + GET_INT_SIZE(*rint, size); + + if (st->buf) { + shift = st->size - size; + if(shift) { + uint8_t *nb = st->buf; + uint8_t *end, *buf = st->buf + shift; + st->size -= shift; /* New size, minus bad bytes */ + end = nb + st->size; + + for(; nb < end; nb++, buf++) + *nb = *buf; + } + } + + return mder_encode_primitive(td, sptr, constr, cb, app_key); +} + /* * Encode INTEGER type using DER. */ @@ -451,7 +542,7 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun lp = lstart - 1; continue; } else { - ASN_DEBUG("state %d at %d", state, lp - lstart); + ASN_DEBUG("state %d at %ld", state, (long)(lp - lstart)); break; } /* [A-Fa-f] */ @@ -486,8 +577,8 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun } /* Found extra non-numeric stuff */ - ASN_DEBUG("Found non-numeric 0x%2x at %d", - lv, lp - lstart); + ASN_DEBUG("Found non-numeric 0x%2x at %ld", + lv, (long)(lp - lstart)); state = ST_EXTRASTUFF; break; } diff --git a/skeletons/INTEGER.h b/skeletons/INTEGER.h index 8411bfcdd..faf02d77f 100644 --- a/skeletons/INTEGER.h +++ b/skeletons/INTEGER.h @@ -37,6 +37,8 @@ typedef struct asn_INTEGER_specifics_s { asn_struct_print_f INTEGER_print; ber_type_decoder_f INTEGER_decode_ber; der_type_encoder_f INTEGER_encode_der; +mder_type_decoder_f INTEGER_decode_mder; +mder_type_encoder_f INTEGER_encode_mder; xer_type_decoder_f INTEGER_decode_xer; xer_type_encoder_f INTEGER_encode_xer; per_type_decoder_f INTEGER_decode_uper; diff --git a/skeletons/ISO646String.c b/skeletons/ISO646String.c index d6ded0efa..efeeba8ad 100644 --- a/skeletons/ISO646String.c +++ b/skeletons/ISO646String.c @@ -25,6 +25,8 @@ asn_TYPE_descriptor_t asn_DEF_ISO646String = { VisibleString_constraint, OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, OCTET_STRING_decode_uper, diff --git a/skeletons/Makefile.am b/skeletons/Makefile.am index 125fb164b..aa685050b 100644 --- a/skeletons/Makefile.am +++ b/skeletons/Makefile.am @@ -64,5 +64,7 @@ libasn1cskeletons_la_SOURCES = \ per_support.c per_support.h \ xer_decoder.c xer_decoder.h \ xer_encoder.c xer_encoder.h \ - xer_support.c xer_support.h + xer_support.c xer_support.h \ + mder_encoder.c mder_encoder.h \ + mder_decoder.c mder_decoder.h diff --git a/skeletons/Makefile.in b/skeletons/Makefile.in index 0109e69c1..bde8f724e 100644 --- a/skeletons/Makefile.in +++ b/skeletons/Makefile.in @@ -61,7 +61,8 @@ am_libasn1cskeletons_la_OBJECTS = ANY.lo BIT_STRING.lo BMPString.lo \ constr_CHOICE.lo constr_SEQUENCE.lo constr_SEQUENCE_OF.lo \ constr_SET.lo constr_SET_OF.lo constr_TYPE.lo constraints.lo \ der_encoder.lo per_decoder.lo per_encoder.lo per_opentype.lo \ - per_support.lo xer_decoder.lo xer_encoder.lo xer_support.lo + per_support.lo xer_decoder.lo xer_encoder.lo xer_support.lo \ + mder_encoder.lo mder_decoder.lo libasn1cskeletons_la_OBJECTS = $(am_libasn1cskeletons_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp @@ -273,7 +274,9 @@ libasn1cskeletons_la_SOURCES = \ per_support.c per_support.h \ xer_decoder.c xer_decoder.h \ xer_encoder.c xer_encoder.h \ - xer_support.c xer_support.h + xer_support.c xer_support.h \ + mder_encoder.c mder_encoder.h \ + mder_decoder.c mder_decoder.h all: all-recursive @@ -369,6 +372,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constr_TYPE.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constraints.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/der_encoder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mder_decoder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mder_encoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/per_decoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/per_encoder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/per_opentype.Plo@am__quote@ diff --git a/skeletons/NULL.c b/skeletons/NULL.c index 6d3316f1c..d23c27428 100644 --- a/skeletons/NULL.c +++ b/skeletons/NULL.c @@ -21,6 +21,8 @@ asn_TYPE_descriptor_t asn_DEF_NULL = { asn_generic_no_constraint, BOOLEAN_decode_ber, /* Implemented in terms of BOOLEAN */ NULL_encode_der, /* Special handling of DER encoding */ + NON_SUP_decode_mder, + NON_SUP_encode_mder, NULL_decode_xer, NULL_encode_xer, NULL_decode_uper, /* Unaligned PER decoder */ @@ -32,7 +34,8 @@ asn_TYPE_descriptor_t asn_DEF_NULL = { sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]), 0, /* No PER visible constraints */ 0, 0, /* No members */ - 0 /* No specifics */ + 0, /* No specifics */ + 0 /* MDER contraints (defined by asn1c compiler) */ }; asn_enc_rval_t diff --git a/skeletons/NativeEnumerated.c b/skeletons/NativeEnumerated.c index 1554220f8..4d1f0a1c9 100644 --- a/skeletons/NativeEnumerated.c +++ b/skeletons/NativeEnumerated.c @@ -26,6 +26,8 @@ asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = { asn_generic_no_constraint, NativeInteger_decode_ber, NativeInteger_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, NativeInteger_decode_xer, NativeEnumerated_encode_xer, NativeEnumerated_decode_uper, @@ -37,7 +39,8 @@ asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = { sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]), 0, /* No PER visible constraints */ 0, 0, /* No members */ - 0 /* No specifics */ + 0, /* No specifics */ + 0 /* MDER contraints (defined by asn1c compiler) */ }; asn_enc_rval_t diff --git a/skeletons/NativeInteger.c b/skeletons/NativeInteger.c index cffd0be8e..a36827cc4 100644 --- a/skeletons/NativeInteger.c +++ b/skeletons/NativeInteger.c @@ -27,6 +27,8 @@ asn_TYPE_descriptor_t asn_DEF_NativeInteger = { asn_generic_no_constraint, NativeInteger_decode_ber, NativeInteger_encode_der, + NativeInteger_decode_mder, + NativeInteger_encode_mder, NativeInteger_decode_xer, NativeInteger_encode_xer, NativeInteger_decode_uper, /* Unaligned PER decoder */ @@ -38,7 +40,8 @@ asn_TYPE_descriptor_t asn_DEF_NativeInteger = { sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]), 0, /* No PER visible constraints */ 0, 0, /* No members */ - 0 /* No specifics */ + 0, /* No specifics */ + 0 /* MDER contraints (defined by asn1c compiler) */ }; /* @@ -126,6 +129,27 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx, return rval; } +#ifdef WORDS_BIGENDIAN /* Opportunistic optimization */ +#define _PREPARE_INTEGER_T(tmp,native) do { \ + tmp.buf = (uint8_t *)&native; \ + tmp.size = sizeof(native); \ +} while(0) +#else /* Works even if WORDS_BIGENDIAN is not set where should've been */ +#define _PREPARE_INTEGER_T(tmp,native) do { \ + /* set where should've been */ \ + uint8_t buf[sizeof(native)]; \ + uint8_t *p; \ + \ + /* Prepare a fake INTEGER */ \ + for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8) \ + *p = (uint8_t)native; \ + \ + tmp.buf = buf; \ + tmp.size = sizeof(buf); \ +} while(0) +#endif /* WORDS_BIGENDIAN */ + + /* * Encode the NativeInteger using the standard INTEGER type DER encoder. */ @@ -137,25 +161,32 @@ NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr, asn_enc_rval_t erval; INTEGER_t tmp; -#ifdef WORDS_BIGENDIAN /* Opportunistic optimization */ + _PREPARE_INTEGER_T(tmp, native); - tmp.buf = (uint8_t *)&native; - tmp.size = sizeof(native); + /* Encode fake INTEGER */ + erval = INTEGER_encode_der(sd, &tmp, tag_mode, tag, cb, app_key); + if(erval.encoded == -1) { + assert(erval.structure_ptr == &tmp); + erval.structure_ptr = ptr; + } + return erval; +} -#else /* Works even if WORDS_BIGENDIAN is not set where should've been */ - uint8_t buf[sizeof(native)]; - uint8_t *p; +/* + * Encode the NativeInteger using MDER encoder. + */ +asn_enc_rval_t +NativeInteger_encode_mder(asn_TYPE_descriptor_t *sd, void *ptr, + asn_mder_contraints_t constr, + asn_app_consume_bytes_f *cb, void *app_key) { + unsigned long native = *(unsigned long *)ptr; /* Disable sign ext. */ + asn_enc_rval_t erval; + INTEGER_t tmp; - /* Prepare a fake INTEGER */ - for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8) - *p = (uint8_t)native; + _PREPARE_INTEGER_T(tmp,native); - tmp.buf = buf; - tmp.size = sizeof(buf); -#endif /* WORDS_BIGENDIAN */ - /* Encode fake INTEGER */ - erval = INTEGER_encode_der(sd, &tmp, tag_mode, tag, cb, app_key); + erval = INTEGER_encode_mder(sd, &tmp, constr, cb, app_key); if(erval.encoded == -1) { assert(erval.structure_ptr == &tmp); erval.structure_ptr = ptr; @@ -163,6 +194,61 @@ NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr, return erval; } +/* + * Decode INTEGER type. + */ +asn_dec_rval_t +NativeInteger_decode_mder(asn_codec_ctx_t *opt_codec_ctx, + asn_TYPE_descriptor_t *td, void **nint_ptr, + const void *buf_ptr, size_t size, asn_mder_contraints_t constr) { + + long *native = (long *)*nint_ptr; + asn_dec_rval_t rval; + mder_restricted_int *rint; + INTEGER_t *tmp = NULL; + long l; + int unsig; + + rint = (constr) ? (mder_restricted_int *)constr : + (mder_restricted_int *)td->mder_constraints; + if (!rint || *rint == INT_INVALID) { + rval.code = RC_FAIL; + rval.consumed = 0; + return rval; + } + + + if(!native) { + native = (long *)(*nint_ptr = CALLOC(1, sizeof(*native))); + if(native == NULL) { + rval.code = RC_FAIL; + rval.consumed = 0; + return rval; + } + } + + rval = INTEGER_decode_mder(opt_codec_ctx, td, (void **)&tmp, + buf_ptr, size, constr); + + if (rval.code != RC_OK){ + return rval; + } + + GET_INT_UNSIGNED(*rint, unsig); + + if((unsig) ? asn_INTEGER2ulong(tmp, (unsigned long *)&l) : + asn_INTEGER2long(tmp, &l)) { + rval.code = RC_FAIL; + rval.consumed = 0; + return rval; + } + + free(tmp); + *native = l; + + return rval; +} + /* * Decode the chunk of XML text encoding INTEGER. */ @@ -182,7 +268,7 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx, } memset(&st, 0, sizeof(st)); - rval = INTEGER_decode_xer(opt_codec_ctx, td, &st_ptr, + rval = INTEGER_decode_xer(opt_codec_ctx, td, &st_ptr, opt_mname, buf_ptr, size); if(rval.code == RC_OK) { long l; diff --git a/skeletons/NativeInteger.h b/skeletons/NativeInteger.h index 4e63a8355..90985c2f7 100644 --- a/skeletons/NativeInteger.h +++ b/skeletons/NativeInteger.h @@ -25,6 +25,8 @@ asn_struct_free_f NativeInteger_free; asn_struct_print_f NativeInteger_print; ber_type_decoder_f NativeInteger_decode_ber; der_type_encoder_f NativeInteger_encode_der; +mder_type_decoder_f NativeInteger_decode_mder; +mder_type_encoder_f NativeInteger_encode_mder; xer_type_decoder_f NativeInteger_decode_xer; xer_type_encoder_f NativeInteger_encode_xer; per_type_decoder_f NativeInteger_decode_uper; diff --git a/skeletons/NativeReal.c b/skeletons/NativeReal.c index a1ff91e18..86d9b9b9a 100644 --- a/skeletons/NativeReal.c +++ b/skeletons/NativeReal.c @@ -28,6 +28,8 @@ asn_TYPE_descriptor_t asn_DEF_NativeReal = { asn_generic_no_constraint, NativeReal_decode_ber, NativeReal_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, NativeReal_decode_xer, NativeReal_encode_xer, NativeReal_decode_uper, diff --git a/skeletons/NumericString.c b/skeletons/NumericString.c index 50fe4491b..ce90b98fb 100644 --- a/skeletons/NumericString.c +++ b/skeletons/NumericString.c @@ -45,6 +45,8 @@ asn_TYPE_descriptor_t asn_DEF_NumericString = { NumericString_constraint, OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, OCTET_STRING_decode_uper, diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c index 0d7043e6b..86b283fe6 100644 --- a/skeletons/OBJECT_IDENTIFIER.c +++ b/skeletons/OBJECT_IDENTIFIER.c @@ -22,6 +22,8 @@ asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = { OBJECT_IDENTIFIER_constraint, ber_decode_primitive, der_encode_primitive, + OBJECT_IDENTIFIER_decode_mder, + OBJECT_IDENTIFIER_encode_mder, OBJECT_IDENTIFIER_decode_xer, OBJECT_IDENTIFIER_encode_xer, OCTET_STRING_decode_uper, @@ -726,4 +728,19 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length, } } +asn_enc_rval_t +OBJECT_IDENTIFIER_encode_mder(struct asn_TYPE_descriptor_s *td, void *sptr, + asn_mder_contraints_t constr, + asn_app_consume_bytes_f *consume_bytes_cb, void *app_key) { + + _ASN_ENCODE_FAILED; +} +asn_dec_rval_t +OBJECT_IDENTIFIER_decode_mder(struct asn_codec_ctx_s *opt_codec_ctx, + struct asn_TYPE_descriptor_s *td, + void **struct_ptr, const void *buf_ptr, size_t size, + asn_mder_contraints_t constr) { + + _ASN_DECODE_FAILED; +} diff --git a/skeletons/OBJECT_IDENTIFIER.h b/skeletons/OBJECT_IDENTIFIER.h index 2bb5d0323..74ed8af22 100644 --- a/skeletons/OBJECT_IDENTIFIER.h +++ b/skeletons/OBJECT_IDENTIFIER.h @@ -8,6 +8,8 @@ #include #include +#include +#include #ifdef __cplusplus extern "C" { @@ -22,6 +24,8 @@ asn_constr_check_f OBJECT_IDENTIFIER_constraint; der_type_encoder_f OBJECT_IDENTIFIER_encode_der; xer_type_decoder_f OBJECT_IDENTIFIER_decode_xer; xer_type_encoder_f OBJECT_IDENTIFIER_encode_xer; +mder_type_decoder_f OBJECT_IDENTIFIER_decode_mder; +mder_type_encoder_f OBJECT_IDENTIFIER_encode_mder; /********************************** * Some handy conversion routines * diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c index 584def8b4..9d87374fd 100644 --- a/skeletons/OCTET_STRING.c +++ b/skeletons/OCTET_STRING.c @@ -1,5 +1,7 @@ /*- * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin . + * Copyright (c) 2010 Jose Antonio Santos-Cadenas . + * Copyright (c) 2010 Santiago Carot-Nemesio . * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ @@ -32,6 +34,8 @@ asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = { asn_generic_no_constraint, OCTET_STRING_decode_ber, OCTET_STRING_encode_der, + OCTET_STRING_decode_mder, + OCTET_STRING_encode_mder, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, OCTET_STRING_decode_uper, /* Unaligned PER decoder */ @@ -45,7 +49,8 @@ asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = { / sizeof(asn_DEF_OCTET_STRING_tags[0]), 0, /* No PER visible constraints */ 0, 0, /* No members */ - &asn_DEF_OCTET_STRING_specs + &asn_DEF_OCTET_STRING_specs, + 0 /* MDER contraints (defined by asn1c compiler) */ }; #undef _CH_PHASE @@ -576,6 +581,100 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr, _ASN_ENCODE_FAILED; } +asn_dec_rval_t +OCTET_STRING_decode_mder(asn_codec_ctx_t *opt_codec_ctx, + asn_TYPE_descriptor_t *td, void **sptr, const void *buf_ptr, + size_t size, asn_mder_contraints_t constr) { + + OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr; + mder_octet_str *oct = (mder_octet_str *)td->mder_constraints; + asn_dec_rval_t rval; + const char *data; + + + /* + * Create the string if does not exist. + */ + if(st == NULL) { + st = (OCTET_STRING_t *)(*sptr = CALLOC(1, sizeof(OCTET_STRING_t))); + if(st == NULL) + _ASN_DECODE_FAILED; + } + + if (!oct) { + if (size < 2) { + rval.code = RC_WMORE; + rval.consumed = 0; + return rval; + } + st->size = 0; + st->size = ((const uint8_t *)buf_ptr)[0]; + st->size = (st->size << 8) | ((const uint8_t *)buf_ptr)[1]; + rval.consumed = 2; + data = (const char *)buf_ptr + 2; + } else { + st->size = *oct; + rval.consumed = 0; + data = (const char *)buf_ptr; + } + if (size < (st->size + rval.consumed)) { + rval.code = RC_WMORE; + rval.consumed = 0; + return rval; + } + + if (OCTET_STRING_fromBuf(st, data, st->size) != 0) + _ASN_DECODE_FAILED; + + rval.code = RC_OK; + rval.consumed += st->size; + return rval; +} + +asn_enc_rval_t +OCTET_STRING_encode_mder(asn_TYPE_descriptor_t *td, void *sptr, + asn_mder_contraints_t constr, + asn_app_consume_bytes_f *cb, void *app_key) +{ + const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr; + mder_octet_str *oct; + asn_enc_rval_t er; + + ASN_DEBUG("%s %s as OCTET STRING", + cb?"Estimating":"Encoding", td->name); + + /* specifics constraints prevail */ + oct = (constr) ? (mder_octet_str *)constr : + (mder_octet_str *)td->mder_constraints; + + if (!st) + _ASN_ENCODE_FAILED; + + if ((st->size > 0) && !st->buf) + _ASN_ENCODE_FAILED; + + if (oct && (st->size != *oct)) + _ASN_ENCODE_FAILED; + + er.encoded = st->size; + if (!oct) + /* Variable Octet String */ + er.encoded += 2; + + if(!cb) + _ASN_ENCODED_OK(er); + + if (!oct) + MDER_OUTPUT_INT_U16_LENGTH(st->size); + + /* Invoke callback for the main part of the buffer */ + _ASN_CALLBACK(st->buf, st->size); + + _ASN_ENCODED_OK(er); +cb_failed: + _ASN_ENCODE_FAILED; +} + asn_enc_rval_t OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, diff --git a/skeletons/OCTET_STRING.h b/skeletons/OCTET_STRING.h index 8df9a182d..126eb0c75 100644 --- a/skeletons/OCTET_STRING.h +++ b/skeletons/OCTET_STRING.h @@ -25,6 +25,8 @@ asn_struct_print_f OCTET_STRING_print; asn_struct_print_f OCTET_STRING_print_utf8; ber_type_decoder_f OCTET_STRING_decode_ber; der_type_encoder_f OCTET_STRING_encode_der; +mder_type_decoder_f OCTET_STRING_decode_mder; +mder_type_encoder_f OCTET_STRING_encode_mder; xer_type_decoder_f OCTET_STRING_decode_xer_hex; /* Hexadecimal */ xer_type_decoder_f OCTET_STRING_decode_xer_binary; /* 01010111010 */ xer_type_decoder_f OCTET_STRING_decode_xer_utf8; /* ASCII/UTF-8 */ diff --git a/skeletons/ObjectDescriptor.c b/skeletons/ObjectDescriptor.c index cd8e8a386..7fe0d84ea 100644 --- a/skeletons/ObjectDescriptor.c +++ b/skeletons/ObjectDescriptor.c @@ -20,6 +20,8 @@ asn_TYPE_descriptor_t asn_DEF_ObjectDescriptor = { asn_generic_unknown_constraint, OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, OCTET_STRING_decode_uper, diff --git a/skeletons/PrintableString.c b/skeletons/PrintableString.c index c8ee3ae3c..1e259db97 100644 --- a/skeletons/PrintableString.c +++ b/skeletons/PrintableString.c @@ -19,7 +19,7 @@ static int _PrintableString_alphabet[256] = { 0,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, /* abcdefghijklmno */ 64,65,66,67,68,69,70,71,72,73,74, 0, 0, 0, 0, 0, /* pqrstuvwxyz */ }; -static int _PrintableString_code2value[74] = { +static int _PrintableString_code2value[74] = { 32,39,40,41,43,44,45,46,47,48,49,50,51,52,53,54, 55,56,57,58,61,63,65,66,67,68,69,70,71,72,73,74, 75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90, @@ -55,6 +55,8 @@ asn_TYPE_descriptor_t asn_DEF_PrintableString = { PrintableString_constraint, OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, OCTET_STRING_decode_uper, diff --git a/skeletons/REAL.c b/skeletons/REAL.c index 5e93ac8ac..1d79bf587 100644 --- a/skeletons/REAL.c +++ b/skeletons/REAL.c @@ -41,6 +41,8 @@ asn_TYPE_descriptor_t asn_DEF_REAL = { asn_generic_no_constraint, ber_decode_primitive, der_encode_primitive, + NON_SUP_decode_mder, + NON_SUP_encode_mder, REAL_decode_xer, REAL_encode_xer, REAL_decode_uper, diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c index 983fc094d..499c0ac17 100644 --- a/skeletons/RELATIVE-OID.c +++ b/skeletons/RELATIVE-OID.c @@ -24,6 +24,8 @@ asn_TYPE_descriptor_t asn_DEF_RELATIVE_OID = { asn_generic_no_constraint, ber_decode_primitive, der_encode_primitive, + RELATIVE_OID_decode_mder, + RELATIVE_OID_encode_mder, RELATIVE_OID_decode_xer, RELATIVE_OID_encode_xer, OCTET_STRING_decode_uper, @@ -240,3 +242,19 @@ RELATIVE_OID_set_arcs(RELATIVE_OID_t *roid, void *arcs, unsigned int arc_type_si return 0; } +asn_enc_rval_t +RELATIVE_OID_encode_mder(struct asn_TYPE_descriptor_s *td, void *sptr, + asn_mder_contraints_t constr, + asn_app_consume_bytes_f *consume_bytes_cb, void *app_key) { + + _ASN_ENCODE_FAILED; +} + +asn_dec_rval_t +RELATIVE_OID_decode_mder(struct asn_codec_ctx_s *opt_codec_ctx, + struct asn_TYPE_descriptor_s *td, + void **struct_ptr, const void *buf_ptr, size_t size, + asn_mder_contraints_t constr) { + + _ASN_DECODE_FAILED; +} diff --git a/skeletons/RELATIVE-OID.h b/skeletons/RELATIVE-OID.h index 2235cfddf..834c681a2 100644 --- a/skeletons/RELATIVE-OID.h +++ b/skeletons/RELATIVE-OID.h @@ -6,6 +6,8 @@ #define _RELATIVE_OID_H_ #include +#include +#include #ifdef __cplusplus extern "C" { @@ -19,6 +21,8 @@ extern asn_TYPE_descriptor_t asn_DEF_RELATIVE_OID; asn_struct_print_f RELATIVE_OID_print; xer_type_decoder_f RELATIVE_OID_decode_xer; xer_type_encoder_f RELATIVE_OID_encode_xer; +mder_type_decoder_f RELATIVE_OID_decode_mder; +mder_type_encoder_f RELATIVE_OID_encode_mder; /********************************** * Some handy conversion routines * diff --git a/skeletons/T61String.c b/skeletons/T61String.c index 98461bbbf..5237b6404 100644 --- a/skeletons/T61String.c +++ b/skeletons/T61String.c @@ -20,6 +20,8 @@ asn_TYPE_descriptor_t asn_DEF_T61String = { asn_generic_unknown_constraint, OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, OCTET_STRING_decode_uper, diff --git a/skeletons/TeletexString.c b/skeletons/TeletexString.c index cc2acada7..fa1c9b633 100644 --- a/skeletons/TeletexString.c +++ b/skeletons/TeletexString.c @@ -20,6 +20,8 @@ asn_TYPE_descriptor_t asn_DEF_TeletexString = { asn_generic_unknown_constraint, OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, OCTET_STRING_decode_uper, diff --git a/skeletons/UTCTime.c b/skeletons/UTCTime.c index 0abe1db74..af82de7ef 100644 --- a/skeletons/UTCTime.c +++ b/skeletons/UTCTime.c @@ -36,6 +36,8 @@ asn_TYPE_descriptor_t asn_DEF_UTCTime = { UTCTime_constraint, OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */ + NON_SUP_decode_mder, + NON_SUP_encode_mder, OCTET_STRING_decode_xer_utf8, UTCTime_encode_xer, OCTET_STRING_decode_uper, diff --git a/skeletons/UTF8String.c b/skeletons/UTF8String.c index 7e73d7759..9f3207e64 100644 --- a/skeletons/UTF8String.c +++ b/skeletons/UTF8String.c @@ -21,6 +21,8 @@ asn_TYPE_descriptor_t asn_DEF_UTF8String = { UTF8String_constraint, /* Check for invalid codes, etc. */ OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, OCTET_STRING_decode_uper, diff --git a/skeletons/UniversalString.c b/skeletons/UniversalString.c index 7d16781f5..74448e93e 100644 --- a/skeletons/UniversalString.c +++ b/skeletons/UniversalString.c @@ -31,6 +31,8 @@ asn_TYPE_descriptor_t asn_DEF_UniversalString = { asn_generic_no_constraint, OCTET_STRING_decode_ber, OCTET_STRING_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, UniversalString_decode_xer, /* Convert from UTF-8 */ UniversalString_encode_xer, /* Convert into UTF-8 */ OCTET_STRING_decode_uper, diff --git a/skeletons/VideotexString.c b/skeletons/VideotexString.c index df7233e5e..8e244fa95 100644 --- a/skeletons/VideotexString.c +++ b/skeletons/VideotexString.c @@ -20,6 +20,8 @@ asn_TYPE_descriptor_t asn_DEF_VideotexString = { asn_generic_unknown_constraint, OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, OCTET_STRING_decode_uper, /* Implemented in terms of OCTET STRING */ diff --git a/skeletons/VisibleString.c b/skeletons/VisibleString.c index 3487b6f93..5887b9e6d 100644 --- a/skeletons/VisibleString.c +++ b/skeletons/VisibleString.c @@ -25,6 +25,8 @@ asn_TYPE_descriptor_t asn_DEF_VisibleString = { VisibleString_constraint, OCTET_STRING_decode_ber, /* Implemented in terms of OCTET STRING */ OCTET_STRING_encode_der, + NON_SUP_decode_mder, + NON_SUP_encode_mder, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, OCTET_STRING_decode_uper, diff --git a/skeletons/asn_codecs_prim.c b/skeletons/asn_codecs_prim.c index 4e5c63937..55a6f6f2b 100644 --- a/skeletons/asn_codecs_prim.c +++ b/skeletons/asn_codecs_prim.c @@ -1,5 +1,8 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin . All rights reserved. + * Copyright (c) 2003, 2004 Lev Walkin . + * Copyright (c) 2010 Santiago Carot-Nemesio + * Copyright (c) 2010 Jose Antonio Santos-Cadenas + * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include @@ -114,6 +117,35 @@ der_encode_primitive(asn_TYPE_descriptor_t *td, void *sptr, _ASN_ENCODED_OK(erval); } +/* +* Encode an always-primitive type using MDER. +*/ +asn_enc_rval_t +mder_encode_primitive(asn_TYPE_descriptor_t *td, void *sptr, + asn_mder_contraints_t constr, + 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 ", + cb?"Encoding":"Estimating", td->name); + + + 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); +} + void ASN__PRIMITIVE_TYPE_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) { diff --git a/skeletons/asn_codecs_prim.h b/skeletons/asn_codecs_prim.h index 0f683fdd0..e5bf766e0 100644 --- a/skeletons/asn_codecs_prim.h +++ b/skeletons/asn_codecs_prim.h @@ -19,6 +19,7 @@ typedef struct ASN__PRIMITIVE_TYPE_s { asn_struct_free_f ASN__PRIMITIVE_TYPE_free; ber_type_decoder_f ber_decode_primitive; der_type_encoder_f der_encode_primitive; +mder_type_encoder_f mder_encode_primitive; /* * A callback specification for the xer_decode_primitive() function below. diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c index a9eb71941..8fd39c226 100644 --- a/skeletons/constr_CHOICE.c +++ b/skeletons/constr_CHOICE.c @@ -1,5 +1,7 @@ /* * Copyright (c) 2003, 2004, 2005, 2006, 2007 Lev Walkin . + * Copyright (c) 2010 Santiago Carot-Nemesio . + * Copyright (c) 2010 Jose Antonio Santos-Cadenas . * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ @@ -41,6 +43,14 @@ consumed_myself += num; \ } while(0) +#undef ADVANCE_MDER +#define ADVANCE_MDER(num_bytes) do { \ + size_t num = num_bytes; \ + ptr = ((const char *)ptr) + num;\ + size -= num; \ + consumed_myself += num; \ + } while(0) + /* * Switch to the next phase of parsing. */ @@ -444,6 +454,154 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr, return erval; } +/* + * The MDER decoder of the CHOICE OF type. + */ +asn_dec_rval_t +CHOICE_decode_mder(asn_codec_ctx_t *opt_codec_ctx, + asn_TYPE_descriptor_t *td, void **sptr, const void *ptr, + size_t size, asn_mder_contraints_t constr) { + + asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; + asn_dec_rval_t rval; + ssize_t consumed_myself = 0; /* Consumed bytes from ptr */ + int *presentp, present_tag, i; + uint16_t comp_size; + asn_TYPE_member_t *elm; /* CHOICE element */ + void *memb_ptr; + asn_struct_ctx_t *ctx; + + if (!*sptr) { + /* Alloc memory for the target structure */ + *sptr = CALLOC(1, specs->struct_size); + if (!*sptr) + RETURN(RC_FAIL); + } + + /* + * Restore parsing context. + */ + ctx = (asn_struct_ctx_t *)((char *)*sptr + specs->ctx_offset); + if (!ctx) + RETURN(RC_FAIL); + if (ctx->phase > 0) + goto phase1; + + if (size < 2) { + RETURN(RC_WMORE); + } + MDER_INPUT_INT_U16(present_tag, ptr); + ADVANCE_MDER(2); + + presentp = (int *)((*(char **)sptr) + specs->pres_offset); + for (i = 0; i < td->elements_count; i++) { + if (specs->sorted_tags[i] == present_tag) { + *presentp = i + 1; + break; + } + } + if(*presentp <= 0 || *presentp > td->elements_count) + RETURN(RC_FAIL); + + ctx->ptr = presentp; + ctx->phase = 1; +phase1: + if (ctx->phase > 1) + goto phase2; + if (size < 2) { + RETURN(RC_WMORE); + } + MDER_INPUT_INT_U16(comp_size, ptr); + ADVANCE_MDER(2); + ctx->phase = 2; + +phase2: + elm = &td->elements[*(int *)ctx->ptr - 1]; + if(elm->flags & ATF_POINTER) { + memb_ptr = *(void **)(*(char **)sptr + elm->memb_offset); + if(memb_ptr == 0) + /* All elements are mandatory in MDER */ + _ASN_DECODE_FAILED; + } else + memb_ptr = (void *)(*(char **)sptr + elm->memb_offset); + rval = elm->type->mder_decoder(opt_codec_ctx, elm->type, &memb_ptr, ptr, + size, elm->mder_constraints); + consumed_myself += rval.consumed; + RETURN(rval.code); +} +/* + * The MDER encoder of the CHOICE type. + */ +asn_enc_rval_t +CHOICE_encode_mder(asn_TYPE_descriptor_t *td, void *sptr, + asn_mder_contraints_t constr, + 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; + int present, tag; + + if (!(sptr && specs->sorted_tags)) _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) + _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) + /* All elements are mandatory in MDER */ + _ASN_ENCODE_FAILED; + } else + memb_ptr = (void *)((char *)sptr + elm->memb_offset); + + /* we need to pre-compute the member size */ + erval = elm->type->mder_encoder(elm->type, memb_ptr, + elm->mder_constraints, 0, 0); + + if(erval.encoded == -1) + return erval; + + if(!cb) { + erval.encoded += 4; /* +4 tag and length*/ + _ASN_ENCODED_OK(erval); + } + + /* Encode element's tag */ + tag = specs->sorted_tags[present-1]; + MDER_OUTPUT_INT_U16_LENGTH(tag); + + /* Encode octets length */ + MDER_OUTPUT_INT_U16_LENGTH(erval.encoded); + + /* + * Encode the single underlying member. + */ + erval = elm->type->mder_encoder(elm->type, memb_ptr, + elm->mder_constraints, cb, app_key); + if(erval.encoded == -1) + return erval; + + erval.encoded += 4; + return erval; +cb_failed: + _ASN_ENCODE_FAILED; +} + ber_tlv_tag_t CHOICE_outmost_tag(asn_TYPE_descriptor_t *td, const void *ptr, int tag_mode, ber_tlv_tag_t tag) { asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; diff --git a/skeletons/constr_CHOICE.h b/skeletons/constr_CHOICE.h index 83404e6d4..b36923d02 100644 --- a/skeletons/constr_CHOICE.h +++ b/skeletons/constr_CHOICE.h @@ -34,6 +34,7 @@ typedef struct asn_CHOICE_specifics_s { * Extensions-related stuff. */ int ext_start; /* First member of extensions, or -1 */ + uint16_t *sorted_tags; /* Tags used by MDER encoder and decoder */ } asn_CHOICE_specifics_t; /* @@ -44,6 +45,8 @@ asn_struct_print_f CHOICE_print; asn_constr_check_f CHOICE_constraint; ber_type_decoder_f CHOICE_decode_ber; der_type_encoder_f CHOICE_encode_der; +mder_type_decoder_f CHOICE_decode_mder; +mder_type_encoder_f CHOICE_encode_mder; xer_type_decoder_f CHOICE_decode_xer; xer_type_encoder_f CHOICE_encode_xer; per_type_decoder_f CHOICE_decode_uper; diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c index bc7f4ad3a..2acc74c34 100644 --- a/skeletons/constr_SEQUENCE.c +++ b/skeletons/constr_SEQUENCE.c @@ -1,5 +1,7 @@ /*- * Copyright (c) 2003, 2004, 2005, 2006, 2007 Lev Walkin . + * Copyright (c) 2010 Jose Antonio Santos-Cadenas . + * Copyright (c) 2010 Santiago Carot-Nemesio . * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ @@ -591,6 +593,118 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td, _ASN_ENCODED_OK(erval); } +/* + * The decoder of the SEQUENCE type. + */ +asn_dec_rval_t +SEQUENCE_decode_mder(asn_codec_ctx_t *opt_codec_ctx, + asn_TYPE_descriptor_t *td, void **sptr, + const void *ptr, size_t size, asn_mder_contraints_t constr) { + + asn_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics; + + void *st = *sptr; /* Target structure. */ + asn_dec_rval_t rval; /* Return code */ + asn_struct_ctx_t *ctx; + + ssize_t consumed_myself = 0; /* Consumed bytes from ptr */ + int edx; /* SEQUENCE element's index */ + + ASN_DEBUG("Decoding %s as SEQUENCE", td->name); + + /* + * Create the target structure if it is not present already. + */ + if(st == 0) { + st = *sptr = CALLOC(1, specs->struct_size); + if(st == 0) { + RETURN(RC_FAIL); + } + } + + /* + * Restore parsing context. + */ + ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset); + if (!ctx) + _ASN_DECODE_FAILED; + + for(edx = ctx->context; edx < td->elements_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + void *memb_ptr; + void **memb_ptr2; + + if(elm->optional) + _ASN_DECODE_FAILED; + + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ + memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { + /* + * A pointer to a pointer + * holding the start of the structure + */ + memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + + rval = elm->type->mder_decoder(opt_codec_ctx, elm->type, + memb_ptr2, ptr, size, elm->mder_constraints); + + consumed_myself += rval.consumed; + ctx->context = edx; + + if (rval.code != RC_OK) + RETURN(rval.code); + + ptr = ((const char *)ptr) + rval.consumed; + size -= rval.consumed; + } + RETURN(RC_OK); +} + +/* + * The MDER encoder of the SEQUENCE type. + */ +asn_enc_rval_t +SEQUENCE_encode_mder(asn_TYPE_descriptor_t *td, + void *sptr, asn_mder_contraints_t constr, + asn_app_consume_bytes_f *cb, void *app_key) { + + asn_enc_rval_t erval; + int edx; + + ASN_DEBUG("%s %s as SEQUENCE", + cb?"Encoding":"Estimating", td->name); + + erval.encoded = 0; + + for(edx = 0; edx < td->elements_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + asn_enc_rval_t tmperval; + void *memb_ptr; + + if(elm->optional) + _ASN_ENCODE_FAILED; + + if (elm->flags & ATF_POINTER) { + memb_ptr = *(void **)((char *)sptr + elm->memb_offset); + if(!memb_ptr) continue; + } else + memb_ptr = (void *)((char *)sptr + elm->memb_offset); + + tmperval = elm->type->mder_encoder(elm->type, memb_ptr, + elm->mder_constraints, + cb, app_key); + + if(tmperval.encoded == -1) + return tmperval; + erval.encoded += tmperval.encoded; + } + + _ASN_ENCODED_OK(erval); +} #undef XER_ADVANCE #define XER_ADVANCE(num_bytes) do { \ diff --git a/skeletons/constr_SEQUENCE.h b/skeletons/constr_SEQUENCE.h index 5f589d5c1..5a3fd5d3a 100644 --- a/skeletons/constr_SEQUENCE.h +++ b/skeletons/constr_SEQUENCE.h @@ -48,6 +48,8 @@ asn_struct_print_f SEQUENCE_print; asn_constr_check_f SEQUENCE_constraint; ber_type_decoder_f SEQUENCE_decode_ber; der_type_encoder_f SEQUENCE_encode_der; +mder_type_decoder_f SEQUENCE_decode_mder; +mder_type_encoder_f SEQUENCE_encode_mder; xer_type_decoder_f SEQUENCE_decode_xer; xer_type_encoder_f SEQUENCE_encode_xer; per_type_decoder_f SEQUENCE_decode_uper; diff --git a/skeletons/constr_SEQUENCE_OF.c b/skeletons/constr_SEQUENCE_OF.c index aa101176d..826a51082 100644 --- a/skeletons/constr_SEQUENCE_OF.c +++ b/skeletons/constr_SEQUENCE_OF.c @@ -1,5 +1,7 @@ /*- * Copyright (c) 2003, 2004, 2006 Lev Walkin . + * Copyright (c) 2010 Jose Antonio Santos Cadenas . + * Copyright (c) 2010 Santiago Carot-Nemesio . * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ @@ -7,6 +9,20 @@ #include #include +#undef ADVANCE_MDER +#define ADVANCE_MDER(n_bytes) do { \ + ptr = ((const char *)ptr) + n_bytes; \ + consumed_myself += n_bytes; \ + size -= n_bytes; \ +}while(0) + +#undef RETURN +#define RETURN(_code) do { \ + rval.code = _code; \ + rval.consumed = consumed_myself;\ + return rval; \ +} while(0) + /* * The DER encoder of the SEQUENCE OF type. */ @@ -87,6 +103,131 @@ SEQUENCE_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr, return erval; } +asn_dec_rval_t +SEQUENCE_OF_decode_mder(asn_codec_ctx_t *opt_codec_ctx, + asn_TYPE_descriptor_t *td, void **sptr, + const void *ptr, size_t size, asn_mder_contraints_t constr) { + + asn_TYPE_member_t *elm = td->elements; + asn_anonymous_sequence_ *list = *((asn_anonymous_sequence_ **)sptr); + ssize_t consumed_myself = 0; /* Consumed bytes from ptr */ + int edx, rec_size; + asn_dec_rval_t rval; /* Return code */ + asn_struct_ctx_t *ctx; + asn_SET_OF_specifics_t *specs; + + specs = (asn_SET_OF_specifics_t *)td->specifics; + + if (!list) { + list = *sptr = CALLOC(1, specs->struct_size); + if(list == 0) { + RETURN(RC_FAIL); + } + } + /* + * Restore parsing context. + */ + ctx = (asn_struct_ctx_t *)((char *)list + specs->ctx_offset); + if (!ctx) + _ASN_DECODE_FAILED; + + if (ctx->phase == 1) + goto phase1; + if (size < 4) { + RETURN(RC_WMORE); + } + MDER_INPUT_INT_U16(list->count, ptr); + ADVANCE_MDER(2); + MDER_INPUT_INT_U16(rec_size, ptr); + ADVANCE_MDER(2); + + /* Allocate memory for the return type*/ + if (list->array) + free(list->array); + list->size = list->count * sizeof(*list->array); + list->array = CALLOC(rec_size, sizeof(*list->array)); + if (!list->array) + RETURN(RC_FAIL); + ctx->phase = 1; + +phase1: + + for(edx = ctx->context; edx < list->count; edx++) { + rval = elm->type->mder_decoder(opt_codec_ctx, elm->type, + &list->array[edx], ptr, size, constr); + ADVANCE_MDER(rval.consumed); + ctx->context = edx; + if (rval.code != RC_OK) + RETURN(rval.code); + } + + RETURN(RC_OK); +} + +/* + * The MDER encoder of the SEQUENCE OF type. + */ +asn_enc_rval_t +SEQUENCE_OF_encode_mder(asn_TYPE_descriptor_t *td, void *sptr, + asn_mder_contraints_t constr, + asn_app_consume_bytes_f *cb, void *app_key) { + asn_TYPE_member_t *elm = td->elements; + asn_anonymous_sequence_ *list = _A_SEQUENCE_FROM_VOID(sptr); + int edx, computed_size = 0, encoding_size = 0; + asn_enc_rval_t er; + + ASN_DEBUG("%s %s as SEQUENCE OF", + cb?"Encoding":"Estimating", 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; + er = elm->type->mder_encoder(elm->type, memb_ptr, + elm->mder_constraints, + 0, 0); + if(er.encoded == -1) + return er; + computed_size += er.encoded; + } + + if(!cb) { + er.encoded = computed_size + 4; /* +4 count and length*/ + _ASN_ENCODED_OK(er); + } + + /* Encode count of elements */ + MDER_OUTPUT_INT_U16_LENGTH(list->count); + + /* Encode octets length */ + MDER_OUTPUT_INT_U16_LENGTH(computed_size); + + /* + * Encode all members. + */ + for(edx = 0; edx < list->count; edx++) { + void *memb_ptr = list->array[edx]; + if(!memb_ptr) continue; + er = elm->type->mder_encoder(elm->type, memb_ptr, + elm->mder_constraints, + cb, app_key); + if(er.encoded == -1) + return er; + encoding_size += er.encoded; + } + + if(computed_size != encoding_size) + goto cb_failed; + + er.encoded = computed_size + 4; /* +4 count and length*/ + _ASN_ENCODED_OK(er); + +cb_failed: + _ASN_ENCODE_FAILED; +} + asn_enc_rval_t SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, int ilevel, enum xer_encoder_flags_e flags, diff --git a/skeletons/constr_SEQUENCE_OF.h b/skeletons/constr_SEQUENCE_OF.h index e2272f326..99a4d70a9 100644 --- a/skeletons/constr_SEQUENCE_OF.h +++ b/skeletons/constr_SEQUENCE_OF.h @@ -23,6 +23,8 @@ extern "C" { #define SEQUENCE_OF_decode_xer SET_OF_decode_xer #define SEQUENCE_OF_decode_uper SET_OF_decode_uper der_type_encoder_f SEQUENCE_OF_encode_der; +mder_type_encoder_f SEQUENCE_OF_encode_mder; +mder_type_decoder_f SEQUENCE_OF_decode_mder; xer_type_encoder_f SEQUENCE_OF_encode_xer; per_type_encoder_f SEQUENCE_OF_encode_uper; diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c index 11eac57a2..d6aef1259 100644 --- a/skeletons/constr_SET_OF.c +++ b/skeletons/constr_SET_OF.c @@ -884,7 +884,7 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, if(!st) { st = *sptr = CALLOC(1, specs->struct_size); if(!st) _ASN_DECODE_FAILED; - } + } list = _A_SET_FROM_VOID(st); /* Figure out which constraints to use */ diff --git a/skeletons/constr_TYPE.h b/skeletons/constr_TYPE.h index 95507c809..9e886a269 100644 --- a/skeletons/constr_TYPE.h +++ b/skeletons/constr_TYPE.h @@ -37,6 +37,8 @@ typedef struct asn_struct_ctx_s { #include /* Basic Encoding Rules decoder */ #include /* Distinguished Encoding Rules encoder */ +#include /* Medical Device Encoding Rules encoder */ +#include /* Medical Device Encoding Rules decoder */ #include /* Decoder of XER (XML, text) */ #include /* Encoder into XER (XML, text) */ #include /* Packet Encoding Rules decoder */ @@ -95,6 +97,8 @@ typedef struct asn_TYPE_descriptor_s { asn_constr_check_f *check_constraints; /* Constraints validator */ ber_type_decoder_f *ber_decoder; /* Generic BER decoder */ der_type_encoder_f *der_encoder; /* Canonical DER encoder */ + mder_type_decoder_f *mder_decoder; /* MDER decoder */ + mder_type_encoder_f *mder_encoder; /* MDER encoder */ xer_type_decoder_f *xer_decoder; /* Generic XER decoder */ xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */ per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */ @@ -126,6 +130,9 @@ typedef struct asn_TYPE_descriptor_s { * functions above. */ void *specifics; + + /* mder constraints */ + asn_mder_contraints_t mder_constraints; } asn_TYPE_descriptor_t; /* @@ -148,6 +155,7 @@ typedef struct asn_TYPE_member_s { asn_per_constraints_t *per_constraints; /* PER compiled constraints */ int (*default_value)(int setval, void **sptr); /* DEFAULT */ char *name; /* ASN.1 identifier of the element */ + asn_mder_contraints_t mder_constraints; /* mder constraints */ } asn_TYPE_member_t; /* diff --git a/skeletons/file-dependencies b/skeletons/file-dependencies index c2a5dae72..9701217c3 100644 --- a/skeletons/file-dependencies +++ b/skeletons/file-dependencies @@ -27,7 +27,7 @@ PrintableString.h PrintableString.c REAL.h REAL.c INTEGER.h RELATIVE-OID.h RELATIVE-OID.c OBJECT_IDENTIFIER.h T61String.h T61String.c -TeletexString.h TeletexString.c +TeletexString.h TeletexString.c UTCTime.h UTCTime.c GeneralizedTime.h UTF8String.h UTF8String.c UniversalString.h UniversalString.c UTF8String.h @@ -53,6 +53,9 @@ ber_tlv_length.h ber_tlv_length.c # BER TLV L (length) ber_tlv_tag.h ber_tlv_tag.c # BER TLV T (tag) ber_decoder.h ber_decoder.c # BER decoder support code der_encoder.h der_encoder.c # DER encoder support code +mder_support.h # MDER restricted types +mder_encoder.h mder_encoder.c # MDER encoder support code +mder_decoder.h mder_decoder.c # MDER decoder support code constr_TYPE.h constr_TYPE.c # Description of a type constraints.h constraints.c # Subtype constraints support xer_support.h xer_support.c # XML parsing diff --git a/skeletons/mder_decoder.c b/skeletons/mder_decoder.c new file mode 100644 index 000000000..4fdaa25d6 --- /dev/null +++ b/skeletons/mder_decoder.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2010 Santiago Carot-Nemesio + * Copyright (c) 2010 Jose Antonio Santos-Cadenas + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#include + +/* + * The MDER decoder of any type. + */ +asn_dec_rval_t +mder_decode(asn_codec_ctx_t *opt_codec_ctx, + asn_TYPE_descriptor_t *type_descriptor, + void **struct_ptr, const void *ptr, size_t size) { + asn_codec_ctx_t s_codec_ctx; + + /* + * Stack checker requires that the codec context + * must be allocated on the stack. + */ + if(opt_codec_ctx) { + if(opt_codec_ctx->max_stack_size) { + s_codec_ctx = *opt_codec_ctx; + opt_codec_ctx = &s_codec_ctx; + } + } else { + /* If context is not given, be security-conscious anyway */ + memset(&s_codec_ctx, 0, sizeof(s_codec_ctx)); + s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX; + opt_codec_ctx = &s_codec_ctx; + } + + /* + * Invoke type-specific decoder. + */ + return type_descriptor->mder_decoder(opt_codec_ctx, type_descriptor, + struct_ptr, /* Pointer to the destination structure */ + ptr, size, /* Buffer and its size */ + 0 /* Default tag mode is 0 */ + ); +} + +asn_dec_rval_t +NON_SUP_decode_mder(struct asn_codec_ctx_s *opt_codec_ctx, + struct asn_TYPE_descriptor_s *td, + void **struct_ptr, const void *buf_ptr, size_t size, + asn_mder_contraints_t constr) { + + _ASN_DECODE_FAILED; +} diff --git a/skeletons/mder_decoder.h b/skeletons/mder_decoder.h new file mode 100644 index 000000000..42559740f --- /dev/null +++ b/skeletons/mder_decoder.h @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2010 Santiago Carot-Nemesio + * Copyright (c) 2010 Jose Antonio Santos-Cadenas + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef _MDER_DECODER_H_ +#define _MDER_DECODER_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct asn_TYPE_descriptor_s; /* Forward declaration */ +struct asn_codec_ctx_s; /* Forward declaration */ + +/* + * The MDER decoder of any type. + * This function may be invoked directly from the application. + * The mder_encode() function (mder_encoder.h) is an opposite to mder_decode(). + */ +asn_dec_rval_t mder_decode(struct asn_codec_ctx_s *opt_codec_ctx, + struct asn_TYPE_descriptor_s *type_descriptor, + void **struct_ptr, /* Pointer to a target structure's pointer */ + const void *buffer, /* Data to be decoded */ + size_t size /* Size of that buffer */ + ); + +/* + * Type of generic function which decodes the byte stream into the structure. + */ +typedef asn_dec_rval_t (mder_type_decoder_f)( + struct asn_codec_ctx_s *opt_codec_ctx, + struct asn_TYPE_descriptor_s *type_descriptor, + void **struct_ptr, const void *buf_ptr, size_t size, + asn_mder_contraints_t constr); + +mder_type_decoder_f NON_SUP_decode_mder; + +#ifdef __cplusplus +} +#endif + +#endif /* _MDER_DECODER_H_ */ diff --git a/skeletons/mder_encoder.c b/skeletons/mder_encoder.c new file mode 100644 index 000000000..542cd88ca --- /dev/null +++ b/skeletons/mder_encoder.c @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2010 Santiago Carot-Nemesio + * Copyright (c) 2010 Jose Antonio Santos-Cadenas + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#include +#include + +asn_enc_rval_t mder_encode(struct asn_TYPE_descriptor_s *type_descriptor, + void *struct_ptr, asn_app_consume_bytes_f *consume_bytes_cb, + void *app_key) +{ + /* + * Invoke type-specific encoder. + */ + return type_descriptor->mder_encoder(type_descriptor, + struct_ptr, /* Pointer to the destination structure */ + 0, /* No specifics constraints */ + consume_bytes_cb, app_key); +} + +/* +* Argument type and callback necessary for mder_encode_to_buffer(). +*/ +typedef struct enc_to_buf_arg { + void *buffer; + size_t left; +} enc_to_buf_arg; + +static int encode_to_buffer_cb(const void *buffer, size_t size, void *key) { + enc_to_buf_arg *arg = (enc_to_buf_arg *)key; + + if(arg->left < size) + return -1; /* Data exceeds the available buffer size */ + + memcpy(arg->buffer, buffer, size); + arg->buffer = ((char *)arg->buffer) + size; + arg->left -= size; + + return 0; +} + +asn_enc_rval_t mder_encode_to_buffer( + struct asn_TYPE_descriptor_s *type_descriptor, void *struct_ptr, + void *buffer, size_t buffer_size) +{ + enc_to_buf_arg arg; + asn_enc_rval_t ec; + + arg.buffer = buffer; + arg.left = buffer_size; + + ec = type_descriptor->mder_encoder(type_descriptor, + struct_ptr, /* Pointer to the destination structure */ + 0, encode_to_buffer_cb, &arg); + if(ec.encoded != -1) { + assert(ec.encoded == (ssize_t)(buffer_size - arg.left)); + /* Return the encoded contents size */ + } + return ec; +} + +asn_enc_rval_t +NON_SUP_encode_mder(struct asn_TYPE_descriptor_s *td, void *sptr, + asn_mder_contraints_t constr, + asn_app_consume_bytes_f *consume_bytes_cb, void *app_key) { + + _ASN_ENCODE_FAILED; +} diff --git a/skeletons/mder_encoder.h b/skeletons/mder_encoder.h new file mode 100644 index 000000000..2b19733ef --- /dev/null +++ b/skeletons/mder_encoder.h @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2010 Santiago Carot-Nemesio + * Copyright (c) 2010 Jose Antonio Santos-Cadenas + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef _MDER_ENCODER_H_ +#define _MDER_ENCODER_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct asn_TYPE_descriptor_s; /* Forward declaration */ + +/* + * The MDER encoder of any type. May be invoked by the application. + */ +asn_enc_rval_t mder_encode(struct asn_TYPE_descriptor_s *type_descriptor, + void *struct_ptr, /* Structure to be encoded */ + asn_app_consume_bytes_f *consume_bytes_cb, + void *app_key /* Arbitrary callback argument */ + ); + +/* A variant of mder_encode() which encodes data into the pre-allocated buffer */ +asn_enc_rval_t mder_encode_to_buffer( + struct asn_TYPE_descriptor_s *type_descriptor, + void *struct_ptr, /* Structure to be encoded */ + void *buffer, /* Pre-allocated buffer */ + size_t buffer_size /* Initial buffer size (maximum) */ + ); + +/* + * Type of the generic MDER encoder. + */ +typedef asn_enc_rval_t (mder_type_encoder_f)( + struct asn_TYPE_descriptor_s *type_descriptor, + void *struct_ptr, /* Structure to be encoded */ + asn_mder_contraints_t constr, /* Specific constraints */ + asn_app_consume_bytes_f *consume_bytes_cb, /* Callback */ + void *app_key /* Arbitrary callback argument */ + ); + +mder_type_encoder_f NON_SUP_encode_mder; + +#ifdef __cplusplus +} +#endif + +#endif /* _MDER_ENCODER_H_ */ diff --git a/skeletons/mder_support.h b/skeletons/mder_support.h new file mode 100644 index 000000000..9142aafeb --- /dev/null +++ b/skeletons/mder_support.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2010 Jose Antonio Santos-Cadenas . + * Copyright (c) 2010 Santiago Carot-Nemesio . + * All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef _MDER_SUPPORT_H_ +#define _MDER_SUPPORT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Size constraints shall be used for all INTEGER data types to define the + * value range of the integer. + */ +typedef enum { + INT_INVALID, + INT_U8, + INT_I8, + INT_U16, + INT_I16, + INT_U32, + INT_I32 +} mder_restricted_int; + +/* + * Get the number of octets needed to encode/decode an integer type + */ +#define GET_INT_SIZE(_int,_size) do { \ + switch (_int) { \ + case INT_U8: \ + case INT_I8: \ + _size = 1; \ + break; \ + case INT_U16: \ + case INT_I16: \ + _size = 2; \ + break; \ + case INT_U32: \ + case INT_I32: \ + _size = 4; \ + break; \ + default: \ + _size = 0; \ + } \ +} while (0) + +#define GET_INT_UNSIGNED(_int,_unsign) do { \ + switch (_int) { \ + case INT_U8: \ + case INT_U16: \ + case INT_U32: \ + _unsign = 1; \ + break; \ + case INT_I8: \ + case INT_I16: \ + case INT_I32: \ + default: \ + _unsign = 0; \ + } \ +} while (0) + +/* + * Size constraints shall be used for all BIT STRING data types to define the + * value range of the bit string. + */ +typedef enum { + BITS_INVALID, + BITS_8 = 1, + BITS_16 = 2, + BITS_32 = 4 +} mder_restricted_bit_str; + +/* + * Pre-computed O-S contraints if they are present + */ +typedef uint16_t mder_octet_str; + +/* + * Pre-computed MDER Subtype constraint info. + */ +typedef void* asn_mder_contraints_t; + +#define CHECK_UINT16(_len) do { \ + if (((_len) < 0) || ((_len) > 65535)) \ + goto cb_failed; \ +} while (0) + +#ifdef WORDS_BIGENDIAN /* Opportunistic optimization */ +#define MDER_OUTPUT_INT_U16_LENGTH(_len) do { \ + CHECK_UINT16(_len); \ + if (cb) { \ + uint16_t aux = (uint16_t)(_len); \ + _ASN_CALLBACK((uint8_t *)&aux, 2); \ + } \ +} while (0) +#else /* Works even if WORDS_BIGENDIAN is not set where should've been */ +#define MDER_OUTPUT_INT_U16_LENGTH(_len) do { \ + CHECK_UINT16(_len); \ + if (cb) { \ + uint8_t lbuf[2]; /* length for variable O-S */ \ + lbuf[0] = ((_len) >> 8) & 0xff; \ + lbuf[1] = (_len) & 0xff; \ + _ASN_CALLBACK(lbuf, 2); \ + } \ +} while (0) +#endif + +#define MDER_INPUT_INT_U16(_int, _buf) do { \ + _int = 0; \ + _int = ((const uint8_t *)_buf)[0]; \ + _int = (_int << 8) | ((const uint8_t *)_buf)[1]; \ +}while (0) + +#ifdef __cplusplus +} +#endif + +#endif /* _MDER_SUPPORT_H_ */ diff --git a/skeletons/per_decoder.c b/skeletons/per_decoder.c index 2b3d2e298..95cc74f33 100644 --- a/skeletons/per_decoder.c +++ b/skeletons/per_decoder.c @@ -81,8 +81,8 @@ uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sp /* Return the number of consumed bits */ rval.consumed = ((pd.buffer - (const uint8_t *)buffer) << 3) + pd.nboff - skip_bits; - ASN_DEBUG("PER decoding consumed %d, counted %d", - rval.consumed, pd.moved); + ASN_DEBUG("PER decoding consumed %ld, counted %ld", + (long)rval.consumed, (long)pd.moved); assert(rval.consumed == pd.moved); } else { /* PER codec is not a restartable */ diff --git a/skeletons/per_encoder.c b/skeletons/per_encoder.c index f4bace060..e76ef74a9 100644 --- a/skeletons/per_encoder.c +++ b/skeletons/per_encoder.c @@ -88,7 +88,7 @@ uper_encode_to_new_buffer(asn_TYPE_descriptor_t *td, asn_per_constraints_t *cons } default: *buffer_r = key.buffer; - ASN_DEBUG("Complete encoded in %d bits", er.encoded); + ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded); return ((er.encoded + 7) >> 3); } } diff --git a/skeletons/per_opentype.c b/skeletons/per_opentype.c index c749c8c6c..6034d463f 100644 --- a/skeletons/per_opentype.c +++ b/skeletons/per_opentype.c @@ -47,8 +47,8 @@ uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints FREEMEM(buf); if(toGo) return -1; - ASN_DEBUG("Open type put %s of length %d + overhead (1byte?)", - td->name, size); + ASN_DEBUG("Open type put %s of length %ld + overhead (1byte?)", + td->name, (long)size); return 0; } @@ -92,8 +92,8 @@ uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, bufLen += chunk_bytes; } while(repeat); - ASN_DEBUG("Getting open type %s encoded in %d bytes", td->name, - bufLen); + ASN_DEBUG("Getting open type %s encoded in %ld bytes", td->name, + (long)bufLen); memset(&spd, 0, sizeof(spd)); spd.buffer = buf; @@ -113,7 +113,7 @@ uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, } FREEMEM(buf); if(padding >= 8) { - ASN_DEBUG("Too large padding %d in open type", padding); + ASN_DEBUG("Too large padding %ld in open type", (long)padding); _ASN_DECODE_FAILED; } else { ASN_DEBUG("Non-zero padding"); @@ -165,24 +165,24 @@ uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, return rv; } - ASN_DEBUG("OpenType %s pd%s old%s unclaimed=%d, repeat=%d" + ASN_DEBUG("OpenType %s pd%s old%s unclaimed=%ld, repeat=%ld" , td->name, per_data_string(pd), per_data_string(&arg.oldpd), - arg.unclaimed, arg.repeat); + (long)arg.unclaimed, (long)arg.repeat); padding = pd->moved % 8; if(padding) { int32_t pvalue; if(padding > 7) { - ASN_DEBUG("Too large padding %d in open type", - padding); + ASN_DEBUG("Too large padding %ld in open type", + (long)padding); rv.code = RC_FAIL; UPDRESTOREPD; return rv; } padding = 8 - padding; - ASN_DEBUG("Getting padding of %d bits", padding); + ASN_DEBUG("Getting padding of %ld bits", (long)padding); pvalue = per_get_few_bits(pd, padding); switch(pvalue) { case -1: @@ -191,8 +191,8 @@ uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, _ASN_DECODE_STARVED; case 0: break; default: - ASN_DEBUG("Non-blank padding (%d bits 0x%02x)", - padding, (int)pvalue); + ASN_DEBUG("Non-blank padding (%ld bits 0x%02x)", + (long)padding, (int)pvalue); UPDRESTOREPD; _ASN_DECODE_FAILED; } @@ -212,14 +212,14 @@ uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td, UPDRESTOREPD; /* Skip data not consumed by the decoder */ - if(arg.unclaimed) ASN_DEBUG("Getting unclaimed %d", arg.unclaimed); if(arg.unclaimed) { + ASN_DEBUG("Getting unclaimed %ld", (long)arg.unclaimed); switch(per_skip_bits(pd, arg.unclaimed)) { case -1: - ASN_DEBUG("Claim of %d failed", arg.unclaimed); + ASN_DEBUG("Claim of %ld failed", (long)arg.unclaimed); _ASN_DECODE_STARVED; case 0: - ASN_DEBUG("Got claim of %d", arg.unclaimed); + ASN_DEBUG("Got claim of %ld", (long)arg.unclaimed); break; default: /* Padding must be blank */ @@ -293,8 +293,8 @@ uper_ugot_refill(asn_per_data_t *pd) { asn_per_data_t *oldpd = &arg->oldpd; - ASN_DEBUG("REFILLING pd->moved=%d, oldpd->moved=%d", - pd->moved, oldpd->moved); + ASN_DEBUG("REFILLING pd->moved=%ld, oldpd->moved=%ld", + (long)pd->moved, (long)oldpd->moved); /* Advance our position to where pd is */ oldpd->buffer = pd->buffer; @@ -314,7 +314,7 @@ uper_ugot_refill(asn_per_data_t *pd) { pd->buffer = oldpd->buffer; pd->nboff = oldpd->nboff - 1; pd->nbits = oldpd->nbits; - ASN_DEBUG("UNCLAIMED <- return from (pd->moved=%d)", pd->moved); + ASN_DEBUG("UNCLAIMED <- return from (pd->moved=%ld)", (long)pd->moved); return 0; } @@ -324,8 +324,8 @@ uper_ugot_refill(asn_per_data_t *pd) { } next_chunk_bytes = uper_get_length(oldpd, -1, &arg->repeat); - ASN_DEBUG("Open type LENGTH %d bytes at off %d, repeat %d", - next_chunk_bytes, oldpd->moved, arg->repeat); + ASN_DEBUG("Open type LENGTH %ld bytes at off %ld, repeat %ld", + (long)next_chunk_bytes, (long)oldpd->moved, (long)arg->repeat); if(next_chunk_bytes < 0) return -1; if(next_chunk_bytes == 0) { pd->refill = 0; /* No more refills, naturally */ @@ -336,14 +336,15 @@ uper_ugot_refill(asn_per_data_t *pd) { if(avail >= next_chunk_bits) { pd->nbits = oldpd->nboff + next_chunk_bits; arg->unclaimed = 0; - ASN_DEBUG("!+Parent frame %d bits, alloting %d [%d..%d] (%d)", - next_chunk_bits, oldpd->moved, - oldpd->nboff, oldpd->nbits, - oldpd->nbits - oldpd->nboff); + ASN_DEBUG("!+Parent frame %ld bits, alloting %ld [%ld..%ld] (%ld)", + (long)next_chunk_bits, (long)oldpd->moved, + (long)oldpd->nboff, (long)oldpd->nbits, + (long)oldpd->nbits - oldpd->nboff); } else { pd->nbits = oldpd->nbits; arg->unclaimed = next_chunk_bits - avail; - ASN_DEBUG("!-Parent frame %d, require %d, will claim %d", avail, next_chunk_bits, arg->unclaimed); + ASN_DEBUG("!-Parent frame %ld, require %ld, will claim %ld", + (long)avail, (long)next_chunk_bits, (long)arg->unclaimed); } pd->buffer = oldpd->buffer; pd->nboff = oldpd->nboff; diff --git a/skeletons/per_support.c b/skeletons/per_support.c index e8299c730..e57b3186d 100644 --- a/skeletons/per_support.c +++ b/skeletons/per_support.c @@ -13,11 +13,11 @@ per_data_string(asn_per_data_t *pd) { static int n; n = (n+1) % 2; snprintf(buf[n], sizeof(buf), - "{m=%d span %+d[%d..%d] (%d)}", - pd->moved, - (((int)pd->buffer) & 0xf), - pd->nboff, pd->nbits, - pd->nbits - pd->nboff); + "{m=%ld span %+ld[%ld..%ld] (%ld)}", + (long)pd->moved, + (((long int)pd->buffer) & 0xf), + (long)pd->nboff, (long)pd->nbits, + (long)(pd->nbits - pd->nboff)); return buf[n]; } @@ -49,7 +49,8 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) { int32_t tailv, vhead; if(!pd->refill || nbits > 31) return -1; /* Accumulate unused bytes before refill */ - ASN_DEBUG("Obtain the rest %d bits (want %d)", nleft, nbits); + ASN_DEBUG("Obtain the rest %ld bits (want %ld)", + (long)nleft, (long)nbits); tailv = per_get_few_bits(pd, nleft); if(tailv < 0) return -1; /* Refill (replace pd contents with new data) */ @@ -103,15 +104,6 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) { accum &= (((uint32_t)1 << nbits) - 1); - ASN_DEBUG(" [PER got %2d<=%2d bits => span %d %+d[%d..%d]:%02x (%d) => 0x%x]", - nbits, nleft, - pd->moved, - (((int)pd->buffer) & 0xf), - pd->nboff, pd->nbits, - pd->buffer[0], - pd->nbits - pd->nboff, - (int)accum); - return accum; } @@ -200,7 +192,7 @@ uper_get_nslength(asn_per_data_t *pd) { if(per_get_few_bits(pd, 1) == 0) { length = per_get_few_bits(pd, 6) + 1; if(length <= 0) return -1; - ASN_DEBUG("l=%d", length); + ASN_DEBUG("l=%ld", (long)length); return length; } else { int repeat; @@ -275,7 +267,7 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) { if(obits <= 0 || obits >= 32) return obits ? -1 : 0; ASN_DEBUG("[PER put %d bits %x to %p+%d bits]", - obits, (int)bits, po->buffer, po->nboff); + obits, (int)bits, po->buffer, (int)po->nboff); /* * Normalize position indicator. @@ -291,8 +283,8 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) { */ if(po->nboff + obits > po->nbits) { int complete_bytes = (po->buffer - po->tmpspace); - ASN_DEBUG("[PER output %d complete + %d]", - complete_bytes, po->flushed_bytes); + ASN_DEBUG("[PER output %d complete + %ld]", + complete_bytes, (long)po->flushed_bytes); if(po->outper(po->tmpspace, complete_bytes, po->op_key) < 0) return -1; if(po->nboff) @@ -312,9 +304,11 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) { /* Clear data of debris before meaningful bits */ bits &= (((uint32_t)1 << obits) - 1); - ASN_DEBUG("[PER out %d %u/%x (t=%d,o=%d) %x&%x=%x]", obits, + ASN_DEBUG("[PER out %d %u/%x (t=%ld,o=%d) %x&%x=%x]", obits, (int)bits, (int)bits, - po->nboff - obits, off, buf[0], omsk&0xff, buf[0] & omsk); + (long)(po->nboff - obits), + (unsigned)off, (unsigned)buf[0], + (unsigned)omsk&0xff, (unsigned)(buf[0] & omsk)); if(off <= 8) /* Completely within 1 byte */ bits <<= (8 - off), @@ -341,8 +335,8 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) { ASN_DEBUG("<-[PER out split %d]", obits); } - ASN_DEBUG("[PER out %u/%x => %02x buf+%d]", - (int)bits, (int)bits, buf[0], po->buffer - po->tmpspace); + ASN_DEBUG("[PER out %u/%x => %02x buf+%ld]", + (int)bits, (int)bits, buf[0], (long)(po->buffer - po->tmpspace)); return 0; }