📄 extensions.c
字号:
TC_Free(ctx->memMgr, bufPtr);
bufPtr = NULL;
*size = 0;
} /* if */
PKIFreeBasicConstraints(ctx->certasnctx, basicConstraints);
*buf = bufPtr;
return status;
} /* CreateBasicConstraintsDER */
/******************************************************************/
/* GetBasicConstraints */
/******************************************************************/
/* Routine to fill a simple (TC) basic constraints structure from */
/* Extension provided. */
/* */
/* Extensions are defined in ITU-T X.509 Recommendation. */
/* */
/* Given an extension, unpack the basic constraints DER into a */
/* simplified basic constraints "C" structure. No checks on data */
/* semantics are performed. */
/* */
/* The caller is responsible for freeing returnBCons. */
/* */
/* Parameters */
/* input */
/* ext - pointer to the given extension */
/* output */
/* returnBCons - ptr to ptr for simple C structure for B.C. */
/* */
/* Return */
/* 0 - okay */
/* TC_E_NOMEMORY - out of memory */
/* TC_E_EXTENSION - error packing extension */
/* TC_E_INVARGS - invalid arguments */
/******************************************************************/
static int GetBasicConstraints(void **returnBCons,
const PKIExtension *ext,
TC_CONTEXT *ctx)
{
PKIBasicConstraints *basicConstraints = NULL;
TC_BASIC_CONSTRAINT *simpleBCons = NULL;
unsigned char *value = NULL;
size_t valueLen = 0;
int errorRet = 0;
int status = 0;
do
{
/* ----- Unpack extension value into basicConstraints ----- */
value = ext->extnValue.val;
valueLen = ext->extnValue.len;
(void)PKIUnpackBasicConstraints(ctx->certasnctx,
&basicConstraints,
value,
valueLen,
&errorRet);
if (errorRet != 0)
{
status = TC_E_EXTENSION;
break;
} /* if */
/* ----- convert ASN.1 structure to simple TC structure ----- */
/* create and init simple basic constraints structure */
simpleBCons = (TC_BASIC_CONSTRAINT *)
TC_Alloc(ctx->memMgr, sizeof (TC_BASIC_CONSTRAINT));
if (simpleBCons == (TC_BASIC_CONSTRAINT *) 0)
{
status = TC_E_NOMEMORY;
break;
} /*if */
/* fill in values for simple structure using ASN.1 struct */
if (basicConstraints->cA != NULL &&
basicConstraints->cA->val == 1)
simpleBCons->cA = (boolean) 1;
else
simpleBCons->cA = (boolean) 0;
if (basicConstraints->pathLenConstraint != NULL)
{
simpleBCons->pathLength =
(int)PKIGetIntVal(ctx->certasnctx,
basicConstraints->pathLenConstraint,
&errorRet);
if (errorRet != 0)
{
status = TC_E_EXTENSION;
break;
}
} /*if basicConstraints */
else
simpleBCons->pathLength = TC_PATH_LENGTH_UNDEFINED;
} while (/* CONSTCOND */ 0);
/* ------- Clean up: assign to return vbls and free space ------ */
PKIFreeBasicConstraints(ctx->certasnctx, basicConstraints );
if ( status != 0 )
TC_Free(ctx->memMgr, simpleBCons);
else
{
*returnBCons = (void *) simpleBCons;
} /* else */
return status;
} /* GetBasicConstraints */
/******************************************************************/
/* GetKeyUsage */
/******************************************************************/
/* Routine to fill a key usage integer from extension provided. */
/* */
/* Extensions are defined in ITU-T X.509 Recommendation. */
/* */
/* Given an extension, unpack the key usage DER into an integer */
/* No checks on data semantics are performed. */
/* */
/* The caller is responsible for freeing returnKeyU. */
/* */
/* Parameters */
/* input */
/* ext - pointer to the given extension */
/* output */
/* returnKeyU - ptr to ptr for simple C structure for key u. */
/* */
/* Return */
/* 0 - okay */
/* TC_E_EXTENSION - error packing extension */
/* TC_E_INVARGS - invalid arguments */
/******************************************************************/
static int GetKeyUsage (void **returnKeyU,
const PKIExtension *ext,
TC_CONTEXT *ctx)
{
PKIKeyUsage *keyUsage = NULL;
unsigned int *intBits = NULL;
unsigned char *value = NULL;
size_t valueLen = 0;
int errorRet = 0;
unsigned char *charBits = NULL;
int bytesUsed = 0;
int unusedBits = 0;
int byteCount = 0;
int status = 0;
int i = 0;
int j = 0;
do
{
/* ----- Unpack extension value into keyUsage ----- */
value = ext->extnValue.val;
valueLen = ext->extnValue.len;
(void) PKIUnpackKeyUsage(ctx->certasnctx,
&keyUsage,
value,
valueLen,
&errorRet);
if ((errorRet != 0) ||
(keyUsage == NULL))
{
status = TC_E_EXTENSION;
break;
} /* if */
/* ----- Set bit values for integer using ASN.1 struct ----- */
bytesUsed = keyUsage->len;
unusedBits = keyUsage->nuub;
charBits = keyUsage->val;
/* Note: charBits array is interpreted left to right. I.e.,
1101000 means digital sig, non repud, data enciph */
/* starting at low-order byte, reverse charBits bit string
and store in intBits integer */
intBits = (unsigned int *)TC_Alloc(ctx->memMgr, sizeof (unsigned int));
if (intBits == NULL)
{
status = TC_E_NOMEMORY;
break;
} /* if */
memset(intBits, 0, sizeof (unsigned int));
j = 7;
for (i = 0; i < bytesUsed * 8 - unusedBits; i++)
{
*intBits = *intBits |
(int) (((charBits[ byteCount ] >> j) & 0x1 ) << i );
j--;
/* reset for next byte */
if (j < 0)
{
byteCount++;
j = 7;
} /* if */
} /* for */
/* Note: intBits is interpreted from right to left. I.e.,
001101 means digital sig, key enciph, data enciph */
#ifdef DEBUG
fprintf(stderr, "bytesUsed: %i\n", bytesUsed);
fprintf(stderr, "unusedBits: %i\n", unusedBits);
if (keyUsage->val == NULL)
fprintf(stderr, "keyUsage->val is NULL\n");
fprintf(stderr, "keyUsage characters: \n");
for (i = 0; i < bytesUsed; i++)
{
print_chars( charBits[i] );
} /* for */
fprintf(stderr, "\n");
fprintf(stderr, "intBits: \n");
print_bits (*intBits);
#endif
} while (/* CONSTCOND */ 0);
/* ----- Clean up: assign to return vbls and free space ----- */
if (status == 0)
{
*returnKeyU = (void *) intBits;
} /* if */
PKIFreeKeyUsage (ctx->certasnctx, keyUsage);
return status;
} /* GetKeyUsage */
/*----- Subject and Issuer Alternative Names -----*/
/****
*
* CheckGeneratlNames()
*
* Check that the structure provided by the user meets some minimum
* requirements.
*
*
*****/
static int
CheckGeneralNames(TC_GEN_NAMES_LIST_T *names)
{
TC_GEN_NAME_T *name;
int i;
/* for alternative names there must be at least one name and CMS
currently supports up to 32 names*/
if ( (names->numberOfNames <= 0) ||
(names->numberOfNames > PKIMAX_GeneralNames) )
return TC_E_INVARGS;
/* we don't support all the types and the provided name must
have a value (eg., no blank strings allowed); all we really
check for here is that there is a length to the provided data */
for(i = 0; i < names->numberOfNames; i++) {
name = names->names[i];
if (name == NULL || name->name == NULL)
return TC_E_INVARGS;
switch (name->nameType) {
case TC_rfc822Name:
case TC_dNSName:
case TC_uniformResourceIdentifier:
case TC_iPAddress:
case TC_registeredID:
if (name->nameLen <= 0)
return TC_E_INVARGS;
break;
case TC_directoryName:
break;
default:
return TC_E_INVARGS;
}
} /* for each name in list */
return 0;
} /* CheckGeneralNames */
static int
tc_GEN_NAME_to_PKIGeneralName (PKIGeneralName *asnName,/*OUT*/
TC_GEN_NAME_T *name,/*IN*/
TC_CONTEXT *ctx)/*IN*/
{
PKIIA5String *string;
PKIOCTET_STRING *octblock;
PKIOBJECT_ID *objidblock;
int status=0;
if(!asnName||!name||!ctx)
return TC_E_INVARGS;
/* set the CHOICE field type and the choice's data; these
are explicitly tagged values, so we need to use the
tag value for the CHOICE field */
switch(name->nameType)
{
case TC_rfc822Name:
asnName->CHOICE_field_type =
PKIrfc822Name_GeneralNameFieldTag;
/*0x80|0x20|0x01;*/
string = PKINewIA5String(ctx->certasnctx);
if (string == NULL)
{
status = TC_E_NOMEMORY;
break;
}
PKIPutOctVal(ctx->certasnctx,
string, (unsigned char *)name->name,
name->nameLen);
asnName->data = (void *)string;
break;
case TC_dNSName:
asnName->CHOICE_field_type =
PKIdNSName_GeneralNameFieldTag;
/*0x80|0x20|0x02;*/
string = PKINewIA5String(ctx->certasnctx);
if (string == NULL)
{
status = TC_E_NOMEMORY;
break;
}
PKIPutOctVal(ctx->certasnctx,
string, (unsigned char *)name->name,
name->nameLen);
asnName->data = (void *)string;
break;
case TC_directoryName:
asnName->CHOICE_field_type =
PKIdirectoryName_GeneralNameFieldTag;
/*0x80|0x20|0x04;*/
CopyName((PKIName **)&asnName->data,
(PKIName *)name->name, ctx);
break;
case TC_uniformResourceIdentifier:
asnName->CHOICE_field_type =
PKIuniformResourceIdentifier_GeneralNameFieldTag;
/*0x80|0x20|0x06;*/
string = PKINewIA5String(ctx->certasnctx);
if (string == NULL)
{
status = TC_E_NOMEMORY;
break;
}
PKIPutOctVal(ctx->certasnctx,
string, (unsigned char *)name->name,
name->nameLen);
asnName->data = (void *)string;
break;
case TC_iPAddress:
asnName->CHOICE_field_type =
PKIiPAddress_GeneralNameFieldTag;
/*0x80|0x20|0x07;*/
octblock = PKINewOCTET_STRING(ctx->certasnctx);
if (octblock == NULL)
{
status = TC_E_NOMEMORY;
break;
}
PKIPutOctVal(ctx->certasnctx,
octblock, (unsigned char *)name->name,
name->nameLen);
asnName->data = (void *)octblock;
break;
case TC_registeredID:
asnName->CHOICE_field_type =
PKIregisteredID_GeneralNameFieldTag;
/*0x80|0x20|0x08;*/
objidblock = PKINewOBJECT_ID(ctx->certasnctx);
if (objidblock == NULL)
{
status = TC_E_NOMEMORY;
break;
}
PKIPutOctVal(ctx->certasnctx,
objidblock, (unsigned char *)name->name,
name->nameLen);
asnName->data = (void *)objidblock;
break;
default:
status = TC_E_OTHER;
break;
}
return status;
} /* tc_GEN_NAME_to_PKIGeneralName */
/* This function allocates the PKI list and fills it. */
int
tc_GEN_NAMES_to_PKIGeneralNames (PKIGeneralNames *localNameList,
TC_GEN_NAMES_LIST_T *nameList,
TC_CONTEXT *ctx)
{
TC_GEN_NAME_T *name;
PKIGeneralName *asnName = NULL;
int i,status = 0;
do
{
/* add each individual name to the ASN data structure list */
for (i = 0; i < nameList->numberOfNames; i++)
{
name = nameList->names[i];
asnName = PKINewGeneralName(ctx->certasnctx);
if (asnName == NULL)
{
status = TC_E_NOMEMORY;
break;
}
status=tc_GEN_NAME_to_PKIGeneralName(asnName,name,ctx);
if (status)
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -