Open xeirwn opened 7 years ago
I think your code is buggy. One of the problems it has is that the upper limit on the octet string size is 81920, while your test_01.png
size is 831368. Naturally, it would fail the constraint check.
$ cat ../Test2.asn1
ImagesModule DEFINITIONS ::= BEGIN
Image ::= SEQUENCE
{
data OCTET STRING SIZE (40..81920)
}
END
$ asn1c -pdu=auto -gen-PER ../Test2.asn1
WARNING: Cannot find standard modules in /opt/local/share/asn1c/standard-modules
Compiled Image.c
Compiled Image.h
Copied /opt/local/share/asn1c/constr_SEQUENCE.h -> constr_SEQUENCE.h
Copied /opt/local/share/asn1c/constr_SEQUENCE.c -> constr_SEQUENCE.c
Copied /opt/local/share/asn1c/asn_application.h -> asn_application.h
Copied /opt/local/share/asn1c/asn_system.h -> asn_system.h
Copied /opt/local/share/asn1c/asn_codecs.h -> asn_codecs.h
Copied /opt/local/share/asn1c/asn_internal.h -> asn_internal.h
Copied /opt/local/share/asn1c/OCTET_STRING.h -> OCTET_STRING.h
Copied /opt/local/share/asn1c/OCTET_STRING.c -> OCTET_STRING.c
Copied /opt/local/share/asn1c/BIT_STRING.h -> BIT_STRING.h
Copied /opt/local/share/asn1c/BIT_STRING.c -> BIT_STRING.c
Copied /opt/local/share/asn1c/asn_codecs_prim.c -> asn_codecs_prim.c
Copied /opt/local/share/asn1c/asn_codecs_prim.h -> asn_codecs_prim.h
Copied /opt/local/share/asn1c/ber_tlv_length.h -> ber_tlv_length.h
Copied /opt/local/share/asn1c/ber_tlv_length.c -> ber_tlv_length.c
Copied /opt/local/share/asn1c/ber_tlv_tag.h -> ber_tlv_tag.h
Copied /opt/local/share/asn1c/ber_tlv_tag.c -> ber_tlv_tag.c
Copied /opt/local/share/asn1c/ber_decoder.h -> ber_decoder.h
Copied /opt/local/share/asn1c/ber_decoder.c -> ber_decoder.c
Copied /opt/local/share/asn1c/der_encoder.h -> der_encoder.h
Copied /opt/local/share/asn1c/der_encoder.c -> der_encoder.c
Copied /opt/local/share/asn1c/constr_TYPE.h -> constr_TYPE.h
Copied /opt/local/share/asn1c/constr_TYPE.c -> constr_TYPE.c
Copied /opt/local/share/asn1c/constraints.h -> constraints.h
Copied /opt/local/share/asn1c/constraints.c -> constraints.c
Copied /opt/local/share/asn1c/xer_support.h -> xer_support.h
Copied /opt/local/share/asn1c/xer_support.c -> xer_support.c
Copied /opt/local/share/asn1c/xer_decoder.h -> xer_decoder.h
Copied /opt/local/share/asn1c/xer_decoder.c -> xer_decoder.c
Copied /opt/local/share/asn1c/xer_encoder.h -> xer_encoder.h
Copied /opt/local/share/asn1c/xer_encoder.c -> xer_encoder.c
Copied /opt/local/share/asn1c/per_support.h -> per_support.h
Copied /opt/local/share/asn1c/per_support.c -> per_support.c
Copied /opt/local/share/asn1c/per_decoder.h -> per_decoder.h
Copied /opt/local/share/asn1c/per_decoder.c -> per_decoder.c
Copied /opt/local/share/asn1c/per_encoder.h -> per_encoder.h
Copied /opt/local/share/asn1c/per_encoder.c -> per_encoder.c
Copied /opt/local/share/asn1c/per_opentype.h -> per_opentype.h
Copied /opt/local/share/asn1c/per_opentype.c -> per_opentype.c
Copied /opt/local/share/asn1c/converter-sample.c -> converter-sample.c
Generated pdu_collection.c
Generated Makefile.am.sample
$ ln Makefile.am.sample Makefile
$ vi Makefile
$ make clean && make all
rm -f progname
rm -f Image.o constr_SEQUENCE.o OCTET_STRING.o BIT_STRING.o asn_codecs_prim.o ber_tlv_length.o ber_tlv_tag.o ber_decoder.o der_encoder.o constr_TYPE.o constraints.o xer_support.o xer_decoder.o xer_encoder.o per_support.o per_decoder.o per_encoder.o per_opentype.o converter-sample.o pdu_collection.o
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o Image.o -c Image.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o constr_SEQUENCE.o -c constr_SEQUENCE.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o OCTET_STRING.o -c OCTET_STRING.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o BIT_STRING.o -c BIT_STRING.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o asn_codecs_prim.o -c asn_codecs_prim.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o ber_tlv_length.o -c ber_tlv_length.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o ber_tlv_tag.o -c ber_tlv_tag.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o ber_decoder.o -c ber_decoder.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o der_encoder.o -c der_encoder.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o constr_TYPE.o -c constr_TYPE.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o constraints.o -c constraints.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o xer_support.o -c xer_support.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o xer_decoder.o -c xer_decoder.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o xer_encoder.o -c xer_encoder.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o per_support.o -c per_support.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o per_decoder.o -c per_decoder.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o per_encoder.o -c per_encoder.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o per_opentype.o -c per_opentype.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o converter-sample.o -c converter-sample.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o pdu_collection.o -c pdu_collection.c
clang -maes -mpclmul -mrdrnd -msse2 -mssse3 -msse4.1 -msse4.2 -Os -Ofast -DASN_PDU_COLLECTION -I. -DPDU=Image -o progname Image.o constr_SEQUENCE.o OCTET_STRING.o BIT_STRING.o asn_codecs_prim.o ber_tlv_length.o ber_tlv_tag.o ber_decoder.o der_encoder.o constr_TYPE.o constraints.o xer_support.o xer_decoder.o xer_encoder.o per_support.o per_decoder.o per_encoder.o per_opentype.o converter-sample.o pdu_collection.o
$ ./progname -h
Usage: ./progname [options] <data.ber> ...
Where options are:
-iper Input is in Unaligned PER (Packed Encoding Rules) (DEFAULT)
-iaper Input is in Aligned PER (Packed Encoding Rules)
-iber Input is in BER (Basic Encoding Rules)
-ixer Input is in XER (XML Encoding Rules)
-oper Output in Unaligned PER (Packed Encoding Rules)
-oaper Output in Aligned PER (Packed Encoding Rules)
-oder Output in DER (Distinguished Encoding Rules)
-oxer Output in XER (XML Encoding Rules) (DEFAULT)
-otext Output in plain semi-structured text (dump)
-onull Verify (decode) input, but do not output
-per-nopad Assume PER PDUs are not padded (-iper)
-p <PDU> Specify PDU type to decode
-p list List available PDUs
-1 Decode only the first PDU in file
-b <size> Set the i/o buffer size (default is 8192)
-c Check ASN.1 constraints after decoding
-d Enable debugging (-dd is even better)
-n <num> Process files <num> times
-s <size> Set the stack usage limit (default is 30000)
$ rm converter-sample.o
$ clang++ -o t -I/opt/local/include -I. main.cpp file_helpers.c string_helpers.c *.o -L/opt/local/lib
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
$ ./t assets/test_01.png
Correctly decoded object from assets/test_01.png
$
This is my fork of asn1c, whose only difference is that a lot of the PRs that have not been applied/merged to the main repo, are applied to mine (and when there's a conflict between those PRs that I chose to apply, I take care of it :)). But probably the main repo would handle this correctly too...
@mouse07410 thank you very much for the feedback.
When I execute the application, test_01.png
always fails
./asn1c_image ../assets/test_01.png
Constraint validation failed: OCTET STRING: constraint failed (/home/developer/Projects/asn1c_image/asn1/Image.c:31)
In Image.c
, have the following header
/*
* Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
* From ASN.1 module "ImagesModule"
* found in "../images.asn1"
* `asn1c -pdu=auto -S /home/developer/asn1c/skeletons/ -fcompound-names -gen-PER`
*/
What version of the asn1c
are you using?
Also, the skeleton files are the same?
In Image.c
, the function memb_data_constraint_1()
, there is this automatically generated check if((size >= 40 && size <= 81920))
is it available in your code as well ?
What version of the asn1c are you using?
As I said - I'm using my fork https://github.com/mouse07410/asn1c.git of this repo. As I said, the main difference is that my fork has most of the outstanding PRs applied, plus some minor fixes.
Also, the skeleton files are the same?
Yes of course.
In Image.c, have the following header ...
Of course.
When I execute the application, test_01.png always fails
What sense does make to make a test that always fails?! Since the size of your image (as I said) is 831368, obviously it is not going to pass through an upper bound filter that cuts above 81920. 831368 is greater than 81920.
As for your other file aptly named "bad_data", I can confirm the problem (it does not get properly encoded/decoded), but the actual constraint statement has nothing to do with it:
$ head -30 Image.c
/*
* Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
* From ASN.1 module "ImagesModule"
* found in "Images.asn1"
* `asn1c -gen-PER -pdu=Image`
*/
#include "Image.h"
static int
memb_data_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
asn_app_constraint_failed_f *ctfailcb, void *app_key) {
const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
size_t size;
if(!sptr) {
ASN__CTFAIL(app_key, td, sptr,
"%s: value not given (%s:%d)",
td->name, __FILE__, __LINE__);
return -1;
}
size = st->size;
if((size <= 81920LL)) {
/* Constraint check succeeded */
return 0;
} else {
ASN__CTFAIL(app_key, td, sptr,
"%s: constraint failed (%s:%d)",
$ ./t assets/bad_data.bin
Failed to decode object from assets/bad_data.bin
$
Note that there's no "constraint failed" message.
Also note that test_01.png
always encodes and decodes correctly when the upper bound is adjusted to fit its size. No problem with lower bound being 40.
More investigation needed.
As I said, the main difference is that my fork has most of the outstanding PRs applied, plus some minor fixes.
You have changes, enough said.
What sense does make to make a test that always fails?!
Making sure constraints are honored. Since the error I suspected had to do with the size constraints.
Note that there's no "constraint failed" message.
Never said there is.
I can confirm the problem (it does not get properly encoded/decoded), but the actual constraint statement has nothing to do with it
Since changing the lower limit, changes the behavior of the code.. then there is something to do with it.
More investigation needed.
I tested another file same size as bad_data.bin
which works fine in all scenarios.
I tested another file same size as bad_data.bin which works fine in all scenarios.
Interesting.
$ ./t assets/bad_data.bin
Failed to decode object from assets/bad_data.bin
I notice that the error message above does not seem to be produced by any of the asn1c
stuff.
I notice that the error message above does not seem to be produced by any of the asn1c stuff.
In main.cpp
, I check the return value of uper_decode()
, when the value is not equal to RC_OK
I print that message.
I'm not sure where to dig. I suspect that the fault is likely to be with your code, specifically with how it encodes and decodes binary data... Some misinterpretation between what asn1c-generated stuff expects and what you're feeding it (and/or how you're using what you're getting back from it).
I still am not enamored by your sample program, but it does look like [UA]PER encoder/decoder is broken.
@vlm that's your code - I'd appreciate if you could step in here. Here's the log that should be self-describing enough (and if not - I'd be happy to explain).
Why I think it's probably having problems in your PER code:
$ git blame skeletons/OCTET_STRING.c
. . . . .
725883b2 (Lev Walkin 2006-10-09 12:07:58 +0000 1194) static int
3a4689a7 (Lev Walkin 2006-11-24 11:20:27 +0000 1195) OCTET_STRING_per_get_characters(asn_per_data_t *po, uint8_t *buf,
3a4689a7 (Lev Walkin 2006-11-24 11:20:27 +0000 1196) size_t units, unsigned int bpc, unsigned int unit_bits,
3a4689a7 (Lev Walkin 2006-11-24 11:20:27 +0000 1197) long lb, long ub, asn_per_constraints_t *pc) {
3a4689a7 (Lev Walkin 2006-11-24 11:20:27 +0000 1198) uint8_t *end = buf + units * bpc;
725883b2 (Lev Walkin 2006-10-09 12:07:58 +0000 1199)
725883b2 (Lev Walkin 2006-10-09 12:07:58 +0000 1200) ASN_DEBUG("Expanding %d characters into (%ld..%ld):%d",
3a4689a7 (Lev Walkin 2006-11-24 11:20:27 +0000 1201) (int)units, lb, ub, unit_bits);
725883b2 (Lev Walkin 2006-10-09 12:07:58 +0000 1202)
725883b2 (Lev Walkin 2006-10-09 12:07:58 +0000 1203) /* X.691: 27.5.4 */
. . . . .
$ git blame skeletons/per_support.c
. . . . .
59b176ee (Lev Walkin 2005-11-26 11:25:14 +0000 57) int32_t
59b176ee (Lev Walkin 2005-11-26 11:25:14 +0000 58) per_get_few_bits(asn_per_data_t *pd, int nbits) {
59b176ee (Lev Walkin 2005-11-26 11:25:14 +0000 59) size_t off; /* Next after last bit offset */
d00657f6 (Lev Walkin 2007-06-26 02:51:10 +0000 60) ssize_t nleft; /* Number of bits left in this stream */
59b176ee (Lev Walkin 2005-11-26 11:25:14 +0000 61) uint32_t accum;
1d9e8dd6 (Lev Walkin 2005-12-07 05:46:03 +0000 62) const uint8_t *buf;
59b176ee (Lev Walkin 2005-11-26 11:25:14 +0000 63)
5b78e1cb (Lev Walkin 2007-06-24 06:26:47 +0000 64) if(nbits < 0)
59b176ee (Lev Walkin 2005-11-26 11:25:14 +0000 65) return -1;
59b176ee (Lev Walkin 2005-11-26 11:25:14 +0000 66)
. . . . .
$ cat Images.asn1
ImagesModule DEFINITIONS ::= BEGIN
Image ::= SEQUENCE
{
data OCTET STRING SIZE (40..81920)
}
END
Random data I'm feeding the encoder/decoder (file itself is hex-encoded for ease of visual inspection):
$ cat assets/random_data.bin
113be77070cb1885a150ab6890669b8dff98e95e2ea17448b35f7e0645e7789f
$
Test-program invocation: ./t assets/random_data.bin
cat assets/random_data.bin.encoded
A113be77070cb1885a150ab6890669b8dff98e95e2ea17448b35f7e0645e7789f
$
$ ./progname -iper -oxer assets/random_data.bin.encoded
Decoding Image as SEQUENCE (UPER) (constr_SEQUENCE.c:1052)
Decoding member data in Image (constr_SEQUENCE.c:1122)
PER Decoding non-extensible size 40 .. 81920 bits -1 (OCTET_STRING.c:1399)
[PER got 8<=528 bits => span 8 +0[8..528]:41 (520) => 0x41] (per_support.c:134)
Got PER length eb -1, len 105, once (OCTET STRING) (OCTET_STRING.c:1465)
Expanding 105 characters into (0..0):8 (OCTET_STRING.c:1201)
[PER got 24<=520 bits => span 32 +1[24..520]:31 (496) => 0x313133] (per_support.c:134)
[PER got 24<=496 bits => span 56 +4[24..496]:62 (472) => 0x626537] (per_support.c:134)
[PER got 24<=472 bits => span 80 +7[24..472]:37 (448) => 0x373037] (per_support.c:134)
[PER got 24<=448 bits => span 104 +10[24..448]:30 (424) => 0x306362] (per_support.c:134)
[PER got 24<=424 bits => span 128 +13[24..424]:31 (400) => 0x313838] (per_support.c:134)
[PER got 24<=400 bits => span 152 +0[24..400]:35 (376) => 0x356131] (per_support.c:134)
[PER got 24<=376 bits => span 176 +3[24..376]:35 (352) => 0x353061] (per_support.c:134)
[PER got 24<=352 bits => span 200 +6[24..352]:62 (328) => 0x623638] (per_support.c:134)
[PER got 24<=328 bits => span 224 +9[24..328]:39 (304) => 0x393036] (per_support.c:134)
[PER got 24<=304 bits => span 248 +12[24..304]:36 (280) => 0x363962] (per_support.c:134)
[PER got 24<=280 bits => span 272 +15[24..280]:38 (256) => 0x386466] (per_support.c:134)
[PER got 24<=256 bits => span 296 +2[24..256]:66 (232) => 0x663938] (per_support.c:134)
[PER got 24<=232 bits => span 320 +5[24..232]:65 (208) => 0x653935] (per_support.c:134)
[PER got 24<=208 bits => span 344 +8[24..208]:65 (184) => 0x653265] (per_support.c:134)
[PER got 24<=184 bits => span 368 +11[24..184]:61 (160) => 0x613137] (per_support.c:134)
[PER got 24<=160 bits => span 392 +14[24..160]:34 (136) => 0x343438] (per_support.c:134)
[PER got 24<=136 bits => span 416 +1[24..136]:62 (112) => 0x623335] (per_support.c:134)
[PER got 24<=112 bits => span 440 +4[24..112]:66 (88) => 0x663765] (per_support.c:134)
[PER got 24<=88 bits => span 464 +7[24..88]:30 (64) => 0x303634] (per_support.c:134)
[PER got 24<=64 bits => span 488 +10[24..64]:35 (40) => 0x356537] (per_support.c:134)
[PER got 24<=40 bits => span 512 +13[24..40]:37 (16) => 0x373839] (per_support.c:134)
Failed decode data in Image (constr_SEQUENCE.c:1127)
Freeing Image as SEQUENCE (constr_SEQUENCE.c:958)
Freeing OCTET STRING as OCTET STRING (OCTET_STRING.c:2091)
Decoding Image as SEQUENCE (UPER) (constr_SEQUENCE.c:1052)
Decoding member data in Image (constr_SEQUENCE.c:1122)
PER Decoding non-extensible size 40 .. 81920 bits -1 (OCTET_STRING.c:1399)
[PER got 8<=528 bits => span 8 +0[8..528]:41 (520) => 0x41] (per_support.c:134)
Got PER length eb -1, len 105, once (OCTET STRING) (OCTET_STRING.c:1465)
Expanding 105 characters into (0..0):8 (OCTET_STRING.c:1201)
[PER got 24<=520 bits => span 32 +1[24..520]:31 (496) => 0x313133] (per_support.c:134)
[PER got 24<=496 bits => span 56 +4[24..496]:62 (472) => 0x626537] (per_support.c:134)
[PER got 24<=472 bits => span 80 +7[24..472]:37 (448) => 0x373037] (per_support.c:134)
[PER got 24<=448 bits => span 104 +10[24..448]:30 (424) => 0x306362] (per_support.c:134)
[PER got 24<=424 bits => span 128 +13[24..424]:31 (400) => 0x313838] (per_support.c:134)
[PER got 24<=400 bits => span 152 +0[24..400]:35 (376) => 0x356131] (per_support.c:134)
[PER got 24<=376 bits => span 176 +3[24..376]:35 (352) => 0x353061] (per_support.c:134)
[PER got 24<=352 bits => span 200 +6[24..352]:62 (328) => 0x623638] (per_support.c:134)
[PER got 24<=328 bits => span 224 +9[24..328]:39 (304) => 0x393036] (per_support.c:134)
[PER got 24<=304 bits => span 248 +12[24..304]:36 (280) => 0x363962] (per_support.c:134)
[PER got 24<=280 bits => span 272 +15[24..280]:38 (256) => 0x386466] (per_support.c:134)
[PER got 24<=256 bits => span 296 +2[24..256]:66 (232) => 0x663938] (per_support.c:134)
[PER got 24<=232 bits => span 320 +5[24..232]:65 (208) => 0x653935] (per_support.c:134)
[PER got 24<=208 bits => span 344 +8[24..208]:65 (184) => 0x653265] (per_support.c:134)
[PER got 24<=184 bits => span 368 +11[24..184]:61 (160) => 0x613137] (per_support.c:134)
[PER got 24<=160 bits => span 392 +14[24..160]:34 (136) => 0x343438] (per_support.c:134)
[PER got 24<=136 bits => span 416 +1[24..136]:62 (112) => 0x623335] (per_support.c:134)
[PER got 24<=112 bits => span 440 +4[24..112]:66 (88) => 0x663765] (per_support.c:134)
[PER got 24<=88 bits => span 464 +7[24..88]:30 (64) => 0x303634] (per_support.c:134)
[PER got 24<=64 bits => span 488 +10[24..64]:35 (40) => 0x356537] (per_support.c:134)
[PER got 24<=40 bits => span 512 +13[24..40]:37 (16) => 0x373839] (per_support.c:134)
Failed decode data in Image (constr_SEQUENCE.c:1127)
Freeing Image as SEQUENCE (constr_SEQUENCE.c:958)
Freeing OCTET STRING as OCTET STRING (OCTET_STRING.c:2091)
assets/random_data.bin.encoded: Decode failed past byte 0: Unexpected end of input
$
To alleviate any possibility of my (or @xeirwn 's) code being the culprit, I've created a clean DER-encoded file. @vlm, please step in.
converter-sample.c
(progname
:) print it as XER to visually check that all is good.converter-sample.c
convert that file to UPER.converter-sample.c
try to convert the above UPER-encoded file to XER for printing - observe how it fails.$ od -t x1 assets/random_data.bin.der.encoded
0000000 30 43 04 41 31 31 33 62 65 37 37 30 37 30 63 62
0000020 31 38 38 35 61 31 35 30 61 62 36 38 39 30 36 36
0000040 39 62 38 64 66 66 39 38 65 39 35 65 32 65 61 31
0000060 37 34 34 38 62 33 35 66 37 65 30 36 34 35 65 37
0000100 37 38 39 66 0a
0000105
$ base64 -i assets/random_data.bin.der.encoded
MEMEQTExM2JlNzcwNzBjYjE4ODVhMTUwYWI2ODkwNjY5YjhkZmY5OGU5NWUyZWExNzQ0OGIzNWY3ZTA2NDVlNzc4OWYK
$
$ ./progname -iber -oxer assets/random_data.bin.der.encoded
Decoding Image as SEQUENCE (constr_SEQUENCE.c:132)
ber_check_tags(Image, size=69, tm=0, step=0, tagno=0) (ber_decoder.c:112)
Fetching tag from {0x7fa8bc012600,69}: len 1, step 0, tagno 0 got [UNIVERSAL 16] (ber_decoder.c:149)
Fetching len = 1 (ber_decoder.c:209)
Structure consumes 67 bytes, buffer 67 (constr_SEQUENCE.c:175)
In Image SEQUENCE left 67, edx=0 flags=0 opt=0 ec=1 (constr_SEQUENCE.c:208)
Current tag in Image SEQUENCE for element 0 (data) is [UNIVERSAL 4] encoded in 1 bytes, of frame 67 (constr_SEQUENCE.c:236)
Inside SEQUENCE Image MF2 (constr_SEQUENCE.c:391)
Decoding OCTET STRING as OCTET STRING (frame 67) (OCTET_STRING.c:196)
ber_check_tags(OCTET STRING, size=67, tm=0, step=0, tagno=0) (ber_decoder.c:112)
Fetching tag from {0x7fa8bc012602,67}: len 1, step 0, tagno 0 got [UNIVERSAL 4] (ber_decoder.c:149)
Fetching len = 1 (ber_decoder.c:209)
Reallocating into 128 (OCTET_STRING.c:486)
Took 67 bytes to encode OCTET STRING: [113be77070cb1885a150ab6890669b8dff98e95e2ea17448b35f7e0645e7789f
]:65 (OCTET_STRING.c:506)
In Image SEQUENCE decoded 0 OCTET STRING of 67 in 67 bytes rval.code 0, size=67 (constr_SEQUENCE.c:419)
SEQUENCE Image Leftover: 0, size = 0 (constr_SEQUENCE.c:444)
<Image>
<data>
31 31 33 62 65 37 37 30 37 30 63 62 31 38 38 35
61 31 35 30 61 62 36 38 39 30 36 36 39 62 38 64
66 66 39 38 65 39 35 65 32 65 61 31 37 34 34 38
62 33 35 66 37 65 30 36 34 35 65 37 37 38 39 66
0A
</data>
</Image>
Freeing Image as SEQUENCE (constr_SEQUENCE.c:958)
Freeing OCTET STRING as OCTET STRING (OCTET_STRING.c:2091)
$ ./progname -iber -oper assets/random_data.bin.der.encoded > assets/random_data.bin.uper.encoded
Decoding Image as SEQUENCE (constr_SEQUENCE.c:132)
ber_check_tags(Image, size=69, tm=0, step=0, tagno=0) (ber_decoder.c:112)
Fetching tag from {0x7fb841003600,69}: len 1, step 0, tagno 0 got [UNIVERSAL 16] (ber_decoder.c:149)
Fetching len = 1 (ber_decoder.c:209)
Structure consumes 67 bytes, buffer 67 (constr_SEQUENCE.c:175)
In Image SEQUENCE left 67, edx=0 flags=0 opt=0 ec=1 (constr_SEQUENCE.c:208)
Current tag in Image SEQUENCE for element 0 (data) is [UNIVERSAL 4] encoded in 1 bytes, of frame 67 (constr_SEQUENCE.c:236)
Inside SEQUENCE Image MF2 (constr_SEQUENCE.c:391)
Decoding OCTET STRING as OCTET STRING (frame 67) (OCTET_STRING.c:196)
ber_check_tags(OCTET STRING, size=67, tm=0, step=0, tagno=0) (ber_decoder.c:112)
Fetching tag from {0x7fb841003602,67}: len 1, step 0, tagno 0 got [UNIVERSAL 4] (ber_decoder.c:149)
Fetching len = 1 (ber_decoder.c:209)
Reallocating into 128 (OCTET_STRING.c:486)
Took 67 bytes to encode OCTET STRING: [113be77070cb1885a150ab6890669b8dff98e95e2ea17448b35f7e0645e7789f
]:65 (OCTET_STRING.c:506)
In Image SEQUENCE decoded 0 OCTET STRING of 67 in 67 bytes rval.code 0, size=67 (constr_SEQUENCE.c:419)
SEQUENCE Image Leftover: 0, size = 0 (constr_SEQUENCE.c:444)
Encoding Image as SEQUENCE (UPER) (constr_SEQUENCE.c:1315)
ext_after = -1, ec = 1, eb = -1 (constr_SEQUENCE.c:1365)
About to encode OCTET STRING (constr_SEQUENCE.c:1376)
Encoding Image->data (constr_SEQUENCE.c:1398)
Encoding OCTET STRING into 65 units of 8 bits (40..81920, effective -1) (OCTET_STRING.c:1574)
Encoding 65 bytes (OCTET_STRING.c:1621)
[PER put 8 bits 41 to 0x7fff5519ad78+0 bits] (per_support.c:511)
[PER out 8 65/41 (t=0,o=8) 0&0=0] (per_support.c:552)
[PER out 65/41 => 41 buf+0] (per_support.c:583)
Encoding 65 of 65 (OCTET_STRING.c:1635)
Squeezing 65 characters into (0..0):8 (1 bpc) (OCTET_STRING.c:1265)
[PER put 24 bits 313133 to 0x7fff5519ad78+8 bits] (per_support.c:511)
[PER out 24 3223859/313133 (t=0,o=24) 0&0=0] (per_support.c:552)
[PER out 3223859/313133 => 31 buf+1] (per_support.c:583)
[PER put 24 bits 626537 to 0x7fff5519ad79+24 bits] (per_support.c:511)
[PER out 24 6448439/626537 (t=0,o=24) 0&0=0] (per_support.c:552)
[PER out 6448439/626537 => 62 buf+4] (per_support.c:583)
[PER put 24 bits 373037 to 0x7fff5519ad7c+24 bits] (per_support.c:511)
[PER out 24 3616823/373037 (t=0,o=24) 0&0=0] (per_support.c:552)
[PER out 3616823/373037 => 37 buf+7] (per_support.c:583)
[PER put 24 bits 306362 to 0x7fff5519ad7f+24 bits] (per_support.c:511)
[PER out 24 3171170/306362 (t=0,o=24) c0&0=0] (per_support.c:552)
[PER out 3171170/306362 => 30 buf+10] (per_support.c:583)
[PER put 24 bits 313838 to 0x7fff5519ad82+24 bits] (per_support.c:511)
[PER out 24 3225656/313838 (t=0,o=24) 7f&0=0] (per_support.c:552)
[PER out 3225656/313838 => 31 buf+13] (per_support.c:583)
[PER put 24 bits 356131 to 0x7fff5519ad85+24 bits] (per_support.c:511)
[PER out 24 3498289/356131 (t=0,o=24) 45&0=0] (per_support.c:552)
[PER out 3498289/356131 => 35 buf+16] (per_support.c:583)
[PER put 24 bits 353061 to 0x7fff5519ad88+24 bits] (per_support.c:511)
[PER out 24 3485793/353061 (t=0,o=24) 0&0=0] (per_support.c:552)
[PER out 3485793/353061 => 35 buf+19] (per_support.c:583)
[PER put 24 bits 623638 to 0x7fff5519ad8b+24 bits] (per_support.c:511)
[PER out 24 6436408/623638 (t=0,o=24) 0&0=0] (per_support.c:552)
[PER out 6436408/623638 => 62 buf+22] (per_support.c:583)
[PER put 24 bits 393036 to 0x7fff5519ad8e+24 bits] (per_support.c:511)
[PER out 24 3747894/393036 (t=0,o=24) d6&0=0] (per_support.c:552)
[PER out 3747894/393036 => 39 buf+25] (per_support.c:583)
[PER put 24 bits 363962 to 0x7fff5519ad91+24 bits] (per_support.c:511)
[PER out 24 3553634/363962 (t=0,o=24) 1&0=0] (per_support.c:552)
[PER out 3553634/363962 => 36 buf+28] (per_support.c:583)
[PER put 24 bits 386466 to 0x7fff5519ad94+24 bits] (per_support.c:511)
[PER output 31 complete + 0] (per_support.c:528)
[PER out 24 3695718/386466 (t=0,o=24) 41&0=0] (per_support.c:552)
[PER out 3695718/386466 => 38 buf+0] (per_support.c:583)
[PER put 24 bits 663938 to 0x7fff5519ad78+24 bits] (per_support.c:511)
[PER out 24 6699320/663938 (t=0,o=24) 33&0=0] (per_support.c:552)
[PER out 6699320/663938 => 66 buf+3] (per_support.c:583)
[PER put 24 bits 653935 to 0x7fff5519ad7b+24 bits] (per_support.c:511)
[PER out 24 6633781/653935 (t=0,o=24) 37&0=0] (per_support.c:552)
[PER out 6633781/653935 => 65 buf+6] (per_support.c:583)
[PER put 24 bits 653265 to 0x7fff5519ad7e+24 bits] (per_support.c:511)
[PER out 24 6632037/653265 (t=0,o=24) 37&0=0] (per_support.c:552)
[PER out 6632037/653265 => 65 buf+9] (per_support.c:583)
[PER put 24 bits 613137 to 0x7fff5519ad81+24 bits] (per_support.c:511)
[PER out 24 6369591/613137 (t=0,o=24) 62&0=0] (per_support.c:552)
[PER out 6369591/613137 => 61 buf+12] (per_support.c:583)
[PER put 24 bits 343438 to 0x7fff5519ad84+24 bits] (per_support.c:511)
[PER out 24 3421240/343438 (t=0,o=24) 38&0=0] (per_support.c:552)
[PER out 3421240/343438 => 34 buf+15] (per_support.c:583)
[PER put 24 bits 623335 to 0x7fff5519ad87+24 bits] (per_support.c:511)
[PER out 24 6435637/623335 (t=0,o=24) 31&0=0] (per_support.c:552)
[PER out 6435637/623335 => 62 buf+18] (per_support.c:583)
[PER put 24 bits 663765 to 0x7fff5519ad8a+24 bits] (per_support.c:511)
[PER out 24 6698853/663765 (t=0,o=24) 61&0=0] (per_support.c:552)
[PER out 6698853/663765 => 66 buf+21] (per_support.c:583)
[PER put 24 bits 303634 to 0x7fff5519ad8d+24 bits] (per_support.c:511)
[PER out 24 3159604/303634 (t=0,o=24) 38&0=0] (per_support.c:552)
[PER out 3159604/303634 => 30 buf+24] (per_support.c:583)
[PER put 24 bits 356537 to 0x7fff5519ad90+24 bits] (per_support.c:511)
[PER out 24 3499319/356537 (t=0,o=24) 36&0=0] (per_support.c:552)
[PER out 3499319/356537 => 35 buf+27] (per_support.c:583)
[PER put 24 bits 373839 to 0x7fff5519ad93+24 bits] (per_support.c:511)
[PER output 30 complete + 31] (per_support.c:528)
[PER out 24 3618873/373839 (t=0,o=24) 38&0=0] (per_support.c:552)
[PER out 3618873/373839 => 37 buf+0] (per_support.c:583)
[PER put 16 bits 660a to 0x7fff5519ad78+24 bits] (per_support.c:511)
[PER out 16 26122/660a (t=0,o=16) 66&0=0] (per_support.c:552)
[PER out 26122/660a => 66 buf+3] (per_support.c:583)
Freeing Image as SEQUENCE (constr_SEQUENCE.c:958)
Freeing OCTET STRING as OCTET STRING (OCTET_STRING.c:2091)
$ ./progname -iper -oxer assets/random_data.bin.uper.encoded
Decoding Image as SEQUENCE (UPER) (constr_SEQUENCE.c:1052)
Decoding member data in Image (constr_SEQUENCE.c:1122)
PER Decoding non-extensible size 40 .. 81920 bits -1 (OCTET_STRING.c:1399)
[PER got 8<=528 bits => span 8 +0[8..528]:41 (520) => 0x41] (per_support.c:134)
Got PER length eb -1, len 105, once (OCTET STRING) (OCTET_STRING.c:1465)
Expanding 105 characters into (0..0):8 (OCTET_STRING.c:1201)
[PER got 24<=520 bits => span 32 +1[24..520]:31 (496) => 0x313133] (per_support.c:134)
[PER got 24<=496 bits => span 56 +4[24..496]:62 (472) => 0x626537] (per_support.c:134)
[PER got 24<=472 bits => span 80 +7[24..472]:37 (448) => 0x373037] (per_support.c:134)
[PER got 24<=448 bits => span 104 +10[24..448]:30 (424) => 0x306362] (per_support.c:134)
[PER got 24<=424 bits => span 128 +13[24..424]:31 (400) => 0x313838] (per_support.c:134)
[PER got 24<=400 bits => span 152 +0[24..400]:35 (376) => 0x356131] (per_support.c:134)
[PER got 24<=376 bits => span 176 +3[24..376]:35 (352) => 0x353061] (per_support.c:134)
[PER got 24<=352 bits => span 200 +6[24..352]:62 (328) => 0x623638] (per_support.c:134)
[PER got 24<=328 bits => span 224 +9[24..328]:39 (304) => 0x393036] (per_support.c:134)
[PER got 24<=304 bits => span 248 +12[24..304]:36 (280) => 0x363962] (per_support.c:134)
[PER got 24<=280 bits => span 272 +15[24..280]:38 (256) => 0x386466] (per_support.c:134)
[PER got 24<=256 bits => span 296 +2[24..256]:66 (232) => 0x663938] (per_support.c:134)
[PER got 24<=232 bits => span 320 +5[24..232]:65 (208) => 0x653935] (per_support.c:134)
[PER got 24<=208 bits => span 344 +8[24..208]:65 (184) => 0x653265] (per_support.c:134)
[PER got 24<=184 bits => span 368 +11[24..184]:61 (160) => 0x613137] (per_support.c:134)
[PER got 24<=160 bits => span 392 +14[24..160]:34 (136) => 0x343438] (per_support.c:134)
[PER got 24<=136 bits => span 416 +1[24..136]:62 (112) => 0x623335] (per_support.c:134)
[PER got 24<=112 bits => span 440 +4[24..112]:66 (88) => 0x663765] (per_support.c:134)
[PER got 24<=88 bits => span 464 +7[24..88]:30 (64) => 0x303634] (per_support.c:134)
[PER got 24<=64 bits => span 488 +10[24..64]:35 (40) => 0x356537] (per_support.c:134)
[PER got 24<=40 bits => span 512 +13[24..40]:37 (16) => 0x373839] (per_support.c:134)
Failed decode data in Image (constr_SEQUENCE.c:1127)
Freeing Image as SEQUENCE (constr_SEQUENCE.c:958)
Freeing OCTET STRING as OCTET STRING (OCTET_STRING.c:2091)
Decoding Image as SEQUENCE (UPER) (constr_SEQUENCE.c:1052)
Decoding member data in Image (constr_SEQUENCE.c:1122)
PER Decoding non-extensible size 40 .. 81920 bits -1 (OCTET_STRING.c:1399)
[PER got 8<=528 bits => span 8 +0[8..528]:41 (520) => 0x41] (per_support.c:134)
Got PER length eb -1, len 105, once (OCTET STRING) (OCTET_STRING.c:1465)
Expanding 105 characters into (0..0):8 (OCTET_STRING.c:1201)
[PER got 24<=520 bits => span 32 +1[24..520]:31 (496) => 0x313133] (per_support.c:134)
[PER got 24<=496 bits => span 56 +4[24..496]:62 (472) => 0x626537] (per_support.c:134)
[PER got 24<=472 bits => span 80 +7[24..472]:37 (448) => 0x373037] (per_support.c:134)
[PER got 24<=448 bits => span 104 +10[24..448]:30 (424) => 0x306362] (per_support.c:134)
[PER got 24<=424 bits => span 128 +13[24..424]:31 (400) => 0x313838] (per_support.c:134)
[PER got 24<=400 bits => span 152 +0[24..400]:35 (376) => 0x356131] (per_support.c:134)
[PER got 24<=376 bits => span 176 +3[24..376]:35 (352) => 0x353061] (per_support.c:134)
[PER got 24<=352 bits => span 200 +6[24..352]:62 (328) => 0x623638] (per_support.c:134)
[PER got 24<=328 bits => span 224 +9[24..328]:39 (304) => 0x393036] (per_support.c:134)
[PER got 24<=304 bits => span 248 +12[24..304]:36 (280) => 0x363962] (per_support.c:134)
[PER got 24<=280 bits => span 272 +15[24..280]:38 (256) => 0x386466] (per_support.c:134)
[PER got 24<=256 bits => span 296 +2[24..256]:66 (232) => 0x663938] (per_support.c:134)
[PER got 24<=232 bits => span 320 +5[24..232]:65 (208) => 0x653935] (per_support.c:134)
[PER got 24<=208 bits => span 344 +8[24..208]:65 (184) => 0x653265] (per_support.c:134)
[PER got 24<=184 bits => span 368 +11[24..184]:61 (160) => 0x613137] (per_support.c:134)
[PER got 24<=160 bits => span 392 +14[24..160]:34 (136) => 0x343438] (per_support.c:134)
[PER got 24<=136 bits => span 416 +1[24..136]:62 (112) => 0x623335] (per_support.c:134)
[PER got 24<=112 bits => span 440 +4[24..112]:66 (88) => 0x663765] (per_support.c:134)
[PER got 24<=88 bits => span 464 +7[24..88]:30 (64) => 0x303634] (per_support.c:134)
[PER got 24<=64 bits => span 488 +10[24..64]:35 (40) => 0x356537] (per_support.c:134)
[PER got 24<=40 bits => span 512 +13[24..40]:37 (16) => 0x373839] (per_support.c:134)
Failed decode data in Image (constr_SEQUENCE.c:1127)
Freeing Image as SEQUENCE (constr_SEQUENCE.c:958)
Freeing OCTET STRING as OCTET STRING (OCTET_STRING.c:2091)
assets/random_data.bin.uper.encoded: Decode failed past byte 0: Unexpected end of input
$
@ikarso, @persandstrom - you seem to be using PER (and this problem manifests with APER as well, same way), so you may want to pitch in too. It doesn't seem to be related to what we're doing, because the original reporter used the unmodified asn1c
version.
I am getting more and more confused. I wrote a small program to encode and decode a similar PDU (except for the same of simplicity I set upper limit to 100 instead of 81920).
It all worked smoothly with random data, correctly refusing to process PDU when constraints were violated.
Here's the log of conversion of the DER-encoded file that failed in the previous post (Test2a
is compiled converter-sample.c
, to avoid having my own code involved):
$ ./Test2a -iber -oxer random_data.der
<Test2a>
<data>
31 31 33 62 65 37 37 30 37 30 63 62 31 38 38 35
61 31 35 30 61 62 36 38 39 30 36 36 39 62 38 64
66 66 39 38 65 39 35 65 32 65 61 31 37 34 34 38
62 33 35 66 37 65 30 36 34 35 65 37 37 38 39 66
0A
</data>
</Test2a>
$ ./Test2a -iber -oper random_data.der > random_data.uper
$ ./Test2a -c -oxer random_data.uper > random_data.xer
$ cat random_data.xer
<Test2a>
<data>
31 31 33 62 65 37 37 30 37 30 63 62 31 38 38 35
61 31 35 30 61 62 36 38 39 30 36 36 39 62 38 64
66 66 39 38 65 39 35 65 32 65 61 31 37 34 34 38
62 33 35 66 37 65 30 36 34 35 65 37 37 38 39 66
0A
</data>
</Test2a>
$
ASN.1 module:
Test2a DEFINITIONS ::=
BEGIN
Test2a ::= SEQUENCE {
data OCTET STRING SIZE (40..100)
}
END
I also found that when I define the upper limit for the OCTET STRING in the ballpark of 70000
+, PER encoding seems to succeed but the decoding fails.
Here's the ASN.1:
Test2a DEFINITIONS ::=
BEGIN
Test2a ::= SEQUENCE {
data OCTET STRING SIZE (40..60000)
}
END
In the failing cases, the encoding starts with the length byte, like hex 48
(the actual strings I'm trying are fairly short - just to pass the lower limit restriction, so this one is 72 bytes long).
In the successful encoding and decoding cases, the UPER-encoded PDU starts with hex 00 20
. The rest of both UPER and APER encoded PDUs contain just the 72 bytes of the actual raw octet string that I'm trying to encode and decode.
It's rather disappointing that those who (presumably) know PER and asn1c
tool better, choose to abstain here, as PER encoding is a tough b...., and its implementation here is not the best-commented one...
Appears fixed in my fork (thanks, @velichkov). @xeirwn feel free to test.
Appears fixed in my fork (thanks, @velichkov). @xeirwn feel free to test.
@mouse07410 https://github.com/mouse07410/asn1c/issues/107
Hello guys,
I've noticed that when I set a
lower bound
limit on the size of anoctet string
, it fails to decode it. To reproduce this scenario I created a small but full example that is located here.The example is an application that uses the code generated by
asn1c
and has the following behavior:octet string
usingOCTET_STRING_fromBuf()
ASN.1
structure usinguper_encode_to_new_buffer()
, afterasn_check_constraints()
succeedsuper_decode()
Methodology To create/view the bug use this
ASN1
data structure as input to theasn1c
compiler:To hide the bug, use:
The only difference between the two versions is the use of a lower limit constraint on the size of the OCTET string.
Compilation command for asn1c From folder
asn1c_image/asn1
we used the following command:Version of asn1c
'ASN.1 Compiler, v0.9.28'
Samples
Inside the archive, there are two files [
test_01.png
,bad_data.bin
].test_01.png
is larger than 80K so it should always fail.bad_data.bin
fails only when there is a lower bound limit on the size