📄 pgpx509cert.c
字号:
}
}
PGPASN_TRACE_INCR_LEVEL;
do {
/* field type of AttributeTypeAndValue */
bytesused += pgpasn_UnpkInPlaceAttributeType(ctx, &(asnstruct->type), buf+bytesused,
localsize-bytesused, PGPASN_ID_AttributeType, erret);
if (bytesused > localsize || *erret != 0)
break;
/* field value of AttributeTypeAndValue */
bytesused += pgpasn_UnpkInPlaceAttributeValue(ctx, &(asnstruct->value), buf+bytesused,
localsize-bytesused, PGPASN_ID_AttributeValue, erret);
if (bytesused > localsize || *erret != 0)
break;
if (indef) {
if ( *(buf+bytesused) != 0x00 &&
*(buf+bytesused+1) != 0x00 ) {
PGPASN_ERR(kPGPASNError_ErrUnpackInvalidEncoding);
break;
}
bytesused += 2;
}
} while(0);
PGPASN_TRACE_DECR_LEVEL;
if (bytesused > localsize && *erret == 0)
PGPASN_ERR(kPGPASNError_ErrUnpackOverrun);
if (!indef && bytesused < localsize && *erret == 0)
PGPASN_ERR(kPGPASNError_ErrUnpackUnderrun);
return bytesused;
} /* pgpasn_UnpkInPlaceAttributeTypeAndValue */
size_t pgpasn_UnpackAttributeTypeAndValueInternal(
PGPASN_CONTEXT *ctx,
PGPASN_AttributeTypeAndValue **asnstruct,
const unsigned char *buf,
size_t buflen,
unsigned char tag,
int *erret)
{
size_t bytesused;
PGPASN_AttributeTypeAndValue *local = NULL;
if (erret == NULL) return 0;
*erret = 0;
if (ctx == NULL) {
PGPASN_ERR(kPGPASNError_ErrBadContext);
return 0;
}
if (asnstruct == NULL) {
PGPASN_ERR(kPGPASNError_ErrUnpackNoStructure);
return 0;
}
*asnstruct = NULL;
if (buflen <= 0) return 0; /* no bytes left */
if ( (*buf & 0xDF) != (tag & 0xDF) )
return 0; /* not correct tag */
local = pgpasn_NewAttributeTypeAndValue(ctx); /* carve a block for it */
bytesused = pgpasn_UnpkInPlaceAttributeTypeAndValue(ctx, local, buf, buflen, tag, erret);
if (*erret != 0) {
if (local != NULL) pgpasn_FreeAttributeTypeAndValue(ctx, local);
return 0;
}
*asnstruct = local;
return bytesused;
} /* pgpasn_UnpackAttributeTypeAndValueInternal */
/******************************************************************
* Routines for AttributeValues
******************************************************************/
size_t pgpasn_SizeofAttributeValuesInternal(
PGPASN_AttributeValues *asnstruct,
int outerSizeFlag,
int expTaggedFlag)
{
size_t body_size = 0;
long i, lth;
if (asnstruct == NULL)
return 0;
lth = asnstruct->n;
if (lth > PGPASN_MAX_AttributeValues)
lth = PGPASN_MAX_AttributeValues; /* clamp it */
for (i=0;i<lth;i++)
body_size += pgpasn_SizeofAttributeValueInternal((asnstruct->elt)[i], PGPASN_TRUE, PGPASN_FALSE);
if (outerSizeFlag == PGPASN_TRUE)
body_size = PGPASN_Tagged(body_size, 1);
if (expTaggedFlag == PGPASN_TRUE)
body_size = PGPASN_Tagged(body_size, 1); /* this is seq like */
return body_size;
} /* pgpasn_SizeofAttributeValuesInternal */
void pgpasn_DropInPlaceAttributeValues(
PGPASN_CONTEXT *ctx,
PGPASN_AttributeValues *f)
{
long i, lth;
if (ctx == NULL) return;
if (f == NULL) return;
lth = f->n;
if (lth > PGPASN_MAX_AttributeValues)
lth = PGPASN_MAX_AttributeValues; /* clamp it */
for (i=0;i<lth;i++) {
pgpasn_FreeAttributeValue(ctx, (f->elt)[i] );
(f->elt)[i] = NULL;
}
} /* pgpasn_DropInPlaceAttributeValues */
size_t pgpasn_PackAttributeValuesInternal(
PGPASN_CONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PGPASN_AttributeValues *asnstruct,
unsigned char tag,
int *erret)
{
size_t bytesused;
size_t tagsize;
size_t datasize;
long numElem;
int i, j;
size_t length;
size_t max = 0;
PGPASN_VariableBlock temp[PGPASN_MAX_AttributeValues];
if (erret == NULL) return 0; /* can't report errors */
if (ctx == NULL) {
PGPASN_ERR(kPGPASNError_ErrBadContext);
return 0;
}
if (asnstruct == NULL) return 0; /* nothing to pack */
/* make sure there aren't too many elements */
numElem = asnstruct->n;
if (numElem > PGPASN_MAX_AttributeValues) {
PGPASN_ERR(kPGPASNError_ErrPackSETOFArrayTooLong);
return 0;
}
datasize = pgpasn_SizeofAttributeValues(ctx, asnstruct, PGPASN_FALSE);
tagsize = 1 + PGPASN_LengthSize(datasize);
if (datasize+tagsize > buflen) {
PGPASN_ERR(kPGPASNError_ErrPackBufferTooShort);
return 0;
}
/* this is a SET_OF */
bytesused = PGPASN_PutTag(buf, (unsigned char)(tag|0x20), datasize);
if (bytesused != tagsize) {
PGPASN_ERR(kPGPASNError_ErrPackOverrun);
return bytesused;
}
datasize += tagsize;
if (numElem == 1) {
bytesused += pgpasn_PackAttributeValueInternal(ctx, buf+bytesused, buflen-bytesused,
(asnstruct->elt)[0], PGPASN_ID_AttributeValue, erret);
}
else {
/* calculate lengths and max */
for (i=0; i<numElem; i++) {
length = pgpasn_SizeofAttributeValue(ctx, (asnstruct->elt)[i], PGPASN_TRUE);
if (length > max)
max = length;
temp[i].len = length;
}
/* temporarily allocate and pack */
*erret = 0;
for (i=0; i<numElem; i++) {
temp[i].val = (unsigned char *)PGPASN_Alloc(ctx->memMgr, max);
memset(temp[i].val, 0, max);
(void) pgpasn_PackAttributeValueInternal(ctx, temp[i].val,
max, (asnstruct->elt)[i],
PGPASN_ID_AttributeValue, erret );
if (*erret != 0) {
for (j=0; j<i; j++)
PGPASN_Free(ctx->memMgr, temp[j].val);
return 0;
}
}
/* sort and look for duplicates */
qsort(temp, numElem, sizeof(PGPASN_VariableBlock), PGPASN_CompareElems);
for (i=0; i<(numElem-1); i++)
if (memcmp(temp[i].val, temp[i+1].val, max) == 0) {
PGPASN_ERR(kPGPASNError_ErrPackSETOFUnsortable);
for (j=0; j<i; j++)
PGPASN_Free(ctx->memMgr, temp[j].val);
return 0;
}
/* pack for real and deallocate temp */
for (i=0; i<numElem; i++) {
(void)memcpy(buf+bytesused, temp[i].val, temp[i].len);
bytesused += temp[i].len;
if (bytesused > datasize)
break;
PGPASN_Free(ctx->memMgr, temp[i].val);
}
}
if (bytesused < datasize && *erret == 0)
PGPASN_ERR(kPGPASNError_ErrPackUnderrun)
else if (bytesused > datasize && *erret == 0)
PGPASN_ERR(kPGPASNError_ErrPackOverrun)
return bytesused;
} /* pgpasn_PackAttributeValuesInternal */
size_t pgpasn_UnpkInPlaceAttributeValues(
PGPASN_CONTEXT *ctx,
PGPASN_AttributeValues *asnstruct,
const unsigned char *buf,
size_t buflen,
unsigned char tag,
int *erret )
{
size_t bytesused;
size_t datasize;
size_t localsize;
long i;
int indef = 0;
PGPASN_TRACE_PRINT_FN((tag|0x20), 0x31, "SET OF", "AttributeValues");
if (erret == NULL) return 0;
if (ctx == NULL) {
PGPASN_ERR(kPGPASNError_ErrBadContext);
return 0;
}
if (asnstruct == NULL) {
PGPASN_ERR(kPGPASNError_ErrUnpackNoStructure);
return 0;
}
if (buf == NULL) {
PGPASN_ERR(kPGPASNError_ErrUnpackNoBlockPtr);
return 0;
}
if (buflen <= 0) return 0; /* out of bytes, no action */
if ( (*buf & 0xDF) != (tag & 0xDF) )
return 0; /* not my kind of block */
if ( (*buf & 0x20) != 0x20) {
PGPASN_ERR(kPGPASNError_ErrUnpackInvalidEncoding);
return 0;
}
PGPASN_TRACE_INCR_LEVEL;
bytesused = 1; /* consume the tag byte */
bytesused += PGPASN_GetLength(buf+bytesused, &datasize);
if ((int)datasize == -1) {
localsize = buflen;
indef = 1;
}
else {
localsize = bytesused + datasize;
if (localsize > buflen) {
PGPASN_ERR(kPGPASNError_ErrUnpackOverrun);
asnstruct->n = -1 ; /* note where (-1 treated as 0) */
PGPASN_TRACE_DECR_LEVEL;
return 0;
}
}
for (i=0; (i < PGPASN_MAX_AttributeValues) && (bytesused < localsize); i++) {
/* if this is indef length and we have EOC, done */
if (indef && *(buf+bytesused) == 0x00 &&
*(buf+bytesused+1) == 0x00 ) {
break;
}
if (asnstruct->elt[i] == NULL)
asnstruct->elt[i] = pgpasn_NewAttributeValue(ctx);
if (asnstruct->elt[i] == NULL) {
PGPASN_ERR(kPGPASNError_ErrOutOfMemory);
break;
}
asnstruct->n = i+1 ; /* note the new element */
bytesused += pgpasn_UnpkInPlaceAttributeValue(ctx, asnstruct->elt[i],
buf+bytesused, localsize-bytesused,
PGPASN_ID_AttributeValue, erret);
if (*erret != 0)
break;
} /* for */
if (indef) {
if ( *(buf+bytesused) != 0x00 &&
*(buf+bytesused+1) != 0x00 ) {
PGPASN_ERR(kPGPASNError_ErrUnpackInvalidEncoding);
}
else
bytesused += 2;
}
PGPASN_TRACE_DECR_LEVEL;
if (bytesused > localsize && *erret == 0)
PGPASN_ERR(kPGPASNError_ErrUnpackOverrun);
if (!indef && bytesused < localsize && *erret == 0)
PGPASN_ERR(kPGPASNError_ErrUnpackUnderrun);
return bytesused;
} /* pgpasn_UnpkInPlaceAttributeValues */
size_t pgpasn_UnpackAttributeValuesInternal(
PGPASN_CONTEXT *ctx,
PGPASN_AttributeValues **asnstruct,
const unsigned char *buf,
size_t buflen,
unsigned char tag,
int *erret)
{
size_t bytesused;
PGPASN_AttributeValues *local = NULL;
if (erret == NULL) return 0;
*erret = 0;
if (ctx == NULL) {
PGPASN_ERR(kPGPASNError_ErrBadContext);
return 0;
}
if (asnstruct == NULL) {
PGPASN_ERR(kPGPASNError_ErrUnpackNoStructure);
return 0;
}
*asnstruct = NULL;
if (buflen <= 0) return 0; /* no bytes left */
if ( (*buf & 0xDF) != (tag & 0xDF) )
return 0; /* not correct tag */
local = pgpasn_NewAttributeValues(ctx); /* carve a block for it */
bytesused = pgpasn_UnpkInPlaceAttributeValues(ctx, local, buf, buflen, tag, erret);
if (*erret != 0) {
if (local != NULL) pgpasn_FreeAttributeValues(ctx, local);
return 0;
}
*asnstruct = local;
return bytesused;
} /* pgpasn_UnpackAttributeValuesInternal */
/******************************************************************
* Routines for BasicConstraints
******************************************************************/
size_t pgpasn_SizeofBasicConstraintsInternal(
PGPASN_BasicConstraints *asnstruct,
int outerSizeFlag,
int expTaggedFlag)
{
size_t body_size = 0;
if (asnstruct == NULL)
return 0;
body_size =
pgpasn_SizeofBOOLEANInternal(asnstruct->cA, PGPASN_TRUE, PGPASN_FALSE)
+ pgpasn_SizeofINTEGERInternal(asnstruct->pathLenConstraint, PGPASN_TRUE, PGPASN_FALSE) ;
if (outerSizeFlag == PGPASN_TRUE)
body_size = PGPASN_Tagged(body_size, 1);
if (expTaggedFlag == PGPASN_TRUE)
body_size = PGPASN_Tagged(body_size, 1); /* this is seq like */
return body_size;
} /* pgpasn_SizeofBasicConstraintsInternal */
void pgpasn_DropInPlaceBasicConstraints(
PGPASN_CONTEXT *ctx,
PGPASN_BasicConstraints *f)
{
if (ctx == NULL)
return;
if (f == NULL) return ;
pgpasn_FreeBOOLEAN(ctx, f->cA);
f->cA = NULL;
pgpasn_FreeINTEGER(ctx, f->pathLenConstraint);
f->pathLenConstraint = NULL;
} /* pgpasn_DropInPlaceBasicConstraints */
size_t pgpasn_PackBasicConstraintsInternal(
PGPASN_CONTEXT *ctx,
unsigned char *buf,
size_t buflen,
PGPASN_BasicConstraints *asnstruct,
unsigned char tag,
int *erret)
{
size_t bytesused;
size_t tagsize;
size_t datasize;
if (erret == NULL) return 0; /* can't report errors */
if (ctx == NULL) {
PGPASN_ERR(kPGPASNError_ErrBadContext);
return 0;
}
if (asnstruct == NULL) return 0;
/* lth of the block body */
datasize = pgpasn_SizeofBasicConstraints(ctx, asnstruct, PGPASN_FALSE);
tagsize = 1 + PGPASN_LengthSize(datasize);
if (datasize+tagsize > buflen) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -