blob: 6f1fcc86a2e61641a2959345f551bb93a0918e04 [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;
Lev Walkina4f8e942017-10-08 19:28:20 -0700175 uint8_t scratch[buf_size];
176 buf = scratch;
Lev Walkinf15320b2004-06-03 03:38:44 +0000177 buf_pos = 0;
178
179 /*
180 * Try to re-create using DER encoding.
181 */
Lev Walkinc7400c52004-09-29 13:14:36 +0000182 erval = der_encode(&asn_DEF_T, tp, buf_fill, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +0000183 assert(erval.encoded != -1);
Lev Walkin5b63acf2014-01-14 01:48:37 -0800184 if(erval.encoded != (ssize_t)cmp_buf_size) {
Lev Walkin1715b322013-03-28 04:02:13 -0700185 printf("%zd != %zd\n", erval.encoded, cmp_buf_size);
Lev Walkinf15320b2004-06-03 03:38:44 +0000186 }
Lev Walkin5b63acf2014-01-14 01:48:37 -0800187 assert(erval.encoded == (ssize_t)cmp_buf_size);
Lev Walkinf15320b2004-06-03 03:38:44 +0000188 for(i = 0; i < cmp_buf_size; i++) {
189 if(buf[i] != cmp_buf[i]) {
190 fprintf(stderr, "Recreated buffer content mismatch:\n");
191 fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n",
Lev Walkin5b63acf2014-01-14 01:48:37 -0800192 (int)i,
Lev Walkinf15320b2004-06-03 03:38:44 +0000193 buf[i], cmp_buf[i],
194 buf[i], cmp_buf[i]
195 );
196 }
197 assert(buf[i] == cmp_buf[i]);
198 }
199}
200
201static void
Lev Walkin5b63acf2014-01-14 01:48:37 -0800202partial_read(uint8_t *data, size_t size) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000203 T_t t, *tp;
Lev Walkin90bf7ae2004-10-20 15:46:56 +0000204 asn_dec_rval_t rval;
Lev Walkin67c2aec2004-06-05 08:47:18 +0000205 size_t i1, i2;
Lev Walkina4f8e942017-10-08 19:28:20 -0700206 uint8_t data1[size];
207 uint8_t data2[size];
208 uint8_t data3[size];
Lev Walkinf15320b2004-06-03 03:38:44 +0000209
210 fprintf(stderr, "\nPartial read sequence...\n");
211
212 /*
213 * Divide the space (size) into three blocks in various combinations:
214 * |<----->i1<----->i2<----->|
Lev Walkin5b63acf2014-01-14 01:48:37 -0800215 * ^ data ^ data+size
Lev Walkinf15320b2004-06-03 03:38:44 +0000216 * Try to read block by block.
217 */
218 for(i1 = 0; i1 < size; i1++) {
219 for(i2 = i1; i2 < size; i2++) {
Lev Walkin5b63acf2014-01-14 01:48:37 -0800220 uint8_t *chunk1 = data;
Lev Walkin67c2aec2004-06-05 08:47:18 +0000221 size_t size1 = i1;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800222 uint8_t *chunk2 = data + size1;
Lev Walkin67c2aec2004-06-05 08:47:18 +0000223 size_t size2 = i2 - i1;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800224 uint8_t *chunk3 = data + size1 + size2;
Lev Walkin67c2aec2004-06-05 08:47:18 +0000225 size_t size3 = size - size1 - size2;
Lev Walkinf15320b2004-06-03 03:38:44 +0000226
Lev Walkin1715b322013-03-28 04:02:13 -0700227 fprintf(stderr, "\n%zd:{%zd, %zd, %zd}...\n",
228 size, size1, size2, size3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000229
Lev Walkin5b63acf2014-01-14 01:48:37 -0800230 memset(data1, 0, size);
231 memset(data2, 0, size);
232 memset(data3, 0, size);
233 memcpy(data1, chunk1, size1);
234 memcpy(data2, chunk2, size2);
235 memcpy(data3, chunk3, size3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000236
237 tp = memset(&t, 0, sizeof(t));
238
Lev Walkin1715b322013-03-28 04:02:13 -0700239 fprintf(stderr, "=> Chunk 1 (%zd):\n", size1);
Lev Walkinc7400c52004-09-29 13:14:36 +0000240 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkin5b63acf2014-01-14 01:48:37 -0800241 data1, size1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000242 assert(rval.code == RC_WMORE);
243 assert(rval.consumed <= size1);
244 if(rval.consumed < size1) {
245 int leftover = size1 - rval.consumed;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800246 memcpy(data2, data1 + rval.consumed, leftover);
247 memcpy(data2 + leftover, chunk2, size2);
Lev Walkinf15320b2004-06-03 03:38:44 +0000248 size2 += leftover;
249 }
250
Lev Walkin1715b322013-03-28 04:02:13 -0700251 fprintf(stderr, "=> Chunk 2 (%zd):\n", size2);
Lev Walkinc7400c52004-09-29 13:14:36 +0000252 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkin5b63acf2014-01-14 01:48:37 -0800253 data2, size2);
Lev Walkinf15320b2004-06-03 03:38:44 +0000254 assert(rval.code == RC_WMORE);
255 assert(rval.consumed <= size2);
256 if(rval.consumed < size2) {
257 int leftover = size2 - rval.consumed;
Lev Walkin5b63acf2014-01-14 01:48:37 -0800258 memcpy(data3, data2 + rval.consumed, leftover);
259 memcpy(data3 + leftover, chunk3, size3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000260 size3 += leftover;
261 }
262
Lev Walkin1715b322013-03-28 04:02:13 -0700263 fprintf(stderr, "=> Chunk 3 (%zd):\n", size3);
Lev Walkinc7400c52004-09-29 13:14:36 +0000264 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkin5b63acf2014-01-14 01:48:37 -0800265 data3, size3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000266 assert(rval.code == RC_OK);
267 assert(rval.consumed == size3);
268
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700269 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkinf15320b2004-06-03 03:38:44 +0000270 }
271 }
272}
273
Lev Walkin2a8672e2004-10-03 09:14:49 +0000274static char xer_buf[128];
Lev Walkin1715b322013-03-28 04:02:13 -0700275static size_t xer_off;
Lev Walkin2a8672e2004-10-03 09:14:49 +0000276
277static int
278xer_cb(const void *buffer, size_t size, void *key) {
279 (void)key;
280 assert(xer_off + size < sizeof(xer_buf));
281 memcpy(xer_buf + xer_off, buffer, size);
282 xer_off += size;
283 return 0;
284}
285
286static void
Lev Walkin5b63acf2014-01-14 01:48:37 -0800287check_xer(uint8_t *data, uint8_t size, char *xer_sample) {
Lev Walkin2a8672e2004-10-03 09:14:49 +0000288 T_t *tp = 0;
Lev Walkin90bf7ae2004-10-20 15:46:56 +0000289 asn_dec_rval_t rval;
Lev Walkin2a8672e2004-10-03 09:14:49 +0000290 asn_enc_rval_t er;
Lev Walkin1715b322013-03-28 04:02:13 -0700291 size_t xer_sample_len = strlen(xer_sample);
Lev Walkin2a8672e2004-10-03 09:14:49 +0000292
Lev Walkin5b63acf2014-01-14 01:48:37 -0800293 rval = ber_decode(0, &asn_DEF_T, (void **)&tp, data, size);
Lev Walkin2a8672e2004-10-03 09:14:49 +0000294 assert(rval.code == RC_OK);
295 assert(rval.consumed == size);
296 assert(tp);
297
298 xer_off = 0;
299 er = xer_encode(&asn_DEF_T, tp, XER_F_CANONICAL, xer_cb, 0);
Lev Walkin2a8672e2004-10-03 09:14:49 +0000300 assert(xer_off);
301 xer_buf[xer_off] = 0;
Lev Walkin1715b322013-03-28 04:02:13 -0700302 printf("[%s] (%zd/%zd) vs [%s] (%zd)\n",
Lev Walkin4a6f3cf2004-10-03 10:54:34 +0000303 xer_buf, er.encoded, xer_off, xer_sample, xer_sample_len);
Lev Walkin5b63acf2014-01-14 01:48:37 -0800304 assert(er.encoded == (ssize_t)xer_off);
Lev Walkin4a6f3cf2004-10-03 10:54:34 +0000305 assert(xer_off == xer_sample_len);
Lev Walkin2a8672e2004-10-03 09:14:49 +0000306 assert(memcmp(xer_buf, xer_sample, xer_off) == 0);
Vasil Velichkovcef21e02017-10-09 23:40:17 +0300307
308 ASN_STRUCT_FREE(asn_DEF_T, tp);
Lev Walkin2a8672e2004-10-03 09:14:49 +0000309}
310
311
Lev Walkinf15320b2004-06-03 03:38:44 +0000312int
313main(int ac, char **av) {
314 T_t t;
315
Lev Walkind9bd7752004-06-05 08:17:50 +0000316 (void)ac; /* Unused argument */
317 (void)av; /* Unused argument */
318
Lev Walkinf15320b2004-06-03 03:38:44 +0000319 check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1));
320 compare(&t, buf1_reconstr, sizeof(buf1_reconstr));
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700321 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin4a6f3cf2004-10-03 10:54:34 +0000322 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 +0000323
324 check(&t, buf2, sizeof(buf2) + 10, sizeof(buf2));
325 compare(&t, buf2_reconstr, sizeof(buf2_reconstr));
Lev Walkin8d99d7b2017-08-25 01:06:00 -0700326 ASN_STRUCT_RESET(asn_DEF_T, &t);
Lev Walkin4a6f3cf2004-10-03 10:54:34 +0000327 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 +0000328
329 /* Split the buffer in parts and check decoder restartability */
330 partial_read(buf1, sizeof(buf1));
331
332 return 0;
333}