📄 a_decode.c
字号:
{
for(subid_bytes = 2, subid_done = 0; left; subid_bytes++)
{
c = (_UINT8) Lcl_Getc(stream);
if(Lcl_Eof(stream))
{
*errp = AE_PREMATURE_END;
return;
}
left--;
if((c & 0x80) == 0)
{
subid_done = 1;
break;
}
}
if((subid_done == 0) || (subid_bytes > 5) || ((subid_bytes == 5) && (first_c > 0x8f)))
{
*errp = AE_WRONG_LENGTH;
return;
}
}
/* finally update the count of the subids */
subids++;
}
(void) Lcl_Seek(stream, content_offset, 0);
/* Null object id if no subidentifier fields */
if(subids == 0)
return;
objp->num_components = subids + 1;
/* Decode the subids and components */
j=0;
for(subid_num = 0; subid_num < subids; subid_num++)
{
/* Decode the subidentifier */
for(subid_val = 0;;)
{
c = (_UINT8) Lcl_Getc(stream);
if(Lcl_Eof(stream))
{
*errp = AE_PREMATURE_END;
objp->num_components = 0;
return;
}
subid_val <<= 7;
subid_val |= (_UINT32) (c & 0x7F);
if(!(c & 0x80))
break;
}
/* Is this the first subidentifier? */
/* i.e. the one that contains TWO components? */
if(subid_num == 0) /*#the first byte is 0x2b,decoded to 1.3#*/
{
if(subid_val < 40)
{
cp[j++]= 0;
cp[j++]= subid_val;
}
else
{
if(subid_val < 80)
{
cp[j++]= 1;
cp[j++]= subid_val - 40;
}
else
{
cp[j++] = 2;
cp[j++] = subid_val - 80;
}
}
}
else
{ /* subid_num != 0, i.e. this is not the first subidentifier */
cp[j++]= subid_val;
}
}
for(j=0;j<objp->num_components;j++)
objp->component_list[j]=cp[j];
return;
}
/********************
A_DecodeObjectIdWTC
PURPOSE: Pull an object identifer from an ASN.1 stream.
The data stream is read using the local I/O package.
On entry stream poINT32er should be positioned to the first byte
of the object identifier's ASN.1 type field.
This version does type checking
On exit, the stream poINT32er will be positioned to at the start
of the next ASN.1 type field.
Parameters:
LCL_FILE * Stream descriptor
OBJ_ID_T * Object identifier structure to receive the object id.
The "component_list" will be "malloc"ed.
component_list == (_UINT32 *)0 indicates that
there is no component_list.
_INT16 * Receives an error code, if any.
_UINT16 The type value
_UINT8 A_IDC_MASK flag values
Returns: Nothing
********************/
void A_DecodeObjectIdWTC(LCL_FILE * stream, OBJ_ID_T * objp, _INT16 *errp, _UINT16 id, _UINT8 flags)
{
_UINT16 length;
if((A_DecodeTypeClass(stream) != flags) || (A_DecodeTypeValue(stream, errp) != id))
{
if(*errp == 0)
*errp = AE_WRONG_TYPE;
return;
}
length = A_DecodeLength(stream, errp);
if(*errp == 0)
A_DecodeObjectIdData(stream, length, objp, errp);
return;
}
/* We only install ui64 routine if the type is installed */
/********************
A_DecodeInteger64Data
PURPOSE: Pull up to a 64 bit INT32eger from an ASN.1 stream.
The data stream is read using the local I/O package.
On entry stream poINT32er should be positioned to the first byte
of the data field.
On exit, the stream poINT32er will be positioned to at the start
of the next ASN.1 type field.
Parameters:
LCL_FILE * Stream descriptor
_UINT16 Length of contents field, from the ASN.1 header
_UINT64_T * Space for the received _INT16
_INT16 * Receives an error code, if any.
Returns: void
WARNING: If the INT32eger occupies more than 8 octets, then high order precision
will be lost, including the sign bit. For unsigned values in which the
basic value occupies all 8 octets, the sign octet, containing a zero sign
bit, will be lost but will not damage the returned value.
********************/
void A_DecodeInteger64Data(LCL_FILE * stream, _UINT16 length, UINT64_T * value, _INT16 *errp)
{
_INT32 firstone = 1;
_UINT8 oct;
value->high = value->low = 0;
while(length-- != 0)
{
oct = (_UINT8) Lcl_Getc(stream);
if(Lcl_Eof(stream))
{
*errp = AE_PREMATURE_END;
return;
}
/* See whether we are receiving something that has the sign bit set */
if(firstone)
{
firstone = 0;
if((length == 8) && (oct != 0))
{
*errp = AE_WRONG_VALUE;
return;
}
if(oct & (_UINT8) 0x80)
{
value->high = (_UINT32) 0xFFFFFFFFL;
value->low = (_UINT32) 0xFFFFFFFFL;
}
}
/* Decide which of the two words to put the octet INT32o */
/* if length >= 4 we are working on the high order bytes */
/* equal sign is because we already decremented length */
if(length >= 4)
{
value->high <<= 8;
value->high |= oct; /* 'oct' better not be sign extended!!! */
}
else
{
value->low <<= 8;
value->low |= oct; /* 'oct' better not be sign extended!!! */
}
}
return;
}
/********************
A_DecodeInteger64
PURPOSE: Pull up to a 64 bit INT32eger from an ASN.1 stream.
The data stream is read using the local I/O package.
On entry stream poINT32er should be positioned to the first byte
of the INT32eger's ASN.1 type field.
On exit, the stream poINT32er will be positioned to at the start
of the next ASN.1 type field.
Parameters:
LCL_FILE * Stream descriptor
_UINT64 * Space to receive the _INT16
_INT16 * Receives an error code, if any.
Returns: _INT32;
********************/
#if 0
void A_DecodeInteger64(LCL_FILE * stream, UINT64_T * value, _INT16 *errp)
{
_UINT16 INT32_length;
(void) A_DecodeTypeValue(stream, errp);
INT32_length = A_DecodeLength(stream, errp);
if(*errp == 0)
{
if(INT32_length > 9)
*errp = AE_WRONG_VALUE;
else
A_DecodeInteger64Data(stream, INT32_length, value, errp);
}
return;
}
#endif
/********************
A_DecodeOctetWTC
PURPOSE: Pull a single octet from an ASN.1 stream
The data stream is read using the local I/O package.
On entry stream poINT32er should be positioned to the first byte
of the octet string's type field.
This version does type checking.
On exit, the stream poINT32er will be positioned to at the start
of the next ASN.1 type field.
An error will be generated if the octet string is longer than 1.
Parameters:
LCL_FILE * Stream descriptor
_INT16 * Receives an error code, if any.
_UINT16 The type value
_UINT8 A_IDC_MASK flag values
Returns: _UINT8 the octet from the stream.
********************/
#if 0
_UINT8 A_DecodeOctetWTC(LCL_FILE * stream, _INT16 *errp, _UINT16 id, _UINT8 flags)
{
_UINT8 buff;
if((A_DecodeTypeClass(stream) != flags) || (A_DecodeTypeValue(stream, errp) != id))
{
if(*errp == 0)
*errp = AE_WRONG_TYPE;
return (0);
}
if((A_DecodeLength(stream, errp) != 1) || *errp)
{
if(*errp == 0)
*errp = AE_WRONG_LENGTH;
return (0);
}
if(Lcl_Read(stream, &buff, 1) != 1)
{
*errp = AE_WRONG_LENGTH;
return (0);
}
return (buff);
}
#endif
/********************
A_DecodeInteger
PURPOSE: Pull an INT32eger from an ASN.1 stream.
The data stream is read using the local I/O package.
On entry stream poINT32er should be positioned to the first byte
of the INT32eger's ASN.1 type field.
On exit, the stream poINT32er will be positioned to at the start
of the next ASN.1 type field.
Parameters:
LCL_FILE * Stream descriptor
_INT16 * Receives an error code, if any.
Returns: _INT32;
********************/
#if 0
_INT32 A_DecodeInteger(LCL_FILE * stream, _INT16 *errp)
{
_UINT16 INT32_length;
(void) A_DecodeTypeValue(stream, errp);
INT32_length = A_DecodeLength(stream, errp);
if(*errp == 0)
{
if(INT32_length > 5)
*errp = AE_WRONG_VALUE;
else
return A_DecodeIntegerData(stream, INT32_length, errp);
}
return (0);
}
#endif
/********************
A_DecodeObjectId
PURPOSE: Pull an object identifer from an ASN.1 stream.
The data stream is read using the local I/O package.
On entry stream poINT32er should be positioned to the first byte
of the object identifier's ASN.1 type field.
On exit, the stream poINT32er will be positioned to at the start
of the next ASN.1 type field.
Parameters:
LCL_FILE * Stream descriptor
OBJ_ID_T * Object identifier structure to receive the object id.
The "component_list" will be "malloc"ed.
component_list == (_UINT32 *)0 indicates that
there is no component_list.
_INT16 * Receives an error code, if any.
Returns: Nothing
********************/
#if 0
void A_DecodeObjectId(LCL_FILE * stream, OBJ_ID_T * objp, _INT16 *errp)
{
_UINT16 leng;
(void) A_DecodeTypeValue(stream, errp);
leng = A_DecodeLength(stream, errp);
if(*errp == 0)
A_DecodeObjectIdData(stream, leng, objp, errp);
return;
}
#endif
/********************
A_DecodeOctetString
PURPOSE: Pull an octet string from an ASN.1 stream.
The data stream is read using the local I/O package.
On entry stream poINT32er should be positioned to the first byte
of the octet string's type field.
On exit, the stream poINT32er will be positioned to at the start
of the next ASN.1 type field.
Parameters:
LCL_FILE * Stream descriptor
_UINT8 * Control structure to receive the data.
_INT16 * Receives an error code, if any.
Returns: Nothing
Note: On return, the "start_bp" component of the buffer structure
poINT32s to a "malloc"-ed area in which the octet string is held.
Note that the octet string is NOT null terminated, may contain
INT32ernal nulls. A null poINT32er, (char *)0, is used if no area
is malloc-ed.
********************/
#if 0
void A_DecodeOctetString(LCL_FILE * stream, _UINT8 * ebuffp, _INT16 *errp)
{
_UINT16 os_length;
(void) A_DecodeTypeValue(stream, errp);
os_length = A_DecodeLength(stream, errp);
if(*errp == 0)
{
A_DecodeOctetStringData(stream, os_length, ebuffp, errp);
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -