Change version after creation of r2 branch
[ric-plt/resource-status-manager.git] / RSM / 3rdparty / asn1codec / e2ap_engine / OCTET_STRING.c
1
2 /*-
3  * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>.
4  * All rights reserved.
5  * Redistribution and modifications are permitted subject to BSD license.
6  */
7 #include <asn_internal.h>
8 #include <OCTET_STRING.h>
9 #include <BIT_STRING.h> /* for .bits_unused member */
10 #include <errno.h>
11
12 /*
13  * OCTET STRING basic type description.
14  */
15 static const ber_tlv_tag_t asn_DEF_OCTET_STRING_tags[] = {
16         (ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
17 };
18 asn_OCTET_STRING_specifics_t asn_SPC_OCTET_STRING_specs = {
19         sizeof(OCTET_STRING_t),
20         offsetof(OCTET_STRING_t, _asn_ctx),
21         ASN_OSUBV_STR
22 };
23
24 asn_TYPE_operation_t asn_OP_OCTET_STRING = {
25         OCTET_STRING_free,
26         OCTET_STRING_print,     /* OCTET STRING generally means a non-ascii sequence */
27         OCTET_STRING_compare,
28         OCTET_STRING_decode_ber,
29         OCTET_STRING_encode_der,
30         OCTET_STRING_decode_xer_hex,
31         OCTET_STRING_encode_xer,
32 #ifdef  ASN_DISABLE_OER_SUPPORT
33         0,
34         0,
35 #else
36         OCTET_STRING_decode_oer,
37         OCTET_STRING_encode_oer,
38 #endif  /* ASN_DISABLE_OER_SUPPORT */
39 #ifdef  ASN_DISABLE_PER_SUPPORT
40         0,
41         0,
42         0,
43         0,
44 #else
45         OCTET_STRING_decode_uper,       /* Unaligned PER decoder */
46         OCTET_STRING_encode_uper,       /* Unaligned PER encoder */
47         OCTET_STRING_decode_aper,       /* Aligned PER decoder */
48         OCTET_STRING_encode_aper,       /* Aligned PER encoder */
49 #endif  /* ASN_DISABLE_PER_SUPPORT */
50         OCTET_STRING_random_fill,
51         0       /* Use generic outmost tag fetcher */
52 };
53 asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
54         "OCTET STRING",         /* Canonical name */
55         "OCTET_STRING",         /* XML tag name */
56         &asn_OP_OCTET_STRING,
57         asn_DEF_OCTET_STRING_tags,
58         sizeof(asn_DEF_OCTET_STRING_tags)
59           / sizeof(asn_DEF_OCTET_STRING_tags[0]),
60         asn_DEF_OCTET_STRING_tags,      /* Same as above */
61         sizeof(asn_DEF_OCTET_STRING_tags)
62           / sizeof(asn_DEF_OCTET_STRING_tags[0]),
63         { 0, 0, asn_generic_no_constraint },
64         0, 0,   /* No members */
65         &asn_SPC_OCTET_STRING_specs
66 };
67
68 #undef  _CH_PHASE
69 #undef  NEXT_PHASE
70 #undef  PREV_PHASE
71 #define _CH_PHASE(ctx, inc) do {                                        \
72                 if(ctx->phase == 0)                                     \
73                         ctx->context = 0;                               \
74                 ctx->phase += inc;                                      \
75         } while(0)
76 #define NEXT_PHASE(ctx) _CH_PHASE(ctx, +1)
77 #define PREV_PHASE(ctx) _CH_PHASE(ctx, -1)
78
79 #undef  ADVANCE
80 #define ADVANCE(num_bytes)      do {                                    \
81                 size_t num = (num_bytes);                               \
82                 buf_ptr = ((const char *)buf_ptr) + num;                \
83                 size -= num;                                            \
84                 consumed_myself += num;                                 \
85         } while(0)
86
87 #undef  RETURN
88 #define RETURN(_code)   do {                                            \
89                 asn_dec_rval_t tmprval;                                 \
90                 tmprval.code = _code;                                   \
91                 tmprval.consumed = consumed_myself;                     \
92                 return tmprval;                                         \
93         } while(0)
94
95 #undef  APPEND
96 #define APPEND(bufptr, bufsize) do {                                    \
97                 size_t _bs = (bufsize);         /* Append size */       \
98                 size_t _ns = ctx->context;      /* Allocated now */     \
99                 size_t _es = st->size + _bs;    /* Expected size */     \
100                 /* int is really a typeof(st->size): */                 \
101                 if((int)_es < 0) RETURN(RC_FAIL);                       \
102                 if(_ns <= _es) {                                        \
103                         void *ptr;                                      \
104                         /* Be nice and round to the memory allocator */ \
105                         do { _ns = _ns ? _ns << 1 : 16; }               \
106                             while(_ns <= _es);                          \
107                         /* int is really a typeof(st->size): */         \
108                         if((int)_ns < 0) RETURN(RC_FAIL);               \
109                         ptr = REALLOC(st->buf, _ns);                    \
110                         if(ptr) {                                       \
111                                 st->buf = (uint8_t *)ptr;               \
112                                 ctx->context = _ns;                     \
113                         } else {                                        \
114                                 RETURN(RC_FAIL);                        \
115                         }                                               \
116                         ASN_DEBUG("Reallocating into %ld", (long)_ns);  \
117                 }                                                       \
118                 memcpy(st->buf + st->size, bufptr, _bs);                \
119                 /* Convenient nul-termination */                        \
120                 st->buf[_es] = '\0';                                    \
121                 st->size = _es;                                         \
122         } while(0)
123
124 /*
125  * The main reason why ASN.1 is still alive is that too much time and effort
126  * is necessary for learning it more or less adequately, thus creating a gut
127  * necessity to demonstrate that aquired skill everywhere afterwards.
128  * No, I am not going to explain what the following stuff is.
129  */
130 struct _stack_el {
131     ber_tlv_len_t left;     /* What's left to read (or -1) */
132     ber_tlv_len_t got;      /* What was actually processed */
133     unsigned cont_level;    /* Depth of subcontainment */
134     int want_nulls;         /* Want null "end of content" octets? */
135     int bits_chopped;       /* Flag in BIT STRING mode */
136     ber_tlv_tag_t tag;      /* For debugging purposes */
137     struct _stack_el *prev;
138     struct _stack_el *next;
139 };
140 struct _stack {
141         struct _stack_el *tail;
142         struct _stack_el *cur_ptr;
143 };
144
145 static struct _stack_el *
146 OS__add_stack_el(struct _stack *st) {
147         struct _stack_el *nel;
148
149         /*
150          * Reuse the old stack frame or allocate a new one.
151          */
152         if(st->cur_ptr && st->cur_ptr->next) {
153                 nel = st->cur_ptr->next;
154                 nel->bits_chopped = 0;
155                 nel->got = 0;
156                 /* Retain the nel->cont_level, it's correct. */
157         } else {
158                 nel = (struct _stack_el *)CALLOC(1, sizeof(struct _stack_el));
159                 if(nel == NULL)
160                         return NULL;
161         
162                 if(st->tail) {
163                         /* Increase a subcontainment depth */
164                         nel->cont_level = st->tail->cont_level + 1;
165                         st->tail->next = nel;
166                 }
167                 nel->prev = st->tail;
168                 st->tail = nel;
169         }
170
171         st->cur_ptr = nel;
172
173         return nel;
174 }
175
176 static struct _stack *
177 _new_stack(void) {
178         return (struct _stack *)CALLOC(1, sizeof(struct _stack));
179 }
180
181 /*
182  * Decode OCTET STRING type.
183  */
184 asn_dec_rval_t
185 OCTET_STRING_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
186                         const asn_TYPE_descriptor_t *td, void **sptr,
187                         const void *buf_ptr, size_t size, int tag_mode) {
188     const asn_OCTET_STRING_specifics_t *specs = td->specifics
189                                 ? (const asn_OCTET_STRING_specifics_t *)td->specifics
190                                 : &asn_SPC_OCTET_STRING_specs;
191         BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
192         asn_dec_rval_t rval;
193         asn_struct_ctx_t *ctx;
194         ssize_t consumed_myself = 0;
195         struct _stack *stck;            /* Expectations stack structure */
196         struct _stack_el *sel = 0;      /* Stack element */
197         int tlv_constr;
198         enum asn_OS_Subvariant type_variant = specs->subvariant;
199
200         ASN_DEBUG("Decoding %s as %s (frame %ld)",
201                 td->name,
202                 (type_variant == ASN_OSUBV_STR) ?
203                         "OCTET STRING" : "OS-SpecialCase",
204                 (long)size);
205
206         /*
207          * Create the string if does not exist.
208          */
209         if(st == NULL) {
210                 st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
211                 if(st == NULL) RETURN(RC_FAIL);
212         }
213
214         /* Restore parsing context */
215         ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
216
217         switch(ctx->phase) {
218         case 0:
219                 /*
220                  * Check tags.
221                  */
222                 rval = ber_check_tags(opt_codec_ctx, td, ctx,
223                         buf_ptr, size, tag_mode, -1,
224                         &ctx->left, &tlv_constr);
225                 if(rval.code != RC_OK)
226                         return rval;
227
228                 if(tlv_constr) {
229                         /*
230                          * Complex operation, requires stack of expectations.
231                          */
232                         ctx->ptr = _new_stack();
233                         if(!ctx->ptr) {
234                                 RETURN(RC_FAIL);
235                         }
236                 } else {
237                         /*
238                          * Jump into stackless primitive decoding.
239                          */
240                         _CH_PHASE(ctx, 3);
241                         if(type_variant == ASN_OSUBV_ANY && tag_mode != 1)
242                                 APPEND(buf_ptr, rval.consumed);
243                         ADVANCE(rval.consumed);
244                         goto phase3;
245                 }
246
247                 NEXT_PHASE(ctx);
248                 /* Fall through */
249         case 1:
250         phase1:
251                 /*
252                  * Fill the stack with expectations.
253                  */
254                 stck = (struct _stack *)ctx->ptr;
255                 sel = stck->cur_ptr;
256           do {
257                 ber_tlv_tag_t tlv_tag;
258                 ber_tlv_len_t tlv_len;
259                 ber_tlv_tag_t expected_tag;
260                 ssize_t tl, ll, tlvl;
261                                 /* This one works even if (sel->left == -1) */
262                 size_t Left = ((!sel||(size_t)sel->left >= size)
263                                         ?size:(size_t)sel->left);
264
265
266                 ASN_DEBUG("%p, s->l=%ld, s->wn=%ld, s->g=%ld\n", (void *)sel,
267                         (long)(sel?sel->left:0),
268                         (long)(sel?sel->want_nulls:0),
269                         (long)(sel?sel->got:0)
270                 );
271                 if(sel && sel->left <= 0 && sel->want_nulls == 0) {
272                         if(sel->prev) {
273                                 struct _stack_el *prev = sel->prev;
274                                 if(prev->left != -1) {
275                                         if(prev->left < sel->got)
276                                                 RETURN(RC_FAIL);
277                                         prev->left -= sel->got;
278                                 }
279                                 prev->got += sel->got;
280                                 sel = stck->cur_ptr = prev;
281                                 if(!sel) break;
282                                 tlv_constr = 1;
283                                 continue;
284                         } else {
285                                 sel = stck->cur_ptr = 0;
286                                 break;  /* Nothing to wait */
287                         }
288                 }
289
290                 tl = ber_fetch_tag(buf_ptr, Left, &tlv_tag);
291                 ASN_DEBUG("fetch tag(size=%ld,L=%ld), %sstack, left=%ld, wn=%ld, tl=%ld",
292                         (long)size, (long)Left, sel?"":"!",
293                         (long)(sel?sel->left:0),
294                         (long)(sel?sel->want_nulls:0),
295                         (long)tl);
296                 switch(tl) {
297                 case -1: RETURN(RC_FAIL);
298                 case 0: RETURN(RC_WMORE);
299                 }
300
301                 tlv_constr = BER_TLV_CONSTRUCTED(buf_ptr);
302
303                 ll = ber_fetch_length(tlv_constr,
304                                 (const char *)buf_ptr + tl,Left - tl,&tlv_len);
305                 ASN_DEBUG("Got tag=%s, tc=%d, left=%ld, tl=%ld, len=%ld, ll=%ld",
306                         ber_tlv_tag_string(tlv_tag), tlv_constr,
307                                 (long)Left, (long)tl, (long)tlv_len, (long)ll);
308                 switch(ll) {
309                 case -1: RETURN(RC_FAIL);
310                 case 0: RETURN(RC_WMORE);
311                 }
312
313                 if(sel && sel->want_nulls
314                         && ((const uint8_t *)buf_ptr)[0] == 0
315                         && ((const uint8_t *)buf_ptr)[1] == 0)
316                 {
317
318                         ASN_DEBUG("Eat EOC; wn=%d--", sel->want_nulls);
319
320                         if(type_variant == ASN_OSUBV_ANY
321                         && (tag_mode != 1 || sel->cont_level))
322                                 APPEND("\0\0", 2);
323
324                         ADVANCE(2);
325                         sel->got += 2;
326                         if(sel->left != -1) {
327                                 sel->left -= 2; /* assert(sel->left >= 2) */
328                         }
329
330                         sel->want_nulls--;
331                         if(sel->want_nulls == 0) {
332                                 /* Move to the next expectation */
333                                 sel->left = 0;
334                                 tlv_constr = 1;
335                         }
336
337                         continue;
338                 }
339
340                 /*
341                  * Set up expected tags,
342                  * depending on ASN.1 type being decoded.
343                  */
344                 switch(type_variant) {
345                 case ASN_OSUBV_BIT:
346                         /* X.690: 8.6.4.1, NOTE 2 */
347                         /* Fall through */
348                 case ASN_OSUBV_STR:
349                 default:
350                         if(sel) {
351                                 unsigned level = sel->cont_level;
352                                 if(level < td->all_tags_count) {
353                                         expected_tag = td->all_tags[level];
354                                         break;
355                                 } else if(td->all_tags_count) {
356                                         expected_tag = td->all_tags
357                                                 [td->all_tags_count - 1];
358                                         break;
359                                 }
360                                 /* else, Fall through */
361                         }
362                         /* Fall through */
363                 case ASN_OSUBV_ANY:
364                         expected_tag = tlv_tag;
365                         break;
366                 }
367
368
369                 if(tlv_tag != expected_tag) {
370                         char buf[2][32];
371                         ber_tlv_tag_snprint(tlv_tag,
372                                 buf[0], sizeof(buf[0]));
373                         ber_tlv_tag_snprint(td->tags[td->tags_count-1],
374                                 buf[1], sizeof(buf[1]));
375                         ASN_DEBUG("Tag does not match expectation: %s != %s",
376                                 buf[0], buf[1]);
377                         RETURN(RC_FAIL);
378                 }
379
380                 tlvl = tl + ll; /* Combined length of T and L encoding */
381                 if((tlv_len + tlvl) < 0) {
382                         /* tlv_len value is too big */
383                         ASN_DEBUG("TLV encoding + length (%ld) is too big",
384                                 (long)tlv_len);
385                         RETURN(RC_FAIL);
386                 }
387
388                 /*
389                  * Append a new expectation.
390                  */
391                 sel = OS__add_stack_el(stck);
392                 if(!sel) RETURN(RC_FAIL);
393
394                 sel->tag = tlv_tag;
395
396                 sel->want_nulls = (tlv_len==-1);
397                 if(sel->prev && sel->prev->left != -1) {
398                         /* Check that the parent frame is big enough */
399                         if(sel->prev->left < tlvl + (tlv_len==-1?0:tlv_len))
400                                 RETURN(RC_FAIL);
401                         if(tlv_len == -1)
402                                 sel->left = sel->prev->left - tlvl;
403                         else
404                                 sel->left = tlv_len;
405                 } else {
406                         sel->left = tlv_len;
407                 }
408                 if(type_variant == ASN_OSUBV_ANY
409                 && (tag_mode != 1 || sel->cont_level))
410                         APPEND(buf_ptr, tlvl);
411                 sel->got += tlvl;
412                 ADVANCE(tlvl);
413
414                 ASN_DEBUG("+EXPECT2 got=%ld left=%ld, wn=%d, clvl=%u",
415                         (long)sel->got, (long)sel->left,
416                         sel->want_nulls, sel->cont_level);
417
418           } while(tlv_constr);
419                 if(sel == NULL) {
420                         /* Finished operation, "phase out" */
421                         ASN_DEBUG("Phase out");
422                         _CH_PHASE(ctx, +3);
423                         break;
424                 }
425
426                 NEXT_PHASE(ctx);
427                 /* Fall through */
428         case 2:
429                 stck = (struct _stack *)ctx->ptr;
430                 sel = stck->cur_ptr;
431                 ASN_DEBUG("Phase 2: Need %ld bytes, size=%ld, alrg=%ld, wn=%d",
432                         (long)sel->left, (long)size, (long)sel->got,
433                                 sel->want_nulls);
434             {
435                 ber_tlv_len_t len;
436
437                 assert(sel->left >= 0);
438
439                 len = ((ber_tlv_len_t)size < sel->left)
440                                 ? (ber_tlv_len_t)size : sel->left;
441                 if(len > 0) {
442                         if(type_variant == ASN_OSUBV_BIT
443                         && sel->bits_chopped == 0) {
444                                 /* Put the unused-bits-octet away */
445                                 st->bits_unused = *(const uint8_t *)buf_ptr;
446                                 APPEND(((const char *)buf_ptr+1), (len - 1));
447                                 sel->bits_chopped = 1;
448                         } else {
449                                 APPEND(buf_ptr, len);
450                         }
451                         ADVANCE(len);
452                         sel->left -= len;
453                         sel->got += len;
454                 }
455
456                 if(sel->left) {
457                         ASN_DEBUG("OS left %ld, size = %ld, wn=%d\n",
458                                 (long)sel->left, (long)size, sel->want_nulls);
459                         RETURN(RC_WMORE);
460                 }
461
462                 PREV_PHASE(ctx);
463                 goto phase1;
464             }
465                 break;
466         case 3:
467         phase3:
468                 /*
469                  * Primitive form, no stack required.
470                  */
471                 assert(ctx->left >= 0);
472
473                 if(size < (size_t)ctx->left) {
474                         if(!size) RETURN(RC_WMORE);
475                         if(type_variant == ASN_OSUBV_BIT && !ctx->context) {
476                                 st->bits_unused = *(const uint8_t *)buf_ptr;
477                                 ctx->left--;
478                                 ADVANCE(1);
479                         }
480                         APPEND(buf_ptr, size);
481                         assert(ctx->context > 0);
482                         ctx->left -= size;
483                         ADVANCE(size);
484                         RETURN(RC_WMORE);
485                 } else {
486                         if(type_variant == ASN_OSUBV_BIT
487                         && !ctx->context && ctx->left) {
488                                 st->bits_unused = *(const uint8_t *)buf_ptr;
489                                 ctx->left--;
490                                 ADVANCE(1);
491                         }
492                         APPEND(buf_ptr, ctx->left);
493                         ADVANCE(ctx->left);
494                         ctx->left = 0;
495
496                         NEXT_PHASE(ctx);
497                 }
498                 break;
499         }
500
501         if(sel) {
502                 ASN_DEBUG("3sel p=%p, wn=%d, l=%ld, g=%ld, size=%ld",
503                         (void *)sel->prev, sel->want_nulls,
504                         (long)sel->left, (long)sel->got, (long)size);
505                 if(sel->prev || sel->want_nulls > 1 || sel->left > 0) {
506                         RETURN(RC_WMORE);
507                 }
508         }
509
510         /*
511          * BIT STRING-specific processing.
512          */
513         if(type_variant == ASN_OSUBV_BIT) {
514         if(st->size) {
515                         if(st->bits_unused < 0 || st->bits_unused > 7) {
516                                 RETURN(RC_FAIL);
517                         }
518                         /* Finalize BIT STRING: zero out unused bits. */
519                         st->buf[st->size-1] &= 0xff << st->bits_unused;
520                 } else {
521                         if(st->bits_unused) {
522                                 RETURN(RC_FAIL);
523                         }
524                 }
525         }
526
527         ASN_DEBUG("Took %ld bytes to encode %s: [%s]:%ld",
528                 (long)consumed_myself, td->name,
529                 (type_variant == ASN_OSUBV_STR) ? (char *)st->buf : "<data>",
530                 (long)st->size);
531
532
533         RETURN(RC_OK);
534 }
535
536 /*
537  * Encode OCTET STRING type using DER.
538  */
539 asn_enc_rval_t
540 OCTET_STRING_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr,
541                         int tag_mode, ber_tlv_tag_t tag,
542                         asn_app_consume_bytes_f *cb, void *app_key) {
543     asn_enc_rval_t er = { 0, 0, 0 };
544         const asn_OCTET_STRING_specifics_t *specs = td->specifics
545                                 ? (const asn_OCTET_STRING_specifics_t *)td->specifics
546                                 : &asn_SPC_OCTET_STRING_specs;
547         const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
548         enum asn_OS_Subvariant type_variant = specs->subvariant;
549         int fix_last_byte = 0;
550
551         ASN_DEBUG("%s %s as OCTET STRING",
552                 cb?"Estimating":"Encoding", td->name);
553
554         /*
555          * Write tags.
556          */
557         if(type_variant != ASN_OSUBV_ANY || tag_mode == 1) {
558                 er.encoded = der_write_tags(td,
559                                 (type_variant == ASN_OSUBV_BIT) + st->size,
560                         tag_mode, type_variant == ASN_OSUBV_ANY, tag,
561                         cb, app_key);
562                 if(er.encoded == -1) {
563                         er.failed_type = td;
564                         er.structure_ptr = sptr;
565                         return er;
566                 }
567         } else {
568                 /* Disallow: [<tag>] IMPLICIT ANY */
569                 assert(type_variant != ASN_OSUBV_ANY || tag_mode != -1);
570                 er.encoded = 0;
571         }
572
573         if(!cb) {
574                 er.encoded += (type_variant == ASN_OSUBV_BIT) + st->size;
575                 ASN__ENCODED_OK(er);
576         }
577
578         /*
579          * Prepare to deal with the last octet of BIT STRING.
580          */
581         if(type_variant == ASN_OSUBV_BIT) {
582                 uint8_t b = st->bits_unused & 0x07;
583                 if(b && st->size) fix_last_byte = 1;
584                 ASN__CALLBACK(&b, 1);
585         }
586
587         /* Invoke callback for the main part of the buffer */
588         ASN__CALLBACK(st->buf, st->size - fix_last_byte);
589
590         /* The last octet should be stripped off the unused bits */
591         if(fix_last_byte) {
592                 uint8_t b = st->buf[st->size-1] & (0xff << st->bits_unused);
593                 ASN__CALLBACK(&b, 1);
594         }
595
596         ASN__ENCODED_OK(er);
597 cb_failed:
598         ASN__ENCODE_FAILED;
599 }
600
601 asn_enc_rval_t
602 OCTET_STRING_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
603                         int ilevel, enum xer_encoder_flags_e flags,
604                         asn_app_consume_bytes_f *cb, void *app_key) {
605     const char * const h2c = "0123456789ABCDEF";
606         const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
607         asn_enc_rval_t er = { 0, 0, 0 };
608         char scratch[16 * 3 + 4];
609         char *p = scratch;
610         uint8_t *buf;
611         uint8_t *end;
612         size_t i;
613
614         if(!st || (!st->buf && st->size))
615                 ASN__ENCODE_FAILED;
616
617         er.encoded = 0;
618
619         /*
620          * Dump the contents of the buffer in hexadecimal.
621          */
622         buf = st->buf;
623         end = buf + st->size;
624         if(flags & XER_F_CANONICAL) {
625                 char *scend = scratch + (sizeof(scratch) - 2);
626                 for(; buf < end; buf++) {
627                         if(p >= scend) {
628                                 ASN__CALLBACK(scratch, p - scratch);
629                                 p = scratch;
630                         }
631                         *p++ = h2c[(*buf >> 4) & 0x0F];
632                         *p++ = h2c[*buf & 0x0F];
633                 }
634
635                 ASN__CALLBACK(scratch, p-scratch);      /* Dump the rest */
636         } else {
637                 for(i = 0; buf < end; buf++, i++) {
638                         if(!(i % 16) && (i || st->size > 16)) {
639                                 ASN__CALLBACK(scratch, p-scratch);
640                                 p = scratch;
641                                 ASN__TEXT_INDENT(1, ilevel);
642                         }
643                         *p++ = h2c[(*buf >> 4) & 0x0F];
644                         *p++ = h2c[*buf & 0x0F];
645                         *p++ = 0x20;
646                 }
647                 if(p - scratch) {
648                         p--;    /* Remove the tail space */
649                         ASN__CALLBACK(scratch, p-scratch); /* Dump the rest */
650                         if(st->size > 16)
651                                 ASN__TEXT_INDENT(1, ilevel-1);
652                 }
653         }
654
655         ASN__ENCODED_OK(er);
656 cb_failed:
657         ASN__ENCODE_FAILED;
658 }
659
660 static const struct OCTET_STRING__xer_escape_table_s {
661         const char *string;
662         int size;
663 } OCTET_STRING__xer_escape_table[] = {
664 #define OSXET(s)        { s, sizeof(s) - 1 }
665         OSXET("\074\156\165\154\057\076"),      /* <nul/> */
666         OSXET("\074\163\157\150\057\076"),      /* <soh/> */
667         OSXET("\074\163\164\170\057\076"),      /* <stx/> */
668         OSXET("\074\145\164\170\057\076"),      /* <etx/> */
669         OSXET("\074\145\157\164\057\076"),      /* <eot/> */
670         OSXET("\074\145\156\161\057\076"),      /* <enq/> */
671         OSXET("\074\141\143\153\057\076"),      /* <ack/> */
672         OSXET("\074\142\145\154\057\076"),      /* <bel/> */
673         OSXET("\074\142\163\057\076"),          /* <bs/> */
674         OSXET("\011"),                          /* \t */
675         OSXET("\012"),                          /* \n */
676         OSXET("\074\166\164\057\076"),          /* <vt/> */
677         OSXET("\074\146\146\057\076"),          /* <ff/> */
678         OSXET("\015"),                          /* \r */
679         OSXET("\074\163\157\057\076"),          /* <so/> */
680         OSXET("\074\163\151\057\076"),          /* <si/> */
681         OSXET("\074\144\154\145\057\076"),      /* <dle/> */
682         OSXET("\074\144\143\061\057\076"),      /* <de1/> */
683         OSXET("\074\144\143\062\057\076"),      /* <de2/> */
684         OSXET("\074\144\143\063\057\076"),      /* <de3/> */
685         OSXET("\074\144\143\064\057\076"),      /* <de4/> */
686         OSXET("\074\156\141\153\057\076"),      /* <nak/> */
687         OSXET("\074\163\171\156\057\076"),      /* <syn/> */
688         OSXET("\074\145\164\142\057\076"),      /* <etb/> */
689         OSXET("\074\143\141\156\057\076"),      /* <can/> */
690         OSXET("\074\145\155\057\076"),          /* <em/> */
691         OSXET("\074\163\165\142\057\076"),      /* <sub/> */
692         OSXET("\074\145\163\143\057\076"),      /* <esc/> */
693         OSXET("\074\151\163\064\057\076"),      /* <is4/> */
694         OSXET("\074\151\163\063\057\076"),      /* <is3/> */
695         OSXET("\074\151\163\062\057\076"),      /* <is2/> */
696         OSXET("\074\151\163\061\057\076"),      /* <is1/> */
697         { 0, 0 },       /* " " */
698         { 0, 0 },       /* ! */
699         { 0, 0 },       /* \" */
700         { 0, 0 },       /* # */
701         { 0, 0 },       /* $ */
702         { 0, 0 },       /* % */
703         OSXET("\046\141\155\160\073"),  /* &amp; */
704         { 0, 0 },       /* ' */
705         {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* ()*+,-./ */
706         {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, /* 01234567 */
707         {0,0},{0,0},{0,0},{0,0},                         /* 89:; */
708         OSXET("\046\154\164\073"),      /* &lt; */
709         { 0, 0 },       /* = */
710         OSXET("\046\147\164\073"),      /* &gt; */
711 };
712
713 static int
714 OS__check_escaped_control_char(const void *buf, int size) {
715         size_t i;
716         /*
717          * Inefficient algorithm which translates the escape sequences
718          * defined above into characters. Returns -1 if not found.
719          * TODO: replace by a faster algorithm (bsearch(), hash or
720          * nested table lookups).
721          */
722         for(i = 0; i < 32 /* Don't spend time on the bottom half */; i++) {
723                 const struct OCTET_STRING__xer_escape_table_s *el;
724                 el = &OCTET_STRING__xer_escape_table[i];
725                 if(el->size == size && memcmp(buf, el->string, size) == 0)
726                         return i;
727         }
728         return -1;
729 }
730
731 static int
732 OCTET_STRING__handle_control_chars(void *struct_ptr, const void *chunk_buf, size_t chunk_size) {
733         /*
734          * This might be one of the escape sequences
735          * for control characters. Check it out.
736          * #11.15.5
737          */
738         int control_char = OS__check_escaped_control_char(chunk_buf,chunk_size);
739         if(control_char >= 0) {
740                 OCTET_STRING_t *st = (OCTET_STRING_t *)struct_ptr;
741                 void *p = REALLOC(st->buf, st->size + 2);
742                 if(p) {
743                         st->buf = (uint8_t *)p;
744                         st->buf[st->size++] = control_char;
745                         st->buf[st->size] = '\0';       /* nul-termination */
746                         return 0;
747                 }
748         }
749         
750         return -1;      /* No, it's not */
751 }
752
753 asn_enc_rval_t
754 OCTET_STRING_encode_xer_utf8(const asn_TYPE_descriptor_t *td, const void *sptr,
755                              int ilevel, enum xer_encoder_flags_e flags,
756                              asn_app_consume_bytes_f *cb, void *app_key) {
757         const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
758         asn_enc_rval_t er = { 0, 0, 0 };
759         uint8_t *buf, *end;
760         uint8_t *ss;    /* Sequence start */
761         ssize_t encoded_len = 0;
762
763         (void)ilevel;   /* Unused argument */
764         (void)flags;    /* Unused argument */
765
766         if(!st || (!st->buf && st->size))
767                 ASN__ENCODE_FAILED;
768
769         buf = st->buf;
770         end = buf + st->size;
771         for(ss = buf; buf < end; buf++) {
772                 unsigned int ch = *buf;
773                 int s_len;      /* Special encoding sequence length */
774
775                 /*
776                  * Escape certain characters: X.680/11.15
777                  */
778                 if(ch < sizeof(OCTET_STRING__xer_escape_table)
779                         /sizeof(OCTET_STRING__xer_escape_table[0])
780                 && (s_len = OCTET_STRING__xer_escape_table[ch].size)) {
781                         if(((buf - ss) && cb(ss, buf - ss, app_key) < 0)
782                         || cb(OCTET_STRING__xer_escape_table[ch].string, s_len,
783                                         app_key) < 0)
784                                 ASN__ENCODE_FAILED;
785                         encoded_len += (buf - ss) + s_len;
786                         ss = buf + 1;
787                 }
788         }
789
790         encoded_len += (buf - ss);
791         if((buf - ss) && cb(ss, buf - ss, app_key) < 0)
792                 ASN__ENCODE_FAILED;
793
794         er.encoded = encoded_len;
795         ASN__ENCODED_OK(er);
796 }
797
798 /*
799  * Convert from hexadecimal format (cstring): "AB CD EF"
800  */
801 static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) {
802         OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
803         const char *chunk_stop = (const char *)chunk_buf;
804         const char *p = chunk_stop;
805         const char *pend = p + chunk_size;
806         unsigned int clv = 0;
807         int half = 0;   /* Half bit */
808         uint8_t *buf;
809
810         /* Reallocate buffer according to high cap estimation */
811         size_t new_size = st->size + (chunk_size + 1) / 2;
812         void *nptr = REALLOC(st->buf, new_size + 1);
813         if(!nptr) return -1;
814         st->buf = (uint8_t *)nptr;
815         buf = st->buf + st->size;
816
817         /*
818          * If something like " a b c " appears here, the " a b":3 will be
819          * converted, and the rest skipped. That is, unless buf_size is greater
820          * than chunk_size, then it'll be equivalent to "ABC0".
821          */
822         for(; p < pend; p++) {
823                 int ch = *(const unsigned char *)p;
824                 switch(ch) {
825                 case 0x09: case 0x0a: case 0x0c: case 0x0d:
826                 case 0x20:
827                         /* Ignore whitespace */
828                         continue;
829                 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/
830                 case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/
831                         clv = (clv << 4) + (ch - 0x30);
832                         break;
833                 case 0x41: case 0x42: case 0x43:        /* ABC */
834                 case 0x44: case 0x45: case 0x46:        /* DEF */
835                         clv = (clv << 4) + (ch - 0x41 + 10);
836                         break;
837                 case 0x61: case 0x62: case 0x63:        /* abc */
838                 case 0x64: case 0x65: case 0x66:        /* def */
839                         clv = (clv << 4) + (ch - 0x61 + 10);
840                         break;
841                 default:
842                         *buf = 0;       /* JIC */
843                         return -1;
844                 }
845                 if(half++) {
846                         half = 0;
847                         *buf++ = clv;
848                         chunk_stop = p + 1;
849                 }
850         }
851
852         /*
853          * Check partial decoding.
854          */
855         if(half) {
856                 if(have_more) {
857                         /*
858                          * Partial specification is fine,
859                          * because no more more PXER_TEXT data is available.
860                          */
861                         *buf++ = clv << 4;
862                         chunk_stop = p;
863                 }
864         } else {
865                 chunk_stop = p;
866         }
867
868         st->size = buf - st->buf;       /* Adjust the buffer size */
869         assert(st->size <= new_size);
870         st->buf[st->size] = 0;          /* Courtesy termination */
871
872         return (chunk_stop - (const char *)chunk_buf);  /* Converted size */
873 }
874
875 /*
876  * Convert from binary format: "00101011101"
877  */
878 static ssize_t OCTET_STRING__convert_binary(void *sptr, const void *chunk_buf, size_t chunk_size, int have_more) {
879         BIT_STRING_t *st = (BIT_STRING_t *)sptr;
880         const char *p = (const char *)chunk_buf;
881         const char *pend = p + chunk_size;
882         int bits_unused = st->bits_unused & 0x7;
883         uint8_t *buf;
884
885         /* Reallocate buffer according to high cap estimation */
886         size_t new_size = st->size + (chunk_size + 7) / 8;
887         void *nptr = REALLOC(st->buf, new_size + 1);
888         if(!nptr) return -1;
889         st->buf = (uint8_t *)nptr;
890         buf = st->buf + st->size;
891
892         (void)have_more;
893
894         if(bits_unused == 0)
895                 bits_unused = 8;
896         else if(st->size)
897                 buf--;
898
899         /*
900          * Convert series of 0 and 1 into the octet string.
901          */
902         for(; p < pend; p++) {
903                 int ch = *(const unsigned char *)p;
904                 switch(ch) {
905                 case 0x09: case 0x0a: case 0x0c: case 0x0d:
906                 case 0x20:
907                         /* Ignore whitespace */
908                         break;
909                 case 0x30:
910                 case 0x31:
911                         if(bits_unused-- <= 0) {
912                                 *++buf = 0;     /* Clean the cell */
913                                 bits_unused = 7;
914                         }
915                         *buf |= (ch&1) << bits_unused;
916                         break;
917                 default:
918                         st->bits_unused = bits_unused;
919                         return -1;
920                 }
921         }
922
923         if(bits_unused == 8) {
924                 st->size = buf - st->buf;
925                 st->bits_unused = 0;
926         } else {
927                 st->size = buf - st->buf + 1;
928                 st->bits_unused = bits_unused;
929         }
930
931         assert(st->size <= new_size);
932         st->buf[st->size] = 0;          /* Courtesy termination */
933
934         return chunk_size;      /* Converted in full */
935 }
936
937 /*
938  * Something like strtod(), but with stricter rules.
939  */
940 static int
941 OS__strtoent(int base, const char *buf, const char *end, int32_t *ret_value) {
942         const int32_t last_unicode_codepoint = 0x10ffff;
943         int32_t val = 0;
944         const char *p;
945
946         for(p = buf; p < end; p++) {
947                 int ch = *p;
948
949                 switch(ch) {
950                 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/
951                 case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/
952                         val = val * base + (ch - 0x30);
953                         break;
954                 case 0x41: case 0x42: case 0x43:        /* ABC */
955                 case 0x44: case 0x45: case 0x46:        /* DEF */
956                         val = val * base + (ch - 0x41 + 10);
957                         break;
958                 case 0x61: case 0x62: case 0x63:        /* abc */
959                 case 0x64: case 0x65: case 0x66:        /* def */
960                         val = val * base + (ch - 0x61 + 10);
961                         break;
962                 case 0x3b:      /* ';' */
963                         *ret_value = val;
964                         return (p - buf) + 1;
965                 default:
966                         return -1;      /* Character set error */
967                 }
968
969                 /* Value exceeds the Unicode range. */
970                 if(val > last_unicode_codepoint) {
971                         return -1;
972                 }
973         }
974
975         *ret_value = -1;
976         return (p - buf);
977 }
978
979 /*
980  * Convert from the plain UTF-8 format, expanding entity references: "2 &lt; 3"
981  */
982 static ssize_t
983 OCTET_STRING__convert_entrefs(void *sptr, const void *chunk_buf,
984                               size_t chunk_size, int have_more) {
985     OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
986         const char *p = (const char *)chunk_buf;
987         const char *pend = p + chunk_size;
988         uint8_t *buf;
989
990         /* Reallocate buffer */
991         size_t new_size = st->size + chunk_size;
992         void *nptr = REALLOC(st->buf, new_size + 1);
993         if(!nptr) return -1;
994         st->buf = (uint8_t *)nptr;
995         buf = st->buf + st->size;
996
997         /*
998          * Convert series of 0 and 1 into the octet string.
999          */
1000         for(; p < pend; p++) {
1001                 int ch = *(const unsigned char *)p;
1002                 int len;        /* Length of the rest of the chunk */
1003
1004                 if(ch != 0x26 /* '&' */) {
1005                         *buf++ = ch;
1006                         continue;       /* That was easy... */
1007                 }
1008
1009                 /*
1010                  * Process entity reference.
1011                  */
1012                 len = chunk_size - (p - (const char *)chunk_buf);
1013                 if(len == 1 /* "&" */) goto want_more;
1014                 if(p[1] == 0x23 /* '#' */) {
1015                         const char *pval;       /* Pointer to start of digits */
1016                         int32_t val = 0;        /* Entity reference value */
1017                         int base;
1018
1019                         if(len == 2 /* "&#" */) goto want_more;
1020                         if(p[2] == 0x78 /* 'x' */)
1021                                 pval = p + 3, base = 16;
1022                         else
1023                                 pval = p + 2, base = 10;
1024                         len = OS__strtoent(base, pval, p + len, &val);
1025                         if(len == -1) {
1026                                 /* Invalid charset. Just copy verbatim. */
1027                                 *buf++ = ch;
1028                                 continue;
1029                         }
1030                         if(!len || pval[len-1] != 0x3b) goto want_more;
1031                         assert(val > 0);
1032                         p += (pval - p) + len - 1; /* Advance past entref */
1033
1034                         if(val < 0x80) {
1035                                 *buf++ = (char)val;
1036                         } else if(val < 0x800) {
1037                                 *buf++ = 0xc0 | ((val >> 6));
1038                                 *buf++ = 0x80 | ((val & 0x3f));
1039                         } else if(val < 0x10000) {
1040                                 *buf++ = 0xe0 | ((val >> 12));
1041                                 *buf++ = 0x80 | ((val >> 6) & 0x3f);
1042                                 *buf++ = 0x80 | ((val & 0x3f));
1043                         } else if(val < 0x200000) {
1044                                 *buf++ = 0xf0 | ((val >> 18));
1045                                 *buf++ = 0x80 | ((val >> 12) & 0x3f);
1046                                 *buf++ = 0x80 | ((val >> 6) & 0x3f);
1047                                 *buf++ = 0x80 | ((val & 0x3f));
1048                         } else if(val < 0x4000000) {
1049                                 *buf++ = 0xf8 | ((val >> 24));
1050                                 *buf++ = 0x80 | ((val >> 18) & 0x3f);
1051                                 *buf++ = 0x80 | ((val >> 12) & 0x3f);
1052                                 *buf++ = 0x80 | ((val >> 6) & 0x3f);
1053                                 *buf++ = 0x80 | ((val & 0x3f));
1054                         } else {
1055                                 *buf++ = 0xfc | ((val >> 30) & 0x1);
1056                                 *buf++ = 0x80 | ((val >> 24) & 0x3f);
1057                                 *buf++ = 0x80 | ((val >> 18) & 0x3f);
1058                                 *buf++ = 0x80 | ((val >> 12) & 0x3f);
1059                                 *buf++ = 0x80 | ((val >> 6) & 0x3f);
1060                                 *buf++ = 0x80 | ((val & 0x3f));
1061                         }
1062                 } else {
1063                         /*
1064                          * Ugly, limited parsing of &amp; &gt; &lt;
1065                          */
1066                         char *sc = (char *)memchr(p, 0x3b, len > 5 ? 5 : len);
1067                         if(!sc) goto want_more;
1068                         if((sc - p) == 4
1069                                 && p[1] == 0x61 /* 'a' */
1070                                 && p[2] == 0x6d /* 'm' */
1071                                 && p[3] == 0x70 /* 'p' */) {
1072                                 *buf++ = 0x26;
1073                                 p = sc;
1074                                 continue;
1075                         }
1076                         if((sc - p) == 3) {
1077                                 if(p[1] == 0x6c) {
1078                                         *buf = 0x3c;    /* '<' */
1079                                 } else if(p[1] == 0x67) {
1080                                         *buf = 0x3e;    /* '>' */
1081                                 } else {
1082                                         /* Unsupported entity reference */
1083                                         *buf++ = ch;
1084                                         continue;
1085                                 }
1086                                 if(p[2] != 0x74) {
1087                                         /* Unsupported entity reference */
1088                                         *buf++ = ch;
1089                                         continue;
1090                                 }
1091                                 buf++;
1092                                 p = sc;
1093                                 continue;
1094                         }
1095                         /* Unsupported entity reference */
1096                         *buf++ = ch;
1097                 }
1098
1099                 continue;
1100         want_more:
1101                 if(have_more) {
1102                         /*
1103                          * We know that no more data (of the same type)
1104                          * is coming. Copy the rest verbatim.
1105                          */
1106                         *buf++ = ch;
1107                         continue;
1108                 }
1109                 chunk_size = (p - (const char *)chunk_buf);
1110                 /* Processing stalled: need more data */
1111                 break;
1112         }
1113
1114         st->size = buf - st->buf;
1115         assert(st->size <= new_size);
1116         st->buf[st->size] = 0;          /* Courtesy termination */
1117
1118         return chunk_size;      /* Converted in full */
1119 }
1120
1121 /*
1122  * Decode OCTET STRING from the XML element's body.
1123  */
1124 static asn_dec_rval_t
1125 OCTET_STRING__decode_xer(
1126     const asn_codec_ctx_t *opt_codec_ctx, const asn_TYPE_descriptor_t *td,
1127     void **sptr, const char *opt_mname, const void *buf_ptr, size_t size,
1128     int (*opt_unexpected_tag_decoder)(void *struct_ptr, const void *chunk_buf,
1129                                       size_t chunk_size),
1130     ssize_t (*body_receiver)(void *struct_ptr, const void *chunk_buf,
1131                              size_t chunk_size, int have_more)) {
1132     OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr;
1133         const asn_OCTET_STRING_specifics_t *specs = td->specifics
1134                                 ? (const asn_OCTET_STRING_specifics_t *)td->specifics
1135                                 : &asn_SPC_OCTET_STRING_specs;
1136         const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
1137         asn_struct_ctx_t *ctx;          /* Per-structure parser context */
1138         asn_dec_rval_t rval;            /* Return value from the decoder */
1139         int st_allocated;
1140
1141         /*
1142          * Create the string if does not exist.
1143          */
1144         if(!st) {
1145                 st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
1146                 *sptr = (void *)st;
1147                 if(!st) goto sta_failed;
1148                 st_allocated = 1;
1149         } else {
1150                 st_allocated = 0;
1151         }
1152         if(!st->buf) {
1153                 /* This is separate from above section */
1154                 st->buf = (uint8_t *)CALLOC(1, 1);
1155                 if(!st->buf) {
1156                         if(st_allocated) {
1157                                 *sptr = 0;
1158                                 goto stb_failed;
1159                         } else {
1160                                 goto sta_failed;
1161                         }
1162                 }
1163         }
1164
1165         /* Restore parsing context */
1166         ctx = (asn_struct_ctx_t *)(((char *)*sptr) + specs->ctx_offset);
1167
1168         return xer_decode_general(opt_codec_ctx, ctx, *sptr, xml_tag,
1169                 buf_ptr, size, opt_unexpected_tag_decoder, body_receiver);
1170
1171 stb_failed:
1172         FREEMEM(st);
1173 sta_failed:
1174         rval.code = RC_FAIL;
1175         rval.consumed = 0;
1176         return rval;
1177 }
1178
1179 /*
1180  * Decode OCTET STRING from the hexadecimal data.
1181  */
1182 asn_dec_rval_t
1183 OCTET_STRING_decode_xer_hex(const asn_codec_ctx_t *opt_codec_ctx,
1184                             const asn_TYPE_descriptor_t *td, void **sptr,
1185                             const char *opt_mname, const void *buf_ptr,
1186                             size_t size) {
1187     return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
1188                 buf_ptr, size, 0, OCTET_STRING__convert_hexadecimal);
1189 }
1190
1191 /*
1192  * Decode OCTET STRING from the binary (0/1) data.
1193  */
1194 asn_dec_rval_t
1195 OCTET_STRING_decode_xer_binary(const asn_codec_ctx_t *opt_codec_ctx,
1196                                const asn_TYPE_descriptor_t *td, void **sptr,
1197                                const char *opt_mname, const void *buf_ptr,
1198                                size_t size) {
1199     return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
1200                 buf_ptr, size, 0, OCTET_STRING__convert_binary);
1201 }
1202
1203 /*
1204  * Decode OCTET STRING from the string (ASCII/UTF-8) data.
1205  */
1206 asn_dec_rval_t
1207 OCTET_STRING_decode_xer_utf8(const asn_codec_ctx_t *opt_codec_ctx,
1208                              const asn_TYPE_descriptor_t *td, void **sptr,
1209                              const char *opt_mname, const void *buf_ptr,
1210                              size_t size) {
1211     return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
1212                 buf_ptr, size,
1213                 OCTET_STRING__handle_control_chars,
1214                 OCTET_STRING__convert_entrefs);
1215 }
1216
1217 #ifndef  ASN_DISABLE_PER_SUPPORT
1218
1219 static int
1220 OCTET_STRING_per_get_characters(asn_per_data_t *po, uint8_t *buf,
1221                 size_t units, unsigned int bpc, unsigned int unit_bits,
1222                 long lb, long ub, const asn_per_constraints_t *pc) {
1223         uint8_t *end = buf + units * bpc;
1224
1225         ASN_DEBUG("Expanding %d characters into (%ld..%ld):%d",
1226                 (int)units, lb, ub, unit_bits);
1227
1228         /* X.691: 27.5.4 */
1229         if((unsigned long)ub <= ((unsigned long)2 << (unit_bits - 1))) {
1230                 /* Decode without translation */
1231                 lb = 0;
1232         } else if(pc && pc->code2value) {
1233                 if(unit_bits > 16)
1234                         return 1;       /* FATAL: can't have constrained
1235                                          * UniversalString with more than
1236                                          * 16 million code points */
1237                 for(; buf < end; buf += bpc) {
1238                         int value;
1239                         int code = per_get_few_bits(po, unit_bits);
1240                         if(code < 0) return -1; /* WMORE */
1241                         value = pc->code2value(code);
1242                         if(value < 0) {
1243                                 ASN_DEBUG("Code %d (0x%02x) is"
1244                                         " not in map (%ld..%ld)",
1245                                         code, code, lb, ub);
1246                                 return 1;       /* FATAL */
1247                         }
1248                         switch(bpc) {
1249                         case 1: *buf = value; break;
1250                         case 2: buf[0] = value >> 8; buf[1] = value; break;
1251                         case 4: buf[0] = value >> 24; buf[1] = value >> 16;
1252                                 buf[2] = value >> 8; buf[3] = value; break;
1253                         }
1254                 }
1255                 return 0;
1256         }
1257
1258         /* Shortcut the no-op copying to the aligned structure */
1259         if(lb == 0 && (unit_bits == 8 * bpc)) {
1260                 return per_get_many_bits(po, buf, 0, unit_bits * units);
1261         }
1262
1263         for(; buf < end; buf += bpc) {
1264                 int32_t code = per_get_few_bits(po, unit_bits);
1265                 int32_t ch = code + lb;
1266                 if(code < 0) return -1; /* WMORE */
1267                 if(ch > ub) {
1268                         ASN_DEBUG("Code %d is out of range (%ld..%ld)",
1269                                 ch, lb, ub);
1270                         return 1;       /* FATAL */
1271                 }
1272                 switch(bpc) {
1273                 case 1: *buf = ch; break;
1274                 case 2: buf[0] = ch >> 8; buf[1] = ch; break;
1275                 case 4: buf[0] = ch >> 24; buf[1] = ch >> 16;
1276                         buf[2] = ch >> 8; buf[3] = ch; break;
1277                 }
1278         }
1279
1280         return 0;
1281 }
1282
1283 static int
1284 OCTET_STRING_per_put_characters(asn_per_outp_t *po, const uint8_t *buf,
1285                 size_t units, unsigned int bpc, unsigned int unit_bits,
1286                 long lb, long ub, const asn_per_constraints_t *pc) {
1287         const uint8_t *end = buf + units * bpc;
1288
1289         ASN_DEBUG("Squeezing %d characters into (%ld..%ld):%d (%d bpc)",
1290                 (int)units, lb, ub, unit_bits, bpc);
1291
1292         /* X.691: 27.5.4 */
1293         if((unsigned long)ub <= ((unsigned long)2 << (unit_bits - 1))) {
1294                 /* Encode as is */
1295                 lb = 0;
1296         } else if(pc && pc->value2code) {
1297                 for(; buf < end; buf += bpc) {
1298                         int code;
1299                         uint32_t value;
1300                         switch(bpc) {
1301                         case 1: value = *(const uint8_t *)buf; break;
1302                         case 2: value = (buf[0] << 8) | buf[1]; break;
1303                         case 4: value = (buf[0] << 24) | (buf[1] << 16)
1304                                         | (buf[2] << 8) | buf[3]; break;
1305                         default: return -1;
1306                         }
1307                         code = pc->value2code(value);
1308                         if(code < 0) {
1309                                 ASN_DEBUG("Character %d (0x%02x) is"
1310                                         " not in map (%ld..%ld)",
1311                                         *buf, *buf, lb, ub);
1312                                 return -1;
1313                         }
1314                         if(per_put_few_bits(po, code, unit_bits))
1315                                 return -1;
1316                 }
1317         }
1318
1319         /* Shortcut the no-op copying to the aligned structure */
1320         if(lb == 0 && (unit_bits == 8 * bpc)) {
1321                 return per_put_many_bits(po, buf, unit_bits * units);
1322         }
1323
1324     for(ub -= lb; buf < end; buf += bpc) {
1325         int ch;
1326         uint32_t value;
1327         switch(bpc) {
1328         case 1:
1329             value = *(const uint8_t *)buf;
1330             break;
1331         case 2:
1332             value = (buf[0] << 8) | buf[1];
1333             break;
1334         case 4:
1335             value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1336             break;
1337         default:
1338             return -1;
1339         }
1340         ch = value - lb;
1341         if(ch < 0 || ch > ub) {
1342             ASN_DEBUG("Character %d (0x%02x) is out of range (%ld..%ld)", *buf,
1343                       value, lb, ub + lb);
1344             return -1;
1345         }
1346         if(per_put_few_bits(po, ch, unit_bits)) return -1;
1347     }
1348
1349     return 0;
1350 }
1351
1352 static asn_per_constraints_t asn_DEF_OCTET_STRING_constraints = {
1353         { APC_CONSTRAINED, 8, 8, 0, 255 },
1354         { APC_SEMI_CONSTRAINED, -1, -1, 0, 0 },
1355         0, 0
1356 };
1357
1358 asn_dec_rval_t
1359 OCTET_STRING_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
1360                          const asn_TYPE_descriptor_t *td,
1361                          const asn_per_constraints_t *constraints, void **sptr,
1362                          asn_per_data_t *pd) {
1363     const asn_OCTET_STRING_specifics_t *specs = td->specifics
1364                 ? (const asn_OCTET_STRING_specifics_t *)td->specifics
1365                 : &asn_SPC_OCTET_STRING_specs;
1366     const asn_per_constraints_t *pc =
1367         constraints ? constraints : td->encoding_constraints.per_constraints;
1368     const asn_per_constraint_t *cval;
1369         const asn_per_constraint_t *csiz;
1370         asn_dec_rval_t rval = { RC_OK, 0 };
1371         OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr;
1372         ssize_t consumed_myself = 0;
1373         int repeat;
1374         enum {
1375                 OS__BPC_CHAR    = 1,
1376                 OS__BPC_U16     = 2,
1377                 OS__BPC_U32     = 4
1378         } bpc;  /* Bytes per character */
1379         unsigned int unit_bits;
1380         unsigned int canonical_unit_bits;
1381
1382         (void)opt_codec_ctx;
1383
1384         if(pc) {
1385                 cval = &pc->value;
1386                 csiz = &pc->size;
1387         } else {
1388                 cval = &asn_DEF_OCTET_STRING_constraints.value;
1389                 csiz = &asn_DEF_OCTET_STRING_constraints.size;
1390         }
1391
1392         switch(specs->subvariant) {
1393         default:
1394         case ASN_OSUBV_ANY:
1395         case ASN_OSUBV_BIT:
1396                 ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant);
1397                 RETURN(RC_FAIL);
1398                 break;
1399         case ASN_OSUBV_STR:
1400                 canonical_unit_bits = unit_bits = 8;
1401                 if(cval->flags & APC_CONSTRAINED)
1402                         unit_bits = cval->range_bits;
1403                 bpc = OS__BPC_CHAR;
1404                 break;
1405         case ASN_OSUBV_U16:
1406                 canonical_unit_bits = unit_bits = 16;
1407                 if(cval->flags & APC_CONSTRAINED)
1408                         unit_bits = cval->range_bits;
1409                 bpc = OS__BPC_U16;
1410                 break;
1411         case ASN_OSUBV_U32:
1412                 canonical_unit_bits = unit_bits = 32;
1413                 if(cval->flags & APC_CONSTRAINED)
1414                         unit_bits = cval->range_bits;
1415                 bpc = OS__BPC_U32;
1416                 break;
1417         }
1418
1419         /*
1420          * Allocate the string.
1421          */
1422         if(!st) {
1423                 st = (OCTET_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
1424                 if(!st) RETURN(RC_FAIL);
1425         }
1426
1427         ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d",
1428                 csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
1429                 csiz->lower_bound, csiz->upper_bound, csiz->effective_bits);
1430
1431         if(csiz->flags & APC_EXTENSIBLE) {
1432                 int inext = per_get_few_bits(pd, 1);
1433                 if(inext < 0) RETURN(RC_WMORE);
1434                 if(inext) {
1435                         csiz = &asn_DEF_OCTET_STRING_constraints.size;
1436                         unit_bits = canonical_unit_bits;
1437                 }
1438         }
1439
1440         if(csiz->effective_bits >= 0) {
1441                 FREEMEM(st->buf);
1442                 if(bpc) {
1443                         st->size = csiz->upper_bound * bpc;
1444                 } else {
1445                         st->size = (csiz->upper_bound + 7) >> 3;
1446                 }
1447                 st->buf = (uint8_t *)MALLOC(st->size + 1);
1448                 if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
1449         }
1450
1451         /* X.691, #16.5: zero-length encoding */
1452         /* X.691, #16.6: short fixed length encoding (up to 2 octets) */
1453         /* X.691, #16.7: long fixed length encoding (up to 64K octets) */
1454         if(csiz->effective_bits == 0) {
1455                 int ret;
1456                 if(bpc) {
1457                         ASN_DEBUG("Encoding OCTET STRING size %ld",
1458                                 csiz->upper_bound);
1459                         ret = OCTET_STRING_per_get_characters(pd, st->buf,
1460                                 csiz->upper_bound, bpc, unit_bits,
1461                                 cval->lower_bound, cval->upper_bound, pc);
1462                         if(ret > 0) RETURN(RC_FAIL);
1463                 } else {
1464                         ASN_DEBUG("Encoding BIT STRING size %ld",
1465                                 csiz->upper_bound);
1466                         ret = per_get_many_bits(pd, st->buf, 0,
1467                                             unit_bits * csiz->upper_bound);
1468                 }
1469                 if(ret < 0) RETURN(RC_WMORE);
1470                 consumed_myself += unit_bits * csiz->upper_bound;
1471                 st->buf[st->size] = 0;
1472                 RETURN(RC_OK);
1473         }
1474
1475         st->size = 0;
1476         do {
1477                 ssize_t raw_len;
1478                 ssize_t len_bytes;
1479                 void *p;
1480                 int ret;
1481
1482                 /* Get the PER length */
1483                 raw_len = uper_get_length(pd, csiz->effective_bits, csiz->lower_bound,
1484                                           &repeat);
1485                 if(raw_len < 0) RETURN(RC_WMORE);
1486                 if(raw_len == 0 && st->buf) break;
1487
1488                 ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
1489                         (long)csiz->effective_bits, (long)raw_len,
1490                         repeat ? "repeat" : "once", td->name);
1491         len_bytes = raw_len * bpc;
1492                 p = REALLOC(st->buf, st->size + len_bytes + 1);
1493                 if(!p) RETURN(RC_FAIL);
1494                 st->buf = (uint8_t *)p;
1495
1496         ret = OCTET_STRING_per_get_characters(pd, &st->buf[st->size], raw_len,
1497                                               bpc, unit_bits, cval->lower_bound,
1498                                               cval->upper_bound, pc);
1499         if(ret > 0) RETURN(RC_FAIL);
1500                 if(ret < 0) RETURN(RC_WMORE);
1501                 st->size += len_bytes;
1502         } while(repeat);
1503         st->buf[st->size] = 0;  /* nul-terminate */
1504
1505         return rval;
1506 }
1507
1508 asn_enc_rval_t
1509 OCTET_STRING_encode_uper(const asn_TYPE_descriptor_t *td,
1510                          const asn_per_constraints_t *constraints,
1511                          const void *sptr, asn_per_outp_t *po) {
1512     const asn_OCTET_STRING_specifics_t *specs = td->specifics
1513                 ? (const asn_OCTET_STRING_specifics_t *)td->specifics
1514                 : &asn_SPC_OCTET_STRING_specs;
1515         const asn_per_constraints_t *pc = constraints ? constraints
1516                                 : td->encoding_constraints.per_constraints;
1517         const asn_per_constraint_t *cval;
1518         const asn_per_constraint_t *csiz;
1519         const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
1520         asn_enc_rval_t er = { 0, 0, 0 };
1521         int inext = 0;          /* Lies not within extension root */
1522         unsigned int unit_bits;
1523         unsigned int canonical_unit_bits;
1524         size_t size_in_units;
1525         const uint8_t *buf;
1526         int ret;
1527         enum {
1528                 OS__BPC_CHAR    = 1,
1529                 OS__BPC_U16     = 2,
1530                 OS__BPC_U32     = 4
1531         } bpc;  /* Bytes per character */
1532         int ct_extensible;
1533
1534         if(!st || (!st->buf && st->size))
1535                 ASN__ENCODE_FAILED;
1536
1537         if(pc) {
1538                 cval = &pc->value;
1539                 csiz = &pc->size;
1540         } else {
1541                 cval = &asn_DEF_OCTET_STRING_constraints.value;
1542                 csiz = &asn_DEF_OCTET_STRING_constraints.size;
1543         }
1544         ct_extensible = csiz->flags & APC_EXTENSIBLE;
1545
1546         switch(specs->subvariant) {
1547         default:
1548         case ASN_OSUBV_ANY:
1549         case ASN_OSUBV_BIT:
1550                 ASN__ENCODE_FAILED;
1551         case ASN_OSUBV_STR:
1552                 canonical_unit_bits = unit_bits = 8;
1553                 if(cval->flags & APC_CONSTRAINED)
1554                         unit_bits = cval->range_bits;
1555                 bpc = OS__BPC_CHAR;
1556                 size_in_units = st->size;
1557                 break;
1558         case ASN_OSUBV_U16:
1559                 canonical_unit_bits = unit_bits = 16;
1560                 if(cval->flags & APC_CONSTRAINED)
1561                         unit_bits = cval->range_bits;
1562                 bpc = OS__BPC_U16;
1563                 size_in_units = st->size >> 1;
1564                 if(st->size & 1) {
1565                         ASN_DEBUG("%s string size is not modulo 2", td->name);
1566                         ASN__ENCODE_FAILED;
1567                 }
1568                 break;
1569         case ASN_OSUBV_U32:
1570                 canonical_unit_bits = unit_bits = 32;
1571                 if(cval->flags & APC_CONSTRAINED)
1572                         unit_bits = cval->range_bits;
1573                 bpc = OS__BPC_U32;
1574                 size_in_units = st->size >> 2;
1575                 if(st->size & 3) {
1576                         ASN_DEBUG("%s string size is not modulo 4", td->name);
1577                         ASN__ENCODE_FAILED;
1578                 }
1579                 break;
1580         }
1581
1582         ASN_DEBUG("Encoding %s into %" ASN_PRI_SIZE " units of %d bits"
1583                 " (%ld..%ld, effective %d)%s",
1584                 td->name, size_in_units, unit_bits,
1585                 csiz->lower_bound, csiz->upper_bound,
1586                 csiz->effective_bits, ct_extensible ? " EXT" : "");
1587
1588         /* Figure out whether size lies within PER visible constraint */
1589
1590     if(csiz->effective_bits >= 0) {
1591         if((ssize_t)size_in_units < csiz->lower_bound
1592            || (ssize_t)size_in_units > csiz->upper_bound) {
1593             if(ct_extensible) {
1594                 csiz = &asn_DEF_OCTET_STRING_constraints.size;
1595                 unit_bits = canonical_unit_bits;
1596                 inext = 1;
1597             } else {
1598                 ASN__ENCODE_FAILED;
1599             }
1600         }
1601     } else {
1602         inext = 0;
1603     }
1604
1605     if(ct_extensible) {
1606                 /* Declare whether length is [not] within extension root */
1607                 if(per_put_few_bits(po, inext, 1))
1608                         ASN__ENCODE_FAILED;
1609         }
1610
1611     if(csiz->effective_bits >= 0 && !inext) {
1612         ASN_DEBUG("Encoding %" ASN_PRI_SIZE " bytes (%ld), length in %d bits", st->size,
1613                   size_in_units - csiz->lower_bound, csiz->effective_bits);
1614         ret = per_put_few_bits(po, size_in_units - csiz->lower_bound,
1615                                csiz->effective_bits);
1616         if(ret) ASN__ENCODE_FAILED;
1617         ret = OCTET_STRING_per_put_characters(po, st->buf, size_in_units, bpc,
1618                                               unit_bits, cval->lower_bound,
1619                                               cval->upper_bound, pc);
1620         if(ret) ASN__ENCODE_FAILED;
1621         ASN__ENCODED_OK(er);
1622     }
1623
1624     ASN_DEBUG("Encoding %" ASN_PRI_SIZE " bytes", st->size);
1625
1626     buf = st->buf;
1627     ASN_DEBUG("Encoding %" ASN_PRI_SIZE " in units", size_in_units);
1628     do {
1629         int need_eom = 0;
1630         ssize_t may_save = uper_put_length(po, size_in_units, &need_eom);
1631         if(may_save < 0) ASN__ENCODE_FAILED;
1632
1633         ASN_DEBUG("Encoding %" ASN_PRI_SSIZE " of %" ASN_PRI_SIZE "%s", may_save, size_in_units,
1634                   need_eom ? ",+EOM" : "");
1635
1636         ret = OCTET_STRING_per_put_characters(po, buf, may_save, bpc, unit_bits,
1637                                               cval->lower_bound,
1638                                               cval->upper_bound, pc);
1639         if(ret) ASN__ENCODE_FAILED;
1640
1641         buf += may_save * bpc;
1642         size_in_units -= may_save;
1643         assert(!(may_save & 0x07) || !size_in_units);
1644         if(need_eom && uper_put_length(po, 0, 0))
1645             ASN__ENCODE_FAILED; /* End of Message length */
1646     } while(size_in_units);
1647
1648     ASN__ENCODED_OK(er);
1649 }
1650
1651 asn_dec_rval_t
1652 OCTET_STRING_decode_aper(const asn_codec_ctx_t *opt_codec_ctx,
1653                          const asn_TYPE_descriptor_t *td,
1654                          const asn_per_constraints_t *constraints,
1655                          void **sptr, asn_per_data_t *pd) {
1656
1657         const asn_OCTET_STRING_specifics_t *specs = td->specifics
1658                 ? (const asn_OCTET_STRING_specifics_t *)td->specifics
1659                 : &asn_SPC_OCTET_STRING_specs;
1660         const asn_per_constraints_t *pc = constraints ? constraints
1661                                 : td->encoding_constraints.per_constraints;
1662         const asn_per_constraint_t *cval;
1663         const asn_per_constraint_t *csiz;
1664         asn_dec_rval_t rval = { RC_OK, 0 };
1665         BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
1666         ssize_t consumed_myself = 0;
1667         int repeat;
1668         enum {
1669                 OS__BPC_BIT     = 0,
1670                 OS__BPC_CHAR    = 1,
1671                 OS__BPC_U16     = 2,
1672                 OS__BPC_U32     = 4
1673         } bpc;  /* Bytes per character */
1674         unsigned int unit_bits;
1675         unsigned int canonical_unit_bits;
1676
1677         (void)opt_codec_ctx;
1678
1679         if(pc) {
1680                 cval = &pc->value;
1681                 csiz = &pc->size;
1682         } else {
1683                 cval = &asn_DEF_OCTET_STRING_constraints.value;
1684                 csiz = &asn_DEF_OCTET_STRING_constraints.size;
1685         }
1686
1687         switch(specs->subvariant) {
1688         default:
1689 /*      case ASN_OSUBV_ANY:
1690                 ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant);
1691                 RETURN(RC_FAIL);
1692 */
1693         case ASN_OSUBV_BIT:
1694                 canonical_unit_bits = unit_bits = 1;
1695                 bpc = OS__BPC_BIT;
1696                 break;
1697         case ASN_OSUBV_ANY:
1698         case ASN_OSUBV_STR:
1699                 canonical_unit_bits = unit_bits = 8;
1700 /*              if(cval->flags & APC_CONSTRAINED)
1701                         unit_bits = cval->range_bits;
1702 */
1703                 bpc = OS__BPC_CHAR;
1704                 break;
1705         case ASN_OSUBV_U16:
1706                 canonical_unit_bits = unit_bits = 16;
1707                 if(cval->flags & APC_CONSTRAINED)
1708                         unit_bits = cval->range_bits;
1709                 bpc = OS__BPC_U16;
1710                 break;
1711         case ASN_OSUBV_U32:
1712                 canonical_unit_bits = unit_bits = 32;
1713                 if(cval->flags & APC_CONSTRAINED)
1714                         unit_bits = cval->range_bits;
1715                 bpc = OS__BPC_U32;
1716                 break;
1717         }
1718
1719         /*
1720          * Allocate the string.
1721          */
1722         if(!st) {
1723                 st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
1724                 if(!st) RETURN(RC_FAIL);
1725         }
1726
1727         ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d",
1728                 csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
1729                 csiz->lower_bound, csiz->upper_bound, csiz->effective_bits);
1730
1731         if(csiz->flags & APC_EXTENSIBLE) {
1732                 int inext = per_get_few_bits(pd, 1);
1733                 if(inext < 0) RETURN(RC_WMORE);
1734                 if(inext) {
1735                         csiz = &asn_DEF_OCTET_STRING_constraints.size;
1736                         cval = &asn_DEF_OCTET_STRING_constraints.value;
1737                         unit_bits = canonical_unit_bits;
1738                 }
1739         }
1740
1741         if(csiz->effective_bits >= 0) {
1742                 FREEMEM(st->buf);
1743                 if(bpc) {
1744                         st->size = csiz->upper_bound * bpc;
1745                 } else {
1746                         st->size = (csiz->upper_bound + 7) >> 3;
1747                 }
1748                 st->buf = (uint8_t *)MALLOC(st->size + 1);
1749                 if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
1750         }
1751
1752         /* X.691, #16.5: zero-length encoding */
1753         /* X.691, #16.6: short fixed length encoding (up to 2 octets) */
1754         /* X.691, #16.7: long fixed length encoding (up to 64K octets) */
1755         if(csiz->effective_bits == 0) {
1756                 int ret;
1757                 if (st->size > 2) { /* X.691 #16 NOTE 1 */
1758                         if (aper_get_align(pd) < 0)
1759                                 RETURN(RC_FAIL);
1760                 }
1761                 if(bpc) {
1762                         ASN_DEBUG("Decoding OCTET STRING size %ld",
1763                                 csiz->upper_bound);
1764                         ret = OCTET_STRING_per_get_characters(pd, st->buf,
1765                                 csiz->upper_bound, bpc, unit_bits,
1766                                 cval->lower_bound, cval->upper_bound, pc);
1767                         if(ret > 0) RETURN(RC_FAIL);
1768                 } else {
1769                         ASN_DEBUG("Decoding BIT STRING size %ld",
1770                                 csiz->upper_bound);
1771                         ret = per_get_many_bits(pd, st->buf, 0,
1772                                             unit_bits * csiz->upper_bound);
1773                 }
1774                 if(ret < 0) RETURN(RC_WMORE);
1775                 consumed_myself += unit_bits * csiz->upper_bound;
1776                 st->buf[st->size] = 0;
1777                 if(bpc == 0) {
1778                         int ubs = (csiz->upper_bound & 0x7);
1779                         st->bits_unused = ubs ? 8 - ubs : 0;
1780                 }
1781                 RETURN(RC_OK);
1782         }
1783
1784         st->size = 0;
1785         do {
1786                 ssize_t raw_len;
1787                 ssize_t len_bytes;
1788                 ssize_t len_bits;
1789                 void *p;
1790                 int ret;
1791
1792                 /* Get the PER length */
1793                 if (csiz->upper_bound - csiz->lower_bound == 0)
1794                         /* Indefinite length case */
1795                         raw_len = aper_get_length(pd, -1, csiz->effective_bits, &repeat);
1796                 else
1797                         raw_len = aper_get_length(pd, csiz->upper_bound - csiz->lower_bound + 1, csiz->effective_bits, &repeat);
1798                 repeat = 0;
1799                 if(raw_len < 0) RETURN(RC_WMORE);
1800                 raw_len += csiz->lower_bound;
1801
1802                 ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
1803                         (long)csiz->effective_bits, (long)raw_len,
1804                         repeat ? "repeat" : "once", td->name);
1805
1806                 if (raw_len > 2) { /* X.691 #16 NOTE 1 */
1807                         if (aper_get_align(pd) < 0)
1808                                 RETURN(RC_FAIL);
1809                 }
1810
1811                 if(bpc) {
1812                         len_bytes = raw_len * bpc;
1813                         len_bits = len_bytes * unit_bits;
1814                 } else {
1815                         len_bits = raw_len;
1816                         len_bytes = (len_bits + 7) >> 3;
1817                         if(len_bits & 0x7)
1818                                 st->bits_unused = 8 - (len_bits & 0x7);
1819                         /* len_bits be multiple of 16K if repeat is set */
1820                 }
1821                 p = REALLOC(st->buf, st->size + len_bytes + 1);
1822                 if(!p) RETURN(RC_FAIL);
1823                 st->buf = (uint8_t *)p;
1824
1825                 if(bpc) {
1826                         ret = OCTET_STRING_per_get_characters(pd,
1827                                 &st->buf[st->size], raw_len, bpc, unit_bits,
1828                                 cval->lower_bound, cval->upper_bound, pc);
1829                         if(ret > 0) RETURN(RC_FAIL);
1830                 } else {
1831                         ret = per_get_many_bits(pd, &st->buf[st->size],
1832                                 0, len_bits);
1833                 }
1834                 if(ret < 0) RETURN(RC_WMORE);
1835                 st->size += len_bytes;
1836         } while(repeat);
1837         st->buf[st->size] = 0;  /* nul-terminate */
1838
1839         return rval;
1840 }
1841
1842 asn_enc_rval_t
1843 OCTET_STRING_encode_aper(const asn_TYPE_descriptor_t *td,
1844                          const asn_per_constraints_t *constraints,
1845                          const void *sptr, asn_per_outp_t *po) {
1846
1847         const asn_OCTET_STRING_specifics_t *specs = td->specifics
1848                 ? (const asn_OCTET_STRING_specifics_t *)td->specifics
1849                 : &asn_SPC_OCTET_STRING_specs;
1850         const asn_per_constraints_t *pc = constraints ? constraints
1851         : td->encoding_constraints.per_constraints;
1852         const asn_per_constraint_t *cval;
1853         const asn_per_constraint_t *csiz;
1854         const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
1855         asn_enc_rval_t er = { 0, 0, 0 };
1856         int inext = 0;          /* Lies not within extension root */
1857         unsigned int unit_bits;
1858         unsigned int canonical_unit_bits;
1859         unsigned int sizeinunits;
1860         const uint8_t *buf;
1861         int ret;
1862         enum {
1863                 OS__BPC_BIT     = 0,
1864                 OS__BPC_CHAR    = 1,
1865                 OS__BPC_U16     = 2,
1866                 OS__BPC_U32     = 4
1867         } bpc;  /* Bytes per character */
1868         int ct_extensible;
1869
1870         if(!st || (!st->buf && st->size))
1871                 ASN__ENCODE_FAILED;
1872
1873         if(pc) {
1874                 cval = &pc->value;
1875                 csiz = &pc->size;
1876         } else {
1877                 cval = &asn_DEF_OCTET_STRING_constraints.value;
1878                 csiz = &asn_DEF_OCTET_STRING_constraints.size;
1879         }
1880         ct_extensible = csiz->flags & APC_EXTENSIBLE;
1881
1882         switch(specs->subvariant) {
1883                 default:
1884                         /*         case ASN_OSUBV_ANY:
1885                                          ASN__ENCODE_FAILED;
1886                         */
1887                 case ASN_OSUBV_BIT:
1888                         canonical_unit_bits = unit_bits = 1;
1889                         bpc = OS__BPC_BIT;
1890                         sizeinunits = st->size * 8 - (st->bits_unused & 0x07);
1891                         ASN_DEBUG("BIT STRING of %d bytes",
1892                                                                 sizeinunits);
1893                 break;
1894         case ASN_OSUBV_ANY:
1895         case ASN_OSUBV_STR:
1896                 canonical_unit_bits = unit_bits = 8;
1897 /*              if(cval->flags & APC_CONSTRAINED)
1898                         unit_bits = 8;
1899 */
1900                 bpc = OS__BPC_CHAR;
1901                 sizeinunits = st->size;
1902                 break;
1903         case ASN_OSUBV_U16:
1904                 canonical_unit_bits = unit_bits = 16;
1905                 if(cval->flags & APC_CONSTRAINED)
1906                         unit_bits = cval->range_bits;
1907                 bpc = OS__BPC_U16;
1908                 sizeinunits = st->size / 2;
1909                 break;
1910         case ASN_OSUBV_U32:
1911                 canonical_unit_bits = unit_bits = 32;
1912                 if(cval->flags & APC_CONSTRAINED)
1913                         unit_bits = cval->range_bits;
1914                 bpc = OS__BPC_U32;
1915                 sizeinunits = st->size / 4;
1916                 break;
1917         }
1918
1919         ASN_DEBUG("Encoding %s into %d units of %d bits"
1920                 " (%ld..%ld, effective %d)%s",
1921                 td->name, sizeinunits, unit_bits,
1922                 csiz->lower_bound, csiz->upper_bound,
1923                 csiz->effective_bits, ct_extensible ? " EXT" : "");
1924
1925         /* Figure out wheter size lies within PER visible constraint */
1926
1927         if(csiz->effective_bits >= 0) {
1928                 if((int)sizeinunits < csiz->lower_bound
1929                 || (int)sizeinunits > csiz->upper_bound) {
1930                         if(ct_extensible) {
1931                                 cval = &asn_DEF_OCTET_STRING_constraints.value;
1932                                 csiz = &asn_DEF_OCTET_STRING_constraints.size;
1933                                 unit_bits = canonical_unit_bits;
1934                                 inext = 1;
1935                         } else
1936                                 ASN__ENCODE_FAILED;
1937                 }
1938         } else {
1939                 inext = 0;
1940         }
1941
1942
1943         if(ct_extensible) {
1944                 /* Declare whether length is [not] within extension root */
1945                 if(per_put_few_bits(po, inext, 1))
1946                         ASN__ENCODE_FAILED;
1947         }
1948
1949         /* X.691, #16.5: zero-length encoding */
1950         /* X.691, #16.6: short fixed length encoding (up to 2 octets) */
1951         /* X.691, #16.7: long fixed length encoding (up to 64K octets) */
1952         if(csiz->effective_bits >= 0) {
1953                 ASN_DEBUG("Encoding %lu bytes (%ld), length in %d bits",
1954                                 st->size, sizeinunits - csiz->lower_bound,
1955                                 csiz->effective_bits);
1956                 if (csiz->effective_bits > 0) {
1957                         ret = aper_put_length(po, csiz->upper_bound - csiz->lower_bound + 1, sizeinunits - csiz->lower_bound);
1958                         if(ret) ASN__ENCODE_FAILED;
1959                 }
1960                 if (st->size > 2) { /* X.691 #16 NOTE 1 */
1961                         if (aper_put_align(po) < 0)
1962                                 ASN__ENCODE_FAILED;
1963                 }
1964                 if(bpc) {
1965                         ret = OCTET_STRING_per_put_characters(po, st->buf,
1966                                 sizeinunits, bpc, unit_bits,
1967                                 cval->lower_bound, cval->upper_bound, pc);
1968                 } else {
1969                         ret = per_put_many_bits(po, st->buf,
1970                                 sizeinunits * unit_bits);
1971                 }
1972                 if(ret) ASN__ENCODE_FAILED;
1973                 ASN__ENCODED_OK(er);
1974         }
1975
1976         ASN_DEBUG("Encoding %lu bytes", st->size);
1977
1978         if(sizeinunits == 0) {
1979                 if(aper_put_length(po, -1, 0))
1980                         ASN__ENCODE_FAILED;
1981                 ASN__ENCODED_OK(er);
1982         }
1983
1984         buf = st->buf;
1985         while(sizeinunits) {
1986                 ssize_t maySave = aper_put_length(po, -1, sizeinunits);
1987
1988                 if(maySave < 0) ASN__ENCODE_FAILED;
1989
1990                 ASN_DEBUG("Encoding %ld of %ld",
1991                         (long)maySave, (long)sizeinunits);
1992
1993                 if(bpc) {
1994                         ret = OCTET_STRING_per_put_characters(po, buf,
1995                                 maySave, bpc, unit_bits,
1996                                 cval->lower_bound, cval->upper_bound, pc);
1997                 } else {
1998                         ret = per_put_many_bits(po, buf, maySave * unit_bits);
1999                 }
2000                 if(ret) ASN__ENCODE_FAILED;
2001
2002                 if(bpc)
2003                         buf += maySave * bpc;
2004                 else
2005                         buf += maySave >> 3;
2006                 sizeinunits -= maySave;
2007                 assert(!(maySave & 0x07) || !sizeinunits);
2008         }
2009
2010         ASN__ENCODED_OK(er);
2011 }
2012
2013 #endif  /* ASN_DISABLE_PER_SUPPORT */
2014
2015 int
2016 OCTET_STRING_print(const asn_TYPE_descriptor_t *td, const void *sptr,
2017                    int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
2018     const char * const h2c = "0123456789ABCDEF";
2019         const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
2020         char scratch[16 * 3 + 4];
2021         char *p = scratch;
2022         uint8_t *buf;
2023         uint8_t *end;
2024         size_t i;
2025
2026         (void)td;       /* Unused argument */
2027
2028         if(!st || (!st->buf && st->size))
2029                 return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
2030
2031         /*
2032          * Dump the contents of the buffer in hexadecimal.
2033          */
2034         buf = st->buf;
2035         end = buf + st->size;
2036         for(i = 0; buf < end; buf++, i++) {
2037                 if(!(i % 16) && (i || st->size > 16)) {
2038                         if(cb(scratch, p - scratch, app_key) < 0)
2039                                 return -1;
2040                         _i_INDENT(1);
2041                         p = scratch;
2042                 }
2043                 *p++ = h2c[(*buf >> 4) & 0x0F];
2044                 *p++ = h2c[*buf & 0x0F];
2045                 *p++ = 0x20;
2046         }
2047
2048         if(p > scratch) {
2049                 p--;    /* Remove the tail space */
2050                 if(cb(scratch, p - scratch, app_key) < 0)
2051                         return -1;
2052         }
2053
2054         return 0;
2055 }
2056
2057 int
2058 OCTET_STRING_print_utf8(const asn_TYPE_descriptor_t *td, const void *sptr,
2059                         int ilevel, asn_app_consume_bytes_f *cb,
2060                         void *app_key) {
2061     const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
2062
2063         (void)td;       /* Unused argument */
2064         (void)ilevel;   /* Unused argument */
2065
2066         if(st && (st->buf || !st->size)) {
2067                 return (cb(st->buf, st->size, app_key) < 0) ? -1 : 0;
2068         } else {
2069                 return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
2070         }
2071 }
2072
2073 void
2074 OCTET_STRING_free(const asn_TYPE_descriptor_t *td, void *sptr,
2075                   enum asn_struct_free_method method) {
2076         OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
2077         const asn_OCTET_STRING_specifics_t *specs;
2078         asn_struct_ctx_t *ctx;
2079         struct _stack *stck;
2080
2081         if(!td || !st)
2082                 return;
2083
2084         specs = td->specifics
2085                     ? (const asn_OCTET_STRING_specifics_t *)td->specifics
2086                     : &asn_SPC_OCTET_STRING_specs;
2087         ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
2088
2089         ASN_DEBUG("Freeing %s as OCTET STRING", td->name);
2090
2091         if(st->buf) {
2092                 FREEMEM(st->buf);
2093                 st->buf = 0;
2094         }
2095
2096         /*
2097          * Remove decode-time stack.
2098          */
2099         stck = (struct _stack *)ctx->ptr;
2100         if(stck) {
2101                 while(stck->tail) {
2102                         struct _stack_el *sel = stck->tail;
2103                         stck->tail = sel->prev;
2104                         FREEMEM(sel);
2105                 }
2106                 FREEMEM(stck);
2107         }
2108
2109     switch(method) {
2110     case ASFM_FREE_EVERYTHING:
2111         FREEMEM(sptr);
2112         break;
2113     case ASFM_FREE_UNDERLYING:
2114         break;
2115     case ASFM_FREE_UNDERLYING_AND_RESET:
2116         memset(sptr, 0,
2117                td->specifics
2118                    ? ((const asn_OCTET_STRING_specifics_t *)(td->specifics))
2119                          ->struct_size
2120                    : sizeof(OCTET_STRING_t));
2121         break;
2122     }
2123 }
2124
2125 /*
2126  * Conversion routines.
2127  */
2128 int
2129 OCTET_STRING_fromBuf(OCTET_STRING_t *st, const char *str, int len) {
2130         void *buf;
2131
2132         if(st == 0 || (str == 0 && len)) {
2133                 errno = EINVAL;
2134                 return -1;
2135         }
2136
2137         /*
2138          * Clear the OCTET STRING.
2139          */
2140         if(str == NULL) {
2141                 FREEMEM(st->buf);
2142                 st->buf = 0;
2143                 st->size = 0;
2144                 return 0;
2145         }
2146
2147         /* Determine the original string size, if not explicitly given */
2148         if(len < 0)
2149                 len = strlen(str);
2150
2151         /* Allocate and fill the memory */
2152         buf = MALLOC(len + 1);
2153         if(buf == NULL)
2154                 return -1;
2155
2156         memcpy(buf, str, len);
2157         ((uint8_t *)buf)[len] = '\0';   /* Couldn't use memcpy(len+1)! */
2158         FREEMEM(st->buf);
2159         st->buf = (uint8_t *)buf;
2160         st->size = len;
2161
2162         return 0;
2163 }
2164
2165 OCTET_STRING_t *
2166 OCTET_STRING_new_fromBuf(const asn_TYPE_descriptor_t *td, const char *str,
2167                          int len) {
2168     const asn_OCTET_STRING_specifics_t *specs =
2169         td->specifics ? (const asn_OCTET_STRING_specifics_t *)td->specifics
2170                       : &asn_SPC_OCTET_STRING_specs;
2171     OCTET_STRING_t *st;
2172
2173         st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
2174         if(st && str && OCTET_STRING_fromBuf(st, str, len)) {
2175                 FREEMEM(st);
2176                 st = NULL;
2177         }
2178
2179         return st;
2180 }
2181
2182 /*
2183  * Lexicographically compare the common prefix of both strings,
2184  * and if it is the same return -1 for the smallest string.
2185  */
2186 int
2187 OCTET_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
2188                      const void *bptr) {
2189     const asn_OCTET_STRING_specifics_t *specs = td->specifics;
2190     const OCTET_STRING_t *a = aptr;
2191     const OCTET_STRING_t *b = bptr;
2192
2193     assert(!specs || specs->subvariant != ASN_OSUBV_BIT);
2194
2195     if(a && b) {
2196         size_t common_prefix_size = a->size <= b->size ? a->size : b->size;
2197         int ret = memcmp(a->buf, b->buf, common_prefix_size);
2198         if(ret == 0) {
2199             /* Figure out which string with equal prefixes is longer. */
2200             if(a->size < b->size) {
2201                 return -1;
2202             } else if(a->size > b->size) {
2203                 return 1;
2204             } else {
2205                 return 0;
2206             }
2207         } else {
2208             return ret < 0 ? -1 : 1;
2209         }
2210     } else if(!a && !b) {
2211         return 0;
2212     } else if(!a) {
2213         return -1;
2214     } else {
2215         return 1;
2216     }
2217
2218 }
2219
2220 /*
2221  * Biased function for randomizing character values around their limits.
2222  */
2223 static uint32_t
2224 OCTET_STRING__random_char(unsigned long lb, unsigned long ub) {
2225     assert(lb <= ub);
2226     switch(asn_random_between(0, 16)) {
2227     case 0:
2228         if(lb < ub) return lb + 1;
2229         /* Fall through */
2230     case 1:
2231         return lb;
2232     case 2:
2233         if(lb < ub) return ub - 1;
2234         /* Fall through */
2235     case 3:
2236         return ub;
2237     default:
2238         return asn_random_between(lb, ub);
2239     }
2240 }
2241
2242
2243 size_t
2244 OCTET_STRING_random_length_constrained(
2245     const asn_TYPE_descriptor_t *td,
2246     const asn_encoding_constraints_t *constraints, size_t max_length) {
2247     const unsigned lengths[] = {0,     1,     2,     3,     4,     8,
2248                                 126,   127,   128,   16383, 16384, 16385,
2249                                 65534, 65535, 65536, 65537};
2250     size_t rnd_len;
2251
2252     /* Figure out how far we should go */
2253     rnd_len = lengths[asn_random_between(
2254         0, sizeof(lengths) / sizeof(lengths[0]) - 1)];
2255
2256     if(!constraints || !constraints->per_constraints)
2257         constraints = &td->encoding_constraints;
2258     if(constraints->per_constraints) {
2259         const asn_per_constraint_t *pc = &constraints->per_constraints->size;
2260         if(pc->flags & APC_CONSTRAINED) {
2261             long suggested_upper_bound = pc->upper_bound < (ssize_t)max_length
2262                                              ? pc->upper_bound
2263                                              : (ssize_t)max_length;
2264             if(max_length <= (size_t)pc->lower_bound) {
2265                 return pc->lower_bound;
2266             }
2267             if(pc->flags & APC_EXTENSIBLE) {
2268                 switch(asn_random_between(0, 5)) {
2269                 case 0:
2270                     if(pc->lower_bound > 0) {
2271                         rnd_len = pc->lower_bound - 1;
2272                         break;
2273                     }
2274                     /* Fall through */
2275                 case 1:
2276                     rnd_len = pc->upper_bound + 1;
2277                     break;
2278                 case 2:
2279                     /* Keep rnd_len from the table */
2280                     if(rnd_len <= max_length) {
2281                         break;
2282                     }
2283                     /* Fall through */
2284                 default:
2285                     rnd_len = asn_random_between(pc->lower_bound,
2286                                                  suggested_upper_bound);
2287                 }
2288             } else {
2289                 rnd_len =
2290                     asn_random_between(pc->lower_bound, suggested_upper_bound);
2291             }
2292         } else {
2293             rnd_len = asn_random_between(0, max_length);
2294         }
2295     } else if(rnd_len > max_length) {
2296         rnd_len = asn_random_between(0, max_length);
2297     }
2298
2299     return rnd_len;
2300 }
2301
2302 asn_random_fill_result_t
2303 OCTET_STRING_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
2304                          const asn_encoding_constraints_t *constraints,
2305                          size_t max_length) {
2306         const asn_OCTET_STRING_specifics_t *specs = td->specifics
2307                                 ? (const asn_OCTET_STRING_specifics_t *)td->specifics
2308                                 : &asn_SPC_OCTET_STRING_specs;
2309     asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
2310     asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
2311     asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
2312     unsigned int unit_bytes = 1;
2313     unsigned long clb = 0;  /* Lower bound on char */
2314     unsigned long cub = 255;  /* Higher bound on char value */
2315     uint8_t *buf;
2316     uint8_t *bend;
2317     uint8_t *b;
2318     size_t rnd_len;
2319     OCTET_STRING_t *st;
2320
2321     if(max_length == 0 && !*sptr) return result_skipped;
2322
2323     switch(specs->subvariant) {
2324     default:
2325     case ASN_OSUBV_ANY:
2326         return result_failed;
2327     case ASN_OSUBV_BIT:
2328         /* Handled by BIT_STRING itself. */
2329         return result_failed;
2330     case ASN_OSUBV_STR:
2331         unit_bytes = 1;
2332         clb = 0;
2333         cub = 255;
2334         break;
2335     case ASN_OSUBV_U16:
2336         unit_bytes = 2;
2337         clb = 0;
2338         cub = 65535;
2339         break;
2340     case ASN_OSUBV_U32:
2341         unit_bytes = 4;
2342         clb = 0;
2343         cub = 0x10FFFF;
2344         break;
2345     }
2346
2347     if(!constraints || !constraints->per_constraints)
2348         constraints = &td->encoding_constraints;
2349     if(constraints->per_constraints) {
2350         const asn_per_constraint_t *pc = &constraints->per_constraints->value;
2351         if(pc->flags & APC_SEMI_CONSTRAINED) {
2352             clb = pc->lower_bound;
2353         } else if(pc->flags & APC_CONSTRAINED) {
2354             clb = pc->lower_bound;
2355             cub = pc->upper_bound;
2356         }
2357     }
2358
2359     rnd_len =
2360         OCTET_STRING_random_length_constrained(td, constraints, max_length);
2361
2362     buf = CALLOC(unit_bytes, rnd_len + 1);
2363     if(!buf) return result_failed;
2364
2365     bend = &buf[unit_bytes * rnd_len];
2366
2367     switch(unit_bytes) {
2368     case 1:
2369         for(b = buf; b < bend; b += unit_bytes) {
2370             *(uint8_t *)b = OCTET_STRING__random_char(clb, cub);
2371         }
2372         *(uint8_t *)b = 0;
2373         break;
2374     case 2:
2375         for(b = buf; b < bend; b += unit_bytes) {
2376             uint32_t code = OCTET_STRING__random_char(clb, cub);
2377             b[0] = code >> 8;
2378             b[1] = code;
2379         }
2380         *(uint16_t *)b = 0;
2381         break;
2382     case 4:
2383         for(b = buf; b < bend; b += unit_bytes) {
2384             uint32_t code = OCTET_STRING__random_char(clb, cub);
2385             b[0] = code >> 24;
2386             b[1] = code >> 16;
2387             b[2] = code >> 8;
2388             b[3] = code;
2389         }
2390         *(uint32_t *)b = 0;
2391         break;
2392     }
2393
2394     if(*sptr) {
2395         st = *sptr;
2396         FREEMEM(st->buf);
2397     } else {
2398         st = (OCTET_STRING_t *)(*sptr = CALLOC(1, specs->struct_size));
2399         if(!st) {
2400             FREEMEM(buf);
2401             return result_failed;
2402         }
2403     }
2404
2405     st->buf = buf;
2406     st->size = unit_bytes * rnd_len;
2407
2408     result_ok.length = st->size;
2409     return result_ok;
2410 }