blob: 0b815577ef7b7df8620f2d920845385395b534cf [file] [log] [blame]
Ron Shacham0eba05c2020-05-08 15:13:19 -04001/*
2 * Copyright (c) 2004-2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
4 */
5#include <asn_internal.h>
6#include <ANY.h>
7#include <errno.h>
8
9asn_OCTET_STRING_specifics_t asn_SPC_ANY_specs = {
10 sizeof(ANY_t),
11 offsetof(ANY_t, _asn_ctx),
12 ASN_OSUBV_ANY
13};
14asn_TYPE_operation_t asn_OP_ANY = {
15 OCTET_STRING_free,
16 OCTET_STRING_print,
17 OCTET_STRING_compare,
18 OCTET_STRING_decode_ber,
19 OCTET_STRING_encode_der,
20 OCTET_STRING_decode_xer_hex,
21 ANY_encode_xer,
22#ifdef ASN_DISABLE_OER_SUPPORT
23 0,
24 0,
25#else
26 0,
27 0,
28#endif /* ASN_DISABLE_OER_SUPPORT */
29#ifdef ASN_DISABLE_PER_SUPPORT
30 0, 0, 0, 0,
31#else
32 ANY_decode_uper,
33 ANY_encode_uper,
34 ANY_decode_aper,
35 ANY_encode_aper,
36#endif /* ASN_DISABLE_PER_SUPPORT */
37 0, /* Random fill is not defined for ANY type */
38 0 /* Use generic outmost tag fetcher */
39};
40asn_TYPE_descriptor_t asn_DEF_ANY = {
41 "ANY",
42 "ANY",
43 &asn_OP_ANY,
44 0, 0, 0, 0,
45 { 0, 0, asn_generic_no_constraint }, /* No constraints */
46 0, 0, /* No members */
47 &asn_SPC_ANY_specs,
48};
49
50#undef RETURN
51#define RETURN(_code) \
52 do { \
53 asn_dec_rval_t tmprval; \
54 tmprval.code = _code; \
55 tmprval.consumed = consumed_myself; \
56 return tmprval; \
57 } while(0)
58
59asn_enc_rval_t
60ANY_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
61 enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb,
62 void *app_key) {
63 if(flags & XER_F_CANONICAL) {
64 /*
65 * Canonical XER-encoding of ANY type is not supported.
66 */
67 ASN__ENCODE_FAILED;
68 }
69
70 /* Dump as binary */
71 return OCTET_STRING_encode_xer(td, sptr, ilevel, flags, cb, app_key);
72}
73
74struct _callback_arg {
75 uint8_t *buffer;
76 size_t offset;
77 size_t size;
78};
79
80static int ANY__consume_bytes(const void *buffer, size_t size, void *key);
81
82int
83ANY_fromType(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
84 struct _callback_arg arg;
85 asn_enc_rval_t erval = {0,0,0};
86
87 if(!st || !td) {
88 errno = EINVAL;
89 return -1;
90 }
91
92 if(!sptr) {
93 if(st->buf) FREEMEM(st->buf);
94 st->size = 0;
95 return 0;
96 }
97
98 arg.offset = arg.size = 0;
99 arg.buffer = 0;
100
101 erval = der_encode(td, sptr, ANY__consume_bytes, &arg);
102 if(erval.encoded == -1) {
103 if(arg.buffer) FREEMEM(arg.buffer);
104 return -1;
105 }
106 assert((size_t)erval.encoded == arg.offset);
107
108 if(st->buf) FREEMEM(st->buf);
109 st->buf = arg.buffer;
110 st->size = arg.offset;
111
112 return 0;
113}
114
115int
116ANY_fromType_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void *sptr) {
117 uint8_t *buffer = NULL;
118 ssize_t erval;
119
120 if(!st || !td) {
121 errno = EINVAL;
122 return -1;
123 }
124
125 if(!sptr) {
126 if(st->buf) FREEMEM(st->buf);
127 st->size = 0;
128 return 0;
129 }
130
131 erval = aper_encode_to_new_buffer(td, td->encoding_constraints.per_constraints, sptr, (void**)&buffer);
132
133 if(erval == -1) {
134 if(buffer) FREEMEM(buffer);
135 return -1;
136 }
137 assert((size_t)erval > 0);
138
139 if(st->buf) FREEMEM(st->buf);
140 st->buf = buffer;
141 st->size = erval;
142
143 return 0;
144}
145
146ANY_t *
147ANY_new_fromType(asn_TYPE_descriptor_t *td, void *sptr) {
148 ANY_t tmp;
149 ANY_t *st;
150
151 if(!td || !sptr) {
152 errno = EINVAL;
153 return 0;
154 }
155
156 memset(&tmp, 0, sizeof(tmp));
157
158 if(ANY_fromType(&tmp, td, sptr)) return 0;
159
160 st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
161 if(st) {
162 *st = tmp;
163 return st;
164 } else {
165 FREEMEM(tmp.buf);
166 return 0;
167 }
168}
169
170ANY_t *
171ANY_new_fromType_aper(asn_TYPE_descriptor_t *td, void *sptr) {
172 ANY_t tmp;
173 ANY_t *st;
174
175 if(!td || !sptr) {
176 errno = EINVAL;
177 return 0;
178 }
179
180 memset(&tmp, 0, sizeof(tmp));
181
182 if(ANY_fromType_aper(&tmp, td, sptr)) return 0;
183
184 st = (ANY_t *)CALLOC(1, sizeof(ANY_t));
185 if(st) {
186 *st = tmp;
187 return st;
188 } else {
189 FREEMEM(tmp.buf);
190 return 0;
191 }
192}
193
194int
195ANY_to_type(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
196 asn_dec_rval_t rval;
197 void *newst = 0;
198
199 if(!st || !td || !struct_ptr) {
200 errno = EINVAL;
201 return -1;
202 }
203
204 if(st->buf == 0) {
205 /* Nothing to convert, make it empty. */
206 *struct_ptr = (void *)0;
207 return 0;
208 }
209
210 rval = ber_decode(0, td, (void **)&newst, st->buf, st->size);
211 if(rval.code == RC_OK) {
212 *struct_ptr = newst;
213 return 0;
214 } else {
215 /* Remove possibly partially decoded data. */
216 ASN_STRUCT_FREE(*td, newst);
217 return -1;
218 }
219}
220
221int
222ANY_to_type_aper(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
223 asn_dec_rval_t rval;
224 void *newst = 0;
225
226 if(!st || !td || !struct_ptr) {
227 errno = EINVAL;
228 return -1;
229 }
230
231 if(st->buf == 0) {
232 /* Nothing to convert, make it empty. */
233 *struct_ptr = (void *)0;
234 return 0;
235 }
236
237 rval = aper_decode(0, td, (void **)&newst, st->buf, st->size, 0, 0);
238 if(rval.code == RC_OK) {
239 *struct_ptr = newst;
240 return 0;
241 } else {
242 /* Remove possibly partially decoded data. */
243 ASN_STRUCT_FREE(*td, newst);
244 return -1;
245 }
246}
247
248static int ANY__consume_bytes(const void *buffer, size_t size, void *key) {
249 struct _callback_arg *arg = (struct _callback_arg *)key;
250
251 if((arg->offset + size) >= arg->size) {
252 size_t nsize = (arg->size ? arg->size << 2 : 16) + size;
253 void *p = REALLOC(arg->buffer, nsize);
254 if(!p) return -1;
255 arg->buffer = (uint8_t *)p;
256 arg->size = nsize;
257 }
258
259 memcpy(arg->buffer + arg->offset, buffer, size);
260 arg->offset += size;
261 assert(arg->offset < arg->size);
262
263 return 0;
264}
265
266#ifndef ASN_DISABLE_PER_SUPPORT
267
268asn_dec_rval_t
269ANY_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
270 const asn_TYPE_descriptor_t *td,
271 const asn_per_constraints_t *constraints, void **sptr,
272 asn_per_data_t *pd) {
273 const asn_OCTET_STRING_specifics_t *specs =
274 td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
275 : &asn_SPC_ANY_specs;
276 size_t consumed_myself = 0;
277 int repeat;
278 ANY_t *st = (ANY_t *)*sptr;
279
280 (void)opt_codec_ctx;
281 (void)constraints;
282
283 /*
284 * Allocate the structure.
285 */
286 if(!st) {
287 st = (ANY_t *)(*sptr = CALLOC(1, specs->struct_size));
288 if(!st) RETURN(RC_FAIL);
289 }
290
291 ASN_DEBUG("UPER Decoding ANY type");
292
293 st->size = 0;
294 do {
295 ssize_t raw_len;
296 ssize_t len_bytes;
297 ssize_t len_bits;
298 void *p;
299 int ret;
300
301 /* Get the PER length */
302 raw_len = uper_get_length(pd, -1, 0, &repeat);
303 if(raw_len < 0) RETURN(RC_WMORE);
304 if(raw_len == 0 && st->buf) break;
305
306 ASN_DEBUG("Got PER length len %" ASN_PRI_SIZE ", %s (%s)", raw_len,
307 repeat ? "repeat" : "once", td->name);
308 len_bytes = raw_len;
309 len_bits = len_bytes * 8;
310
311 p = REALLOC(st->buf, st->size + len_bytes + 1);
312 if(!p) RETURN(RC_FAIL);
313 st->buf = (uint8_t *)p;
314
315 ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
316 if(ret < 0) RETURN(RC_WMORE);
317 consumed_myself += len_bits;
318 st->size += len_bytes;
319 } while(repeat);
320 st->buf[st->size] = 0; /* nul-terminate */
321
322 RETURN(RC_OK);
323}
324
325asn_enc_rval_t
326ANY_encode_uper(const asn_TYPE_descriptor_t *td,
327 const asn_per_constraints_t *constraints, const void *sptr,
328 asn_per_outp_t *po) {
329 const ANY_t *st = (const ANY_t *)sptr;
330 asn_enc_rval_t er = {0, 0, 0};
331 const uint8_t *buf;
332 size_t size;
333 int ret;
334
335 (void)constraints;
336
337 if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED;
338
339 buf = st->buf;
340 size = st->size;
341 do {
342 int need_eom = 0;
343 ssize_t may_save = uper_put_length(po, size, &need_eom);
344 if(may_save < 0) ASN__ENCODE_FAILED;
345
346 ret = per_put_many_bits(po, buf, may_save * 8);
347 if(ret) ASN__ENCODE_FAILED;
348
349 buf += may_save;
350 size -= may_save;
351 assert(!(may_save & 0x07) || !size);
352 if(need_eom && uper_put_length(po, 0, 0))
353 ASN__ENCODE_FAILED; /* End of Message length */
354 } while(size);
355
356 ASN__ENCODED_OK(er);
357}
358
359asn_dec_rval_t
360ANY_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
361 const asn_TYPE_descriptor_t *td,
362 const asn_per_constraints_t *constraints, void **sptr,
363 asn_per_data_t *pd) {
364 const asn_OCTET_STRING_specifics_t *specs =
365 td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
366 : &asn_SPC_ANY_specs;
367 size_t consumed_myself = 0;
368 int repeat;
369 ANY_t *st = (ANY_t *)*sptr;
370
371 (void)opt_codec_ctx;
372 (void)constraints;
373
374 /*
375 * Allocate the structure.
376 */
377 if(!st) {
378 st = (ANY_t *)(*sptr = CALLOC(1, specs->struct_size));
379 if(!st) RETURN(RC_FAIL);
380 }
381
382 ASN_DEBUG("APER Decoding ANY type");
383
384 st->size = 0;
385 do {
386 ssize_t raw_len;
387 ssize_t len_bytes;
388 ssize_t len_bits;
389 void *p;
390 int ret;
391
392 /* Get the PER length */
393 raw_len = aper_get_length(pd, -1, 0, &repeat);
394 if(raw_len < 0) RETURN(RC_WMORE);
395 if(raw_len == 0 && st->buf) break;
396
397 ASN_DEBUG("Got PER length len %" ASN_PRI_SIZE ", %s (%s)", raw_len,
398 repeat ? "repeat" : "once", td->name);
399 len_bytes = raw_len;
400 len_bits = len_bytes * 8;
401
402 p = REALLOC(st->buf, st->size + len_bytes + 1);
403 if(!p) RETURN(RC_FAIL);
404 st->buf = (uint8_t *)p;
405
406 ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
407 if(ret < 0) RETURN(RC_WMORE);
408 consumed_myself += len_bits;
409 st->size += len_bytes;
410 } while(repeat);
411 st->buf[st->size] = 0; /* nul-terminate */
412
413 RETURN(RC_OK);
414}
415
416asn_enc_rval_t
417ANY_encode_aper(const asn_TYPE_descriptor_t *td,
418 const asn_per_constraints_t *constraints, const void *sptr,
419 asn_per_outp_t *po) {
420 const ANY_t *st = (const ANY_t *)sptr;
421 asn_enc_rval_t er = {0, 0, 0};
422 const uint8_t *buf;
423 size_t size;
424 int ret;
425
426 (void)constraints;
427
428 if(!st || (!st->buf && st->size)) ASN__ENCODE_FAILED;
429
430 buf = st->buf;
431 size = st->size;
432 do {
433 int need_eom = 0;
434 ssize_t may_save = uper_put_length(po, size, &need_eom);
435 if(may_save < 0) ASN__ENCODE_FAILED;
436
437 ret = per_put_many_bits(po, buf, may_save * 8);
438 if(ret) ASN__ENCODE_FAILED;
439
440 buf += may_save;
441 size -= may_save;
442 assert(!(may_save & 0x07) || !size);
443 if(need_eom && uper_put_length(po, 0, 0))
444 ASN__ENCODE_FAILED; /* End of Message length */
445 } while(size);
446
447 ASN__ENCODED_OK(er);
448}
449#endif /* ASN_DISABLE_PER_SUPPORT */
450