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 + -
显示快捷键?