blob: edc2ea2d3c2b73c547c730776c3db0b53c80119b [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#undef NDEBUG
2#include <stdio.h>
3#include <stdlib.h>
4#include <sys/types.h>
5#include <string.h>
6#include <assert.h>
7
8#include <T.h>
9
10uint8_t buf1[] = {
11 32 | 17, /* [UNIVERSAL 17], constructed */
Lev Walkin4a6f3cf2004-10-03 10:54:34 +000012 15, /* L */
Lev Walkinf15320b2004-06-03 03:38:44 +000013
14 /* b CHOICE { b2 ObjectDescriptor }*/
15 7, /* [UNIVERSAL 7] */
16 1, /* L */
17 'z',
18
19 /* c BOOLEAN */
20 1, /* [UNIVERSAL 1] */
21 0, /* L */
22
23 /* a NumericString */
24 18, /* [UNIVERSAL 18] */
Lev Walkin4a6f3cf2004-10-03 10:54:34 +000025 4, /* L */
26 '=',
27 '<',
28 '&',
29 '>',
Lev Walkinf15320b2004-06-03 03:38:44 +000030
31 /* d.r-oid RELATIVE-OID */
32 13, /* [UNIVERSAL 13] */
33 2, /* L */
34 85,
35 79,
36
37};
38
39uint8_t buf1_reconstr[] = {
40 32 | 17, /* [UNIVERSAL 17], constructed */
Lev Walkin4a6f3cf2004-10-03 10:54:34 +000041 16, /* L */
Lev Walkinf15320b2004-06-03 03:38:44 +000042
43 /* c BOOLEAN */
44 1, /* [UNIVERSAL 1] */
45 1, /* L */
46 0,
47
48 /* b CHOICE { b2 ObjectDescriptor }*/
49 7, /* [UNIVERSAL 7] */
50 1, /* L */
51 'z',
52
53 /* d.r-oid RELATIVE-OID */
54 13, /* [UNIVERSAL 1] */
55 2, /* L */
56 85,
57 79,
58
59 /* a NumericString */
60 18, /* [UNIVERSAL 18] */
Lev Walkin4a6f3cf2004-10-03 10:54:34 +000061 4, /* L */
62 '=',
63 '<',
64 '&',
65 '>',
Lev Walkinf15320b2004-06-03 03:38:44 +000066};
67
68uint8_t buf2[] = {
69 32 | 17, /* [UNIVERSAL 17], constructed */
Lev Walkin4a6f3cf2004-10-03 10:54:34 +000070 15, /* L */
Lev Walkinf15320b2004-06-03 03:38:44 +000071
72 /* a NumericString */
73 18, /* [UNIVERSAL 18] */
Lev Walkin4a6f3cf2004-10-03 10:54:34 +000074 4, /* L */
75 '=',
76 '<',
77 '&',
78 '>',
Lev Walkinf15320b2004-06-03 03:38:44 +000079
80 /* c BOOLEAN */
81 1, /* [UNIVERSAL 1] */
82 1, /* L */
83 2, /* True */
84
85 /* b CHOICE { b1 IA5String }*/
86 22, /* [UNIVERSAL 22] */
87 1, /* L */
88 'z',
89
90 /* d.oid RELATIVE-OID */
91 6, /* [UNIVERSAL 6] */
92 1, /* L */
93 81,
94
95};
96
97uint8_t buf2_reconstr[] = {
98 32 | 17, /* [UNIVERSAL 17], constructed */
Lev Walkin4a6f3cf2004-10-03 10:54:34 +000099 15, /* L */
Lev Walkinf15320b2004-06-03 03:38:44 +0000100
101 /* c BOOLEAN */
102 1, /* [UNIVERSAL 1] */
103 1, /* L */
104 0xff, /* Canonical True */
105
106 /* d.oid RELATIVE-OID */
107 6, /* [UNIVERSAL 6] */
108 1, /* L */
109 81,
110
111 /* a NumericString */
112 18, /* [UNIVERSAL 18] */
Lev Walkin4a6f3cf2004-10-03 10:54:34 +0000113 4, /* L */
114 '=',
115 '<',
116 '&',
117 '>',
Lev Walkinf15320b2004-06-03 03:38:44 +0000118
119 /* b CHOICE { b1 IA5String }*/
120 22, /* [UNIVERSAL 22] */
121 1, /* L */
122 'z'
123};
124
125static void
Lev Walkin1715b322013-03-28 04:02:13 -0700126check(T_t *tp, uint8_t *buf, size_t size, size_t consumed) {
Lev Walkin90bf7ae2004-10-20 15:46:56 +0000127 asn_dec_rval_t rval;
Lev Walkinf15320b2004-06-03 03:38:44 +0000128
129 tp = memset(tp, 0, sizeof(*tp));
130
Lev Walkin1715b322013-03-28 04:02:13 -0700131 fprintf(stderr, "Buf %p (%zd)\n", buf, size);
Lev Walkinc7400c52004-09-29 13:14:36 +0000132 rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size);
Lev Walkin1715b322013-03-28 04:02:13 -0700133 fprintf(stderr, "Returned code %d, consumed %zd\n",
134 (int)rval.code, rval.consumed);
Lev Walkinf15320b2004-06-03 03:38:44 +0000135
136 assert(rval.code == RC_OK);
137 assert(rval.consumed == consumed);
138
Lev Walkin5b63acf2014-01-14 01:48:37 -0800139 assert(strcmp((char *)tp->a.buf, "=<&>") == 0);
140 assert(strcmp((char *)tp->b.choice.b1.buf, "z") == 0
141 && strcmp((char *)tp->b.choice.b2.buf, "z") == 0);
Lev Walkina9cc46e2004-09-22 16:06:28 +0000142
Lev Walkinc7400c52004-09-29 13:14:36 +0000143 asn_fprint(stderr, &asn_DEF_T, tp);
144 xer_fprint(stderr, &asn_DEF_T, tp);
Lev Walkinf15320b2004-06-03 03:38:44 +0000145}
146
Lev Walkin67c2aec2004-06-05 08:47:18 +0000147size_t buf_pos;
148size_t buf_size;
Lev Walkinf15320b2004-06-03 03:38:44 +0000149uint8_t *buf;
150
151static int
152buf_fill(const void *buffer, size_t size, void *app_key) {
153
Lev Walkin67c2aec2004-06-05 08:47:18 +0000154 (void)app_key;
155
Lev Walkinf15320b2004-06-03 03:38:44 +0000156 if(buf_pos + size > buf_size) {
Lev Walkin1715b322013-03-28 04:02:13 -0700157 fprintf(stderr, "%zd + %zd > %zd\n",
158 buf_pos, size, buf_size);
Lev Walkinf15320b2004-06-03 03:38:44 +0000159 return -1;
160 }
161
162 memcpy(buf + buf_pos, buffer, size);
163 buf_pos += size;
Lev Walkin1715b322013-03-28 04:02:13 -0700164 fprintf(stderr, " written %zd (%zd)\n", size, buf_pos);
Lev Walkinf15320b2004-06-03 03:38:44 +0000165
166 return 0;
167}
168
Lev Walkin6fc56602004-08-20 13:16:42 +0000169static void
Lev Walkin1715b322013-03-28 04:02:13 -0700170compare(T_t *tp, uint8_t *cmp_buf, size_t cmp_buf_size) {
Lev Walkina9cc46e2004-09-22 16:06:28 +0000171 asn_enc_rval_t erval;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800172 size_t i;
Lev Walkinf15320b2004-06-03 03:38:44 +0000173
174 buf_size = cmp_buf_size + 100;
175 buf = alloca(buf_size);
176 buf_pos = 0;
177
178 /*
179 * Try to re-create using DER encoding.
180 */
Lev Walkinc7400c52004-09-29 13:14:36 +0000181 erval = der_encode(&asn_DEF_T, tp, buf_fill, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +0000182 assert(erval.encoded != -1);
Lev Walkin5b63acf2014-01-14 01:48:37 -0800183 if(erval.encoded != (ssize_t)cmp_buf_size) {
Lev Walkin1715b322013-03-28 04:02:13 -0700184 printf("%zd != %zd\n", erval.encoded, cmp_buf_size);
Lev Walkinf15320b2004-06-03 03:38:44 +0000185 }
Lev Walkin5b63acf2014-01-14 01:48:37 -0800186 assert(erval.encoded == (ssize_t)cmp_buf_size);
Lev Walkinf15320b2004-06-03 03:38:44 +0000187 for(i = 0; i < cmp_buf_size; i++) {
188 if(buf[i] != cmp_buf[i]) {
189 fprintf(stderr, "Recreated buffer content mismatch:\n");
190 fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
Lev Walkin5b63acf2014-01-14 01:48:37 -0800191 (int)i,
Lev Walkinf15320b2004-06-03 03:38:44 +0000192 buf[i], cmp_buf[i],
193 buf[i], cmp_buf[i]
194 );
195 }
196 assert(buf[i] == cmp_buf[i]);
197 }
198}
199
200static void
Lev Walkin5b63acf2014-01-14 01:48:37 -0800201partial_read(uint8_t *data, size_t size) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000202 T_t t, *tp;
Lev Walkin90bf7ae2004-10-20 15:46:56 +0000203 asn_dec_rval_t rval;
Lev Walkin67c2aec2004-06-05 08:47:18 +0000204 size_t i1, i2;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800205 uint8_t *data1 = alloca(size);
206 uint8_t *data2 = alloca(size);
207 uint8_t *data3 = alloca(size);
Lev Walkinf15320b2004-06-03 03:38:44 +0000208
209 fprintf(stderr, "\nPartial read sequence...\n");
210
211 /*
212 * Divide the space (size) into three blocks in various combinations:
213 * |<----->i1<----->i2<----->|
Lev Walkin5b63acf2014-01-14 01:48:37 -0800214 * ^ data ^ data+size
Lev Walkinf15320b2004-06-03 03:38:44 +0000215 * Try to read block by block.
216 */
217 for(i1 = 0; i1 < size; i1++) {
218 for(i2 = i1; i2 < size; i2++) {
Lev Walkin5b63acf2014-01-14 01:48:37 -0800219 uint8_t *chunk1 = data;
Lev Walkin67c2aec2004-06-05 08:47:18 +0000220 size_t size1 = i1;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800221 uint8_t *chunk2 = data + size1;
Lev Walkin67c2aec2004-06-05 08:47:18 +0000222 size_t size2 = i2 - i1;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800223 uint8_t *chunk3 = data + size1 + size2;
Lev Walkin67c2aec2004-06-05 08:47:18 +0000224 size_t size3 = size - size1 - size2;
Lev Walkinf15320b2004-06-03 03:38:44 +0000225
Lev Walkin1715b322013-03-28 04:02:13 -0700226 fprintf(stderr, "\n%zd:{%zd, %zd, %zd}...\n",
227 size, size1, size2, size3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000228
Lev Walkin5b63acf2014-01-14 01:48:37 -0800229 memset(data1, 0, size);
230 memset(data2, 0, size);
231 memset(data3, 0, size);
232 memcpy(data1, chunk1, size1);
233 memcpy(data2, chunk2, size2);
234 memcpy(data3, chunk3, size3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000235
236 tp = memset(&t, 0, sizeof(t));
237
Lev Walkin1715b322013-03-28 04:02:13 -0700238 fprintf(stderr, "=> Chunk 1 (%zd):\n", size1);
Lev Walkinc7400c52004-09-29 13:14:36 +0000239 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkin5b63acf2014-01-14 01:48:37 -0800240 data1, size1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000241 assert(rval.code == RC_WMORE);
242 assert(rval.consumed <= size1);
243 if(rval.consumed < size1) {
244 int leftover = size1 - rval.consumed;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800245 memcpy(data2, data1 + rval.consumed, leftover);
246 memcpy(data2 + leftover, chunk2, size2);
Lev Walkinf15320b2004-06-03 03:38:44 +0000247 size2 += leftover;
248 }
249
Lev Walkin1715b322013-03-28 04:02:13 -0700250 fprintf(stderr, "=> Chunk 2 (%zd):\n", size2);
Lev Walkinc7400c52004-09-29 13:14:36 +0000251 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkin5b63acf2014-01-14 01:48:37 -0800252 data2, size2);
Lev Walkinf15320b2004-06-03 03:38:44 +0000253 assert(rval.code == RC_WMORE);
254 assert(rval.consumed <= size2);
255 if(rval.consumed < size2) {
256 int leftover = size2 - rval.consumed;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800257 memcpy(data3, data2 + rval.consumed, leftover);
258 memcpy(data3 + leftover, chunk3, size3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000259 size3 += leftover;
260 }
261
Lev Walkin1715b322013-03-28 04:02:13 -0700262 fprintf(stderr, "=> Chunk 3 (%zd):\n", size3);
Lev Walkinc7400c52004-09-29 13:14:36 +0000263 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkin5b63acf2014-01-14 01:48:37 -0800264 data3, size3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000265 assert(rval.code == RC_OK);
266 assert(rval.consumed == size3);
267
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700268 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkinf15320b2004-06-03 03:38:44 +0000269 }
270 }
271}
272
Lev Walkin2a8672e2004-10-03 09:14:49 +0000273static char xer_buf[128];
Lev Walkin1715b322013-03-28 04:02:13 -0700274static size_t xer_off;
Lev Walkin2a8672e2004-10-03 09:14:49 +0000275
276static int
277xer_cb(const void *buffer, size_t size, void *key) {
278 (void)key;
279 assert(xer_off + size < sizeof(xer_buf));
280 memcpy(xer_buf + xer_off, buffer, size);
281 xer_off += size;
282 return 0;
283}
284
285static void
Lev Walkin5b63acf2014-01-14 01:48:37 -0800286check_xer(uint8_t *data, uint8_t size, char *xer_sample) {
Lev Walkin2a8672e2004-10-03 09:14:49 +0000287 T_t *tp = 0;
Lev Walkin90bf7ae2004-10-20 15:46:56 +0000288 asn_dec_rval_t rval;
Lev Walkin2a8672e2004-10-03 09:14:49 +0000289 asn_enc_rval_t er;
Lev Walkin1715b322013-03-28 04:02:13 -0700290 size_t xer_sample_len = strlen(xer_sample);
Lev Walkin2a8672e2004-10-03 09:14:49 +0000291
Lev Walkin5b63acf2014-01-14 01:48:37 -0800292 rval = ber_decode(0, &asn_DEF_T, (void **)&tp, data, size);
Lev Walkin2a8672e2004-10-03 09:14:49 +0000293 assert(rval.code == RC_OK);
294 assert(rval.consumed == size);
295 assert(tp);
296
297 xer_off = 0;
298 er = xer_encode(&asn_DEF_T, tp, XER_F_CANONICAL, xer_cb, 0);
Lev Walkin2a8672e2004-10-03 09:14:49 +0000299 assert(xer_off);
300 xer_buf[xer_off] = 0;
Lev Walkin1715b322013-03-28 04:02:13 -0700301 printf("[%s] (%zd/%zd) vs [%s] (%zd)\n",
Lev Walkin4a6f3cf2004-10-03 10:54:34 +0000302 xer_buf, er.encoded, xer_off, xer_sample, xer_sample_len);
Lev Walkin5b63acf2014-01-14 01:48:37 -0800303 assert(er.encoded == (ssize_t)xer_off);
Lev Walkin4a6f3cf2004-10-03 10:54:34 +0000304 assert(xer_off == xer_sample_len);
Lev Walkin2a8672e2004-10-03 09:14:49 +0000305 assert(memcmp(xer_buf, xer_sample, xer_off) == 0);
306}
307
308
Lev Walkinf15320b2004-06-03 03:38:44 +0000309int
310main(int ac, char **av) {
311 T_t t;
312
Lev Walkind9bd7752004-06-05 08:17:50 +0000313 (void)ac; /* Unused argument */
314 (void)av; /* Unused argument */
315
Lev Walkinf15320b2004-06-03 03:38:44 +0000316 check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1));
317 compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700318 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin4a6f3cf2004-10-03 10:54:34 +0000319 check_xer(buf1, sizeof(buf1), "<T><c><false/></c><b><b2>z</b2></b><a>=&lt;&amp;&gt;</a><d><r-oid>85.79</r-oid></d></T>");
Lev Walkinf15320b2004-06-03 03:38:44 +0000320
321 check(&t, buf2, sizeof(buf2) + 10, sizeof(buf2));
322 compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700323 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin4a6f3cf2004-10-03 10:54:34 +0000324 check_xer(buf2, sizeof(buf2), "<T><c><true/></c><b><b1>z</b1></b><a>=&lt;&amp;&gt;</a><d><oid>2.1</oid></d></T>");
Lev Walkinf15320b2004-06-03 03:38:44 +0000325
326 /* Split the buffer in parts and check decoder restartability */
327 partial_read(buf1, sizeof(buf1));
328
329 return 0;
330}