decode.c

来自「一个非常美妙的proxy。功能强大。基于sip的协议。如果还要的话」· C语言 代码 · 共 1,051 行 · 第 1/2 页

C
1,051
字号
         }         else             pOctStr->data = 0;                  return stat;      }   }      nocts = getComponentLength (pctxt, 8);   if (nocts < 0) return LOG_ASN1ERR (pctxt, nocts);   else if (nocts == 0) {      pOctStr->numocts = 0;      ptmp = 0;   }   /* Allocate memory for the target string */   else {      ptmp = (ASN1OCTET*) ASN1MALLOC (pctxt, nocts);      if (0 == ptmp) return LOG_ASN1ERR (pctxt, ASN_E_NOMEM);   }   /* Call static octet string decode function */   stat = decodeOctetString (pctxt, &pOctStr->numocts, ptmp, nocts);   pOctStr->data = ptmp;   return stat;}int decodeLength (OOCTXT* pctxt, ASN1UINT* pvalue){   Asn1SizeCnst* pSize;   ASN1UINT lower, upper;   ASN1BOOL bitValue, extbit;   int      stat;   /* If size constraint is present and extendable, decode extension    */   /* bit..                                                             */   if (isExtendableSize(pctxt->pSizeConstraint)) {      stat = DECODEBIT (pctxt, &extbit);      if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);   }   else extbit = 0;   /* Now use the value of the extension bit to select the proper       */   /* size constraint range specification..                             */   pSize = getSizeConstraint (pctxt, extbit);   lower = (pSize) ? pSize->lower : 0;   upper = (pSize) ? pSize->upper : ASN1UINT_MAX;   /* Reset the size constraint in the context block structure */   pctxt->pSizeConstraint = 0;   /* If upper limit is less than 64k, constrained case */   if (upper < 65536) {      if (lower == upper) {         *pvalue = 0;         stat = ASN_OK;      }      else         stat = decodeConsWholeNumber (pctxt, pvalue, (upper - lower + 1));      if (stat == ASN_OK) *pvalue += lower;   }   else {      /* unconstrained case OR constrained with upper bound >= 64K*/      stat = decodeByteAlign (pctxt);      if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);      stat = DECODEBIT (pctxt, &bitValue);      if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);      if (bitValue == 0) {         stat = decodeBits (pctxt, pvalue, 7);   /* 10.9.3.6 */         if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);      }      else {         stat = DECODEBIT (pctxt, &bitValue);         if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);         if (bitValue == 0) {            stat = decodeBits (pctxt, pvalue, 14);  /* 10.9.3.7 */            if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);         }         else {            ASN1UINT multiplier;            stat = decodeBits (pctxt, &multiplier, 6);            if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);            *pvalue = 16384 * multiplier;            stat = ASN_OK_FRAG;         }      }   }   return stat;}int decodeObjectIdentifier (OOCTXT* pctxt, ASN1OBJID* pvalue){   ASN1UINT  len;   int       stat, j;   unsigned  subid;   ASN1UINT  b;   /* Decode unconstrained length */   if ((stat = decodeLength (pctxt, &len)) < 0) {      return LOG_ASN1ERR (pctxt, stat);   }   /* Copy contents to a byte-aligned local buffer */   j = 0;   while (len > 0 && stat == ASN_OK) {      if (j < ASN_K_MAXSUBIDS) {         /* Parse a subidentifier out of the contents field */         pvalue->subid[j] = 0;         do {            if ((stat = decodeBits (pctxt, &b, 8)) == ASN_OK) {               pvalue->subid[j] = (pvalue->subid[j] * 128) + (b & 0x7F);               len--;            }         } while (b & 0x80 && stat == ASN_OK);         /* Handle the first subidentifier special case: the first two   */         /* sub-id's are encoded into one using the formula (x * 40) + y */         if (j == 0) {            subid = pvalue->subid[0];            pvalue->subid[0] = ((subid / 40) >= 2) ? 2 : subid / 40;            pvalue->subid[1] = (pvalue->subid[0] == 2) ?                subid - 80 : subid % 40;            j = 2;         }         else j++;      }      else         stat = ASN_E_INVOBJID;    }   pvalue->numids = j;   if (stat == ASN_OK && len != 0) stat = ASN_E_INVLEN;   return (stat);}static int decodeOctets (OOCTXT* pctxt, ASN1OCTET* pbuffer, ASN1UINT bufsiz, ASN1UINT nbits){    ASN1UINT nbytes = (nbits + 7) / 8 ;   ASN1UINT i = 0, j;   ASN1UINT rshift = pctxt->buffer.bitOffset;   ASN1UINT lshift = 8 - rshift;   ASN1UINT nbitsInLastOctet;   ASN1OCTET mask;   int stat;   /* Check to make sure buffer contains number of bits requested */   if ((pctxt->buffer.byteIndex + nbytes) > pctxt->buffer.size) {      return LOG_ASN1ERR (pctxt, ASN_E_ENDOFBUF);   }   /* Check to make sure buffer is big enough to hold requested         */   /* number of bits..                                                  */   if (nbytes > bufsiz) {      return LOG_ASN1ERR (pctxt, ASN_E_STROVFLW);   }   /* If on a byte boundary, can do a direct memcpy to target buffer */   if (pctxt->buffer.bitOffset == 8) {      memcpy (pbuffer, &pctxt->buffer.data[pctxt->buffer.byteIndex], nbytes);      stat = moveBitCursor (pctxt, nbits);      if (stat != ASN_OK) return stat;      i = nbytes - 1; nbits %= 8;   }   else {      while (nbits >= 8) {         /* Transfer lower bits from stream octet to upper bits of      */         /* target octet..                                              */         pbuffer[i] = pctxt->buffer.data[pctxt->buffer.byteIndex++]            << lshift;         /* Transfer upper bits from next stream octet to lower bits    */         /* target octet..                                              */         pbuffer[i++] |= pctxt->buffer.data[pctxt->buffer.byteIndex]            >> rshift;         nbits -= 8;      }      /* Copy last partial byte */      if (nbits >= rshift) {         pbuffer[i] =             pctxt->buffer.data[pctxt->buffer.byteIndex++] << lshift;         nbitsInLastOctet = nbits - rshift;         if (nbitsInLastOctet > 0) {            pbuffer[i] |=                pctxt->buffer.data[pctxt->buffer.byteIndex] >> rshift;         }         pctxt->buffer.bitOffset = 8 - nbitsInLastOctet;      }      else if (nbits > 0) {  /* nbits < rshift */         pbuffer[i] =             pctxt->buffer.data[pctxt->buffer.byteIndex] << lshift;         pctxt->buffer.bitOffset = rshift - nbits;      }   }   /* Mask unused bits off of last byte */   if (nbits > 0) {      mask = 0;      for (j = 0; j < nbits; j++) {         mask >>= 1;         mask |= 0x80;      }      pbuffer[i] &= mask;   }   return ASN_OK;}int decodeOctetString (OOCTXT* pctxt, ASN1UINT* numocts_p, ASN1OCTET* buffer, ASN1UINT bufsiz){   ASN1UINT octcnt;   int lstat, octidx = 0, stat;   Asn1SizeCnst* pSizeList = pctxt->pSizeConstraint;   for (*numocts_p = 0;;) {      lstat = decodeLength (pctxt, &octcnt);      if (lstat < 0) return LOG_ASN1ERR (pctxt, lstat);      if (octcnt > 0) {         *numocts_p += octcnt;         if (TRUE) {            ASN1BOOL doAlign;            stat = bitAndOctetStringAlignmentTest                (pSizeList, octcnt, FALSE, &doAlign);            if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);            if (doAlign) {               stat = decodeByteAlign (pctxt);               if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);            }         }         stat = decodeOctets (pctxt, &buffer[octidx],                            bufsiz - octidx, (octcnt * 8));         if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);      }      if (lstat == ASN_OK_FRAG) {         octidx += octcnt;      }      else break;   }   return ASN_OK;}int decodeOpenType (OOCTXT* pctxt, const ASN1OCTET** object_p2, ASN1UINT* numocts_p){   ASN1DynOctStr octStr;   int stat;   stat = decodeDynOctetString (pctxt, &octStr);   if (stat == ASN_OK) {      *numocts_p = octStr.numocts;      *object_p2 = octStr.data;   }   return stat;}int decodeSemiConsInteger (OOCTXT* pctxt, ASN1INT* pvalue, ASN1INT lower){   signed char b;   unsigned char ub;   ASN1UINT nbytes;   int stat;   stat = decodeLength (pctxt, &nbytes);   if (stat < 0) return LOG_ASN1ERR (pctxt, stat);   if (nbytes > 0) {      /* Align buffer */      stat = decodeByteAlign (pctxt);      if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);      /* Decode first byte into a signed byte value and assign to integer. */      /* This should handle sign extension..                               */      stat = decodeOctets (pctxt, (ASN1OCTET*)&b, 1, 8);      if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);      *pvalue = b;      nbytes--;      /* Decode remaining bytes and add to result */      while (nbytes > 0) {         stat = decodeOctets (pctxt, (ASN1OCTET*)&ub, 1, 8);         if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);         *pvalue = (*pvalue * 256) + ub;         nbytes--;      }   }   else {  /* nbytes == 0 */      *pvalue = 0;   }   if (lower > ASN1INT_MIN)      *pvalue += lower;   return ASN_OK;}int decodeSemiConsUnsigned (OOCTXT* pctxt, ASN1UINT* pvalue, ASN1UINT lower){   ASN1UINT nbytes;   int stat;   stat = decodeLength (pctxt, &nbytes);   if (stat < 0) return LOG_ASN1ERR (pctxt, stat);      if (nbytes > 0) {      stat = decodeByteAlign (pctxt);      if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);      stat = decodeBits (pctxt, pvalue, nbytes * 8);   }   else      *pvalue = 0;   *pvalue += lower;   return stat;}int decodeSmallNonNegWholeNumber (OOCTXT* pctxt, ASN1UINT* pvalue){    ASN1BOOL bitValue;   ASN1UINT len;   int ret;   if ((ret = DECODEBIT (pctxt, &bitValue)) != ASN_OK)      return ret;   if (bitValue == 0) {      return decodeBits (pctxt, pvalue, 6);   /* 10.6.1 */   }   else {      if ((ret = decodeLength (pctxt, &len)) < 0)         return ret;      if ((ret = decodeByteAlign (pctxt)) != ASN_OK)         return ret;      return decodeBits (pctxt, pvalue, len*8);   }}int decodeVarWidthCharString (OOCTXT* pctxt, const char** pvalue){   int        stat;   ASN1OCTET* tmpstr;   ASN1UINT   len;   /* note: need to save size constraint for use in alignCharStr     */   /* because it will be cleared in decodeLength from the context..        */   Asn1SizeCnst* psize = pctxt->pSizeConstraint;   /* Decode length */   stat = decodeLength (pctxt, &len);   if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);   /* Byte-align */   if (alignCharStr (pctxt, len, 8, psize)) {      stat = decodeByteAlign (pctxt);      if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);   }   /* Decode data */   tmpstr = (ASN1OCTET*) ASN1MALLOC (pctxt, len + 1);   if (0 != tmpstr) {      if ((stat = decodeOctets (pctxt, tmpstr, len, len * 8)) != ASN_OK)         return LOG_ASN1ERR (pctxt, stat);      tmpstr[len] = '\0';  /* add null-terminator */   }   else      return LOG_ASN1ERR (pctxt, ASN_E_NOMEM);   *pvalue = (char*)tmpstr;   return ASN_OK;}static int decode16BitConstrainedString (OOCTXT* pctxt, Asn116BitCharString* pString, Asn116BitCharSet* pCharSet){   ASN1UINT i, idx, nbits = pCharSet->alignedBits;   int stat;   /* Decode length */   stat = decodeLength (pctxt, &pString->nchars);   if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);   /* Byte-align */   stat = decodeByteAlign (pctxt);   if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);   /* Decode data */   pString->data = (ASN116BITCHAR*)      ASN1MALLOC (pctxt, pString->nchars*sizeof(ASN116BITCHAR));   if (pString->data) {      for (i = 0; i < pString->nchars; i++) {         stat = decodeBits (pctxt, &idx, nbits);         if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);         pString->data[i] = (pCharSet->charSet.data == 0) ?             idx + pCharSet->firstChar : pCharSet->charSet.data[idx];      }   }   else      return LOG_ASN1ERR (pctxt, ASN_E_NOMEM);   return ASN_OK;}static int getComponentLength (OOCTXT* pctxt, ASN1UINT itemBits){   OOCTXT lctxt;   ASN1UINT len, totalLen = 0;   int stat;   stat = initSubContext (&lctxt, pctxt);   if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);   stat = setPERBufferUsingCtxt (&lctxt, pctxt);   if (stat != ASN_OK) {      freeContext (&lctxt);      return LOG_ASN1ERR (pctxt, stat);   }   lctxt.pSizeConstraint = pctxt->pSizeConstraint;   for (;;) {      stat = decodeLength (&lctxt, &len);      if (stat < 0) {         freeContext (&lctxt);         return LOG_ASN1ERR (pctxt, stat);      }      totalLen += len;      if (stat == ASN_OK_FRAG) {         stat = moveBitCursor (&lctxt, len * itemBits);         if (stat != ASN_OK) {            freeContext (&lctxt);            return LOG_ASN1ERR (pctxt, stat);         }      }      else break;   }   freeContext (&lctxt);   return totalLen;}int moveBitCursor (OOCTXT* pctxt, int bitOffset){   int currBitOffset =      (pctxt->buffer.byteIndex * 8) + (8 - pctxt->buffer.bitOffset);   currBitOffset += bitOffset;   pctxt->buffer.byteIndex = (currBitOffset / 8);   pctxt->buffer.bitOffset = 8 - (currBitOffset % 8);   if (pctxt->buffer.byteIndex > pctxt->buffer.size) {      return (ASN_E_ENDOFBUF);   }         return ASN_OK;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?