Skip to content

Commit

Permalink
Add EXTERNAL support. gh-140
Browse files Browse the repository at this point in the history
- Remove EXTERNAL from asn1p_l.l and asn1p_y.y
- Add EXTERNAL ASN.1 definition from ITU-T X.208 in
  skeletons/standard-modules/ASN1C-UsefulInformationObjectClasses.asn1
- Add a test case:
  tests/135-EXTERNAL-OK.asn and
  asn1c/tests/check-src/check-135.c
- Regenerate all tests/*.asn1.-Pfwide-types files
  • Loading branch information
velichkov committed Mar 27, 2017
1 parent 4bbea5e commit 9632f5d
Show file tree
Hide file tree
Showing 57 changed files with 10,318 additions and 4 deletions.
2 changes: 1 addition & 1 deletion TODO
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@

2. MEDIUM:

2.1 Support for EXTERNAL, EMBEDDED-PDV and CHARACTER STRING types.
2.1 Support for EMBEDDED-PDV and CHARACTER STRING types.
Requires something from 1.2 (Information Object Classes).
1 change: 1 addition & 0 deletions asn1c/tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ TESTS += check-src/check-127.-gen-PER.c
TESTS += check-src/check-131.-gen-PER.c
TESTS += check-src/check-132.-gen-PER.c
TESTS += check-src/check-133.-gen-PER.c
TESTS += check-src/check-135.c
TESTS += check-src/check-19.c
TESTS += check-src/check-22.-fwide-types.c
TESTS += check-src/check-24.-fwide-types.c
Expand Down
135 changes: 135 additions & 0 deletions asn1c/tests/check-src/check-135.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#undef NDEBUG
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>

#include "T.h"


uint8_t buf1[] = {
0x28,0x18,
0x06,0x07,0x00,0x11,0x86,0x05,0x01,0x01,0x01,
0xa0,0x0d,
0x60,0x0b,
0xa1,0x09,
0x06,0x07,0x04,0x00,0x00,0x01,0x00,0x05,0x03
};


uint8_t buf1_reconstr[] = {
0x28,0x18,
0x06,0x07,0x00,0x11,0x86,0x05,0x01,0x01,0x01,
0xa0,0x0d,
0x60,0x0b,
0xa1,0x09,
0x06,0x07,0x04,0x00,0x00,0x01,0x00,0x05,0x03
};


static void
check(T_t *tp, uint8_t *buf, size_t size, size_t consumed) {
asn_dec_rval_t rval;

tp = memset(tp, 0, sizeof(*tp));

fprintf(stderr, "Buf %p (%zd)\n", buf, size);
rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size);
fprintf(stderr, "Returned code %d, consumed %zd\n",
(int)rval.code, rval.consumed);

assert(rval.code == RC_OK);
assert(rval.consumed == consumed);

const uint8_t direct_reference[] = {0x00,0x11,0x86,0x05,0x01,0x01,0x01};
assert(tp->direct_reference);
assert(tp->direct_reference->size == sizeof(direct_reference));
assert(memcmp(tp->direct_reference->buf, direct_reference,
sizeof(direct_reference)) == 0);

assert(tp->indirect_reference == NULL);
assert(tp->data_value_descriptor == NULL);

const uint8_t single_asn1_type[] = {
0x60,0x0b,0xa1,0x09,0x06,0x07,0x04,0x00,0x00,0x01,0x00,0x05,0x03};
assert(tp->encoding.present == encoding_PR_single_ASN1_type);
assert(tp->encoding.choice.single_ASN1_type.size == sizeof(single_asn1_type));
assert(memcmp(tp->encoding.choice.single_ASN1_type.buf, single_asn1_type,
sizeof(single_asn1_type)) == 0);
}

size_t buf_pos;
size_t buf_size;
uint8_t *buf;

static int
buf_fill(const void *buffer, size_t size, void *app_key) {

(void)app_key; /* Unused argument */

if(buf_pos + size > buf_size) {
fprintf(stderr, "%zd + %zd > %zd\n",
buf_pos, size, buf_size);
return -1;
}

memcpy(buf + buf_pos, buffer, size);
buf_pos += size;
fprintf(stderr, " written %zd (%zd)\n", size, buf_pos);

return 0;
}

static void
compare(T_t *tp, uint8_t *cmp_buf, ssize_t cmp_buf_size) {
asn_enc_rval_t erval;
int i;

buf_size = cmp_buf_size + 100;
buf = alloca(buf_size);
buf_pos = 0;

/*
* Try to re-create using DER encoding.
*/
erval = der_encode(&asn_DEF_T, tp, buf_fill, 0);
assert(erval.encoded != -1);
if(erval.encoded != cmp_buf_size) {
printf("%zd != %zd\n", erval.encoded, cmp_buf_size);
}
assert(erval.encoded == cmp_buf_size);
for(i = 0; i < cmp_buf_size; i++) {
if(buf[i] != cmp_buf[i]) {
fprintf(stderr, "Recreated buffer content mismatch:\n");
fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
i,
buf[i], cmp_buf[i],
buf[i], cmp_buf[i]
);
}
assert(buf[i] == cmp_buf[i]);
}
}

int
main(int ac, char **av) {
T_t t;

(void)ac; /* Unused argument */
(void)av; /* Unused argument */

/* Check exact buf1 */
check(&t, buf1, sizeof(buf1), sizeof(buf1));
compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
asn_fprint(stderr, &asn_DEF_T, &t);
asn_DEF_T.free_struct(&asn_DEF_T, &t, 1);

/* Check slightly more than buf1 */
check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1));
compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
asn_fprint(stderr, &asn_DEF_T, &t);
asn_DEF_T.free_struct(&asn_DEF_T, &t, 1);

return 0;
}
2 changes: 1 addition & 1 deletion libasn1parser/asn1p_l.l
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ EXCEPT return TOK_EXCEPT;
EXPLICIT return TOK_EXPLICIT;
EXPORTS return TOK_EXPORTS;
EXTENSIBILITY return TOK_EXTENSIBILITY;
EXTERNAL return TOK_EXTERNAL;
/*EXTERNAL return TOK_EXTERNAL;*/
FALSE return TOK_FALSE;
FROM return TOK_FROM;
GeneralizedTime return TOK_GeneralizedTime;
Expand Down
4 changes: 2 additions & 2 deletions libasn1parser/asn1p_y.y
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ static asn1p_module_t *currentModule;
%token TOK_EXPLICIT
%token TOK_EXPORTS
%token TOK_EXTENSIBILITY
%token TOK_EXTERNAL
/*%token TOK_EXTERNAL*/
%token TOK_FALSE
%token TOK_FROM
%token TOK_GeneralizedTime
Expand Down Expand Up @@ -1607,7 +1607,7 @@ BasicTypeId:
| TOK_OCTET TOK_STRING { $$ = ASN_BASIC_OCTET_STRING; }
| TOK_OBJECT TOK_IDENTIFIER { $$ = ASN_BASIC_OBJECT_IDENTIFIER; }
| TOK_RELATIVE_OID { $$ = ASN_BASIC_RELATIVE_OID; }
| TOK_EXTERNAL { $$ = ASN_BASIC_EXTERNAL; }
/* | TOK_EXTERNAL { $$ = ASN_BASIC_EXTERNAL; } */
| TOK_EMBEDDED TOK_PDV { $$ = ASN_BASIC_EMBEDDED_PDV; }
| TOK_CHARACTER TOK_STRING { $$ = ASN_BASIC_CHARACTER_STRING; }
| TOK_UTCTime { $$ = ASN_BASIC_UTCTime; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,16 @@ DEFINITIONS ::= BEGIN
&property BIT STRING { handles-invalid-encodings(0) } DEFAULT {}
} WITH SYNTAX { &Type IDENTIFIED BY &id [HAS PROPERTY &property] }

--
-- From "ITU-T Recommendation X.208", "34 The external type"
--
EXTERNAL ::= [UNIVERSAL 8] IMPLICIT SEQUENCE
{direct-reference OBJECT IDENTIFIER OPTIONAL,
indirect-reference INTEGER OPTIONAL,
data-value-descriptor ObjectDescriptor OPTIONAL,
encoding CHOICE
{single-ASN1-type [0] ANY,
octet-aligned [1] IMPLICIT OCTET STRING,
arbitrary [2] IMPLICIT BIT STRING}}

END
201 changes: 201 additions & 0 deletions tests/03-enum-OK.asn1.-Pfwide-types
Original file line number Diff line number Diff line change
Expand Up @@ -816,3 +816,204 @@ asn_TYPE_descriptor_t asn_DEF_Enum5 = {
&asn_SPC_Enum5_specs_1 /* Additional specs */
};


/*** <<< INCLUDES [EXTERNAL] >>> ***/

#include <OBJECT_IDENTIFIER.h>
#include <INTEGER.h>
#include <ObjectDescriptor.h>
#include <ANY.h>
#include <OCTET_STRING.h>
#include <BIT_STRING.h>
#include <constr_CHOICE.h>
#include <constr_SEQUENCE.h>

/*** <<< DEPS [EXTERNAL] >>> ***/

typedef enum encoding_PR {
encoding_PR_NOTHING, /* No components present */
encoding_PR_single_ASN1_type,
encoding_PR_octet_aligned,
encoding_PR_arbitrary
} encoding_PR;

/*** <<< TYPE-DECLS [EXTERNAL] >>> ***/

typedef struct EXTERNAL {
OBJECT_IDENTIFIER_t *direct_reference /* OPTIONAL */;
INTEGER_t *indirect_reference /* OPTIONAL */;
ObjectDescriptor_t *data_value_descriptor /* OPTIONAL */;
struct encoding {
encoding_PR present;
union EXTERNAL__encoding_u {
ANY_t single_ASN1_type;
OCTET_STRING_t octet_aligned;
BIT_STRING_t arbitrary;
} choice;

/* Context for parsing across buffer boundaries */
asn_struct_ctx_t _asn_ctx;
} encoding;

/* Context for parsing across buffer boundaries */
asn_struct_ctx_t _asn_ctx;
} EXTERNAL_t;

/*** <<< FUNC-DECLS [EXTERNAL] >>> ***/

extern asn_TYPE_descriptor_t asn_DEF_EXTERNAL;

/*** <<< STAT-DEFS [EXTERNAL] >>> ***/

