📄 cert_util.c
字号:
PKICONTEXT *ctx,
PKINULL **nullstruct,
const unsigned char *buf,
size_t buflen,
unsigned char tag,
int *erret) /* error return */
{
size_t bytesused;
PKINULL *local = NULL;
if (erret == NULL)
return 0;
*erret = 0;
if (ctx == NULL) {
PKIERR(PKIErrBadContext);
return 0;
}
if (nullstruct == NULL) {
PKIERR(PKIErrUnpackNoStructure);
return 0;
}
*nullstruct = NULL;
if (buflen <= 0) return 0;
if (*buf != tag) return 0;
local = PKINewNULL(ctx); /* carve a block for it */
bytesused = PKIUnpkInPlaceNULL(ctx, local, buf, buflen, tag, erret);
if (*erret != 0) {
if (local != NULL) PKIFreeNULL(ctx, local);
return 0;
}
*nullstruct = local;
return bytesused;
} /* PKIUnpackNULLInternal */
/************************************************************************
* PKIBOOLEAN routines
*************************************************************************/
PKIBOOLEAN *PKINewBOOLEAN(
PKICONTEXT *ctx)
{
PKIBOOLEAN *f = NULL;
if (ctx == NULL)
return NULL;
f = (PKIBOOLEAN *)PKIAlloc(ctx->memMgr, sizeof(PKIBOOLEAN) );
if (f != NULL)
memset(f, 0, sizeof(PKIBOOLEAN) );
return ((PKIBOOLEAN *) f);
} /* NewBOOLEAN */
void PKIDropInPlaceBOOLEAN(
PKICONTEXT *ctx,
PKIBOOLEAN *f)
{
(void)ctx;
(void)f;
return ;
} /* PKIDropInPlaceBOOLEAN */
void PKIFreeBOOLEAN(
PKICONTEXT *ctx,
PKIBOOLEAN *g )
{
if (ctx == NULL)
return;
if (g != NULL)
PKIFree(ctx->memMgr, g);
} /* PKIFreeBOOLEAN */
size_t PKISizeofBOOLEAN(
PKICONTEXT *ctx,
PKIBOOLEAN *boolblock,
int outerSizeFlag)
{
(void)ctx; /* for future use */
return PKISizeofBOOLEANInternal(boolblock, outerSizeFlag, PKIFALSE);
}
size_t PKISizeofBOOLEANInternal(
PKIBOOLEAN *boolblock,
int outerSizeFlag,
int expTaggedSize)
{
size_t length = 1;
if (boolblock == NULL)
return 0;
if (outerSizeFlag == PKITRUE)
length = 3;
if (expTaggedSize == PKITRUE)
length = PKITagged(length, 0);
return length;
} /* PKISizeofBOOLEANInternal */
size_t PKIPackBOOLEAN(
PKICONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PKIBOOLEAN *boolblock,
int *erret )
{
return(PKIPackBOOLEANInternal(ctx, buf, buflen, boolblock, PKIID_BOOLEAN, erret));
} /* PKIPackBOOLEAN */
size_t PKIPackBOOLEANInternal(
PKICONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PKIBOOLEAN *boolblock,
unsigned char tag,
int *erret )
{
unsigned char value = 0x00;
size_t bytesused;
(void)ctx; /* for future use */
if (boolblock == NULL) return 0;
if (boolblock->val != 0) value = 0xff;
bytesused = PKIPutByte(buf, tag); /* this is a PKIBOOLEAN */
bytesused += PKIPutByte(buf+bytesused, 1); /* length = 1 byte */
bytesused += PKIPutByte(buf+bytesused, value); /* the value */
if (bytesused > buflen) {
PKIERR(PKIErrPackOverrun); /* note this error */
return 0;
}
return bytesused;
} /* PKIPackBOOLEANInternal */
size_t PKIUnpkInPlaceBOOLEAN(
PKICONTEXT *ctx,
PKIBOOLEAN *boolstruct, /* 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;
(void)ctx;
PKITRACE_PRINT_FM(tag, 0x01, "BOOLEAN");
if (erret == NULL) return 0; /* can't report errors */
if (boolstruct == NULL) {
PKIERR(PKIErrUnpackNoStructure);
return 0;
}
if (buf == NULL) {
PKIERR(PKIErrUnpackNoBlockPtr);
return 0;
}
if (buflen <= 0) return 0; /* no error -- no block */
if (*buf != tag) return 0;
bytesused = 1;
bytesused += PKIGetLength(buf+bytesused, &datasize);
if (datasize != 1) {
PKIERR( PKIErrUnpackBooleanLth);
return 0;
}
if (bytesused+datasize > buflen) {
PKIERR(PKIErrUnpackOverrun); /* note this error */
return 0;
}
PKITRACE_PRINT_DATA(buf+bytesused,1);
bytesused += PKIGetByte(buf+bytesused, (unsigned char *)&(boolstruct->val));
if (boolstruct->val != 0) boolstruct->val = PKITRUE;
return bytesused;
} /* PKIUnpkInPlaceBOOLEAN */
size_t PKIUnpackBOOLEAN(
PKICONTEXT *ctx,
PKIBOOLEAN **boolstruct,
const unsigned char *buf,
size_t buflen,
int *erret) /* error return */
{
return(PKIUnpackBOOLEANInternal(ctx, boolstruct, buf, buflen,
PKIID_BOOLEAN, erret));
}
size_t PKIUnpackBOOLEANInternal(
PKICONTEXT *ctx,
PKIBOOLEAN **boolstruct,
const unsigned char *buf,
size_t buflen,
unsigned char tag,
int *erret) /* error return */
{
size_t bytesused;
PKIBOOLEAN *local = NULL;
if (erret == NULL)
return 0;
*erret = 0;
if (ctx == NULL) {
PKIERR(PKIErrBadContext);
return 0;
}
if (boolstruct == NULL) {
PKIERR(PKIErrUnpackNoStructure);
return 0;
}
*boolstruct = NULL;
if (buflen <= 0) return 0;
if (*buf != tag) return 0;
local = PKINewBOOLEAN(ctx); /* carve a block for it */
bytesused = PKIUnpkInPlaceBOOLEAN(ctx, local, buf, buflen, tag, erret);
if (*erret != 0) {
if (local != NULL) PKIFreeBOOLEAN(ctx, local);
return 0;
}
*boolstruct = local;
return bytesused;
} /* PKIUnpackBOOLEANInternal */
/************************************************************************
* Routines for PKIBIT_STRING
*************************************************************************/
PKIBIT_STRING *PKINewBIT_STRING(
PKICONTEXT *ctx)
{
PKIBIT_STRING *f = NULL ;
if (ctx == NULL)
return NULL;
f = (PKIBIT_STRING *)PKIAlloc(ctx->memMgr, sizeof(PKIBIT_STRING) );
if (f != NULL)
memset( f, 0, sizeof(PKIBIT_STRING) );
return ((PKIBIT_STRING *) f);
} /* PKINewBIT_STRING */
void PKIDropInPlaceBIT_STRING(
PKICONTEXT *ctx,
PKIBIT_STRING *f )
{
if (ctx == NULL)
return;
if (f != NULL) {
if ((f->val) != NULL) {
PKIFree(ctx->memMgr, f->val);
}
f->val = NULL ;
}
return ;
} /* PKIDropInPlaceBIT_STRING */
void PKIFreeBIT_STRING(
PKICONTEXT *ctx,
PKIBIT_STRING *f )
{
if (ctx == NULL)
return;
PKIDropInPlaceBIT_STRING(ctx, f);
if (f != NULL)
PKIFree(ctx->memMgr, f);
} /* PKIFreeBIT_STRING */
size_t PKISizeofBIT_STRING(
PKICONTEXT *ctx,
PKIBIT_STRING *bitblock,
int outerSizeFlag)
{
(void)ctx; /* for future use */
return PKISizeofBIT_STRINGInternal(bitblock, outerSizeFlag, PKIFALSE);
}
size_t PKISizeofBIT_STRINGInternal(
PKIBIT_STRING *bitblock,
int outerSizeFlag,
int expTaggedSize)
{
size_t body_size;
if (bitblock == NULL)
return (0);
body_size = 1 + bitblock->len;
if (outerSizeFlag == PKITRUE)
body_size = PKITagged(body_size, 0);
if (expTaggedSize == PKITRUE)
body_size = PKITagged(body_size, 0);
return body_size;
} /* PKISizeofBIT_STRINGInternal */
size_t PKIPackBIT_STRING(
PKICONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PKIBIT_STRING *bitblock,
int *erret)
{
return (PackVariableBlock(ctx, PKIID_BIT_STRING, PKITRUE,
(unsigned char)bitblock->nuub,
buf, buflen, (PKIVariableBlock *)bitblock, erret));
}
size_t PKIPackBIT_STRINGInternal(
PKICONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PKIBIT_STRING *bitblock,
unsigned char tag,
int *erret)
{
return (PackVariableBlock(ctx, tag, PKITRUE,
(unsigned char)bitblock->nuub,
buf, buflen, (PKIVariableBlock *)bitblock, erret));
} /* PKIPackBIT_STRINGInternal */
static size_t uipBitSegments(
PKICONTEXT *ctx,
int indefFlag, /* is this an indefinite length block or not? */
unsigned char exptag, /* my expected block tag */
PKIBIT_STRING *bitblock, /* output block */
const unsigned char *buf, /* loc of input pointer */
size_t buflen, /* max end of my region */
int *erret) /* error return location */
{
size_t bytesused = 0;
size_t datasize;
/* validity of erret and ctx checked in UnpkInPlaceBIT_STRING */
if (buf == NULL) {
PKIERR(PKIErrUnpackNoBlockPtr);
return 0;
}
/* validity of bitblock checked in UnpkInPlaceBIT_STRING */
bitblock->val = NULL;
bitblock->len = 0;
bitblock->nuub = 0;
/* while there are segments */
while (1) {
/* For indef length end-of-contents is 0x00 0x00 and we
have to eat those two bytes, otherwise we see if we've
used up all the available data yet */
if ( indefFlag == 1 &&
(*(buf+bytesused) == 0x00 && *(buf+bytesused+1) == 0x00) ) {
bytesused += 2;
break;
}
else if (indefFlag == 0 && bytesused == buflen)
break;
if (*buf != exptag) {
PKIERR(PKIErrUnpackInvalidEncoding);
return 0;
}
bytesused++; /* skip the tag byte */
datasize = 0;
bytesused += PKIGetLength(buf+bytesused, &datasize);
if ((int)datasize == -1) { /* no nested indef lengths for bit string types */
PKIERR(PKIErrUnpackInvalidEncoding);
return 0;
}
if (bytesused + datasize > buflen) {
PKIERR(PKIErrUnpackOverrun); /* note this error */
return 0;
}
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++;
PKIRealloc(ctx->memMgr,
(void **)&bitblock->val, bitblock->len+datasize-1);
if (bitblock->val == NULL) {
PKIERR(PKIErrOutOfMemory);
return 0;
}
memcpy(bitblock->val + bitblock->len,
buf+bytesused, datasize-1);
bitblock->len += datasize-1;
bytesused += datasize-1;
}
else { /* error */
PKIERR(PKIErrUnpackInvalidEncoding);
return 0;
}
} /* while there are segments */
return bytesused;
} /* UnpkInPlacebit_segments */
size_t PKIUnpkInPlaceBIT_STRING(
PKICONTEXT *ctx,
PKIBIT_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) {
PKIERR(PKIErrBadContext);
return 0;
}
if (bitstruct == NULL) {
PKIERR(PKIErrUnpackNoStructure);
return 0;
}
PKITRACE_PRINT_FM(tag, 0x03, "BIT STRING");
if (buf == NULL) {
PKIERR(PKIErrUnpackNoBlockPtr);
return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -