new constraints model

This commit is contained in:
Lev Walkin 2004-08-20 13:23:42 +00:00
parent e64460f66b
commit 449f8324e9
36 changed files with 244 additions and 215 deletions

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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) {

View File

@ -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.
*/

View File

@ -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;

View File

@ -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).
*/

View File

@ -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;

View File

@ -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;

View File

@ -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).
*/

View File

@ -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;
}

View File

@ -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;
/*

View File

@ -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.
*/