📄 derhelp.c
字号:
buf[0] = 0x88;
buf[1] = (unsigned char)(length >> 56);
buf[2] = (unsigned char)(length >> 48);
buf[3] = (unsigned char)(length >> 40);
buf[4] = (unsigned char)(length >> 32);
buf[5] = (unsigned char)(length >> 24);
buf[6] = (unsigned char)(length >> 16);
buf[7] = (unsigned char)(length >> 8);
buf[8] = (unsigned char)length;
return (10);
#endif /* VOLT_SIZE_OF_UNSIGNED_INT > 4 */
#endif /* VOLT_SIZE_OF_UNSIGNED_INT > 2 */
#endif /* VOLT_SIZE_OF_UNSIGNED_INT > 1 */
}
int VoltGetNextDerElement (
VoltLibCtx *libCtx,
unsigned char *encoding,
unsigned int encodingLen,
unsigned int explicitTag,
unsigned int expectedTag,
unsigned int valueFlag,
VoltDerElement *derElement,
unsigned int *bytesRead
)
{
int status;
unsigned int offset, index, lengthLen, count;
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* If there's nothing to read, or if it's already captured, there's
* nothing to do.
*/
*bytesRead = 0;
if ( (encodingLen == 0) || (derElement->complete != 0) )
return (0);
/* If there's an EXPLICIT tag, and it has not been collected yet,
* collect it. If explicitLen is not 0, it has been captured.
*/
if ( (explicitTag != 0) && (derElement->explicitLen == 0) )
{
status = VoltGetNextDerElement (
libCtx, encoding, encodingLen, 0, explicitTag, 0, derElement,
bytesRead);
if (status != 0)
return (status);
/* Has it captured the EXPLICIT tag and len?
*/
if (derElement->complete == 0)
return (0);
/* We have the EXPLICIT captured, transfer it to the appropriate
* fields.
*/
derElement->explicitTag = explicitTag;
derElement->explicitLen = derElement->tlvLen;
derElement->elementLen = 0;
derElement->tlvLen = 0;
derElement->totalLen = 0;
derElement->complete = 0;
encodingLen -= *bytesRead;
encoding += *bytesRead;
if (encodingLen == 0)
return (0);
}
/* If totalLen is 0, we have not yet collected the tag and length.
*/
offset = 0;
if (derElement->totalLen == 0)
{
switch (derElement->elementLen)
{
case 0:
/* There's nothing in the struct, everything's in the encoding.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if ((unsigned int)(encoding[0]) != expectedTag)
{
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, VT_ERROR_INVALID_ENCODING, VT_ERROR_TYPE_PRIMARY,
fnctLine, "VoltGetNextDerElement", (char *)0)
return (VT_ERROR_INVALID_ENCODING);
}
/* Collect the first octet of the length.
*/
if (encodingLen != 1)
{
lengthLen = (unsigned int)(encoding[1]);
offset = 2;
break;
}
/* Only the tag was available, store it and return.
*/
derElement->tlvLen = 0;
derElement->totalLen = 0;
*bytesRead += 1;
return (StoreElementData (libCtx, derElement, encoding, 1));
case 1:
/* We have the tag in the element buffer, but that's it. The
* first (possibly only) length octet is the next byte.
*/
lengthLen = (unsigned int)(encoding[0]);
offset = 1;
break;
default:
/* We have the first octet of the length in the element buffer.
*/
lengthLen = (unsigned int)(derElement->element[1]);
offset = 0;
}
/* The lengthLen variable contains the first byte of the length. If
* it's less than 0x80, it's the only byte.
*/
if (lengthLen <= 0x7f)
{
derElement->tlvLen = lengthLen;
derElement->totalLen = 2;
*bytesRead += offset;
VOLT_SET_FNCT_LINE (fnctLine)
status = StoreElementData (libCtx, derElement, encoding, offset);
if (status != 0)
{
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, status, 0,
fnctLine, "VoltGetNextDerElement", (char *)0)
return (status);
}
}
else if (lengthLen == 0x80)
{
VOLT_SET_FNCT_LINE (fnctLine)
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, VT_ERROR_UNSUPPORTED, VT_ERROR_TYPE_PRIMARY,
fnctLine, "VoltGetNextDerElement", (char *)0)
/* This function does not accept indefinite length.
*/
return (VT_ERROR_UNSUPPORTED);
}
else
{
/* The length is built from more than one octet. Isolate the
* actual length len.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if ((lengthLen & 0xf0) != 0x80)
{
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, VT_ERROR_INVALID_ENCODING, VT_ERROR_TYPE_PRIMARY,
fnctLine, "VoltGetNextDerElement", (char *)0)
return (VT_ERROR_INVALID_ENCODING);
}
lengthLen &= 0xf;
/* This implementation does not allow length len's longer than an
* unsigned int.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (lengthLen > sizeof (unsigned int))
{
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, VT_ERROR_UNSUPPORTED, VT_ERROR_TYPE_PRIMARY,
fnctLine, "VoltGetNextDerElement", (char *)0)
return (VT_ERROR_UNSUPPORTED);
}
/* Do we have all necessary octets?
*/
count = encodingLen - offset;
if (offset == 0)
count += derElement->elementLen - 2;
if (count < lengthLen)
{
derElement->tlvLen = 0;
derElement->totalLen = 0;
*bytesRead += encodingLen;
return (StoreElementData (libCtx, derElement, encoding, encodingLen));
}
/* Get the entire length octets into the element buffer.
*/
offset = lengthLen + 2 - derElement->elementLen;
*bytesRead += offset;
VOLT_SET_FNCT_LINE (fnctLine)
status = StoreElementData (libCtx, derElement, encoding, offset);
if (status != 0)
{
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, status, 0,
fnctLine, "VoltGetNextDerElement", (char *)0)
return (status);
}
/* Build the length as an unsigned int.
*/
derElement->tlvLen = 0;
for (index = 0; index < lengthLen; ++index)
{
derElement->tlvLen <<= 8;
derElement->tlvLen += (unsigned int)(derElement->element[index + 2]);
}
derElement->totalLen = 2 + lengthLen;
}
/* If the value is not requested, we're done.
*/
derElement->complete = 1;
if (valueFlag == 0)
return (0);
/* The caller wants the value, the totalLen needs to reflect that.
*/
derElement->complete = 0;
derElement->totalLen += derElement->tlvLen;
}
encoding += offset;
encodingLen -= offset;
/* How many bytes of the value do we want to copy?
*/
count = derElement->totalLen - derElement->elementLen;
/* Do we have that many bytes in the encoding buffer?
*/
if (encodingLen < count)
count = encodingLen;
VOLT_SET_FNCT_LINE (fnctLine)
status = StoreElementData (libCtx, derElement, encoding, count);
if (status != 0)
{
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, status, 0,
fnctLine, "VoltGetNextDerElement", (char *)0)
return (status);
}
*bytesRead += count;
if (derElement->totalLen == derElement->elementLen)
derElement->complete = 1;
return (0);
}
void VoltResetDerElement (
VoltDerElement *derElement
)
{
derElement->elementLen = 0;
derElement->tlvLen = 0;
derElement->totalLen = 0;
derElement->explicitTag = 0;
derElement->explicitLen = 0;
derElement->complete = 0;
}
static int StoreElementData (
VoltLibCtx *libCtx,
VoltDerElement *derElement,
unsigned char *dataToStore,
unsigned int dataToStoreLen
)
{
int status;
unsigned int totalLen;
unsigned char *buffer = (unsigned char *)0;
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* We need a buffer big enough to handle the data in the buffer
* along with the new data.
*/
totalLen = derElement->elementLen + dataToStoreLen;
if (derElement->elementSize < totalLen)
{
status = VT_ERROR_MEMORY;
VOLT_SET_FNCT_LINE (fnctLine)
buffer = (unsigned char *)Z2Malloc (totalLen, VOLT_MEMORY_SENSITIVE);
if (buffer == (unsigned char *)0)
break;
/* Copy the old into the new and destroy the old.
*/
if (derElement->element != (unsigned char *)0)
{
Z2Memcpy (buffer, derElement->element, derElement->elementLen);
Z2Free (derElement->element);
}
derElement->element = buffer;
derElement->elementSize = totalLen;
}
/* Append new to end of old.
*/
Z2Memcpy (
derElement->element + derElement->elementLen,
dataToStore, dataToStoreLen);
derElement->elementLen += dataToStoreLen;
status = 0;
} while (0);
VOLT_LOG_ERROR_COMPARE (
status, (VtLibCtx)libCtx, status, VT_ERROR_TYPE_PRIMARY,
fnctLine, "StoreElementData", (char *)0)
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -