mirror of https://gerrit.osmocom.org/asn1c
new constraints model
This commit is contained in:
parent
e64460f66b
commit
449f8324e9
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_BIT_STRING = {
|
|||
/ sizeof(asn1_DEF_BIT_STRING_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
(void *)-1 /* Special indicator that this is a BIT STRING */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_BMPString = {
|
|||
/ sizeof(asn1_DEF_BMPString_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ asn1_TYPE_descriptor_t asn1_DEF_BOOLEAN = {
|
|||
sizeof(asn1_DEF_BOOLEAN_tags)/sizeof(asn1_DEF_BOOLEAN_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
0, /* Always in primitive form */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ asn1_TYPE_descriptor_t asn1_DEF_ENUMERATED = {
|
|||
sizeof(asn1_DEF_ENUMERATED_tags)/sizeof(asn1_DEF_ENUMERATED_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
0, /* Primitive */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_GeneralString = {
|
|||
/ sizeof(asn1_DEF_GeneralString_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ asn1_TYPE_descriptor_t asn1_DEF_GeneralizedTime = {
|
|||
/ sizeof(asn1_DEF_GeneralizedTime_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_GraphicString = {
|
|||
/ sizeof(asn1_DEF_GraphicString_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_IA5String = {
|
|||
/ sizeof(asn1_DEF_IA5String_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ asn1_TYPE_descriptor_t asn1_DEF_INTEGER = {
|
|||
sizeof(asn1_DEF_INTEGER_tags)/sizeof(asn1_DEF_INTEGER_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
0, /* Always in primitive form */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_ISO646String = {
|
|||
/ sizeof(asn1_DEF_ISO646String_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_NULL = {
|
|||
sizeof(asn1_DEF_NULL_tags)/sizeof(asn1_DEF_NULL_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
0, /* Always in primitive form */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -29,5 +29,7 @@ asn1_TYPE_descriptor_t asn1_DEF_NativeEnumerated = {
|
|||
sizeof(asn1_DEF_NativeEnumerated_tags)/sizeof(asn1_DEF_NativeEnumerated_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
0, /* Always in primitive form */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ asn1_TYPE_descriptor_t asn1_DEF_NativeInteger = {
|
|||
sizeof(asn1_DEF_NativeInteger_tags)/sizeof(asn1_DEF_NativeInteger_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
0, /* Always in primitive form */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_NumericString = {
|
|||
/ sizeof(asn1_DEF_NumericString_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ asn1_TYPE_descriptor_t asn1_DEF_OBJECT_IDENTIFIER = {
|
|||
/ sizeof(asn1_DEF_OBJECT_IDENTIFIER_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
0, /* Always in primitive form */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ asn1_TYPE_descriptor_t asn1_DEF_OCTET_STRING = {
|
|||
/ sizeof(asn1_DEF_OCTET_STRING_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine (primitive and constructed) */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_ObjectDescriptor = {
|
|||
/ sizeof(asn1_DEF_ObjectDescriptor_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_PrintableString = {
|
|||
/ sizeof(asn1_DEF_PrintableString_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ asn1_TYPE_descriptor_t asn1_DEF_RELATIVE_OID = {
|
|||
/ sizeof(asn1_DEF_RELATIVE_OID_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
0, /* Always in primitive form */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_T61String = {
|
|||
/ sizeof(asn1_DEF_T61String_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_TeletexString = {
|
|||
/ sizeof(asn1_DEF_TeletexString_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ asn1_TYPE_descriptor_t asn1_DEF_UTCTime = {
|
|||
/ sizeof(asn1_DEF_UTCTime_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_UTF8String = {
|
|||
/ sizeof(asn1_DEF_UTF8String_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_UniversalString = {
|
|||
/ sizeof(asn1_DEF_UniversalString_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_VideotexString = {
|
|||
/ sizeof(asn1_DEF_VideotexString_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ asn1_TYPE_descriptor_t asn1_DEF_VisibleString = {
|
|||
/ sizeof(asn1_DEF_VisibleString_tags[0]),
|
||||
1, /* Single UNIVERSAL tag may be implicitly overriden */
|
||||
-1, /* Both ways are fine */
|
||||
0, 0, /* No members */
|
||||
0 /* No specifics */
|
||||
};
|
||||
|
||||
|
|
|
@ -93,13 +93,13 @@ _search4tag(const void *ap, const void *bp) {
|
|||
* The decoder of the CHOICE type.
|
||||
*/
|
||||
ber_dec_rval_t
|
||||
CHOICE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
||||
CHOICE_decode_ber(asn1_TYPE_descriptor_t *td,
|
||||
void **struct_ptr, void *ptr, size_t size, int tag_mode) {
|
||||
/*
|
||||
* Bring closer parts of structure description.
|
||||
*/
|
||||
asn1_CHOICE_specifics_t *specs = (asn1_CHOICE_specifics_t *)sd->specifics;
|
||||
asn1_CHOICE_element_t *elements = specs->elements;
|
||||
asn1_CHOICE_specifics_t *specs = (asn1_CHOICE_specifics_t *)td->specifics;
|
||||
asn1_TYPE_member_t *elements = td->elements;
|
||||
|
||||
/*
|
||||
* Parts of the structure being constructed.
|
||||
|
@ -114,7 +114,7 @@ CHOICE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
|
||||
ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
|
||||
|
||||
ASN_DEBUG("Decoding %s as CHOICE", sd->name);
|
||||
ASN_DEBUG("Decoding %s as CHOICE", td->name);
|
||||
|
||||
/*
|
||||
* Create the target structure if it is not present already.
|
||||
|
@ -142,12 +142,12 @@ CHOICE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
* perfectly fits our expectations.
|
||||
*/
|
||||
|
||||
if(tag_mode || sd->tags_count) {
|
||||
rval = ber_check_tags(sd, ctx, ptr, size,
|
||||
if(tag_mode || td->tags_count) {
|
||||
rval = ber_check_tags(td, ctx, ptr, size,
|
||||
tag_mode, &ctx->left, 0);
|
||||
if(rval.code != RC_OK) {
|
||||
ASN_DEBUG("%s tagging check failed: %d",
|
||||
sd->name, rval.code);
|
||||
td->name, rval.code);
|
||||
consumed_myself += rval.consumed;
|
||||
RETURN(rval.code);
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ CHOICE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
* Fetch the T from TLV.
|
||||
*/
|
||||
tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag);
|
||||
ASN_DEBUG("In %s CHOICE tag length %d", sd->name, (int)tag_len);
|
||||
ASN_DEBUG("In %s CHOICE tag length %d", td->name, (int)tag_len);
|
||||
switch(tag_len) {
|
||||
case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
|
||||
/* Fall through */
|
||||
|
@ -197,7 +197,7 @@ CHOICE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
} else if(specs->extensible == 0) {
|
||||
ASN_DEBUG("Unexpected tag %s "
|
||||
"in non-extensible CHOICE %s",
|
||||
ber_tlv_tag_string(tlv_tag), sd->name);
|
||||
ber_tlv_tag_string(tlv_tag), td->name);
|
||||
RETURN(RC_FAIL);
|
||||
} else {
|
||||
/* Skip this tag */
|
||||
|
@ -227,7 +227,7 @@ CHOICE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
* Read in the element.
|
||||
*/
|
||||
do {
|
||||
asn1_CHOICE_element_t *elm; /* CHOICE's element */
|
||||
asn1_TYPE_member_t *elm;/* CHOICE's element */
|
||||
void *memb_ptr; /* Pointer to the member */
|
||||
void **memb_ptr2; /* Pointer to that pointer */
|
||||
|
||||
|
@ -252,6 +252,9 @@ CHOICE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
/*
|
||||
* Invoke the member fetch routine according to member's type
|
||||
*/
|
||||
printf("elm->name = %s\n", elm->name);
|
||||
printf("elm->td = %p\n", elm->type);
|
||||
printf("elm->td->name = %s\n", elm->type->name);
|
||||
rval = elm->type->ber_decoder(elm->type,
|
||||
memb_ptr2, ptr, LEFT,
|
||||
elm->tag_mode);
|
||||
|
@ -278,8 +281,8 @@ CHOICE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
/* Fall through */
|
||||
case 3:
|
||||
ASN_DEBUG("CHOICE %s Leftover: %ld, size = %ld, tm=%d, tc=%d",
|
||||
sd->name, (long)ctx->left, (long)size,
|
||||
tag_mode, sd->tags_count);
|
||||
td->name, (long)ctx->left, (long)size,
|
||||
tag_mode, td->tags_count);
|
||||
|
||||
if(ctx->left > 0) {
|
||||
/*
|
||||
|
@ -290,7 +293,7 @@ CHOICE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
}
|
||||
|
||||
if(ctx->left == -1
|
||||
&& !(tag_mode || sd->tags_count)) {
|
||||
&& !(tag_mode || td->tags_count)) {
|
||||
/*
|
||||
* This is an untagged CHOICE.
|
||||
* It doesn't contain nothing
|
||||
|
@ -331,7 +334,7 @@ CHOICE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
}
|
||||
} else {
|
||||
ASN_DEBUG("Unexpected continuation in %s",
|
||||
sd->name);
|
||||
td->name);
|
||||
RETURN(RC_FAIL);
|
||||
}
|
||||
|
||||
|
@ -349,19 +352,19 @@ CHOICE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
}
|
||||
|
||||
der_enc_rval_t
|
||||
CHOICE_encode_der(asn1_TYPE_descriptor_t *sd,
|
||||
CHOICE_encode_der(asn1_TYPE_descriptor_t *td,
|
||||
void *struct_ptr,
|
||||
int tag_mode, ber_tlv_tag_t tag,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn1_CHOICE_specifics_t *specs = (asn1_CHOICE_specifics_t *)sd->specifics;
|
||||
asn1_CHOICE_element_t *elm; /* CHOICE element */
|
||||
asn1_CHOICE_specifics_t *specs = (asn1_CHOICE_specifics_t *)td->specifics;
|
||||
asn1_TYPE_member_t *elm; /* CHOICE element */
|
||||
der_enc_rval_t erval;
|
||||
void *memb_ptr;
|
||||
size_t computed_size = 0;
|
||||
int present;
|
||||
|
||||
ASN_DEBUG("%s %s as CHOICE",
|
||||
cb?"Encoding":"Estimating", sd->name);
|
||||
cb?"Encoding":"Estimating", td->name);
|
||||
|
||||
present = _fetch_present_idx(struct_ptr,
|
||||
specs->pres_offset, specs->pres_size);
|
||||
|
@ -370,14 +373,14 @@ CHOICE_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
* If the structure was not initialized, it cannot be encoded:
|
||||
* can't deduce what to encode in the choice type.
|
||||
*/
|
||||
if(present <= 0 || present > specs->elements_count) {
|
||||
if(present == 0 && specs->elements_count == 0) {
|
||||
if(present <= 0 || present > td->elements_count) {
|
||||
if(present == 0 && td->elements_count == 0) {
|
||||
/* The CHOICE is empty?! */
|
||||
erval.encoded = 0;
|
||||
return erval;
|
||||
}
|
||||
erval.encoded = -1;
|
||||
erval.failed_type = sd;
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = struct_ptr;
|
||||
return erval;
|
||||
}
|
||||
|
@ -385,7 +388,7 @@ CHOICE_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
/*
|
||||
* Seek over the present member of the structure.
|
||||
*/
|
||||
elm = &specs->elements[present-1];
|
||||
elm = &td->elements[present-1];
|
||||
if(elm->optional) {
|
||||
memb_ptr = *(void **)((char *)struct_ptr + elm->memb_offset);
|
||||
if(memb_ptr == 0) {
|
||||
|
@ -401,7 +404,7 @@ CHOICE_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
* T ::= [2] EXPLICIT CHOICE { ... }
|
||||
* Then emit the appropriate tags.
|
||||
*/
|
||||
if(tag_mode == 1 || sd->tags_count) {
|
||||
if(tag_mode == 1 || td->tags_count) {
|
||||
/*
|
||||
* For this, we need to pre-compute the member.
|
||||
*/
|
||||
|
@ -414,11 +417,11 @@ CHOICE_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
return erval;
|
||||
|
||||
/* Encode CHOICE with parent or my own tag */
|
||||
ret = der_write_tags(sd, erval.encoded, tag_mode, tag,
|
||||
ret = der_write_tags(td, erval.encoded, tag_mode, tag,
|
||||
cb, app_key);
|
||||
if(ret == -1) {
|
||||
erval.encoded = -1;
|
||||
erval.failed_type = sd;
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = struct_ptr;
|
||||
return erval;
|
||||
}
|
||||
|
@ -454,8 +457,8 @@ CHOICE_outmost_tag(asn1_TYPE_descriptor_t *td, const void *ptr, int tag_mode, be
|
|||
*/
|
||||
present = _fetch_present_idx(ptr, specs->pres_offset, specs->pres_size);
|
||||
|
||||
if(present > 0 || present <= specs->elements_count) {
|
||||
asn1_CHOICE_element_t *elm = &specs->elements[present-1];
|
||||
if(present > 0 || present <= td->elements_count) {
|
||||
asn1_TYPE_member_t *elm = &td->elements[present-1];
|
||||
const void *memb_ptr;
|
||||
|
||||
if(elm->optional) {
|
||||
|
@ -489,8 +492,8 @@ CHOICE_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
|
|||
* Figure out which CHOICE element is encoded.
|
||||
*/
|
||||
present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
|
||||
if(present > 0 && present <= specs->elements_count) {
|
||||
asn1_CHOICE_element_t *elm = &specs->elements[present-1];
|
||||
if(present > 0 && present <= td->elements_count) {
|
||||
asn1_TYPE_member_t *elm = &td->elements[present-1];
|
||||
const void *memb_ptr;
|
||||
|
||||
if(elm->optional) {
|
||||
|
@ -500,8 +503,19 @@ CHOICE_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
|
|||
memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
|
||||
}
|
||||
|
||||
return elm->type->check_constraints(elm->type, memb_ptr,
|
||||
if(elm->memb_constraints) {
|
||||
return elm->memb_constraints(elm->type, memb_ptr,
|
||||
app_errlog, app_key);
|
||||
} else {
|
||||
int ret = elm->type->check_constraints(elm->type,
|
||||
memb_ptr, app_errlog, app_key);
|
||||
/*
|
||||
* Cannot inherit it eralier:
|
||||
* need to make sure we get the updated version.
|
||||
*/
|
||||
elm->memb_constraints = elm->type->check_constraints;
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
_ASN_ERRLOG(app_errlog, app_key,
|
||||
"%s: no CHOICE element given", td->name);
|
||||
|
@ -525,8 +539,8 @@ CHOICE_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
|||
/*
|
||||
* Free that element.
|
||||
*/
|
||||
if(present > 0 && present <= specs->elements_count) {
|
||||
asn1_CHOICE_element_t *elm = &specs->elements[present-1];
|
||||
if(present > 0 && present <= td->elements_count) {
|
||||
asn1_TYPE_member_t *elm = &td->elements[present-1];
|
||||
const void *memb_ptr;
|
||||
|
||||
if(elm->optional) {
|
||||
|
@ -566,8 +580,8 @@ CHOICE_free(asn1_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
|||
/*
|
||||
* Free that element.
|
||||
*/
|
||||
if(present > 0 && present <= specs->elements_count) {
|
||||
asn1_CHOICE_element_t *elm = &specs->elements[present-1];
|
||||
if(present > 0 && present <= td->elements_count) {
|
||||
asn1_TYPE_member_t *elm = &td->elements[present-1];
|
||||
void *memb_ptr;
|
||||
|
||||
if(elm->optional) {
|
||||
|
|
|
@ -7,18 +7,6 @@
|
|||
|
||||
#include <constr_TYPE.h>
|
||||
|
||||
/*
|
||||
* A single element of the CHOICE type.
|
||||
*/
|
||||
typedef struct asn1_CHOICE_element_s {
|
||||
int memb_offset; /* Offset of the element */
|
||||
int optional; /* Whether the element is optional */
|
||||
ber_tlv_tag_t tag; /* Outmost (most immediate) tag */
|
||||
int tag_mode; /* IMPLICIT/no/EXPLICIT tag at current level */
|
||||
asn1_TYPE_descriptor_t *type; /* Member type descriptor */
|
||||
char *name; /* ASN.1 identifier of the element */
|
||||
} asn1_CHOICE_element_t;
|
||||
|
||||
typedef struct asn1_CHOICE_specifics_s {
|
||||
/*
|
||||
* Target structure description.
|
||||
|
@ -28,12 +16,6 @@ typedef struct asn1_CHOICE_specifics_s {
|
|||
int pres_offset; /* Identifier of the present member */
|
||||
int pres_size; /* Size of the identifier (enum) */
|
||||
|
||||
/*
|
||||
* Members of the CHOICE structure.
|
||||
*/
|
||||
asn1_CHOICE_element_t *elements;
|
||||
int elements_count;
|
||||
|
||||
/*
|
||||
* Tags to members mapping table.
|
||||
*/
|
||||
|
|
|
@ -103,13 +103,13 @@ _t2e_cmp(const void *ap, const void *bp) {
|
|||
* The decoder of the SEQUENCE type.
|
||||
*/
|
||||
ber_dec_rval_t
|
||||
SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
||||
SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *td,
|
||||
void **struct_ptr, void *ptr, size_t size, int tag_mode) {
|
||||
/*
|
||||
* Bring closer parts of structure description.
|
||||
*/
|
||||
asn1_SEQUENCE_specifics_t *specs = (asn1_SEQUENCE_specifics_t *)sd->specifics;
|
||||
asn1_SEQUENCE_element_t *elements = specs->elements;
|
||||
asn1_SEQUENCE_specifics_t *specs = (asn1_SEQUENCE_specifics_t *)td->specifics;
|
||||
asn1_TYPE_member_t *elements = td->elements;
|
||||
|
||||
/*
|
||||
* Parts of the structure being constructed.
|
||||
|
@ -124,7 +124,7 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
|
||||
int edx; /* SEQUENCE element's index */
|
||||
|
||||
ASN_DEBUG("Decoding %s as SEQUENCE", sd->name);
|
||||
ASN_DEBUG("Decoding %s as SEQUENCE", td->name);
|
||||
|
||||
/*
|
||||
* Create the target structure if it is not present already.
|
||||
|
@ -152,11 +152,11 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
* perfectly fits our expectations.
|
||||
*/
|
||||
|
||||
rval = ber_check_tags(sd, ctx, ptr, size,
|
||||
rval = ber_check_tags(td, ctx, ptr, size,
|
||||
tag_mode, &ctx->left, 0);
|
||||
if(rval.code != RC_OK) {
|
||||
ASN_DEBUG("%s tagging check failed: %d",
|
||||
sd->name, rval.code);
|
||||
td->name, rval.code);
|
||||
consumed_myself += rval.consumed;
|
||||
RETURN(rval.code);
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
* that member:
|
||||
* step = (<member_number> * 2 + <microphase>).
|
||||
*/
|
||||
for(edx = (ctx->step >> 1); edx < specs->elements_count;
|
||||
for(edx = (ctx->step >> 1); edx < td->elements_count;
|
||||
edx++, ctx->step = (ctx->step & ~1) + 2) {
|
||||
void *memb_ptr; /* Pointer to the member */
|
||||
void **memb_ptr2; /* Pointer to that pointer */
|
||||
|
@ -198,20 +198,20 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
* MICROPHASE 1: Synchronize decoding.
|
||||
*/
|
||||
ASN_DEBUG("In %s SEQUENCE left %d, edx=%d opt=%d ec=%d",
|
||||
sd->name, (int)ctx->left,
|
||||
edx, elements[edx].optional, specs->elements_count);
|
||||
td->name, (int)ctx->left,
|
||||
edx, elements[edx].optional, td->elements_count);
|
||||
|
||||
if(ctx->left == 0 /* No more stuff is expected */
|
||||
&& (
|
||||
/* Explicit OPTIONAL specification reaches the end */
|
||||
(edx + elements[edx].optional == specs->elements_count)
|
||||
(edx + elements[edx].optional == td->elements_count)
|
||||
||
|
||||
/* All extensions are optional */
|
||||
(IN_EXTENSION_GROUP(specs, edx)
|
||||
&& specs->ext_before > specs->elements_count)
|
||||
&& specs->ext_before > td->elements_count)
|
||||
)
|
||||
) {
|
||||
ASN_DEBUG("End of SEQUENCE %s", sd->name);
|
||||
ASN_DEBUG("End of SEQUENCE %s", td->name);
|
||||
/*
|
||||
* Found the legitimate end of the structure.
|
||||
*/
|
||||
|
@ -224,7 +224,7 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
*/
|
||||
tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag);
|
||||
ASN_DEBUG("In %s SEQUENCE for %d %s next tag length %d",
|
||||
sd->name, edx, elements[edx].name, (int)tag_len);
|
||||
td->name, edx, elements[edx].name, (int)tag_len);
|
||||
switch(tag_len) {
|
||||
case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
|
||||
/* Fall through */
|
||||
|
@ -236,8 +236,8 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
*/
|
||||
use_bsearch = 0;
|
||||
opt_edx_end = edx + elements[edx].optional + 1;
|
||||
if(opt_edx_end > specs->elements_count)
|
||||
opt_edx_end = specs->elements_count; /* Cap */
|
||||
if(opt_edx_end > td->elements_count)
|
||||
opt_edx_end = td->elements_count; /* Cap */
|
||||
else if(opt_edx_end - edx > 8) {
|
||||
/* Limit the scope of linear search... */
|
||||
opt_edx_end = edx + 8;
|
||||
|
@ -340,7 +340,7 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
BER_TLV_CONSTRUCTED(ptr),
|
||||
(char *)ptr + tag_len, LEFT - tag_len);
|
||||
ASN_DEBUG("Skip length %d in %s",
|
||||
(int)skip, sd->name);
|
||||
(int)skip, td->name);
|
||||
switch(skip) {
|
||||
case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
|
||||
/* Fall through */
|
||||
|
@ -359,7 +359,7 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
*/
|
||||
ctx->step |= 1; /* Confirm entering next microphase */
|
||||
microphase2:
|
||||
ASN_DEBUG("Inside SEQUENCE %s MF2", sd->name);
|
||||
ASN_DEBUG("Inside SEQUENCE %s MF2", td->name);
|
||||
|
||||
/*
|
||||
* Compute the position of the member inside a structure,
|
||||
|
@ -385,7 +385,7 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
memb_ptr2, ptr, LEFT,
|
||||
elements[edx].tag_mode);
|
||||
ASN_DEBUG("In %s SEQUENCE decoded %d %s in %d bytes code %d",
|
||||
sd->name, edx, elements[edx].type->name,
|
||||
td->name, edx, elements[edx].type->name,
|
||||
(int)rval.consumed, rval.code);
|
||||
switch(rval.code) {
|
||||
case RC_OK:
|
||||
|
@ -409,7 +409,7 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
case 4: /* only 00's expected */
|
||||
|
||||
ASN_DEBUG("SEQUENCE %s Leftover: %ld, size = %ld",
|
||||
sd->name, (long)ctx->left, (long)size);
|
||||
td->name, (long)ctx->left, (long)size);
|
||||
|
||||
/*
|
||||
* Skip everything until the end of the SEQUENCE.
|
||||
|
@ -445,12 +445,12 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
}
|
||||
}
|
||||
|
||||
if(!IN_EXTENSION_GROUP(specs, specs->elements_count)
|
||||
if(!IN_EXTENSION_GROUP(specs, td->elements_count)
|
||||
|| ctx->phase == 4) {
|
||||
ASN_DEBUG("Unexpected continuation "
|
||||
"of a non-extensible type "
|
||||
"%s (SEQUENCE): %s",
|
||||
sd->name,
|
||||
td->name,
|
||||
ber_tlv_tag_string(tlv_tag));
|
||||
RETURN(RC_FAIL);
|
||||
}
|
||||
|
@ -478,23 +478,22 @@ SEQUENCE_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
* The DER encoder of the SEQUENCE type.
|
||||
*/
|
||||
der_enc_rval_t
|
||||
SEQUENCE_encode_der(asn1_TYPE_descriptor_t *sd,
|
||||
SEQUENCE_encode_der(asn1_TYPE_descriptor_t *td,
|
||||
void *ptr, int tag_mode, ber_tlv_tag_t tag,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn1_SEQUENCE_specifics_t *specs = (asn1_SEQUENCE_specifics_t *)sd->specifics;
|
||||
size_t computed_size = 0;
|
||||
der_enc_rval_t erval;
|
||||
ssize_t ret;
|
||||
int edx;
|
||||
|
||||
ASN_DEBUG("%s %s as SEQUENCE",
|
||||
cb?"Encoding":"Estimating", sd->name);
|
||||
cb?"Encoding":"Estimating", td->name);
|
||||
|
||||
/*
|
||||
* Gather the length of the underlying members sequence.
|
||||
*/
|
||||
for(edx = 0; edx < specs->elements_count; edx++) {
|
||||
asn1_SEQUENCE_element_t *elm = &specs->elements[edx];
|
||||
for(edx = 0; edx < td->elements_count; edx++) {
|
||||
asn1_TYPE_member_t *elm = &td->elements[edx];
|
||||
void *memb_ptr;
|
||||
if(elm->optional) {
|
||||
memb_ptr = *(void **)((char *)ptr + elm->memb_offset);
|
||||
|
@ -515,11 +514,11 @@ SEQUENCE_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
/*
|
||||
* Encode the TLV for the sequence itself.
|
||||
*/
|
||||
ret = der_write_tags(sd, computed_size, tag_mode, tag, cb, app_key);
|
||||
ret = der_write_tags(td, computed_size, tag_mode, tag, cb, app_key);
|
||||
ASN_DEBUG("Wrote tags: %ld (+%ld)", (long)ret, (long)computed_size);
|
||||
if(ret == -1) {
|
||||
erval.encoded = -1;
|
||||
erval.failed_type = sd;
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = ptr;
|
||||
return erval;
|
||||
}
|
||||
|
@ -530,8 +529,8 @@ SEQUENCE_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
/*
|
||||
* Encode all members.
|
||||
*/
|
||||
for(edx = 0; edx < specs->elements_count; edx++) {
|
||||
asn1_SEQUENCE_element_t *elm = &specs->elements[edx];
|
||||
for(edx = 0; edx < td->elements_count; edx++) {
|
||||
asn1_TYPE_member_t *elm = &td->elements[edx];
|
||||
der_enc_rval_t tmperval;
|
||||
void *memb_ptr;
|
||||
|
||||
|
@ -548,7 +547,7 @@ SEQUENCE_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
return tmperval;
|
||||
computed_size -= tmperval.encoded;
|
||||
ASN_DEBUG("Member %d %s of SEQUENCE %s encoded in %d bytes",
|
||||
edx, elm->name, sd->name, tmperval.encoded);
|
||||
edx, elm->name, td->name, tmperval.encoded);
|
||||
}
|
||||
|
||||
if(computed_size != 0) {
|
||||
|
@ -556,7 +555,7 @@ SEQUENCE_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
* Encoded size is not equal to the computed size.
|
||||
*/
|
||||
erval.encoded = -1;
|
||||
erval.failed_type = sd;
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = ptr;
|
||||
}
|
||||
|
||||
|
@ -566,7 +565,6 @@ SEQUENCE_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
int
|
||||
SEQUENCE_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn1_SEQUENCE_specifics_t *specs = (asn1_SEQUENCE_specifics_t *)td->specifics;
|
||||
int edx;
|
||||
int ret;
|
||||
|
||||
|
@ -577,8 +575,8 @@ SEQUENCE_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
|||
|| cb(" ::= {\n", 7, app_key))
|
||||
return -1;
|
||||
|
||||
for(edx = 0; edx < specs->elements_count; edx++) {
|
||||
asn1_SEQUENCE_element_t *elm = &specs->elements[edx];
|
||||
for(edx = 0; edx < td->elements_count; edx++) {
|
||||
asn1_TYPE_member_t *elm = &td->elements[edx];
|
||||
const void *memb_ptr;
|
||||
|
||||
if(elm->optional) {
|
||||
|
@ -614,7 +612,6 @@ SEQUENCE_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
|||
|
||||
void
|
||||
SEQUENCE_free(asn1_TYPE_descriptor_t *td, void *sptr, int contents_only) {
|
||||
asn1_SEQUENCE_specifics_t *specs = (asn1_SEQUENCE_specifics_t *)td->specifics;
|
||||
int edx;
|
||||
|
||||
if(!td || !sptr)
|
||||
|
@ -622,8 +619,8 @@ SEQUENCE_free(asn1_TYPE_descriptor_t *td, void *sptr, int contents_only) {
|
|||
|
||||
ASN_DEBUG("Freeing %s as SEQUENCE", td->name);
|
||||
|
||||
for(edx = 0; edx < specs->elements_count; edx++) {
|
||||
asn1_SEQUENCE_element_t *elm = &specs->elements[edx];
|
||||
for(edx = 0; edx < td->elements_count; edx++) {
|
||||
asn1_TYPE_member_t *elm = &td->elements[edx];
|
||||
void *memb_ptr;
|
||||
if(elm->optional) {
|
||||
memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
|
||||
|
@ -643,7 +640,6 @@ SEQUENCE_free(asn1_TYPE_descriptor_t *td, void *sptr, int contents_only) {
|
|||
int
|
||||
SEQUENCE_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
|
||||
asn_app_consume_bytes_f *app_errlog, void *app_key) {
|
||||
asn1_SEQUENCE_specifics_t *specs = (asn1_SEQUENCE_specifics_t *)td->specifics;
|
||||
int edx;
|
||||
|
||||
if(!sptr) {
|
||||
|
@ -655,8 +651,8 @@ SEQUENCE_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
|
|||
/*
|
||||
* Iterate over structure members and check their validity.
|
||||
*/
|
||||
for(edx = 0; edx < specs->elements_count; edx++) {
|
||||
asn1_SEQUENCE_element_t *elm = &specs->elements[edx];
|
||||
for(edx = 0; edx < td->elements_count; edx++) {
|
||||
asn1_TYPE_member_t *elm = &td->elements[edx];
|
||||
const void *memb_ptr;
|
||||
|
||||
if(elm->optional) {
|
||||
|
@ -666,8 +662,20 @@ SEQUENCE_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
|
|||
memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
|
||||
}
|
||||
|
||||
return elm->type->check_constraints(elm->type, memb_ptr,
|
||||
app_errlog, app_key);
|
||||
if(elm->memb_constraints) {
|
||||
int ret = elm->memb_constraints(elm->type, memb_ptr,
|
||||
app_errlog, app_key);
|
||||
if(ret) return ret;
|
||||
} else {
|
||||
int ret = elm->type->check_constraints(elm->type,
|
||||
memb_ptr, app_errlog, app_key);
|
||||
if(ret) return ret;
|
||||
/*
|
||||
* Cannot inherit it earlier:
|
||||
* need to make sure we get the updated version.
|
||||
*/
|
||||
elm->memb_constraints = elm->type->check_constraints;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -7,18 +7,6 @@
|
|||
|
||||
#include <constr_TYPE.h>
|
||||
|
||||
/*
|
||||
* A single element of the SEQUENCE type.
|
||||
*/
|
||||
typedef struct asn1_SEQUENCE_element_s {
|
||||
int memb_offset; /* Offset of the element */
|
||||
int optional; /* Whether the element is optional */
|
||||
ber_tlv_tag_t tag; /* Outmost (most immediate) tag */
|
||||
int tag_mode; /* IMPLICIT/no/EXPLICIT tag at current level */
|
||||
asn1_TYPE_descriptor_t *type; /* Member type descriptor */
|
||||
char *name; /* ASN.1 identifier of the element */
|
||||
} asn1_SEQUENCE_element_t;
|
||||
|
||||
typedef struct asn1_SEQUENCE_specifics_s {
|
||||
/*
|
||||
* Target structure description.
|
||||
|
@ -26,12 +14,6 @@ typedef struct asn1_SEQUENCE_specifics_s {
|
|||
int struct_size; /* Size of the target structure. */
|
||||
int ctx_offset; /* Offset of the ber_dec_ctx_t member */
|
||||
|
||||
/*
|
||||
* Members of the SEQUENCE structure.
|
||||
*/
|
||||
asn1_SEQUENCE_element_t *elements;
|
||||
int elements_count;
|
||||
|
||||
/*
|
||||
* Tags to members mapping table (sorted).
|
||||
*/
|
||||
|
|
|
@ -9,18 +9,17 @@
|
|||
* The DER encoder of the SEQUENCE OF type.
|
||||
*/
|
||||
der_enc_rval_t
|
||||
SEQUENCE_OF_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
|
||||
SEQUENCE_OF_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
|
||||
int tag_mode, ber_tlv_tag_t tag,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn1_SET_OF_specifics_t *specs = (asn1_SET_OF_specifics_t *)sd->specifics;
|
||||
asn1_SET_OF_element_t *elm = specs->element;
|
||||
asn1_TYPE_member_t *elm = td->elements;
|
||||
A_SEQUENCE_OF(void) *list;
|
||||
size_t computed_size = 0;
|
||||
ssize_t encoding_size = 0;
|
||||
der_enc_rval_t erval;
|
||||
int edx;
|
||||
|
||||
ASN_DEBUG("Estimating size of SEQUENCE OF %s", sd->name);
|
||||
ASN_DEBUG("Estimating size of SEQUENCE OF %s", td->name);
|
||||
|
||||
/*
|
||||
* Gather the length of the underlying members sequence.
|
||||
|
@ -39,11 +38,11 @@ SEQUENCE_OF_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
|
|||
/*
|
||||
* Encode the TLV for the sequence itself.
|
||||
*/
|
||||
encoding_size = der_write_tags(sd, computed_size, tag_mode, tag,
|
||||
encoding_size = der_write_tags(td, computed_size, tag_mode, tag,
|
||||
cb, app_key);
|
||||
if(encoding_size == -1) {
|
||||
erval.encoded = -1;
|
||||
erval.failed_type = sd;
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = ptr;
|
||||
return erval;
|
||||
}
|
||||
|
@ -54,7 +53,7 @@ SEQUENCE_OF_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
|
|||
return erval;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Encoding members of SEQUENCE OF %s", sd->name);
|
||||
ASN_DEBUG("Encoding members of SEQUENCE OF %s", td->name);
|
||||
|
||||
/*
|
||||
* Encode all members.
|
||||
|
@ -74,7 +73,7 @@ SEQUENCE_OF_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
|
|||
* Encoded size is not equal to the computed size.
|
||||
*/
|
||||
erval.encoded = -1;
|
||||
erval.failed_type = sd;
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = ptr;
|
||||
} else {
|
||||
erval.encoded = computed_size;
|
||||
|
|
|
@ -93,13 +93,13 @@ _t2e_cmp(const void *ap, const void *bp) {
|
|||
* The decoder of the SET type.
|
||||
*/
|
||||
ber_dec_rval_t
|
||||
SET_decode_ber(asn1_TYPE_descriptor_t *sd,
|
||||
SET_decode_ber(asn1_TYPE_descriptor_t *td,
|
||||
void **struct_ptr, void *ptr, size_t size, int tag_mode) {
|
||||
/*
|
||||
* Bring closer parts of structure description.
|
||||
*/
|
||||
asn1_SET_specifics_t *specs = (asn1_SET_specifics_t *)sd->specifics;
|
||||
asn1_SET_element_t *elements = specs->elements;
|
||||
asn1_SET_specifics_t *specs = (asn1_SET_specifics_t *)td->specifics;
|
||||
asn1_TYPE_member_t *elements = td->elements;
|
||||
|
||||
/*
|
||||
* Parts of the structure being constructed.
|
||||
|
@ -114,7 +114,7 @@ SET_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
|
||||
int edx; /* SET element's index */
|
||||
|
||||
ASN_DEBUG("Decoding %s as SET", sd->name);
|
||||
ASN_DEBUG("Decoding %s as SET", td->name);
|
||||
|
||||
/*
|
||||
* Create the target structure if it is not present already.
|
||||
|
@ -142,11 +142,11 @@ SET_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
* perfectly fits our expectations.
|
||||
*/
|
||||
|
||||
rval = ber_check_tags(sd, ctx, ptr, size,
|
||||
rval = ber_check_tags(td, ctx, ptr, size,
|
||||
tag_mode, &ctx->left, 0);
|
||||
if(rval.code != RC_OK) {
|
||||
ASN_DEBUG("%s tagging check failed: %d",
|
||||
sd->name, rval.code);
|
||||
td->name, rval.code);
|
||||
consumed_myself += rval.consumed;
|
||||
RETURN(rval.code);
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ SET_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
* canonical order of their tags. So, there is a room
|
||||
* for optimization.
|
||||
*/
|
||||
for(edx = (ctx->step >> 1); edx < specs->elements_count;
|
||||
for(edx = (ctx->step >> 1); edx < td->elements_count;
|
||||
ctx->step = (ctx->step & ~1) + 2,
|
||||
edx = (ctx->step >> 1)) {
|
||||
void *memb_ptr; /* Pointer to the member */
|
||||
|
@ -247,7 +247,7 @@ SET_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
} else if(specs->extensible == 0) {
|
||||
ASN_DEBUG("Unexpected tag %s "
|
||||
"in non-extensible SET %s",
|
||||
ber_tlv_tag_string(tlv_tag), sd->name);
|
||||
ber_tlv_tag_string(tlv_tag), td->name);
|
||||
RETURN(RC_FAIL);
|
||||
} else {
|
||||
/* Skip this tag */
|
||||
|
@ -285,7 +285,7 @@ SET_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
*/
|
||||
if(ASN_SET_ISPRESENT2((char *)st + specs->pres_offset, edx)) {
|
||||
ASN_DEBUG("SET %s: Duplicate element %s (%d)",
|
||||
sd->name, elements[edx].name, edx);
|
||||
td->name, elements[edx].name, edx);
|
||||
RETURN(RC_FAIL);
|
||||
}
|
||||
|
||||
|
@ -335,7 +335,7 @@ SET_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
case 3:
|
||||
case 4: /* Only 00 is expected */
|
||||
ASN_DEBUG("SET %s Leftover: %ld, size = %ld",
|
||||
sd->name, (long)ctx->left, (long)size);
|
||||
td->name, (long)ctx->left, (long)size);
|
||||
|
||||
/*
|
||||
* Skip everything until the end of the SET.
|
||||
|
@ -374,7 +374,7 @@ SET_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
if(specs->extensible == 0 || ctx->phase == 4) {
|
||||
ASN_DEBUG("Unexpected continuation "
|
||||
"of a non-extensible type %s",
|
||||
sd->name);
|
||||
td->name);
|
||||
RETURN(RC_FAIL);
|
||||
}
|
||||
|
||||
|
@ -395,7 +395,7 @@ SET_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
/*
|
||||
* Check that all mandatory elements are present.
|
||||
*/
|
||||
for(edx = 0; edx < specs->elements_count;
|
||||
for(edx = 0; edx < td->elements_count;
|
||||
edx += (8 * sizeof(specs->_mandatory_elements[0]))) {
|
||||
unsigned int midx, pres, must;
|
||||
|
||||
|
@ -411,7 +411,7 @@ SET_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
ASN_DEBUG("One or more mandatory elements "
|
||||
"of a SET %s %d (%08x.%08x)=%08x "
|
||||
"are not present",
|
||||
sd->name,
|
||||
td->name,
|
||||
midx,
|
||||
pres,
|
||||
must,
|
||||
|
@ -431,13 +431,13 @@ SET_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
* The DER encoder of the SET type.
|
||||
*/
|
||||
der_enc_rval_t
|
||||
SET_encode_der(asn1_TYPE_descriptor_t *sd,
|
||||
SET_encode_der(asn1_TYPE_descriptor_t *td,
|
||||
void *ptr, int tag_mode, ber_tlv_tag_t tag,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn1_SET_specifics_t *specs = (asn1_SET_specifics_t *)sd->specifics;
|
||||
asn1_SET_specifics_t *specs = (asn1_SET_specifics_t *)td->specifics;
|
||||
size_t computed_size = 0;
|
||||
der_enc_rval_t my_erval;
|
||||
int t2m_build_own = (specs->tag2el_count != specs->elements_count);
|
||||
int t2m_build_own = (specs->tag2el_count != td->elements_count);
|
||||
asn1_TYPE_tag2member_t *t2m;
|
||||
int t2m_count;
|
||||
ssize_t ret;
|
||||
|
@ -447,10 +447,10 @@ SET_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
* Use existing, or build our own tags map.
|
||||
*/
|
||||
if(t2m_build_own) {
|
||||
(void *)t2m = alloca(specs->elements_count * sizeof(t2m[0]));
|
||||
(void *)t2m = alloca(td->elements_count * sizeof(t2m[0]));
|
||||
if(!t2m) { /* There are such platforms */
|
||||
my_erval.encoded = -1;
|
||||
my_erval.failed_type = sd;
|
||||
my_erval.failed_type = td;
|
||||
my_erval.structure_ptr = ptr;
|
||||
return my_erval;
|
||||
}
|
||||
|
@ -467,8 +467,8 @@ SET_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
/*
|
||||
* Gather the length of the underlying members sequence.
|
||||
*/
|
||||
for(edx = 0; edx < specs->elements_count; edx++) {
|
||||
asn1_SET_element_t *elm = &specs->elements[edx];
|
||||
for(edx = 0; edx < td->elements_count; edx++) {
|
||||
asn1_TYPE_member_t *elm = &td->elements[edx];
|
||||
der_enc_rval_t erval;
|
||||
void *memb_ptr;
|
||||
|
||||
|
@ -513,7 +513,7 @@ SET_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
/*
|
||||
* Finalize order of the components.
|
||||
*/
|
||||
assert(t2m_count == specs->elements_count);
|
||||
assert(t2m_count == td->elements_count);
|
||||
if(t2m_build_own) {
|
||||
/*
|
||||
* Sort the underlying members according to their
|
||||
|
@ -529,10 +529,10 @@ SET_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
/*
|
||||
* Encode the TLV for the sequence itself.
|
||||
*/
|
||||
ret = der_write_tags(sd, computed_size, tag_mode, tag, cb, app_key);
|
||||
ret = der_write_tags(td, computed_size, tag_mode, tag, cb, app_key);
|
||||
if(ret == -1) {
|
||||
my_erval.encoded = -1;
|
||||
my_erval.failed_type = sd;
|
||||
my_erval.failed_type = td;
|
||||
my_erval.structure_ptr = ptr;
|
||||
return my_erval;
|
||||
}
|
||||
|
@ -543,13 +543,13 @@ SET_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
/*
|
||||
* Encode all members.
|
||||
*/
|
||||
for(edx = 0; edx < specs->elements_count; edx++) {
|
||||
asn1_SET_element_t *elm;
|
||||
for(edx = 0; edx < td->elements_count; edx++) {
|
||||
asn1_TYPE_member_t *elm;
|
||||
der_enc_rval_t erval;
|
||||
void *memb_ptr;
|
||||
|
||||
/* Encode according to the tag order */
|
||||
elm = &specs->elements[t2m[edx].el_no];
|
||||
elm = &td->elements[t2m[edx].el_no];
|
||||
|
||||
if(elm->optional) {
|
||||
memb_ptr = *(void **)((char *)ptr + elm->memb_offset);
|
||||
|
@ -570,7 +570,7 @@ SET_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
* Encoded size is not equal to the computed size.
|
||||
*/
|
||||
my_erval.encoded = -1;
|
||||
my_erval.failed_type = sd;
|
||||
my_erval.failed_type = td;
|
||||
my_erval.structure_ptr = ptr;
|
||||
}
|
||||
|
||||
|
@ -580,7 +580,6 @@ SET_encode_der(asn1_TYPE_descriptor_t *sd,
|
|||
int
|
||||
SET_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn1_SET_specifics_t *specs = (asn1_SET_specifics_t *)td->specifics;
|
||||
int edx;
|
||||
int ret;
|
||||
|
||||
|
@ -591,8 +590,8 @@ SET_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
|||
|| cb(" ::= {\n", 7, app_key))
|
||||
return -1;
|
||||
|
||||
for(edx = 0; edx < specs->elements_count; edx++) {
|
||||
asn1_SET_element_t *elm = &specs->elements[edx];
|
||||
for(edx = 0; edx < td->elements_count; edx++) {
|
||||
asn1_TYPE_member_t *elm = &td->elements[edx];
|
||||
const void *memb_ptr;
|
||||
|
||||
if(elm->optional) {
|
||||
|
@ -627,7 +626,6 @@ SET_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
|||
|
||||
void
|
||||
SET_free(asn1_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
||||
asn1_SET_specifics_t *specs = (asn1_SET_specifics_t *)td->specifics;
|
||||
int edx;
|
||||
|
||||
if(!td || !ptr)
|
||||
|
@ -635,8 +633,8 @@ SET_free(asn1_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
|||
|
||||
ASN_DEBUG("Freeing %s as SET", td->name);
|
||||
|
||||
for(edx = 0; edx < specs->elements_count; edx++) {
|
||||
asn1_SET_element_t *elm = &specs->elements[edx];
|
||||
for(edx = 0; edx < td->elements_count; edx++) {
|
||||
asn1_TYPE_member_t *elm = &td->elements[edx];
|
||||
void *memb_ptr;
|
||||
if(elm->optional) {
|
||||
memb_ptr = *(void **)((char *)ptr + elm->memb_offset);
|
||||
|
@ -668,8 +666,8 @@ SET_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
|
|||
/*
|
||||
* Iterate over structure members and check their validity.
|
||||
*/
|
||||
for(edx = 0; edx < specs->elements_count; edx++) {
|
||||
asn1_SET_element_t *elm = &specs->elements[edx];
|
||||
for(edx = 0; edx < td->elements_count; edx++) {
|
||||
asn1_TYPE_member_t *elm = &td->elements[edx];
|
||||
const void *memb_ptr;
|
||||
|
||||
if(elm->optional) {
|
||||
|
@ -689,8 +687,20 @@ SET_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
|
|||
memb_ptr = (const void *)((const char *)sptr + elm->memb_offset);
|
||||
}
|
||||
|
||||
return elm->type->check_constraints(elm->type, memb_ptr,
|
||||
app_errlog, app_key);
|
||||
if(elm->memb_constraints) {
|
||||
int ret = elm->memb_constraints(elm->type, memb_ptr,
|
||||
app_errlog, app_key);
|
||||
if(ret) return ret;
|
||||
} else {
|
||||
int ret = elm->type->check_constraints(elm->type,
|
||||
memb_ptr, app_errlog, app_key);
|
||||
if(ret) return ret;
|
||||
/*
|
||||
* Cannot inherit it earlier:
|
||||
* need to make sure we get the updated version.
|
||||
*/
|
||||
elm->memb_constraints = elm->type->check_constraints;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -7,18 +7,6 @@
|
|||
|
||||
#include <constr_TYPE.h>
|
||||
|
||||
/*
|
||||
* Description of a single element of the SET type.
|
||||
*/
|
||||
typedef struct asn1_SET_element_s {
|
||||
int memb_offset; /* Offset of the element */
|
||||
int optional; /* Whether the element is optional */
|
||||
ber_tlv_tag_t tag; /* Outmost (most immediate) tag */
|
||||
int tag_mode; /* IMPLICIT/no/EXPLICIT tag at current level */
|
||||
asn1_TYPE_descriptor_t *type; /* Member type descriptor */
|
||||
char *name; /* ASN.1 identifier of the element */
|
||||
} asn1_SET_element_t;
|
||||
|
||||
|
||||
typedef struct asn1_SET_specifics_s {
|
||||
/*
|
||||
|
@ -28,12 +16,6 @@ typedef struct asn1_SET_specifics_s {
|
|||
int ctx_offset; /* Offset of the ber_dec_ctx_t member */
|
||||
int pres_offset; /* Offset of _presence_map member */
|
||||
|
||||
/*
|
||||
* Members of the SET structure.
|
||||
*/
|
||||
asn1_SET_element_t *elements;
|
||||
int elements_count;
|
||||
|
||||
/*
|
||||
* Tags to members mapping table (sorted).
|
||||
*/
|
||||
|
|
|
@ -60,13 +60,13 @@
|
|||
* The decoder of the SET OF type.
|
||||
*/
|
||||
ber_dec_rval_t
|
||||
SET_OF_decode_ber(asn1_TYPE_descriptor_t *sd,
|
||||
SET_OF_decode_ber(asn1_TYPE_descriptor_t *td,
|
||||
void **struct_ptr, void *ptr, size_t size, int tag_mode) {
|
||||
/*
|
||||
* Bring closer parts of structure description.
|
||||
*/
|
||||
asn1_SET_OF_specifics_t *specs = (asn1_SET_OF_specifics_t *)sd->specifics;
|
||||
asn1_SET_OF_element_t *element = specs->element;
|
||||
asn1_SET_OF_specifics_t *specs = (asn1_SET_OF_specifics_t *)td->specifics;
|
||||
asn1_TYPE_member_t *element = td->elements; /* Single one */
|
||||
|
||||
/*
|
||||
* Parts of the structure being constructed.
|
||||
|
@ -80,7 +80,7 @@ SET_OF_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
|
||||
ssize_t consumed_myself = 0; /* Consumed bytes from ptr */
|
||||
|
||||
ASN_DEBUG("Decoding %s as SET OF", sd->name);
|
||||
ASN_DEBUG("Decoding %s as SET OF", td->name);
|
||||
|
||||
/*
|
||||
* Create the target structure if it is not present already.
|
||||
|
@ -108,11 +108,11 @@ SET_OF_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
* perfectly fits our expectations.
|
||||
*/
|
||||
|
||||
rval = ber_check_tags(sd, ctx, ptr, size,
|
||||
rval = ber_check_tags(td, ctx, ptr, size,
|
||||
tag_mode, &ctx->left, 0);
|
||||
if(rval.code != RC_OK) {
|
||||
ASN_DEBUG("%s tagging check failed: %d",
|
||||
sd->name, rval.code);
|
||||
td->name, rval.code);
|
||||
consumed_myself += rval.consumed;
|
||||
RETURN(rval.code);
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ SET_OF_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
*/
|
||||
|
||||
if(ctx->left == 0) {
|
||||
ASN_DEBUG("End of SET OF %s", sd->name);
|
||||
ASN_DEBUG("End of SET OF %s", td->name);
|
||||
/*
|
||||
* No more things to decode.
|
||||
* Exit out of here.
|
||||
|
@ -185,9 +185,9 @@ SET_OF_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
*/
|
||||
} else {
|
||||
ASN_DEBUG("Unexpected tag %s fixed SET OF %s",
|
||||
ber_tlv_tag_string(tlv_tag), sd->name);
|
||||
ber_tlv_tag_string(tlv_tag), td->name);
|
||||
ASN_DEBUG("%s SET OF has tag %s",
|
||||
sd->name, ber_tlv_tag_string(element->tag));
|
||||
td->name, ber_tlv_tag_string(element->tag));
|
||||
RETURN(RC_FAIL);
|
||||
}
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ SET_OF_decode_ber(asn1_TYPE_descriptor_t *sd,
|
|||
rval = element->type->ber_decoder(element->type,
|
||||
&ctx->ptr, ptr, LEFT, 0);
|
||||
ASN_DEBUG("In %s SET OF %s code %d consumed %d",
|
||||
sd->name, element->type->name,
|
||||
td->name, element->type->name,
|
||||
rval.code, (int)rval.consumed);
|
||||
switch(rval.code) {
|
||||
case RC_OK:
|
||||
|
@ -305,11 +305,10 @@ static int _el_buf_cmp(const void *ap, const void *bp) {
|
|||
* The DER encoder of the SET OF type.
|
||||
*/
|
||||
der_enc_rval_t
|
||||
SET_OF_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
|
||||
SET_OF_encode_der(asn1_TYPE_descriptor_t *td, void *ptr,
|
||||
int tag_mode, ber_tlv_tag_t tag,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn1_SET_OF_specifics_t *specs = (asn1_SET_OF_specifics_t *)sd->specifics;
|
||||
asn1_SET_OF_element_t *elm = specs->element;
|
||||
asn1_TYPE_member_t *elm = td->elements;
|
||||
asn1_TYPE_descriptor_t *elm_type = elm->type;
|
||||
der_type_encoder_f *der_encoder = elm_type->der_encoder;
|
||||
A_SET_OF(void) *list;
|
||||
|
@ -321,7 +320,7 @@ SET_OF_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
|
|||
int ret;
|
||||
int edx;
|
||||
|
||||
ASN_DEBUG("Estimating size for SET OF %s", sd->name);
|
||||
ASN_DEBUG("Estimating size for SET OF %s", td->name);
|
||||
|
||||
/*
|
||||
* Gather the length of the underlying members sequence.
|
||||
|
@ -342,11 +341,11 @@ SET_OF_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
|
|||
/*
|
||||
* Encode the TLV for the sequence itself.
|
||||
*/
|
||||
encoding_size = der_write_tags(sd, computed_size, tag_mode, tag,
|
||||
encoding_size = der_write_tags(td, computed_size, tag_mode, tag,
|
||||
cb, app_key);
|
||||
if(encoding_size == -1) {
|
||||
erval.encoded = -1;
|
||||
erval.failed_type = sd;
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = ptr;
|
||||
return erval;
|
||||
}
|
||||
|
@ -365,12 +364,12 @@ SET_OF_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
|
|||
(void *)encoded_els = MALLOC(list->count * sizeof(encoded_els[0]));
|
||||
if(encoded_els == NULL) {
|
||||
erval.encoded = -1;
|
||||
erval.failed_type = sd;
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = ptr;
|
||||
return erval;
|
||||
}
|
||||
|
||||
ASN_DEBUG("Encoding members of %s SET OF", sd->name);
|
||||
ASN_DEBUG("Encoding members of %s SET OF", td->name);
|
||||
|
||||
/*
|
||||
* Encode all members.
|
||||
|
@ -391,7 +390,7 @@ SET_OF_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
|
|||
FREEMEM(encoded_els[edx].buf);
|
||||
FREEMEM(encoded_els);
|
||||
erval.encoded = -1;
|
||||
erval.failed_type = sd;
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = ptr;
|
||||
return erval;
|
||||
}
|
||||
|
@ -436,7 +435,7 @@ SET_OF_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
|
|||
* encoded size is not equal to the computed size.
|
||||
*/
|
||||
erval.encoded = -1;
|
||||
erval.failed_type = sd;
|
||||
erval.failed_type = td;
|
||||
erval.structure_ptr = ptr;
|
||||
} else {
|
||||
erval.encoded = computed_size;
|
||||
|
@ -448,8 +447,7 @@ SET_OF_encode_der(asn1_TYPE_descriptor_t *sd, void *ptr,
|
|||
int
|
||||
SET_OF_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
||||
asn_app_consume_bytes_f *cb, void *app_key) {
|
||||
asn1_SET_OF_specifics_t *specs = (asn1_SET_OF_specifics_t *)td->specifics;
|
||||
asn1_SET_OF_element_t *element = specs->element;
|
||||
asn1_TYPE_member_t *element = td->elements;
|
||||
const A_SET_OF(void) *list;
|
||||
int ret;
|
||||
int i;
|
||||
|
@ -486,8 +484,7 @@ SET_OF_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
|
|||
void
|
||||
SET_OF_free(asn1_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
||||
if(td && ptr) {
|
||||
asn1_SET_OF_specifics_t *specs = (asn1_SET_OF_specifics_t *)td->specifics;
|
||||
asn1_SET_OF_element_t *element = specs->element;
|
||||
asn1_TYPE_member_t *element = td->elements;
|
||||
A_SET_OF(void) *list;
|
||||
int i;
|
||||
|
||||
|
@ -514,8 +511,8 @@ SET_OF_free(asn1_TYPE_descriptor_t *td, void *ptr, int contents_only) {
|
|||
int
|
||||
SET_OF_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
|
||||
asn_app_consume_bytes_f *app_errlog, void *app_key) {
|
||||
asn1_SET_OF_specifics_t *specs = (asn1_SET_OF_specifics_t *)td->specifics;
|
||||
asn1_SET_OF_element_t *element = specs->element;
|
||||
asn1_TYPE_member_t *element = td->elements;
|
||||
asn_constr_check_f *constr;
|
||||
const A_SET_OF(void) *list;
|
||||
int i;
|
||||
|
||||
|
@ -526,12 +523,30 @@ SET_OF_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
|
|||
}
|
||||
|
||||
(const void *)list = sptr;
|
||||
|
||||
constr = element->memb_constraints;
|
||||
if(!constr) constr = element->type->check_constraints;
|
||||
|
||||
/*
|
||||
* Iterate over the members of an array.
|
||||
* Validate each in turn, until one fails.
|
||||
*/
|
||||
for(i = 0; i < list->count; i++) {
|
||||
const void *memb_ptr = list->array[i];
|
||||
int ret;
|
||||
|
||||
if(!memb_ptr) continue;
|
||||
return element->type->check_constraints(element->type, memb_ptr,
|
||||
app_errlog, app_key);
|
||||
|
||||
ret = constr(element->type, memb_ptr, app_errlog, app_key);
|
||||
if(ret) return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cannot inherit it eralier:
|
||||
* need to make sure we get the updated version.
|
||||
*/
|
||||
if(!element->memb_constraints)
|
||||
element->memb_constraints = element->type->check_constraints;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,22 +7,12 @@
|
|||
|
||||
#include <constr_TYPE.h>
|
||||
|
||||
typedef struct asn1_SET_OF_element_s {
|
||||
ber_tlv_tag_t tag; /* Outmost (most immediate) tag */
|
||||
asn1_TYPE_descriptor_t *type; /* Member type descriptor */
|
||||
} asn1_SET_OF_element_t;
|
||||
|
||||
typedef struct asn1_SET_OF_specifics_s {
|
||||
/*
|
||||
* Target structure description.
|
||||
*/
|
||||
int struct_size; /* Size of the target structure. */
|
||||
int ctx_offset; /* Offset of the ber_dec_ctx_t member */
|
||||
|
||||
/*
|
||||
* Members of the SET OF list.
|
||||
*/
|
||||
asn1_SET_OF_element_t *element;
|
||||
} asn1_SET_OF_specifics_t;
|
||||
|
||||
/*
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <constraints.h>
|
||||
|
||||
struct asn1_TYPE_descriptor_s; /* Forward declaration */
|
||||
struct asn1_TYPE_member_s; /* Forward declaration */
|
||||
|
||||
/*
|
||||
* Free the structure according to its specification.
|
||||
|
@ -43,7 +44,7 @@ typedef int (asn_struct_print_f)(
|
|||
typedef ber_tlv_tag_t (asn_outmost_tag_f)(
|
||||
struct asn1_TYPE_descriptor_s *type_descriptor,
|
||||
const void *struct_ptr, int tag_mode, ber_tlv_tag_t tag);
|
||||
/* The instance of the above function type */
|
||||
/* The instance of the above function type; used internally. */
|
||||
asn_outmost_tag_f asn1_TYPE_outmost_tag;
|
||||
|
||||
|
||||
|
@ -76,6 +77,12 @@ typedef struct asn1_TYPE_descriptor_s {
|
|||
int tags_impl_skip; /* Tags to skip in implicit mode */
|
||||
int last_tag_form; /* Acceptable form of the tag (prim, constr) */
|
||||
|
||||
/*
|
||||
* An ASN.1 production type members (members of SEQUENCE, SET, CHOICE).
|
||||
*/
|
||||
struct asn1_TYPE_member_s *elements;
|
||||
int elements_count;
|
||||
|
||||
/*
|
||||
* Additional information describing the type, used by appropriate
|
||||
* functions above.
|
||||
|
@ -83,6 +90,19 @@ typedef struct asn1_TYPE_descriptor_s {
|
|||
void *specifics;
|
||||
} asn1_TYPE_descriptor_t;
|
||||
|
||||
/*
|
||||
* An element of the constructed type, i.e. SEQUENCE, SET, CHOICE.
|
||||
*/
|
||||
typedef struct asn1_TYPE_member_s {
|
||||
int optional; /* Whether the element is optional */
|
||||
int memb_offset; /* Offset of the element */
|
||||
ber_tlv_tag_t tag; /* Outmost (most immediate) tag */
|
||||
int tag_mode; /* IMPLICIT/no/EXPLICIT tag at current level */
|
||||
asn1_TYPE_descriptor_t *type; /* Member type descriptor */
|
||||
asn_constr_check_f *memb_constraints; /* Constraints validator */
|
||||
char *name; /* ASN.1 identifier of the element */
|
||||
} asn1_TYPE_member_t;
|
||||
|
||||
/*
|
||||
* BER tag to element number mapping.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue