"Fossies" - the Fresh Open Source Software Archive

Member "mod_auth_gssapi-1.6.3/src/asn1c/per_opentype.c" (15 Mar 2017, 9566 Bytes) of package /linux/www/apache_httpd_modules/mod_auth_gssapi-1.6.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "per_opentype.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (c) 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
    3  * Redistribution and modifications are permitted subject to BSD license.
    4  */
    5 #include <asn_internal.h>
    6 #include <per_support.h>
    7 #include <constr_TYPE.h>
    8 #include <per_opentype.h>
    9 
   10 typedef struct uper_ugot_key {
   11     asn_per_data_t oldpd;   /* Old per data source */
   12     size_t unclaimed;
   13     size_t ot_moved;    /* Number of bits moved by OT processing */
   14     int repeat;
   15 } uper_ugot_key;
   16 
   17 static int uper_ugot_refill(asn_per_data_t *pd);
   18 static int per_skip_bits(asn_per_data_t *pd, int skip_nbits);
   19 static asn_dec_rval_t uper_sot_suck(asn_codec_ctx_t *, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd);
   20 
   21 /*
   22  * Encode an "open type field".
   23  * #10.1, #10.2
   24  */
   25 int
   26 uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
   27     void *buf;
   28     void *bptr;
   29     ssize_t size;
   30     size_t toGo;
   31 
   32     ASN_DEBUG("Open type put %s ...", td->name);
   33 
   34     size = uper_encode_to_new_buffer(td, constraints, sptr, &buf);
   35     if(size <= 0) return -1;
   36 
   37     for(bptr = buf, toGo = size; toGo;) {
   38         ssize_t maySave = uper_put_length(po, toGo);
   39         ASN_DEBUG("Prepending length %d to %s and allowing to save %d",
   40             (int)size, td->name, (int)maySave);
   41         if(maySave < 0) break;
   42         if(per_put_many_bits(po, bptr, maySave * 8)) break;
   43         bptr = (char *)bptr + maySave;
   44         toGo -= maySave;
   45     }
   46 
   47     FREEMEM(buf);
   48     if(toGo) return -1;
   49 
   50     ASN_DEBUG("Open type put %s of length %ld + overhead (1byte?)",
   51         td->name, (long)size);
   52 
   53     return 0;
   54 }
   55 
   56 static asn_dec_rval_t
   57 uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
   58     asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
   59     asn_dec_rval_t rv;
   60     ssize_t chunk_bytes;
   61     int repeat;
   62     uint8_t *buf = 0;
   63     size_t bufLen = 0;
   64     size_t bufSize = 0;
   65     asn_per_data_t spd;
   66     size_t padding;
   67 
   68     _ASN_STACK_OVERFLOW_CHECK(ctx);
   69 
   70     ASN_DEBUG("Getting open type %s...", td->name);
   71 
   72     do {
   73         chunk_bytes = uper_get_length(pd, -1, &repeat);
   74         if(chunk_bytes < 0) {
   75             FREEMEM(buf);
   76             _ASN_DECODE_STARVED;
   77         }
   78         if(bufLen + chunk_bytes > bufSize) {
   79             void *ptr;
   80             bufSize = chunk_bytes + (bufSize << 2);
   81             ptr = REALLOC(buf, bufSize);
   82             if(!ptr) {
   83                 FREEMEM(buf);
   84                 _ASN_DECODE_FAILED;
   85             }
   86             buf = ptr;
   87         }
   88         if(per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) {
   89             FREEMEM(buf);
   90             _ASN_DECODE_STARVED;
   91         }
   92         bufLen += chunk_bytes;
   93     } while(repeat);
   94 
   95     ASN_DEBUG("Getting open type %s encoded in %ld bytes", td->name,
   96         (long)bufLen);
   97 
   98     memset(&spd, 0, sizeof(spd));
   99     spd.buffer = buf;
  100     spd.nbits = bufLen << 3;
  101 
  102     ASN_DEBUG_INDENT_ADD(+4);
  103     rv = td->uper_decoder(ctx, td, constraints, sptr, &spd);
  104     ASN_DEBUG_INDENT_ADD(-4);
  105 
  106     if(rv.code == RC_OK) {
  107         /* Check padding validity */
  108         padding = spd.nbits - spd.nboff;
  109                 if ((padding < 8 ||
  110         /* X.691#10.1.3 */
  111         (spd.nboff == 0 && spd.nbits == 8 && spd.buffer == buf)) &&
  112                     per_get_few_bits(&spd, padding) == 0) {
  113             /* Everything is cool */
  114             FREEMEM(buf);
  115             return rv;
  116         }
  117         FREEMEM(buf);
  118         if(padding >= 8) {
  119             ASN_DEBUG("Too large padding %d in open type", (int)padding);
  120             _ASN_DECODE_FAILED;
  121         } else {
  122             ASN_DEBUG("Non-zero padding");
  123             _ASN_DECODE_FAILED;
  124         }
  125     } else {
  126         FREEMEM(buf);
  127         /* rv.code could be RC_WMORE, nonsense in this context */
  128         rv.code = RC_FAIL; /* Noone would give us more */
  129     }
  130 
  131     return rv;
  132 }
  133 
  134 static asn_dec_rval_t GCC_NOTUSED
  135 uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
  136     asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
  137     uper_ugot_key arg;
  138     asn_dec_rval_t rv;
  139     ssize_t padding;
  140 
  141     _ASN_STACK_OVERFLOW_CHECK(ctx);
  142 
  143     ASN_DEBUG("Getting open type %s from %s", td->name,
  144         per_data_string(pd));
  145     arg.oldpd = *pd;
  146     arg.unclaimed = 0;
  147     arg.ot_moved = 0;
  148     arg.repeat = 1;
  149     pd->refill = uper_ugot_refill;
  150     pd->refill_key = &arg;
  151     pd->nbits = pd->nboff;  /* 0 good bits at this point, will refill */
  152     pd->moved = 0;  /* This now counts the open type size in bits */
  153 
  154     ASN_DEBUG_INDENT_ADD(+4);
  155     rv = td->uper_decoder(ctx, td, constraints, sptr, pd);
  156     ASN_DEBUG_INDENT_ADD(-4);
  157 
  158 #define UPDRESTOREPD    do {                        \
  159     /* buffer and nboff are valid, preserve them. */        \
  160     pd->nbits = arg.oldpd.nbits - (pd->moved - arg.ot_moved);   \
  161     pd->moved = arg.oldpd.moved + (pd->moved - arg.ot_moved);   \
  162     pd->refill = arg.oldpd.refill;                  \
  163     pd->refill_key = arg.oldpd.refill_key;              \
  164   } while(0)
  165 
  166     if(rv.code != RC_OK) {
  167         UPDRESTOREPD;
  168         return rv;
  169     }
  170 
  171     ASN_DEBUG("OpenType %s pd%s old%s unclaimed=%d, repeat=%d", td->name,
  172         per_data_string(pd),
  173         per_data_string(&arg.oldpd),
  174         (int)arg.unclaimed, (int)arg.repeat);
  175 
  176     padding = pd->moved % 8;
  177     if(padding) {
  178         int32_t pvalue;
  179         if(padding > 7) {
  180             ASN_DEBUG("Too large padding %d in open type",
  181                 (int)padding);
  182             rv.code = RC_FAIL;
  183             UPDRESTOREPD;
  184             return rv;
  185         }
  186         padding = 8 - padding;
  187         ASN_DEBUG("Getting padding of %d bits", (int)padding);
  188         pvalue = per_get_few_bits(pd, padding);
  189         switch(pvalue) {
  190         case -1:
  191             ASN_DEBUG("Padding skip failed");
  192             UPDRESTOREPD;
  193             _ASN_DECODE_STARVED;
  194         case 0: break;
  195         default:
  196             ASN_DEBUG("Non-blank padding (%d bits 0x%02x)",
  197                 (int)padding, (int)pvalue);
  198             UPDRESTOREPD;
  199             _ASN_DECODE_FAILED;
  200         }
  201     }
  202     if(pd->nboff != pd->nbits) {
  203         ASN_DEBUG("Open type %s overhead pd%s old%s", td->name,
  204             per_data_string(pd), per_data_string(&arg.oldpd));
  205         if(1) {
  206             UPDRESTOREPD;
  207             _ASN_DECODE_FAILED;
  208         } else {
  209             arg.unclaimed += pd->nbits - pd->nboff;
  210         }
  211     }
  212 
  213     /* Adjust pd back so it points to original data */
  214     UPDRESTOREPD;
  215 
  216     /* Skip data not consumed by the decoder */
  217     if(arg.unclaimed) {
  218         ASN_DEBUG("Getting unclaimed %d", (int)arg.unclaimed);
  219         switch(per_skip_bits(pd, arg.unclaimed)) {
  220         case -1:
  221             ASN_DEBUG("Claim of %d failed", (int)arg.unclaimed);
  222             _ASN_DECODE_STARVED;
  223         case 0:
  224             ASN_DEBUG("Got claim of %d", (int)arg.unclaimed);
  225             break;
  226         default:
  227             /* Padding must be blank */
  228             ASN_DEBUG("Non-blank unconsumed padding");
  229             _ASN_DECODE_FAILED;
  230         }
  231         arg.unclaimed = 0;
  232     }
  233 
  234     if(arg.repeat) {
  235         ASN_DEBUG("Not consumed the whole thing");
  236         rv.code = RC_FAIL;
  237         return rv;
  238     }
  239 
  240     return rv;
  241 }
  242 
  243 
  244 asn_dec_rval_t
  245 uper_open_type_get(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
  246     asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
  247 
  248     return uper_open_type_get_simple(ctx, td, constraints, sptr, pd);
  249 }
  250 
  251 int
  252 uper_open_type_skip(asn_codec_ctx_t *ctx, asn_per_data_t *pd) {
  253     asn_TYPE_descriptor_t s_td;
  254     asn_dec_rval_t rv;
  255 
  256     s_td.name = "<unknown extension>";
  257     s_td.uper_decoder = uper_sot_suck;
  258 
  259     rv = uper_open_type_get(ctx, &s_td, 0, 0, pd);
  260     if(rv.code != RC_OK)
  261         return -1;
  262     else
  263         return 0;
  264 }
  265 
  266 /*
  267  * Internal functions.
  268  */
  269 
  270 static asn_dec_rval_t
  271 uper_sot_suck(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
  272     asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
  273     asn_dec_rval_t rv;
  274 
  275     (void)ctx;
  276     (void)td;
  277     (void)constraints;
  278     (void)sptr;
  279 
  280     while(per_get_few_bits(pd, 24) >= 0);
  281 
  282     rv.code = RC_OK;
  283     rv.consumed = pd->moved;
  284 
  285     return rv;
  286 }
  287 
  288 static int
  289 uper_ugot_refill(asn_per_data_t *pd) {
  290     uper_ugot_key *arg = pd->refill_key;
  291     ssize_t next_chunk_bytes, next_chunk_bits;
  292     ssize_t avail;
  293 
  294     asn_per_data_t *oldpd = &arg->oldpd;
  295 
  296     ASN_DEBUG("REFILLING pd->moved=%ld, oldpd->moved=%ld",
  297         (long)pd->moved, (long)oldpd->moved);
  298 
  299     /* Advance our position to where pd is */
  300     oldpd->buffer = pd->buffer;
  301     oldpd->nboff  = pd->nboff;
  302     oldpd->nbits -= pd->moved - arg->ot_moved;
  303     oldpd->moved += pd->moved - arg->ot_moved;
  304     arg->ot_moved = pd->moved;
  305 
  306     if(arg->unclaimed) {
  307         /* Refill the container */
  308         if(per_get_few_bits(oldpd, 1))
  309             return -1;
  310         if(oldpd->nboff == 0) {
  311             assert(0);
  312             return -1;
  313         }
  314         pd->buffer = oldpd->buffer;
  315         pd->nboff = oldpd->nboff - 1;
  316         pd->nbits = oldpd->nbits;
  317         ASN_DEBUG("UNCLAIMED <- return from (pd->moved=%ld)",
  318             (long)pd->moved);
  319         return 0;
  320     }
  321 
  322     if(!arg->repeat) {
  323         ASN_DEBUG("Want more but refill doesn't have it");
  324         return -1;
  325     }
  326 
  327     next_chunk_bytes = uper_get_length(oldpd, -1, &arg->repeat);
  328     ASN_DEBUG("Open type LENGTH %ld bytes at off %ld, repeat %ld",
  329         (long)next_chunk_bytes, (long)oldpd->moved, (long)arg->repeat);
  330     if(next_chunk_bytes < 0) return -1;
  331     if(next_chunk_bytes == 0) {
  332         pd->refill = 0; /* No more refills, naturally */
  333         assert(!arg->repeat);   /* Implementation guarantee */
  334     }
  335     next_chunk_bits = next_chunk_bytes << 3;
  336     avail = oldpd->nbits - oldpd->nboff;
  337     if(avail >= next_chunk_bits) {
  338         pd->nbits = oldpd->nboff + next_chunk_bits;
  339         arg->unclaimed = 0;
  340         ASN_DEBUG("!+Parent frame %ld bits, alloting %ld [%ld..%ld] (%ld)",
  341             (long)next_chunk_bits, (long)oldpd->moved,
  342             (long)oldpd->nboff, (long)oldpd->nbits,
  343             (long)(oldpd->nbits - oldpd->nboff));
  344     } else {
  345         pd->nbits = oldpd->nbits;
  346         arg->unclaimed = next_chunk_bits - avail;
  347         ASN_DEBUG("!-Parent frame %ld, require %ld, will claim %ld",
  348             (long)avail, (long)next_chunk_bits,
  349             (long)arg->unclaimed);
  350     }
  351     pd->buffer = oldpd->buffer;
  352     pd->nboff = oldpd->nboff;
  353     ASN_DEBUG("Refilled pd%s old%s",
  354         per_data_string(pd), per_data_string(oldpd));
  355     return 0;
  356 }
  357 
  358 static int
  359 per_skip_bits(asn_per_data_t *pd, int skip_nbits) {
  360     int hasNonZeroBits = 0;
  361     while(skip_nbits > 0) {
  362         int skip;
  363 
  364         /* per_get_few_bits() is more efficient when nbits <= 24 */
  365         if(skip_nbits < 24)
  366             skip = skip_nbits;
  367         else
  368             skip = 24;
  369         skip_nbits -= skip;
  370 
  371         switch(per_get_few_bits(pd, skip)) {
  372         case -1: return -1; /* Starving */
  373         case 0: continue;   /* Skipped empty space */
  374         default: hasNonZeroBits = 1; continue;
  375         }
  376     }
  377     return hasNonZeroBits;
  378 }