static asn_TYPE_member_t asn_MBR_encoding_5[] = {
{ ATF_NOFLAGS, 0, offsetof(struct encoding, choice.single_ASN1_type),
.tag = (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
.tag_mode = +1, /* EXPLICIT tag at current level */
.type = &asn_DEF_ANY,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.per_constraints = 0, /* PER is not compiled, use -gen-PER */
.default_value = 0,
.name = "single-ASN1-type"
},
{ ATF_NOFLAGS, 0, offsetof(struct encoding, choice.octet_aligned),
.tag = (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = &asn_DEF_OCTET_STRING,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.per_constraints = 0, /* PER is not compiled, use -gen-PER */
.default_value = 0,
.name = "octet-aligned"
},
{ ATF_NOFLAGS, 0, offsetof(struct encoding, choice.arbitrary),
.tag = (ASN_TAG_CLASS_CONTEXT | (2 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = &asn_DEF_BIT_STRING,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.per_constraints = 0, /* PER is not compiled, use -gen-PER */
.default_value = 0,
.name = "arbitrary"
},
};
static const asn_TYPE_tag2member_t asn_MAP_encoding_tag2el_5[] = {
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* single-ASN1-type */
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* octet-aligned */
{ (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 } /* arbitrary */
};
static asn_CHOICE_specifics_t asn_SPC_encoding_specs_5 = {
sizeof(struct encoding),
offsetof(struct encoding, _asn_ctx),
offsetof(struct encoding, present),
sizeof(((struct encoding *)0)->present),
asn_MAP_encoding_tag2el_5,
3, /* Count of tags in the map */
.canonical_order = 0,
.ext_start = -1 /* Extensions start */
};
static /* Use -fall-defs-global to expose */
asn_TYPE_descriptor_t asn_DEF_encoding_5 = {
"encoding",
"encoding",
CHOICE_free,
CHOICE_print,
CHOICE_constraint,
CHOICE_decode_ber,
CHOICE_encode_der,
CHOICE_decode_xer,
CHOICE_encode_xer,
0, 0, /* No UPER support, use "-gen-PER" to enable */
0, 0, /* No APER support, use "-gen-PER" to enable */
CHOICE_outmost_tag,
0, /* No effective tags (pointer) */
0, /* No effective tags (count) */
0, /* No tags (pointer) */
0, /* No tags (count) */
0, /* No PER visible constraints */
asn_MBR_encoding_5,
3, /* Elements count */
&asn_SPC_encoding_specs_5 /* Additional specs */
};

static asn_TYPE_member_t asn_MBR_EXTERNAL_1[] = {
{ ATF_POINTER, 3, offsetof(struct EXTERNAL, direct_reference),
.tag = (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)),
.tag_mode = 0,
.type = &asn_DEF_OBJECT_IDENTIFIER,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.per_constraints = 0, /* PER is not compiled, use -gen-PER */
.default_value = 0,
.name = "direct-reference"
},
{ ATF_POINTER, 2, offsetof(struct EXTERNAL, indirect_reference),
.tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
.tag_mode = 0,
.type = &asn_DEF_INTEGER,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.per_constraints = 0, /* PER is not compiled, use -gen-PER */
.default_value = 0,
.name = "indirect-reference"
},
{ ATF_POINTER, 1, offsetof(struct EXTERNAL, data_value_descriptor),
.tag = (ASN_TAG_CLASS_UNIVERSAL | (7 << 2)),
.tag_mode = 0,
.type = &asn_DEF_ObjectDescriptor,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.per_constraints = 0, /* PER is not compiled, use -gen-PER */
.default_value = 0,
.name = "data-value-descriptor"
},
{ ATF_NOFLAGS, 0, offsetof(struct EXTERNAL, encoding),
.tag = -1 /* Ambiguous tag (CHOICE?) */,
.tag_mode = 0,
.type = &asn_DEF_encoding_5,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.per_constraints = 0, /* PER is not compiled, use -gen-PER */
.default_value = 0,
.name = "encoding"
},
};
static const ber_tlv_tag_t asn_DEF_EXTERNAL_tags_1[] = {
(ASN_TAG_CLASS_UNIVERSAL | (8 << 2)),
(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
};
static const asn_TYPE_tag2member_t asn_MAP_EXTERNAL_tag2el_1[] = {
{ (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 0 }, /* indirect-reference */
{ (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 0 }, /* direct-reference */
{ (ASN_TAG_CLASS_UNIVERSAL | (7 << 2)), 2, 0, 0 }, /* data-value-descriptor */
{ (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 3, 0, 0 }, /* single-ASN1-type */
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 3, 0, 0 }, /* octet-aligned */
{ (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 3, 0, 0 } /* arbitrary */
};
static asn_SEQUENCE_specifics_t asn_SPC_EXTERNAL_specs_1 = {
sizeof(struct EXTERNAL),
offsetof(struct EXTERNAL, _asn_ctx),
asn_MAP_EXTERNAL_tag2el_1,
6, /* Count of tags in the map */
0, 0, 0, /* Optional elements (not needed) */
-1, /* Start extensions */
-1 /* Stop extensions */
};
asn_TYPE_descriptor_t asn_DEF_EXTERNAL = {
"EXTERNAL",
"EXTERNAL",
SEQUENCE_free,
SEQUENCE_print,
SEQUENCE_constraint,
SEQUENCE_decode_ber,
SEQUENCE_encode_der,
SEQUENCE_decode_xer,
SEQUENCE_encode_xer,
0, 0, /* No UPER support, use "-gen-PER" to enable */
0, 0, /* No APER support, use "-gen-PER" to enable */
0, /* Use generic outmost tag fetcher */
asn_DEF_EXTERNAL_tags_1,
sizeof(asn_DEF_EXTERNAL_tags_1)
/sizeof(asn_DEF_EXTERNAL_tags_1[0]) - 1, /* 1 */
asn_DEF_EXTERNAL_tags_1, /* Same as above */
sizeof(asn_DEF_EXTERNAL_tags_1)
/sizeof(asn_DEF_EXTERNAL_tags_1[0]), /* 2 */
0, /* No PER visible constraints */
asn_MBR_EXTERNAL_1,
4, /* Elements count */
&asn_SPC_EXTERNAL_specs_1 /* Additional specs */
};

Loading

0 comments on commit 9632f5d

Please sign in to comment.