📄 derhelp.c
字号:
/* Copyright 2003-2005, Voltage Security, all rights reserved.
*/
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "derhelp.h"
#include "errorctx.h"
/* Store the given data in the element buffer of the derElement struct.
* If the buffer is big enough already, just store the data and set the
* elementLen. If the buffer is not big enough, realloc and store.
* <p>This function will append data. That is, if the elementLen is not
* 0, the routine will keep the old data, append the new data onto the
* end and increment elementLen. If elementLen is 0, this routine will
* store the input as a new element buffer.
*
* @param libCtx
* @param derElement
* @param dataToStore
* @param dataToStoreLen
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV StoreElementData VOLT_PROTO_LIST ((
VoltLibCtx *libCtx,
VoltDerElement *derElement,
unsigned char *dataToStore,
unsigned int dataToStoreLen
));
int VoltDecodeTagAndLen (
unsigned char *encoding,
unsigned int encodingLen,
unsigned int *theTag,
unsigned int *lengthLen,
unsigned int *valueLen
)
{
int status;
unsigned int len, index, val;
do
{
/* There must be at least 2 bytes, tag and len.
*/
status = VT_ERROR_INVALID_INPUT_LENGTH;
if (encodingLen < 2)
break;
status = VT_ERROR_INVALID_ENCODING;
if (encoding == (unsigned char *)0)
break;
*theTag = (unsigned int)(encoding[0]);
len = (unsigned int)(encoding[1]);
/* If the length octet is <= 0x80, it's the only length octet and it
* is the return value for valueLen.
*/
if (len <= 0x80)
{
status = 0;
*lengthLen = 1;
*valueLen = len;
break;
}
/* The 1st length octet is > 0x80, it describes how many length octets
* there are: 0x8i where i is the number of length octets in addition
* to the 1st length octet.
*/
if ((len & 0xf0) != 0x80)
break;
/* If the number of length octets exceed the size of an unsigned int,
* error.
*/
len &= 0xf;
if (len > sizeof (unsigned int))
break;
/* Make sure the encoding has that many bytes (plus the tag and 1st
* length octet).
*/
status = VT_ERROR_INVALID_INPUT_LENGTH;
if (encodingLen < (len + 2))
break;
/* Get the value length from the next len octets.
*/
val = 0;
for (index = 0; index < len; ++index)
{
val <<= 8;
val += (unsigned int)(encoding[index + 2]);
}
*lengthLen = len + 1;
*valueLen = val;
status = 0;
} while (0);
return (status);
}
int VoltDecodeDerLength (
unsigned char *encoding,
unsigned int encodingLen,
unsigned int *lengthLen,
unsigned int *valueLen
)
{
unsigned int len, index, val;
if (encoding == (unsigned char *)0)
return (VT_ERROR_INVALID_ENCODING);
/* There must be at least 2 bytes, tag and len.
*/
if (encodingLen < 2)
return (VT_ERROR_INVALID_ENCODING);
len = (unsigned int)(encoding[1]);
/* If the length octet is < 0x80, it's the only length octet and it
* is the value length.
*/
if (len < 0x80)
{
*lengthLen = 1;
*valueLen = len;
return (0);
}
/* If 1st length octet is > 0x80, it describes how many length octets
* there are: 0x8i where i is the number of length octets in addition
* to the 1st length octet.
*/
if ((len & 0xf0) != 0x80)
return (VT_ERROR_INVALID_ENCODING);
/* Assume the length len is not more than 8.
* Also, this is DER, if the value is 0x80, it's indefinite length,
* which is BER.
*/
len &= 0xf;
if ( (len == 0) || (len > 8) )
return (VT_ERROR_INVALID_ENCODING);
/* Make sure the encoding has that many bytes (plus the tag and 1st
* length octet).
*/
if (encodingLen < (len + 2))
return (VT_ERROR_INVALID_ENCODING);
/* Get the value length from the next len octets.
*/
val = 0;
for (index = 0; index < len; ++index)
{
val <<= 8;
val += (unsigned int)(encoding[index + 2]);
}
*lengthLen = len + 1;
*valueLen = val;
return (0);
}
unsigned int VoltDetermineDerLengthLen (
unsigned int length
)
{
if (length <= 0x7f)
return (1);
/* We're assuming the size of an unsigned int will be 1, 2, 4, or 8
* bytes long.
*/
#if VOLT_SIZE_OF_UNSIGNED_INT > 1
if (length <= 0x00ff)
return (2);
#if VOLT_SIZE_OF_UNSIGNED_INT > 2
if (length <= 0x0000ffff)
return (3);
if (length <= 0x00ffffff)
return (4);
#if VOLT_SIZE_OF_UNSIGNED_INT > 4
if (length <= 0x00000000ffffffff)
return (5);
if (length <= 0x000000ffffffffff)
return (6);
if (length <= 0x0000ffffffffffff)
return (7);
if (length <= 0x00ffffffffffffff)
return (8);
#endif /* VOLT_SIZE_OF_UNSIGNED_INT > 4 */
#endif /* VOLT_SIZE_OF_UNSIGNED_INT > 2 */
#endif /* VOLT_SIZE_OF_UNSIGNED_INT > 1 */
return (VOLT_SIZE_OF_UNSIGNED_INT + 1);
}
unsigned int VoltWriteDerTagAndLen (
unsigned char *buf,
unsigned int tag,
unsigned int length
)
{
buf[0] = (unsigned char)tag;
buf++;
if (length <= 0x7f)
{
buf[0] = (unsigned char)length;
return (2);
}
#if VOLT_SIZE_OF_UNSIGNED_INT == 1
buf[0] = 0x81;
buf[1] = (unsigned char)length;
return (3);
#endif
/* We're assuming the size of an unsigned int will be 1, 2, 4, or 8
* bytes long.
*/
#if VOLT_SIZE_OF_UNSIGNED_INT > 1
if (length <= 0x00ff)
{
buf[0] = 0x81;
buf[1] = (unsigned char)length;
return (3);
}
#if VOLT_SIZE_OF_UNSIGNED_INT == 2
buf[0] = 0x82;
buf[1] = (unsigned char)(length >> 8);
buf[2] = (unsigned char)length;
return (4);
#endif
#if VOLT_SIZE_OF_UNSIGNED_INT > 2
if (length <= 0x0000ffff)
{
buf[0] = 0x82;
buf[1] = (unsigned char)(length >> 8);
buf[2] = (unsigned char)length;
return (4);
}
if (length <= 0x00ffffff)
{
buf[0] = 0x83;
buf[1] = (unsigned char)(length >> 16);
buf[2] = (unsigned char)(length >> 8);
buf[3] = (unsigned char)length;
return (5);
}
#if VOLT_SIZE_OF_UNSIGNED_INT == 4
buf[0] = 0x84;
buf[1] = (unsigned char)(length >> 24);
buf[2] = (unsigned char)(length >> 16);
buf[3] = (unsigned char)(length >> 8);
buf[4] = (unsigned char)length;
return (6);
#endif
#if VOLT_SIZE_OF_UNSIGNED_INT > 4
if (length <= 0x00000000ffffffff)
{
buf[0] = 0x84;
buf[1] = (unsigned char)(length >> 24);
buf[2] = (unsigned char)(length >> 16);
buf[3] = (unsigned char)(length >> 8);
buf[4] = (unsigned char)length;
return (6);
}
if (length <= 0x000000ffffffffff)
{
buf[0] = 0x85;
buf[1] = (unsigned char)(length >> 32);
buf[2] = (unsigned char)(length >> 24);
buf[3] = (unsigned char)(length >> 16);
buf[4] = (unsigned char)(length >> 8);
buf[5] = (unsigned char)length;
return (7);
}
if (length <= 0x0000ffffffffffff)
{
buf[0] = 0x86;
buf[1] = (unsigned char)(length >> 40);
buf[2] = (unsigned char)(length >> 32);
buf[3] = (unsigned char)(length >> 24);
buf[4] = (unsigned char)(length >> 16);
buf[5] = (unsigned char)(length >> 8);
buf[6] = (unsigned char)length;
return (8);
}
if (length <= 0x00ffffffffffffff)
{
buf[0] = 0x87;
buf[1] = (unsigned char)(length >> 48);
buf[2] = (unsigned char)(length >> 40);
buf[3] = (unsigned char)(length >> 32);
buf[4] = (unsigned char)(length >> 24);
buf[5] = (unsigned char)(length >> 16);
buf[6] = (unsigned char)(length >> 8);
buf[7] = (unsigned char)length;
return (9);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -