📄 pgpx509cert_util.c
字号:
if (datasize == 0)
continue;
/* All segments but the last must be multiples of 8 bits, so
the nuub value for all segments but the last must have 0
for the nuub. So we check for 0 nuub here, if the previous
segment did not have 0 nuub, then its an error. If this is
the last segment, we will exit the loop so the new nuub can be other
then 0. */
if (bitblock->nuub == 0) {
/* the first byte of the data is the number of unused bits */
bitblock->nuub = *(buf+bytesused);
bytesused++;
PGPASN_Realloc(ctx->memMgr,
(void **)&bitblock->val, bitblock->len+datasize-1);
if (bitblock->val == NULL) {
PGPASN_ERR(kPGPASNError_ErrOutOfMemory);
return 0;
}
memcpy(bitblock->val + bitblock->len,
buf+bytesused, datasize-1);
bitblock->len += datasize-1;
bytesused += datasize-1;
}
else { /* error */
PGPASN_ERR(kPGPASNError_ErrUnpackInvalidEncoding);
return 0;
}
} /* while there are segments */
return bytesused;
} /* UnpkInPlacebit_segments */
size_t pgpasn_UnpkInPlaceBIT_STRING(
PGPASN_CONTEXT *ctx,
PGPASN_BIT_STRING *bitstruct, /* output block */
const unsigned char *buf, /* loc of input pointer */
size_t buflen, /* max end of my region */
unsigned char tag,
int *erret) /* error return location */
{
size_t bytesused;
size_t datasize;
int constructed = 0;
int indef = 0;
if (erret == NULL)
return 0; /* can't report errors */
*erret = 0;
if (ctx == NULL) {
PGPASN_ERR(kPGPASNError_ErrBadContext);
return 0;
}
if (bitstruct == NULL) {
PGPASN_ERR(kPGPASNError_ErrUnpackNoStructure);
return 0;
}
PGPASN_TRACE_PRINT_FM(tag, 0x03, "BIT STRING");
if (buf == NULL) {
PGPASN_ERR(kPGPASNError_ErrUnpackNoBlockPtr);
return 0;
}
if (buflen <= 0)
return 0; /* no error -- no block */
/* see note in UnpkInPlaceVariableBlock */
if ( (*buf & 0xDF) != (tag & 0xDF) )
return 0;
if ( (*buf & 0x20) == 0x20)
constructed = 1;
bytesused = 1; /* eat the tag byte */
bytesused += PGPASN_GetLength(buf+bytesused, &datasize);
if ((int)datasize == -1) { /* indef length */
datasize = 0;
indef = 1;
}
if (bytesused+datasize > buflen) {
PGPASN_ERR(kPGPASNError_ErrUnpackOverrun); /* note this error */
return 0;
}
if (indef == 1 && constructed != 1) {
PGPASN_ERR(kPGPASNError_ErrUnpackInvalidEncoding);
return 0;
}
if (bitstruct->val != NULL)
PGPASN_Free(ctx->memMgr, bitstruct->val);
PGPASN_TRACE_PRINT_DATA(buf+bytesused,datasize);
if (constructed == 0) { /* primitive */
/* the first byte of the data is the number of unused bits */
bitstruct->nuub = *(buf+bytesused);
bytesused++;
/* the len is -1 since we just used one byte for the nuub value */
bitstruct->len = datasize-1;
bitstruct->val = (unsigned char *)PGPASN_Alloc(ctx->memMgr, bitstruct->len);
if (bitstruct->val == NULL) {
PGPASN_ERR(kPGPASNError_ErrOutOfMemory);
return 0;
}
memcpy(bitstruct->val, buf+bytesused, bitstruct->len);
bytesused += bitstruct->len;
}
else if (indef == 1) { /* constructed, indefinite length */
bytesused += uipBitSegments(ctx, indef,
(unsigned char)(tag & 0xDF), bitstruct,
buf+bytesused,
buflen-bytesused, erret);
}
else { /* constructed, definite length */
bytesused += uipBitSegments(ctx, indef,
(unsigned char)(tag & 0xDF), bitstruct,
buf+bytesused,
datasize, erret);
}
return bytesused;
} /* pgpasn_UnpkInPlaceBIT_STRING */
size_t pgpasn_UnpackBIT_STRING(
PGPASN_CONTEXT *ctx,
PGPASN_BIT_STRING **bitstruct,
const unsigned char *buf,
size_t buflen,
int *erret)
{
return(pgpasn_UnpackBIT_STRINGInternal(ctx, bitstruct, buf, buflen,
PGPASN_ID_BIT_STRING, erret));
}
size_t pgpasn_UnpackBIT_STRINGInternal(
PGPASN_CONTEXT *ctx,
PGPASN_BIT_STRING **bitstruct,
const unsigned char *buf,
size_t buflen,
unsigned char tag,
int *erret) /* error return */
{
size_t bytesused;
PGPASN_BIT_STRING *local = NULL;
if (erret == NULL)
return 0;
*erret = 0;
if (ctx == NULL) {
PGPASN_ERR(kPGPASNError_ErrBadContext);
return 0;
}
if (bitstruct == NULL) {
PGPASN_ERR(kPGPASNError_ErrUnpackNoStructure);
return 0;
}
*bitstruct = NULL;
if (buflen <= 0) return 0;
/* see note in UnpkInPlaceVariableBlock */
if ( (*buf & 0xDF) != (tag & 0xDF) ) return 0;
local = pgpasn_NewBIT_STRING(ctx);
bytesused = pgpasn_UnpkInPlaceBIT_STRING(ctx, local, buf, buflen, tag, erret);
if (*erret != 0) {
if (local != NULL) pgpasn_FreeBIT_STRING(ctx, local);
return 0;
}
*bitstruct = local;
return bytesused;
} /* pgpasn_UnpackBIT_STRINGInternal */
/************************************************************************
* Routines for PGPASN_GeneralizedTime
*************************************************************************/
size_t pgpasn_PackGeneralizedTime(
PGPASN_CONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PGPASN_GeneralizedTime *timeblock,
int *erret)
{
return(PackVariableBlock(ctx, PGPASN_ID_GeneralizedTime, PGPASN_FALSE, 0, buf, buflen,
timeblock, erret));
}
size_t pgpasn_PackGeneralizedTimeInternal(
PGPASN_CONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PGPASN_GeneralizedTime *timeblock,
unsigned char tag,
int *erret)
{
return(PackVariableBlock(ctx, tag, PGPASN_FALSE, 0, buf, buflen, timeblock, erret));
} /* pgpasn_PackGeneralizedTimeInternal */
size_t pgpasn_UnpkInPlaceGeneralizedTime(
PGPASN_CONTEXT *ctx,
PGPASN_GeneralizedTime *timestruct, /* output block */
const unsigned char *buf, /* loc of input pointer */
size_t buflen, /* max end of my region */
unsigned char tag,
int *erret) /* error return location */
{
return(UnpkInPlaceVariableBlock(ctx, tag, "GeneralizedTime", 0x18, timestruct,
buf, buflen, erret));
} /* pgpasn_UnpkInPlaceGeneralizedTime */
size_t pgpasn_UnpackGeneralizedTime(
PGPASN_CONTEXT *ctx,
PGPASN_GeneralizedTime **timestruct,
const unsigned char *buf,
size_t buflen,
int *erret)
{
return(pgpasn_UnpackGeneralizedTimeInternal(ctx, timestruct, buf, buflen,
PGPASN_ID_GeneralizedTime, erret));
}
size_t pgpasn_UnpackGeneralizedTimeInternal(
PGPASN_CONTEXT *ctx,
PGPASN_GeneralizedTime **timestruct,
const unsigned char *buf,
size_t buflen,
unsigned char tag,
int *erret) /* error return */
{
size_t bytesused;
PGPASN_GeneralizedTime *local = NULL;
if (erret == NULL) return 0;
*erret = 0;
if (ctx == NULL) {
PGPASN_ERR(kPGPASNError_ErrBadContext);
return 0;
}
if (timestruct == NULL) {
PGPASN_ERR(kPGPASNError_ErrUnpackNoStructure);
return 0;
}
*timestruct = NULL;
if (buflen <= 0) return 0;
/* see note in UnpkInPlaceVariableBlock */
if ( (*buf & 0xDF) != (tag & 0xDF) ) return 0;
local = pgpasn_NewGeneralizedTime(ctx); /* carve a block for it */
bytesused = pgpasn_UnpkInPlaceGeneralizedTime(ctx, local, buf, buflen, tag, erret);
if (*erret != 0) {
if (local != NULL) pgpasn_FreeGeneralizedTime(ctx, local);
return 0;
}
*timestruct = local;
return bytesused;
} /* pgpasn_UnpackGeneralizedTimeInternal */
/************************************************************************
* Routines for PGPASN_IA5String
*************************************************************************/
size_t pgpasn_PackIA5String(
PGPASN_CONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PGPASN_IA5String *strblock,
int *erret)
{
return(PackVariableBlock(ctx, PGPASN_ID_IA5String, PGPASN_FALSE, 0, buf, buflen,
strblock, erret));
} /* pgpasn_PackIA5String */
size_t pgpasn_PackIA5StringInternal(
PGPASN_CONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PGPASN_IA5String *strblock,
unsigned char tag,
int *erret)
{
return(PackVariableBlock(ctx, tag, PGPASN_FALSE, 0, buf, buflen, strblock, erret));
} /* pgpasn_PackIA5StringInternal */
size_t pgpasn_UnpkInPlaceIA5String(
PGPASN_CONTEXT *ctx,
PGPASN_IA5String *strblock, /* output block */
const unsigned char *buf, /* loc of input pointer */
size_t buflen, /* max end of my region */
unsigned char tag,
int *erret) /* error return location */
{
return (UnpkInPlaceVariableBlock(ctx, tag, "IA5String", 0x16, strblock, buf, buflen, erret));
} /* pgpasn_UnpkInPlaceIA5String */
size_t pgpasn_UnpackIA5String(
PGPASN_CONTEXT *ctx,
PGPASN_IA5String **strblock,
const unsigned char *buf,
size_t buflen, /* my end pointer */
int *erret)
{
return(pgpasn_UnpackIA5StringInternal(ctx, strblock, buf, buflen,
PGPASN_ID_IA5String, erret));
}
size_t pgpasn_UnpackIA5StringInternal(
PGPASN_CONTEXT *ctx,
PGPASN_IA5String **strblock,
const unsigned char *buf,
size_t buflen, /* my end pointer */
unsigned char tag,
int *erret) /* error return */
{
size_t bytesused;
PGPASN_IA5String *local = NULL;
if (erret == NULL) return 0;
*erret = 0;
if (ctx == NULL) {
PGPASN_ERR(kPGPASNError_ErrBadContext);
return 0;
}
if (strblock == NULL) {
PGPASN_ERR(kPGPASNError_ErrUnpackNoStructure);
return 0;
}
*strblock = NULL;
if (buflen <= 0) return 0;
/* see note in UnpkInPlaceVariableBlock */
if ( (*buf & 0xDF) != (tag & 0xDF) ) return 0;
local = pgpasn_NewIA5String(ctx); /* carve a block for it */
bytesused = pgpasn_UnpkInPlaceIA5String(ctx, local, buf, buflen, tag, erret);
if (*erret != 0) {
if (local != NULL) pgpasn_FreeIA5String(ctx, local);
return 0;
}
*strblock = local;
return bytesused;
} /* pgpasn_UnpackIA5StringInternal */
/************************************************************************
* Routines for PGPASN_INTEGER
*************************************************************************/
/************************************************************************
* normalize
*
* remove leading 0's from the integer byte string/
* This routine isn't the most efficient, but it should never have to
* move any bytes because all numbers should be normalized already.
*************************************************************************/
static void normalize( PGPASN_INTEGER *b )
{
size_t i ;
unsigned char *x ;
if (b == NULL) return ;
if ((b->val) == NULL) {
b->len = 0 ; /* no bytes, no length */
return ;
}
x = b->val ; /* point to the array */
while ( (((x[0]^x[1])&0x80) == 0)
&& ((x[0] == 0)||(x[0] == 0xff))
&& ((b->len) > 1) ) { /* shorten this by 1 byte */
(b->len)-- ; /* note the shortening */
for (i=0; i<(b->len); i++) x[i] = x[i+1] ; /* do it */
} /* while */
return ;
} /* normalize */
size_t pgpasn_SizeofINTEGER(
PGPASN_CONTEXT *ctx,
PGPASN_INTEGER *intblock,
int outerSizeFlag)
{
(void)ctx; /* for future use */
return pgpasn_SizeofINTEGERInternal(intblock, outerSizeFlag, PGPASN_FALSE);
}
size_t pgpasn_SizeofINTEGERInternal(
PGPASN_INTEGER *intblock,
int outerSizeFlag,
int expTaggedSize)
{
size_t length;
if (intblock == NULL)
return 0;
normalize(intblock);
length = intblock->len;
if (outerSizeFlag == PGPASN_TRUE)
length = length + 1 + PGPASN_LengthSize(length);
if (expTaggedSize == PGPASN_TRUE)
length = PGPASN_Tagged(length, 0);
return length;
} /* pgpasn_SizeofINTEGERInternal */
size_t pgpasn_PackINTEGER(
PGPASN_CONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PGPASN_INTEGER *intblock,
int *erret)
{
return(pgpasn_PackINTEGERInternal(ctx, buf, buflen, intblock, PGPASN_ID_INTEGER, erret));
}
size_t pgpasn_PackINTEGERInternal(
PGPASN_CONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PGPASN_INTEGER *intblock,
unsigned char tag,
int *erret)
{
if (intblock == NULL) return 0;
normalize(intblock);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -