mirror of https://gerrit.osmocom.org/asn1c
246 lines
6.1 KiB
C
246 lines
6.1 KiB
C
#include "asn1fix_internal.h"
|
|
#include "asn1fix_crange.h"
|
|
|
|
/*
|
|
* Check that a specific constraint is compatible
|
|
* with the given expression type.
|
|
*/
|
|
int
|
|
asn1constraint_compatible(asn1p_expr_type_e expr_type,
|
|
enum asn1p_constraint_type_e constr_type, int fbless_SIZE) {
|
|
|
|
if(expr_type == ASN_BASIC_REAL)
|
|
return -1; /* Not yet supported */
|
|
|
|
/*
|
|
* X.680-0207, Table 9.
|
|
*/
|
|
|
|
switch(constr_type) {
|
|
case ACT_INVALID:
|
|
return 0;
|
|
case ACT_EL_TYPE:
|
|
return 1;
|
|
case ACT_EL_VALUE:
|
|
return 1;
|
|
case ACT_EL_RANGE:
|
|
case ACT_EL_LLRANGE:
|
|
case ACT_EL_RLRANGE:
|
|
case ACT_EL_ULRANGE:
|
|
switch(expr_type) {
|
|
case ASN_BASIC_ENUMERATED:
|
|
case ASN_BASIC_BOOLEAN:
|
|
/*
|
|
* The ValueRange constraint is not formally
|
|
* applicable to the above types. However, we
|
|
* support it just fine.
|
|
*/
|
|
/* Fall through */
|
|
case ASN_BASIC_INTEGER:
|
|
case ASN_BASIC_REAL:
|
|
return 1;
|
|
default:
|
|
if(expr_type & ASN_STRING_MASK)
|
|
return 1;
|
|
}
|
|
return 0;
|
|
case ACT_EL_EXT:
|
|
return -1;
|
|
case ACT_CT_FROM:
|
|
if(expr_type & ASN_STRING_MASK)
|
|
return 1;
|
|
return 0;
|
|
case ACT_CT_SIZE:
|
|
switch(expr_type) {
|
|
case ASN_BASIC_INTEGER:
|
|
case ASN_BASIC_ENUMERATED:
|
|
if(fbless_SIZE)
|
|
return 1;
|
|
break;
|
|
case ASN_BASIC_BIT_STRING:
|
|
case ASN_BASIC_OCTET_STRING:
|
|
case ASN_BASIC_CHARACTER_STRING:
|
|
case ASN_CONSTR_SEQUENCE_OF:
|
|
case ASN_CONSTR_SET_OF:
|
|
return 1;
|
|
default:
|
|
if(expr_type & ASN_STRING_MASK)
|
|
return 1;
|
|
}
|
|
return 0;
|
|
case ACT_CT_WCOMP:
|
|
case ACT_CT_WCOMPS:
|
|
switch(expr_type) {
|
|
case A1TC_INSTANCE:
|
|
case ASN_BASIC_EXTERNAL:
|
|
case ASN_BASIC_EMBEDDED_PDV:
|
|
case ASN_BASIC_REAL:
|
|
case ASN_BASIC_CHARACTER_STRING:
|
|
case ASN_CONSTR_CHOICE:
|
|
case ASN_CONSTR_SEQUENCE:
|
|
case ASN_CONSTR_SEQUENCE_OF:
|
|
case ASN_CONSTR_SET:
|
|
case ASN_CONSTR_SET_OF:
|
|
return 1;
|
|
default: break;
|
|
}
|
|
return 0;
|
|
case ACT_CT_CTDBY:
|
|
return 1;
|
|
case ACT_CT_CTNG: /* X.682, #11 */
|
|
switch(expr_type) {
|
|
case ASN_BASIC_OCTET_STRING:
|
|
case ASN_BASIC_BIT_STRING:
|
|
return 1;
|
|
default:
|
|
return 0;
|
|
}
|
|
case ACT_CT_PATTERN:
|
|
if(expr_type & ASN_STRING_MASK)
|
|
return 1;
|
|
return 0;
|
|
case ACT_CA_SET:
|
|
case ACT_CA_CRC:
|
|
case ACT_CA_CSV:
|
|
case ACT_CA_UNI:
|
|
case ACT_CA_INT:
|
|
case ACT_CA_EXC:
|
|
case ACT_CA_AEX:
|
|
return 1;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
#define DECL_RANGE(foo, val1, val2, pv) \
|
|
static asn1cnst_range_t range_ ## foo = { \
|
|
{ ARE_VALUE, 0, val1 }, \
|
|
{ ARE_VALUE, 0, val2 }, \
|
|
0, 0, 0, 0, 0, 0, pv }
|
|
|
|
#define DECL(foo, val1, val2) DECL_RANGE(foo, val1, val2, 0)
|
|
#define DECL_notPV(foo, val1, val2) DECL_RANGE(foo, val1, val2, 1)
|
|
|
|
asn1cnst_range_t *
|
|
asn1constraint_default_alphabet(asn1p_expr_type_e expr_type) {
|
|
DECL_notPV(octstr, 0x00, 0xff); /* Not PER-visible */
|
|
DECL_notPV(utf8, 0x00, 0x7fffffff); /* Not PER-visible */
|
|
DECL(bmp, 0x00, 65533); /* 64K-2 cells */
|
|
DECL(uint7, 0x00, 0x7f);
|
|
DECL(uint32, 0x00, 0xffffffff);
|
|
DECL(Space, 0x20, 0x20);
|
|
DECL(ApostropheAndParens, 0x27, 0x29);
|
|
DECL(PlusTillColon, 0x2b, 0x3a);
|
|
DECL(Equal, 0x3d, 0x3d);
|
|
DECL(QuestionMark, 0x3f, 0x3f);
|
|
DECL(Digits, 0x30, 0x39);
|
|
DECL(AlphaCap, 0x41, 0x5a);
|
|
DECL(AlphaLow, 0x61, 0x7a);
|
|
DECL(PlusCommaMinusDot, 0x2b, 0x2e);
|
|
DECL(Plus, 0x2b, 0x2b);
|
|
DECL(MinusDot, 0x2d, 0x2e);
|
|
DECL(Z, 0x5a, 0x5a);
|
|
static asn1cnst_range_t *range_NumericString_array[] = {
|
|
&range_Space, &range_Digits };
|
|
static asn1cnst_range_t *range_PrintableString_array[] = {
|
|
&range_Space,
|
|
&range_ApostropheAndParens,
|
|
&range_PlusTillColon,
|
|
&range_Equal,
|
|
&range_QuestionMark,
|
|
&range_AlphaCap,
|
|
&range_AlphaLow
|
|
};
|
|
static asn1cnst_range_t *range_UTCTime_array[] = {
|
|
&range_Plus, &range_MinusDot, &range_Digits, &range_Z };
|
|
static asn1cnst_range_t *range_GeneralizedTime_array[] = {
|
|
&range_PlusCommaMinusDot, &range_Digits, &range_Z };
|
|
|
|
static asn1cnst_range_t range_notPERVisible = {
|
|
{ ARE_MIN, 0, 0 },
|
|
{ ARE_MAX, 0, 0 },
|
|
0, 0, 0, 0, 0, 0, 1 };
|
|
static asn1cnst_range_t range_NumericString = {
|
|
{ ARE_VALUE, 0, 0x20 },
|
|
{ ARE_VALUE, 0, 0x39 },
|
|
range_NumericString_array,
|
|
sizeof(range_NumericString_array)
|
|
/sizeof(range_NumericString_array[0]),
|
|
0, 0, 0, 0, 0 };
|
|
static asn1cnst_range_t range_PrintableString = {
|
|
{ ARE_VALUE, 0, 0x20 },
|
|
{ ARE_VALUE, 0, 0x7a },
|
|
range_PrintableString_array,
|
|
sizeof(range_PrintableString_array)
|
|
/sizeof(range_PrintableString_array[0]),
|
|
0, 0, 0, 0, 0 };
|
|
static asn1cnst_range_t range_VisibleString = {
|
|
{ ARE_VALUE, 0, 0x20 },
|
|
{ ARE_VALUE, 0, 0x7e },
|
|
0, 0, 0, 0, 0, 0, 0 };
|
|
static asn1cnst_range_t range_UTCTime = {
|
|
{ ARE_VALUE, 0, 0x2b },
|
|
{ ARE_VALUE, 0, 0x5a },
|
|
range_UTCTime_array,
|
|
sizeof(range_UTCTime_array)
|
|
/sizeof(range_UTCTime_array[0]),
|
|
0, 0, 0, 0, 1 };
|
|
static asn1cnst_range_t range_GeneralizedTime = {
|
|
{ ARE_VALUE, 0, 0x2b },
|
|
{ ARE_VALUE, 0, 0x5a },
|
|
range_GeneralizedTime_array,
|
|
sizeof(range_GeneralizedTime_array)
|
|
/sizeof(range_GeneralizedTime_array[0]),
|
|
0, 0, 0, 0, 1 };
|
|
|
|
switch(expr_type) {
|
|
case ASN_STRING_NumericString:
|
|
return &range_NumericString;
|
|
case ASN_STRING_PrintableString:
|
|
return &range_PrintableString;
|
|
case ASN_STRING_VisibleString:
|
|
return &range_VisibleString;
|
|
case ASN_STRING_IA5String:
|
|
return &range_uint7;
|
|
case ASN_STRING_BMPString:
|
|
return &range_bmp;
|
|
case ASN_STRING_UTF8String:
|
|
/*
|
|
* X.691, #9.3.6
|
|
* Not a known-multipler character string type.
|
|
*/
|
|
assert(range_utf8.not_PER_visible);
|
|
return &range_utf8;
|
|
case ASN_STRING_UniversalString:
|
|
return &range_uint32;
|
|
case ASN_BASIC_UTCTime:
|
|
/* Permitted alphabet constraint is not applicable */
|
|
assert(range_UTCTime.not_PER_visible);
|
|
return &range_UTCTime;
|
|
case ASN_BASIC_GeneralizedTime:
|
|
/* Permitted alphabet constraint is not applicable */
|
|
assert(range_GeneralizedTime.not_PER_visible);
|
|
return &range_GeneralizedTime;
|
|
case ASN_BASIC_OCTET_STRING:
|
|
/*
|
|
* Permitted alphabet constraint is not applicable
|
|
* to this type. However, we support it, albeit not
|
|
* in a strict PER mode.
|
|
*/
|
|
assert(range_octstr.not_PER_visible);
|
|
return &range_octstr;
|
|
default:
|
|
if(!(expr_type & ASN_STRING_MASK))
|
|
break;
|
|
assert(expr_type & ASN_STRING_NKM_MASK);
|
|
/*
|
|
* X.691, 9.3.6
|
|
* Not a known-multiplier character string.
|
|
*/
|
|
return &range_notPERVisible;
|
|
}
|
|
|
|
return NULL;
|
|
}
|