📄 pgpx509cert_util.c
字号:
} /* while there are segments */
return bytesused;
} /* UnpkInPlaceSegments */
static size_t UnpkInPlaceVariableBlock(
PGPASN_CONTEXT *ctx,
unsigned char exptag, /* my expected block tag */
const char *name, /* my block name */
unsigned char tag, /* my real tag */
PGPASN_VariableBlock *asnblock, /* 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;
size_t datasize;
int constructed = 0;
int indef = 0;
PGPASN_TRACE_name(name);
PGPASN_TRACE_PRINT_FM(exptag, tag, name);
if (erret == NULL)
return 0; /* can't report errors */
if (ctx == NULL) {
PGPASN_ERR(kPGPASNError_ErrBadContext);
return 0;
}
if (asnblock == NULL) {
PGPASN_ERR(kPGPASNError_ErrUnpackNoStructure);
return 0;
}
if (buf == NULL) {
PGPASN_ERR(kPGPASNError_ErrUnpackNoBlockPtr);
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 += 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 (asnblock->val != NULL)
PGPASN_Free(ctx->memMgr, asnblock->val); /* about to carve it */
PGPASN_TRACE_PRINT_DATA(buf+bytesused,datasize);
if (constructed == 0) { /* primitive */
asnblock->len = datasize; /* record the length */
asnblock->val = (unsigned char *)PGPASN_Alloc(ctx->memMgr, datasize);
if (asnblock->val == NULL) {
PGPASN_ERR(kPGPASNError_ErrOutOfMemory);
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 PGPASN_VariableBlock -- 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(
PGPASN_CONTEXT *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,
PGPASN_VariableBlock *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) {
PGPASN_ERR(kPGPASNError_ErrPackNoBlock);
return 0;
}
/* need room for tag + length bytes*/
if (buflen < (1 + PGPASN_LengthSize(block->len+pad)) ) {
PGPASN_ERR(kPGPASNError_ErrPackOverrun);
return 0;
}
bytesused = PGPASN_PutTag(buf, blockType, block->len+pad);
if (pad) {
/* error here if padbyte > 7??? */
if (buflen < (bytesused + 1 + block->len) ) {
PGPASN_ERR(kPGPASNError_ErrPackOverrun);
return 0;
}
/* add the pad byte before the data */
bytesused += PGPASN_PutByte( 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) ) {
PGPASN_ERR(kPGPASNError_ErrPackOverrun);
return 0;
}
/* just add the data */
memcpy(buf+bytesused, block->val, block->len);
bytesused += block->len;
}
return bytesused;
} /* PackVariableBlock */
/************************************************************************
* pgpasn_PutOctVal
*
* Put a octet buffer value away in a vbl block.
*************************************************************************/
int pgpasn_PutOctVal(
PGPASN_CONTEXT *ctx,
PGPASN_VariableBlock *block, /* the block for the value */
const unsigned char *value, /* the value */
size_t lth) /* the length */
{
if (ctx == NULL)
return kPGPASNError_ErrBadContext;
if (block == NULL)
return (-1);
if (block->val != NULL)
PGPASN_Free(ctx->memMgr, block->val);
memset (block, 0, sizeof(PGPASN_VariableBlock));
block->val = (unsigned char *)PGPASN_Alloc(ctx->memMgr, lth);
if (block->val == NULL)
return (-1);
memcpy( block->val, value, lth ) ;
block->len = lth ;
return (0);
} /* pgpasn_PutOctVal */
/************************************************************************
* pgpasn_PutStrVal
*
* Put a string value away in a vbl block.
*************************************************************************/
int pgpasn_PutStrVal(
PGPASN_CONTEXT *ctx,
PGPASN_VariableBlock *block, /* the block for the value */
const char *value) /* the value */
{
if (ctx == NULL)
return kPGPASNError_ErrBadContext;
if (block == NULL) return (-1);
if (block->val != NULL)
PGPASN_Free(ctx->memMgr, block->val);
memset(block, 0, sizeof(PGPASN_VariableBlock));
block->len = strlen(value);
block->val = (unsigned char *)PGPASN_Alloc(ctx->memMgr, block->len);
if (block->val == NULL)
return (-1);
memcpy(block->val, value, block->len);
return (0);
} /* pgpasn_PutStrVal */
/************************************************************************
*pgpasn_GetStrVal
*
* Return a string value found in a vbl block.
*************************************************************************/
char *pgpasn_GetStrVal(
PGPASN_CONTEXT *ctx,
PGPASN_VariableBlock *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 *)PGPASN_Alloc(ctx->memMgr, block->len + 1);
if (string == NULL)
return NULL;
memcpy(string, block->val, block->len);
string[block->len] = '\0';
return string;
} /* pgpasn_GetStrVal */
/************************************************************************
* pgpasn_PutBitString
*
* Put a bit string value away in a bitstring block.
************************************************************************/
int pgpasn_PutBitString (
PGPASN_CONTEXT *ctx,
PGPASN_BitstringBlock *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 kPGPASNError_ErrBadContext;
if (block == NULL)
return (-1);
if ((block->val) != NULL)
PGPASN_Free(ctx->memMgr, block->val);
memset (block, 0, sizeof(PGPASN_BitstringBlock));
block->val = (unsigned char *)PGPASN_Alloc(ctx->memMgr, lth);
if (block->val == NULL)
return (-1);
memcpy(block->val, string, lth);
block->len = lth;
block->nuub = nuub;
return 0;
}
/************************************************************************
* pgpasn_PutBoolVal
*
* Put a boolean value in an PGPASN_BOOLEAN block.
*************************************************************************/
int pgpasn_PutBoolVal(
PGPASN_CONTEXT *ctx,
PGPASN_BOOLEAN *block, /* the block for the value */
int val) /* */
{
(void)ctx; /* for future use */
if (block == NULL)
return (-1);
if (val != 0) block->val = PGPASN_TRUE;
else block->val = PGPASN_FALSE;
block->len = 1;
return 0;
}
/************************************************************************
* pgpasn_GetBoolVal
*
* Put a boolean value in an PGPASN_BOOLEAN block.
*************************************************************************/
int pgpasn_GetBoolVal(
PGPASN_CONTEXT *ctx,
PGPASN_BOOLEAN *block) /* the block for the value */
{
(void)ctx; /* for future use */
if (block == NULL) return (-1);
if (block->val != 0) return PGPASN_TRUE;
else return PGPASN_FALSE;
}
/************************************************************************
* NULL routines
*************************************************************************/
PGPASN_NULL *pgpasn_NewNULL(
PGPASN_CONTEXT *ctx)
{
PGPASN_NULL *f = NULL;
if (ctx == NULL)
return NULL;
f = (PGPASN_NULL *)PGPASN_Alloc(ctx->memMgr, sizeof(PGPASN_NULL));
if (f != NULL)
memset(f, 0, sizeof(PGPASN_NULL) );
return ((PGPASN_NULL *) f);
} /* pgpasn_NewNULL */
void pgpasn_DropInPlaceNULL(
PGPASN_CONTEXT *ctx,
PGPASN_NULL *f)
{
(void)ctx;
(void)f;
return ;
} /* pgpasn_DropInPlaceNULL */
void pgpasn_FreeNULL(
PGPASN_CONTEXT *ctx,
PGPASN_NULL *g)
{
if (ctx == NULL)
return;
if (g != NULL)
PGPASN_Free(ctx->memMgr, g);
} /* pgpasn_FreeNULL */
size_t pgpasn_SizeofNULL(
PGPASN_CONTEXT *ctx,
PGPASN_NULL *b,
int outerSizeFlag)
{
(void)ctx; /* for future use */
return pgpasn_SizeofNULLInternal(b, outerSizeFlag, PGPASN_FALSE);
} /* pgpasn_SizeofNULL */
size_t pgpasn_SizeofNULLInternal(
PGPASN_NULL *b,
int outerSizeFlag,
int expTaggedFlag)
{
size_t length = 0;
if (b == NULL)
return 0;
if (outerSizeFlag == PGPASN_TRUE)
length = 2;
if (expTaggedFlag == PGPASN_TRUE)
length = PGPASN_Tagged(length, 0);
return length;
} /* pgpasn_SizeofNULLInternal */
size_t pgpasn_PackNULL(
PGPASN_CONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PGPASN_NULL *asnblock,
int *erret)
{
return (pgpasn_PackNULLInternal(ctx, buf, buflen, asnblock, PGPASN_ID_NULL, erret));
}
size_t pgpasn_PackNULLInternal(
PGPASN_CONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PGPASN_NULL *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 = PGPASN_PutByte(buf, tag);
bytesused += PGPASN_PutByte(buf+bytesused, 0x00); /* length = 0 bytes */
if (bytesused > buflen) {
PGPASN_ERR(kPGPASNError_ErrPackOverrun); /* note this error */
return 0;
}
return bytesused;
} /* pgpasn_PackNULLInternal */
size_t pgpasn_UnpkInPlaceNULL(
PGPASN_CONTEXT *ctx,
PGPASN_NULL *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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -