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