decode.c
来自「一个非常美妙的proxy。功能强大。基于sip的协议。如果还要的话」· C语言 代码 · 共 1,051 行 · 第 1/2 页
C
1,051 行
/* * Copyright (C) 1997-2005 by Objective Systems, Inc. * * This software is furnished under an open source license and may be * used and copied only in accordance with the terms of this license. * The text of the license may generally be found in the root * directory of this installation in the COPYING file. It * can also be viewed online at the following URL: * * http://www.obj-sys.com/open/license.html * * Any redistributions of this file including modified versions must * maintain this copyright notice. * *****************************************************************************/#include "ooasn1.h"static int decode16BitConstrainedString (OOCTXT* pctxt, Asn116BitCharString* pString, Asn116BitCharSet* pCharSet);static int decodeOctets (OOCTXT* pctxt, ASN1OCTET* pbuffer, ASN1UINT bufsiz, ASN1UINT nbits);static int getComponentLength (OOCTXT* pctxt, ASN1UINT itemBits);int decodeBits (OOCTXT* pctxt, ASN1UINT* pvalue, ASN1UINT nbits){ unsigned char mask; if (nbits == 0) { *pvalue = 0; return ASN_OK; } /* If the number of bits is less than the current bit offset, mask */ /* off the required number of bits and return.. */ if (nbits < (unsigned)pctxt->buffer.bitOffset) { /* Check if buffer contains number of bits requested */ if (pctxt->buffer.byteIndex >= pctxt->buffer.size) return LOG_ASN1ERR (pctxt, ASN_E_ENDOFBUF); pctxt->buffer.bitOffset -= nbits; *pvalue = ((pctxt->buffer.data[pctxt->buffer.byteIndex]) >> pctxt->buffer.bitOffset) & ((1 << nbits) - 1); return ASN_OK; } /* Otherwise, we first need to mask off the remaining bits in the */ /* current byte, followed by a loop to extract bits from full bytes, */ /* followed by logic to mask of remaining bits from the start of */ /* of the last byte.. */ else { /* Check if buffer contains number of bits requested */ int nbytes = (((nbits - pctxt->buffer.bitOffset) + 7) / 8); if ((pctxt->buffer.byteIndex + nbytes) >= pctxt->buffer.size) { return LOG_ASN1ERR (pctxt, ASN_E_ENDOFBUF); } /* first read current byte remaining bits */ mask = ((1 << pctxt->buffer.bitOffset) - 1); *pvalue = (pctxt->buffer.data[pctxt->buffer.byteIndex]) & mask; nbits -= pctxt->buffer.bitOffset; pctxt->buffer.bitOffset = 8; pctxt->buffer.byteIndex++; /* second read bytes from next byteIndex */ while (nbits >= 8) { *pvalue = (*pvalue << 8) | (pctxt->buffer.data[pctxt->buffer.byteIndex]); pctxt->buffer.byteIndex++; nbits -= 8; } /* third read bits & set bitoffset of the byteIndex */ if (nbits > 0) { pctxt->buffer.bitOffset = 8 - nbits; *pvalue = (*pvalue << nbits) | ((pctxt->buffer.data[pctxt->buffer.byteIndex]) >> pctxt->buffer.bitOffset); } return ASN_OK; }}int decodeBitString (OOCTXT* pctxt, ASN1UINT* numbits_p, ASN1OCTET* buffer, ASN1UINT bufsiz){ ASN1UINT bitcnt; int lstat, octidx = 0, stat; Asn1SizeCnst* pSizeList = pctxt->pSizeConstraint; ASN1BOOL doAlign; for (*numbits_p = 0;;) { lstat = decodeLength (pctxt, &bitcnt); if (lstat < 0) return LOG_ASN1ERR (pctxt, lstat); if (bitcnt > 0) { *numbits_p += bitcnt; stat = bitAndOctetStringAlignmentTest (pSizeList, bitcnt, TRUE, &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, bitcnt); if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat); } if (lstat == ASN_OK_FRAG) { octidx += (bitcnt / 8); } else break; } return ASN_OK;}int decodeBMPString (OOCTXT* pctxt, ASN1BMPString* pvalue, Asn116BitCharSet* permCharSet){ Asn116BitCharSet charSet; int stat; /* Set character set */ init16BitCharSet (&charSet, BMP_FIRST, BMP_LAST, BMP_ABITS, BMP_UBITS); if (permCharSet) { set16BitCharSet (pctxt, &charSet, permCharSet); } /* Decode constrained string */ stat = decode16BitConstrainedString (pctxt, pvalue, &charSet); if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat); return (stat);}int decodeByteAlign (OOCTXT* pctxt){ if (pctxt->buffer.bitOffset != 8) { pctxt->buffer.byteIndex++; pctxt->buffer.bitOffset = 8; } return ASN_OK;}int decodeConstrainedStringEx (OOCTXT* pctxt, const char** string, const char* charSet, ASN1UINT abits, ASN1UINT ubits, ASN1UINT canSetBits){ int stat; char* tmpstr; ASN1UINT i, idx, len, nbits = abits; /* 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, nbits, psize)) { stat = decodeByteAlign (pctxt); if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat); } /* Decode data */ tmpstr = (char*) ASN1MALLOC (pctxt, len+1); if (0 != tmpstr) { if (nbits >= canSetBits && canSetBits > 4) { for (i = 0; i < len; i++) { if ((stat = decodeBits (pctxt, &idx, nbits)) == ASN_OK) { tmpstr[i] = (char) idx; } else break; } } else if (0 != charSet) { ASN1UINT nchars = strlen (charSet); for (i = 0; i < len; i++) { if ((stat = decodeBits (pctxt, &idx, nbits)) == ASN_OK) { if (idx < nchars) { tmpstr[i] = charSet[idx]; } else return LOG_ASN1ERR (pctxt, ASN_E_CONSVIO); } else break; } } else stat = ASN_E_INVPARAM; if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat); tmpstr[i] = '\0'; /* add null-terminator */ } else return LOG_ASN1ERR (pctxt, ASN_E_NOMEM); *string = tmpstr; return ASN_OK;}int decodeConsInteger (OOCTXT* pctxt, ASN1INT* pvalue, ASN1INT lower, ASN1INT upper){ ASN1UINT range_value = upper - lower; ASN1UINT adjusted_value; int stat = ASN_OK; if (range_value != ASN1UINT_MAX) { range_value += 1; } if (lower > upper) return ASN_E_RANGERR; else if (lower != upper) { stat = decodeConsWholeNumber (pctxt, &adjusted_value, range_value); if (stat == ASN_OK) { *pvalue = adjusted_value + lower; if (*pvalue < lower || *pvalue > upper) stat = ASN_E_CONSVIO; } } else { *pvalue = lower; } return stat;}int decodeConsUInt8 (OOCTXT* pctxt, ASN1UINT8* pvalue, ASN1UINT lower, ASN1UINT upper){ ASN1UINT range_value, value; ASN1UINT adjusted_value; int stat = ASN_OK; /* Check for special case: if lower is 0 and upper is ASN1UINT_MAX, */ /* set range to ASN1UINT_MAX; otherwise to upper - lower + 1 */ range_value = (lower == 0 && upper == ASN1UINT_MAX) ? ASN1UINT_MAX : upper - lower + 1; if (lower != upper) { ASN1UINT range_bitcnt; /* If range is <= 255, bit-field case (10.5.7a) */ if (range_value <= 255) { range_bitcnt = getUIntBitCount (range_value - 1); } /* If range is exactly 256, one-octet case (10.5.7b) */ else if (range_value == 256) { stat = decodeByteAlign (pctxt); if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat); range_bitcnt = 8; } stat = decodeBits (pctxt, &adjusted_value, range_bitcnt); if (stat == ASN_OK) { value = adjusted_value + lower; if (value < lower || value > upper) stat = ASN_E_CONSVIO; *pvalue = (ASN1OCTET)value; } } else *pvalue = (ASN1OCTET)lower; return stat;}int decodeConsUInt16 (OOCTXT* pctxt, ASN1USINT* pvalue, ASN1UINT lower, ASN1UINT upper){ ASN1UINT range_value, value; ASN1UINT adjusted_value; int stat = ASN_OK; /* Check for special case: if lower is 0 and upper is ASN1UINT_MAX, */ /* set range to ASN1UINT_MAX; otherwise to upper - lower + 1 */ range_value = (lower == 0 && upper == ASN1UINT_MAX) ? ASN1UINT_MAX : upper - lower + 1; if (lower != upper) { stat = decodeConsWholeNumber (pctxt, &adjusted_value, range_value); if (stat == ASN_OK) { value = adjusted_value + lower; /* Verify value is within given range (ED, 1/15/2002) */ if (value < lower || value > upper) stat = ASN_E_CONSVIO; *pvalue = (ASN1USINT) value; } } else *pvalue = (ASN1USINT) lower; return stat;}int decodeConsUnsigned (OOCTXT* pctxt, ASN1UINT* pvalue, ASN1UINT lower, ASN1UINT upper){ ASN1UINT range_value; ASN1UINT adjusted_value; int stat = ASN_OK; /* Check for special case: if lower is 0 and upper is ASN1UINT_MAX, */ /* set range to ASN1UINT_MAX; otherwise to upper - lower + 1 */ range_value = (lower == 0 && upper == ASN1UINT_MAX) ? ASN1UINT_MAX : upper - lower + 1; if (lower != upper) { stat = decodeConsWholeNumber (pctxt, &adjusted_value, range_value); if (stat == ASN_OK) { *pvalue = adjusted_value + lower; if (*pvalue < lower || *pvalue > upper) stat = ASN_E_CONSVIO; } } else *pvalue = lower; return stat;}int decodeConsWholeNumber (OOCTXT* pctxt, ASN1UINT* padjusted_value, ASN1UINT range_value){ ASN1UINT nocts, range_bitcnt; int stat; /* If unaligned, decode non-negative binary integer in the minimum */ /* number of bits necessary to represent the range (10.5.6) */ if (!TRUE) { range_bitcnt = getUIntBitCount (range_value - 1); } /* If aligned, encoding depended on range value (10.5.7) */ else { /* aligned */ /* If range is <= 255, bit-field case (10.5.7a) */ if (range_value <= 255) { range_bitcnt = getUIntBitCount (range_value - 1); } /* If range is exactly 256, one-octet case (10.5.7b) */ else if (range_value == 256) { stat = decodeByteAlign (pctxt); if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat); range_bitcnt = 8; } /* If range > 256 and <= 64k (65535), two-octet case (10.5.7c) */ else if (range_value <= 65536) { stat = decodeByteAlign (pctxt); if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat); range_bitcnt = 16; } /* If range > 64k, indefinite-length case (10.5.7d) */ else { stat = decodeBits (pctxt, &nocts, 2); if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat); stat = decodeByteAlign (pctxt); if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat); range_bitcnt = (nocts + 1) * 8; } } return decodeBits (pctxt, padjusted_value, range_bitcnt);}int decodeDynBitString (OOCTXT* pctxt, ASN1DynBitStr* pBitStr){ ASN1UINT nocts; ASN1OCTET* ptmp; int nbits, stat = ASN_OK; /* If "fast copy" option is not set (ASN1FATSCOPY) or if constructed, * copy the bit string value into a dynamic memory buffer; * otherwise, store the pointer to the value in the decode * buffer in the data pointer argument. */ if (pctxt->flags & ASN1FASTCOPY) { /* check is it possible to do optimized decoding */ ASN1OCTET bit; ASN1UINT byteIndex = pctxt->buffer.byteIndex; /* save byte index */ ASN1USINT bitOffset = pctxt->buffer.bitOffset; /* save bit offset */ stat = decodeByteAlign (pctxt); if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat); stat = DECODEBIT (pctxt, &bit); /* read first bit of length determinant */ if (bit == 1 && stat == ASN_OK) stat = DECODEBIT (pctxt, &bit); /* read second bit */ pctxt->buffer.byteIndex = byteIndex; /* restore byte index */ pctxt->buffer.bitOffset = bitOffset; /* restore bit offset */ /* if either first or second bit != 0 - not fragmented */ if (bit == 0 && stat == ASN_OK) { ASN1UINT bitcnt; stat = decodeLength (pctxt, &bitcnt); if (stat != 0) return LOG_ASN1ERR (pctxt, stat); pBitStr->numbits = bitcnt; if (bitcnt > 0) { pBitStr->data = ASN1BUFPTR (pctxt); stat = moveBitCursor (pctxt, bitcnt); if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat); } else pBitStr->data = 0; return stat; } } nbits = getComponentLength (pctxt, 1); if (nbits < 0) return LOG_ASN1ERR (pctxt, nbits); else if (nbits == 0) { pBitStr->numbits = 0; ptmp = 0; } nocts = (nbits + 7) / 8; /* Allocate memory for the target string */ if (nocts > 0) { ptmp = (ASN1OCTET*) ASN1MALLOC (pctxt, nocts); if (0 == ptmp) return LOG_ASN1ERR (pctxt, ASN_E_NOMEM); /* Call static bit string decode function */ stat = decodeBitString (pctxt, &pBitStr->numbits, ptmp, nocts); } pBitStr->data = ptmp; return stat;}int decodeDynOctetString (OOCTXT* pctxt, ASN1DynOctStr* pOctStr){ ASN1OCTET* ptmp; int nocts, stat; /* If "fast copy" option is not set (ASN1FASTCOPY) or if constructed, * copy the octet string value into a dynamic memory buffer; * otherwise, store the pointer to the value in the decode * buffer in the data pointer argument. */ if (pctxt->flags & ASN1FASTCOPY) { /* check if it is possible to do optimized decoding */ ASN1OCTET bit; ASN1UINT byteIndex = pctxt->buffer.byteIndex; /* save byte index */ ASN1USINT bitOffset = pctxt->buffer.bitOffset; /* save bit offset */ stat = decodeByteAlign (pctxt); if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat); stat = DECODEBIT (pctxt, &bit); /* read first bit of length determinant */ if (bit == 1 && stat == ASN_OK) stat = DECODEBIT (pctxt, &bit); /* read second bit */ pctxt->buffer.byteIndex = byteIndex; /* restore byte index */ pctxt->buffer.bitOffset = bitOffset; /* restore bit offset */ /* if either first or second bit != 0 - not fragmented */ if (bit == 0 && stat == ASN_OK) { ASN1UINT octcnt; stat = decodeLength (pctxt, &octcnt); if (stat != 0) return LOG_ASN1ERR (pctxt, stat); pOctStr->numocts = octcnt; if (octcnt > 0) { pOctStr->data = ASN1BUFPTR (pctxt); stat = moveBitCursor (pctxt, octcnt * 8); if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?