blob: 6ff4f9938702bb50185f3730af3ca575ad342fd4 [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 Walkind9bd7752004-06-05 08:17:50 +0000126check(T_t *tp, uint8_t *buf, int 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 Walkinb4eb8b52004-08-16 07:02:39 +0000131 fprintf(stderr, "Buf %p (%d)\n", buf, (int)size);
Lev Walkinc7400c52004-09-29 13:14:36 +0000132 rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size);
Lev Walkinf15320b2004-06-03 03:38:44 +0000133 fprintf(stderr, "Returned code %d, consumed %d\n",
134 (int)rval.code, (int)rval.consumed);
135
136 assert(rval.code == RC_OK);
137 assert(rval.consumed == consumed);
138
Lev Walkin4a6f3cf2004-10-03 10:54:34 +0000139 assert(strcmp(tp->a.buf, "=<&>") == 0);
Lev Walkinf15320b2004-06-03 03:38:44 +0000140 assert(strcmp(tp->b.choice.b1.buf, "z") == 0
141 && strcmp(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 Walkinb4eb8b52004-08-16 07:02:39 +0000157 fprintf(stderr, "%d + %d > %d\n",
158 (int)buf_pos, (int)size, (int)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 Walkinb4eb8b52004-08-16 07:02:39 +0000164 fprintf(stderr, " written %d (%d)\n", (int)size, (int)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 Walkinf15320b2004-06-03 03:38:44 +0000170compare(T_t *tp, uint8_t *cmp_buf, int cmp_buf_size) {
Lev Walkina9cc46e2004-09-22 16:06:28 +0000171 asn_enc_rval_t erval;
Lev Walkinf15320b2004-06-03 03:38:44 +0000172 int i;
173
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);
183 if(erval.encoded != cmp_buf_size) {
184 printf("%d != %d\n", erval.encoded, cmp_buf_size);
185 }
186 assert(erval.encoded == cmp_buf_size);
187 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",
191 i,
192 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 Walkin67c2aec2004-06-05 08:47:18 +0000201partial_read(uint8_t *buf, 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 Walkinf15320b2004-06-03 03:38:44 +0000205 uint8_t *buf1 = alloca(size);
206 uint8_t *buf2 = alloca(size);
207 uint8_t *buf3 = alloca(size);
208
209 fprintf(stderr, "\nPartial read sequence...\n");
210
211 /*
212 * Divide the space (size) into three blocks in various combinations:
213 * |<----->i1<----->i2<----->|
Lev Walkin2a8672e2004-10-03 09:14:49 +0000214 * ^ buf ^ buf+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++) {
219 uint8_t *chunk1 = buf;
Lev Walkin67c2aec2004-06-05 08:47:18 +0000220 size_t size1 = i1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000221 uint8_t *chunk2 = buf + size1;
Lev Walkin67c2aec2004-06-05 08:47:18 +0000222 size_t size2 = i2 - i1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000223 uint8_t *chunk3 = buf + size1 + size2;
Lev Walkin67c2aec2004-06-05 08:47:18 +0000224 size_t size3 = size - size1 - size2;
Lev Walkinf15320b2004-06-03 03:38:44 +0000225
226 fprintf(stderr, "\n%d:{%d, %d, %d}...\n",
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000227 (int)size, (int)size1, (int)size2, (int)size3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000228
229 memset(buf1, 0, size);
230 memset(buf2, 0, size);
231 memset(buf3, 0, size);
232 memcpy(buf1, chunk1, size1);
233 memcpy(buf2, chunk2, size2);
234 memcpy(buf3, chunk3, size3);
235
236 tp = memset(&t, 0, sizeof(t));
237
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000238 fprintf(stderr, "=> Chunk 1 (%d):\n", (int)size1);
Lev Walkinc7400c52004-09-29 13:14:36 +0000239 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkinf15320b2004-06-03 03:38:44 +0000240 buf1, size1);
241 assert(rval.code == RC_WMORE);
242 assert(rval.consumed <= size1);
243 if(rval.consumed < size1) {
244 int leftover = size1 - rval.consumed;
245 memcpy(buf2, buf1 + rval.consumed, leftover);
246 memcpy(buf2 + leftover, chunk2, size2);
247 size2 += leftover;
248 }
249
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000250 fprintf(stderr, "=> Chunk 2 (%d):\n", (int)size2);
Lev Walkinc7400c52004-09-29 13:14:36 +0000251 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkinf15320b2004-06-03 03:38:44 +0000252 buf2, size2);
253 assert(rval.code == RC_WMORE);
254 assert(rval.consumed <= size2);
255 if(rval.consumed < size2) {
256 int leftover = size2 - rval.consumed;
257 memcpy(buf3, buf2 + rval.consumed, leftover);
258 memcpy(buf3 + leftover, chunk3, size3);
259 size3 += leftover;
260 }
261
Lev Walkinb4eb8b52004-08-16 07:02:39 +0000262 fprintf(stderr, "=> Chunk 3 (%d):\n", (int)size3);
Lev Walkinc7400c52004-09-29 13:14:36 +0000263 rval = ber_decode(0, &asn_DEF_T, (void **)&tp,
Lev Walkinf15320b2004-06-03 03:38:44 +0000264 buf3, size3);
265 assert(rval.code == RC_OK);
266 assert(rval.consumed == size3);
267
Lev Walkinc7400c52004-09-29 13:14:36 +0000268 asn_DEF_T.free_struct(&asn_DEF_T, &t, 1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000269 }
270 }
271}
272
Lev Walkin2a8672e2004-10-03 09:14:49 +0000273static char xer_buf[128];
274static int xer_off;
275
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
286check_xer(uint8_t *buf, uint8_t size, char *xer_sample) {
287 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;
290 int xer_sample_len = strlen(xer_sample);
291
292 rval = ber_decode(0, &asn_DEF_T, (void **)&tp, buf, size);
293 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 Walkin4a6f3cf2004-10-03 10:54:34 +0000301 printf("[%s] (%d/%d) vs [%s] (%d)\n",
302 xer_buf, er.encoded, xer_off, xer_sample, xer_sample_len);
303 assert(er.encoded == xer_off);
304 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 Walkinc7400c52004-09-29 13:14:36 +0000318 asn_DEF_T.free_struct(&asn_DEF_T, &t, 1);
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 Walkinc7400c52004-09-29 13:14:36 +0000323 asn_DEF_T.free_struct(&asn_DEF_T, &t, 1);
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}