📄 cert_util.c
字号:
if (erret == NULL)
return 0; /* can't report errors */
if (ctx == NULL) {
PKIERR(PKIErrBadContext);
return 0;
}
if (asnblock == NULL) {
PKIERR(PKIErrUnpackNoStructure);
return 0;
}
if (buf == NULL) {
PKIERR(PKIErrUnpackNoBlockPtr);
return 0;
}
if (buflen <= 0)
return 0; /* no error -- no block */
/* we need to ignore the 6th bit for this check, if this is
BER then it may be set, the checks below
test for those cases */
if ( (*buf & 0xDF) != (exptag & 0xDF) )
return 0; /* no error code, just no block */
if ( (*buf & 0x20) == 0x20)
constructed = 1;
bytesused = 1;
bytesused += PKIGetLength(buf+bytesused, &datasize);
if ((int)datasize == -1) { /* indef length */
datasize = 0;
indef = 1;
}
if (bytesused+datasize > buflen) {
PKIERR(PKIErrUnpackOverrun); /* note this error */
return 0;
}
if (indef == 1 && constructed != 1) {
PKIERR(PKIErrUnpackInvalidEncoding);
return 0;
}
if (asnblock->val != NULL)
PKIFree(ctx->memMgr, asnblock->val); /* about to carve it */
PKITRACE_PRINT_DATA(buf+bytesused,datasize);
if (constructed == 0) { /* primitive */
asnblock->len = datasize; /* record the length */
asnblock->val = (unsigned char *)PKIAlloc(ctx->memMgr, datasize);
if (asnblock->val == NULL) {
PKIERR(PKIErrOutOfMemory);
return 0;
}
memcpy(asnblock->val, buf+bytesused, datasize);
bytesused += datasize;
}
else if (indef == 1) { /* constructed, indefinite length */
bytesused += UnpkInPlaceSegments(ctx, indef, tag, asnblock,
buf+bytesused,
buflen-bytesused, erret);
}
else { /* constructed, definite length */
bytesused += UnpkInPlaceSegments(ctx, indef,
(unsigned char)(exptag & 0xDF), asnblock,
buf+bytesused,
datasize, erret);
}
return bytesused;
} /* UnpkInPlaceVariableBlock */
/************************************************************************
* PackVariableBlock
*
* Pack up an PKIVariableBlock -- which could be an INTEGER, BIT STRING or
* OCTET STRING.
*
* Those three differ in padding (or its inverse).
*
* For OCTET STRING, pad = 0
* For BIT STRING, pad = 1, padb = # unused bits in the LSByte
* For INTEGER, pad = 0..-N, where N is the # of unnecesary leading
* 0x00 or 0xff bytes
*
* pad and padb have to be filled in by the caller.
*************************************************************************/
static size_t PackVariableBlock(
PKICONTEXT *ctx,
unsigned char blockType, /* my block type */
int pad, /* padding? (boolean) */
unsigned char padbyte, /* pad byte if (pad) */
unsigned char *buf, /* the output pointer pointer */
size_t buflen,
PKIVariableBlock *block, /* the block I'm packing */
int *erret) /* an error */
{
size_t bytesused = 0;
unsigned char *lastbyte;
unsigned char mask = 0xFF;
(void)ctx; /* for future use */
if (block == NULL) return 0;
if (buf == NULL) {
PKIERR(PKIErrPackNoBlock);
return 0;
}
/* need room for tag + length bytes*/
if (buflen < (1 + PKILengthSize(block->len+pad)) ) {
PKIERR(PKIErrPackOverrun);
return 0;
}
bytesused = PKIPutTag(buf, blockType, block->len+pad);
if (pad) {
/* error here if padbyte > 7??? */
if (buflen < (bytesused + 1 + block->len) ) {
PKIERR(PKIErrPackOverrun);
return 0;
}
/* add the pad byte before the data */
bytesused += PKIPutByte( buf+bytesused, padbyte);
memcpy(buf+bytesused, block->val, block->len);
bytesused += block->len;
/* for DER bit strings, the padding bits must be zeros */
if (padbyte != 0) {
lastbyte = buf + bytesused - 1;
mask = mask << padbyte; /* zeros are shifted in */
*lastbyte = *lastbyte & mask;
}
}
else {
if (buflen < (bytesused + block->len) ) {
PKIERR(PKIErrPackOverrun);
return 0;
}
/* just add the data */
memcpy(buf+bytesused, block->val, block->len);
bytesused += block->len;
}
return bytesused;
} /* PackVariableBlock */
/************************************************************************
* PKIPutOctVal
*
* Put a octet buffer value away in a vbl block.
*************************************************************************/
int PKIPutOctVal(
PKICONTEXT *ctx,
PKIVariableBlock *block, /* the block for the value */
const unsigned char *value, /* the value */
size_t lth) /* the length */
{
if (ctx == NULL)
return PKIErrBadContext;
if (block == NULL)
return (-1);
if (block->val != NULL)
PKIFree(ctx->memMgr, block->val);
memset (block, 0, sizeof(PKIVariableBlock));
block->val = (unsigned char *)PKIAlloc(ctx->memMgr, lth);
if (block->val == NULL)
return (-1);
memcpy( block->val, value, lth ) ;
block->len = lth ;
return (0);
} /* PKIPutOctVal */
/************************************************************************
* PKIPutStrVal
*
* Put a string value away in a vbl block.
*************************************************************************/
int PKIPutStrVal(
PKICONTEXT *ctx,
PKIVariableBlock *block, /* the block for the value */
const char *value) /* the value */
{
if (ctx == NULL)
return PKIErrBadContext;
if (block == NULL) return (-1);
if (block->val != NULL)
PKIFree(ctx->memMgr, block->val);
memset(block, 0, sizeof(PKIVariableBlock));
block->len = strlen(value);
block->val = (unsigned char *)PKIAlloc(ctx->memMgr, block->len);
if (block->val == NULL)
return (-1);
memcpy(block->val, value, block->len);
return (0);
} /* PKIPutStrVal */
/************************************************************************
*PKIGetStrVal
*
* Return a string value found in a vbl block.
*************************************************************************/
char *PKIGetStrVal(
PKICONTEXT *ctx,
PKIVariableBlock *block)
{
char *string;
if (ctx == NULL)
return NULL;
if (block == NULL)
return NULL;
if (block->val == NULL || block->len == 0)
return NULL;
/* '+1' for NULL char */
string = (char *)PKIAlloc(ctx->memMgr, block->len + 1);
if (string == NULL)
return NULL;
memcpy(string, block->val, block->len);
string[block->len] = '\0';
return string;
} /* PKIGetStrVal */
/************************************************************************
* PKIPutBitString
*
* Put a bit string value away in a bitstring block.
************************************************************************/
int PKIPutBitString (
PKICONTEXT *ctx,
PKIBitstringBlock *block, /* the block for the value */
const unsigned char *string, /* the value */
size_t lth, /* the length */
int nuub) /* number of unused bits LSB */
{
if (ctx == NULL)
return PKIErrBadContext;
if (block == NULL)
return (-1);
if ((block->val) != NULL)
PKIFree(ctx->memMgr, block->val);
memset (block, 0, sizeof(PKIBitstringBlock));
block->val = (unsigned char *)PKIAlloc(ctx->memMgr, lth);
if (block->val == NULL)
return (-1);
memcpy(block->val, string, lth);
block->len = lth;
block->nuub = nuub;
return 0;
}
/************************************************************************
* PKIPutBoolVal
*
* Put a boolean value in an PKIBOOLEAN block.
*************************************************************************/
int PKIPutBoolVal(
PKICONTEXT *ctx,
PKIBOOLEAN *block, /* the block for the value */
int val) /* */
{
(void)ctx; /* for future use */
if (block == NULL)
return (-1);
if (val != 0) block->val = PKITRUE;
else block->val = PKIFALSE;
block->len = 1;
return 0;
}
/************************************************************************
* PKIGetBoolVal
*
* Put a boolean value in an PKIBOOLEAN block.
*************************************************************************/
int PKIGetBoolVal(
PKICONTEXT *ctx,
PKIBOOLEAN *block) /* the block for the value */
{
(void)ctx; /* for future use */
if (block == NULL) return (-1);
if (block->val != 0) return PKITRUE;
else return PKIFALSE;
}
/************************************************************************
* NULL routines
*************************************************************************/
PKINULL *PKINewNULL(
PKICONTEXT *ctx)
{
PKINULL *f = NULL;
if (ctx == NULL)
return NULL;
f = (PKINULL *)PKIAlloc(ctx->memMgr, sizeof(PKINULL));
if (f != NULL)
memset(f, 0, sizeof(PKINULL) );
return ((PKINULL *) f);
} /* PKINewNULL */
void PKIDropInPlaceNULL(
PKICONTEXT *ctx,
PKINULL *f)
{
(void)ctx;
(void)f;
return ;
} /* PKIDropInPlaceNULL */
void PKIFreeNULL(
PKICONTEXT *ctx,
PKINULL *g)
{
if (ctx == NULL)
return;
if (g != NULL)
PKIFree(ctx->memMgr, g);
} /* PKIFreeNULL */
size_t PKISizeofNULL(
PKICONTEXT *ctx,
PKINULL *b,
int outerSizeFlag)
{
(void)ctx; /* for future use */
return PKISizeofNULLInternal(b, outerSizeFlag, PKIFALSE);
} /* PKISizeofNULL */
size_t PKISizeofNULLInternal(
PKINULL *b,
int outerSizeFlag,
int expTaggedFlag)
{
size_t length = 0;
if (b == NULL)
return 0;
if (outerSizeFlag == PKITRUE)
length = 2;
if (expTaggedFlag == PKITRUE)
length = PKITagged(length, 0);
return length;
} /* PKISizeofNULLInternal */
size_t PKIPackNULL(
PKICONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PKINULL *asnblock,
int *erret)
{
return (PKIPackNULLInternal(ctx, buf, buflen, asnblock, PKIID_NULL, erret));
}
size_t PKIPackNULLInternal(
PKICONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PKINULL *asnblock,
unsigned char tag,
int *erret)
{
size_t bytesused;
(void)ctx; /* for future use */
if (erret == NULL) return 0;
if (asnblock == NULL) return 0;
bytesused = PKIPutByte(buf, tag);
bytesused += PKIPutByte(buf+bytesused, 0x00); /* length = 0 bytes */
if (bytesused > buflen) {
PKIERR(PKIErrPackOverrun); /* note this error */
return 0;
}
return bytesused;
} /* PKIPackNULLInternal */
size_t PKIUnpkInPlaceNULL(
PKICONTEXT *ctx,
PKINULL *nullstruct, /* output block */
const unsigned char *buf, /* loc of input pointer */
size_t buflen, /* max end of my region */
unsigned char tag, /* tag to use */
int *erret /* error return location */ )
{
size_t bytesused;
size_t datasize;
PKITRACE_PRINT_FM(tag, 0x05, "NULL");
(void)ctx;
if (erret == NULL) return 0; /* can't report errors */
if (nullstruct == 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; /* no error, no block */
bytesused = 1;
bytesused += PKIGetLength(buf+bytesused, &datasize);
if (datasize != 0) {
PKIERR(PKIErrUnpackNullLth);
return 0;
}
if (bytesused > buflen) {
PKIERR(PKIErrUnpackOverrun); /* note this error */
return 0;
}
nullstruct->len = 0;
return bytesused;
} /* PKIUnpkInPlaceNULL */
size_t PKIUnpackNULL(
PKICONTEXT *ctx,
PKINULL **nullstruct,
const unsigned char *buf,
size_t buflen,
int *erret) /* error return */
{
return(PKIUnpackNULLInternal(ctx, nullstruct, buf, buflen, PKIID_NULL, erret));
} /* PKIUnpackNULL */
size_t PKIUnpackNULLInternal(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -