📄 pkixcertpathval.c
字号:
if(status)
goto error;
/* check subjectAltName if present */
if(san)
{
for(j=0;j<san->n;j++)
{
status=tc_check_name_constraints(san->elt[j],
tree,
flags,
ctx);
if(status)
goto error;
}
}
error:
return status;
}
/* reverse's certificate chain such that the CA certificate is at index 0 */
static void tc_reverse_chain (TC_CERT **cert, int count) {
int i;
TC_CERT *p;
for (i = 0; i < count / 2 ; i++) {
p = cert[count - i - 1];
cert[count - i - 1] = cert[i];
cert[i] = p;
}
}
static int
tc_find_policy (PKIOBJECT_ID *oid, PKICertificatePolicies *pol)
{
int i;
for (i = 0; i < pol->n; i++)
{
if (tc_compare_block (oid, &pol->elt[i]->policyIdentifier) == 1)
return i;
}
return TC_E_NOTFOUND;
}
static int
tc_verify_policy (PKICertificatePolicies *req, TC_CERT *cert, TC_CONTEXT *ctx)
{
int status, i, j;
PKIExtension *ext;
PKICertificatePolicies *pol;
status = tc_find_extension (&ext,
cert->tbsCertificate->extensions,
PKIid_ce_certificatePolicies_OID,
PKIid_ce_certificatePolicies_OID_LEN,
ctx);
if (status)
return status;
if (!req)
return 0; /* NULL means "any policy" */
PKIUnpackCertificatePolicies (ctx->certasnctx, &pol, ext->extnValue.val, ext->extnValue.len, &status);
if (status)
{
status = compiler2tc_error (status);
return status;
}
for ( i = 0 ; i < pol->n ; i++ )
{
for ( j = 0 ; j < req->n ; i++ )
{
if ( tc_compare_block ( &pol->elt[i]->policyIdentifier,
&req->elt[j]->policyIdentifier ) == 1 )
{
PKIFreeCertificatePolicies (ctx->certasnctx, pol);
return 0;
}
}
}
PKIFreeCertificatePolicies (ctx->certasnctx, pol);
return TC_E_MISSINGPOLICY;
}
static int
tc_policy_intersect (TC_CERT *cert,
PKICertificatePolicies **req,
TC_CONTEXT *ctx)
{
PKIExtension *ext;
PKICertificatePolicies *i, *pol;
PKIPolicyInformation *piElement;
int j, status;
if (cert->tbsCertificate->extensions == NULL)
return 0;
status = tc_find_extension (&ext,
cert->tbsCertificate->extensions,
PKIid_ce_certificatePolicies_OID,
PKIid_ce_certificatePolicies_OID_LEN,
ctx);
if (status)
return ((status == TC_E_NOTFOUND) ? 0 /* no error */ : status);
if (ext->critical && (ext->critical->val != 0)) {
PKIUnpackCertificatePolicies (ctx->certasnctx,
&pol,
ext->extnValue.val,
ext->extnValue.len,
&status);
if (status) {
status = compiler2tc_error (status);
return status;
}
i = PKINewCertificatePolicies (ctx->certasnctx);
for (j = 0; j < pol->n; j++) {
if (tc_find_policy (&pol->elt[j]->policyIdentifier, *req) >= 0) {
piElement = PKINewPolicyInformation(ctx->certasnctx);
PKIPutOctVal (ctx->certasnctx,
&piElement->policyIdentifier,
pol->elt[j]->policyIdentifier.val,
pol->elt[j]->policyIdentifier.len);
PKIAddOfElement(ctx->certasnctx, piElement, i);
/*i->elt[i->n] = PKINewPolicyInformation (ctx->certasnctx);
PKIPutOctVal (ctx->certasnctx, &i->elt[i->n]->policyIdentifier,
pol->elt[j]->policyIdentifier.val,
pol->elt[j]->policyIdentifier.len);
i->n++;*/
}
}
PKIFreeCertificatePolicies (ctx->certasnctx, pol);
if (i->n == 0) {
PKIFreeCertificatePolicies (ctx->certasnctx, i);
return TC_E_INVALIDPOLICY; /* doesn't match acceptable use */
}
PKIFreeCertificatePolicies (ctx->certasnctx, *req);
*req = i;
}
return 0;
}
static int
tc_process_basic_constraints (TC_CERT *cert, int *maxPathLen, TC_CONTEXT *ctx)
{
PKIBasicConstraints *bc;
PKIExtension *ext;
int n, status;
status = tc_find_extension (&ext,
cert->tbsCertificate->extensions,
PKIid_ce_basicConstraints_OID,
PKIid_ce_basicConstraints_OID_LEN,
ctx);
if (status)
return 0; /* TODO: should this blindly accept any cert as a CA? */
PKIUnpackBasicConstraints (ctx->certasnctx,
&bc,
ext->extnValue.val,
ext->extnValue.len,
&status);
if (status)
return (compiler2tc_error (status));
if (bc->cA != NULL && bc->cA->val != 0)
{
if (bc->pathLenConstraint)
{
n = PKIGetIntVal (ctx->certasnctx, bc->pathLenConstraint, &status);
/* `n' is the number of CA certs which can appear, so we can have
`n'+1 certs in the chain */
if (n + 1 < *maxPathLen)
*maxPathLen = n + 1;
}
}
PKIFreeBasicConstraints (ctx->certasnctx, bc);
return 0;
}
static int
tc_copy_GeneralName (PKIGeneralName *dst, PKIGeneralName *src, TC_CONTEXT *ctx)
{
PKIVariableBlock *asn, *srcasn;
dst->CHOICE_field_type = src->CHOICE_field_type;
switch (dst->CHOICE_field_type)
{
case 0xa1:
case 0xa2:
case 0xa6:
case 0xa7:
case 0xa8:
srcasn = (PKIVariableBlock *) src->data;
asn = PKINewVariableBlock (ctx->certasnctx);
PKIPutOctVal (ctx->certasnctx, asn, srcasn->val, srcasn->len);
dst->data = (void *) asn;
break;
default:
return TC_E_COPYNOTSUPPORTED;
}
return 0;
}
/* returns the union of 'a' and 'b' as 'u' */
static int
tc_general_subtrees_union (PKIGeneralSubtrees *u, /* OUT */
PKIGeneralSubtrees *a, /* IN */
PKIGeneralSubtrees *b, /* IN */
TC_CONTEXT *ctx)
{
int i, j, status = 0;
PKIGeneralSubtree *element;
/* first copy 'a' to 'u' */
for (i = 0; i < a->n ; i++) {
element = PKINewGeneralSubtree (ctx->certasnctx);
status = tc_copy_GeneralName (&u->elt[u->n-1]->base,
&element->base,
ctx);
if (status) {
PKIFreeGeneralSubtree(ctx->certasnctx, element);
goto error;
}
PKIAddOfElement(ctx->certasnctx, element, u);
/*u->elt[u->n] = PKINewGeneralSubtree (ctx->certasnctx);
u->n++;
status = tc_copy_GeneralName (&u->elt[u->n-1]->base,
&a->elt[i]->base,
ctx);
if (status)
goto error;*/
}
/* add missing elements of 'b' to 'u' */
for (i = 0; i < b->n; i++) {
for (j = 0; j < u->n; j++) {
if (tc_compare_GeneralName (&b->elt[i]->base, &u->elt[j]->base, ctx) == 1)
break;
}
if (j == u->n) {
element = PKINewGeneralSubtree (ctx->certasnctx);
status = tc_copy_GeneralName (&u->elt[u->n-1]->base,
&element->base,
ctx);
if (status) {
PKIFreeGeneralSubtree(ctx->certasnctx, element);
goto error;
}
PKIAddOfElement(ctx->certasnctx, element, u);
/*u->elt[u->n] = PKINewGeneralSubtree (ctx->certasnctx);
u->n++;
status = tc_copy_GeneralName (&u->elt[u->n-1]->base, &b->elt[i]->base,ctx);
if (status)
goto error;*/
}
}
error:
if (status) {
for (i = 0; i < u->n; i++)
PKIFreeGeneralSubtree (ctx->certasnctx, u->elt[i]);
}
return status;
}
static int
tc_name_constraints_intersect (TC_CERT *cert,
PKIGeneralSubtrees **constraints,
PKIGeneralSubtrees **exclude,
TC_CONTEXT *ctx)
{
PKINameConstraints *nc;
PKIExtension *ext;
PKIGeneralSubtrees *gs=NULL;
PKIGeneralSubtree *element;
int i, j, status;
if (cert->tbsCertificate->extensions == NULL)
return 0;
status = tc_find_extension (&ext,
cert->tbsCertificate->extensions,
PKIid_ce_nameConstraints_OID,
PKIid_ce_nameConstraints_OID_LEN,
ctx);
if (status)
return ((status == TC_E_NOTFOUND) ? 0 : status);
PKIUnpackNameConstraints (ctx->certasnctx,
&nc,
ext->extnValue.val,
ext->extnValue.len,
&status);
if (status)
return (compiler2tc_error (status));
if (nc->permittedSubtrees) {
if (*constraints == NULL) {
*constraints = nc->permittedSubtrees;
nc->permittedSubtrees = NULL;
}
else {
/* find the intersection */
gs = PKINewGeneralSubtrees (ctx->certasnctx);
for (i = 0; i < nc->permittedSubtrees->n; i++) {
for (j = 0; j < (*constraints)->n; j++) {
/* TODO: if the compare doesn't understand one of the
general name types (like EDIPartyName), it will
silently be ignored, what to do in that case? */
if (tc_compare_GeneralName (&nc->permittedSubtrees->elt[i]->base,
&(*constraints)->elt[j]->base,
ctx) == 1)
{
element = PKINewGeneralSubtree (ctx->certasnctx);
status = tc_copy_GeneralName (&element->base,
&nc->permittedSubtrees->elt[i]->base,
ctx);
if (status) {
PKIFreeGeneralSubtree (ctx->certasnctx, element);
goto error;
}
PKIAddOfElement(ctx->certasnctx, element, gs);
/*gs->elt[gs->n] = PKINewGeneralSubtree (ctx->certasnctx);
gs->n++;
status = tc_copy_GeneralName (&gs->elt[gs->n-1]->base,
&nc->permittedSubtrees->elt[i]->base,
ctx);
if (status)
goto error;*/
}
}
}
PKIFreeGeneralSubtrees (ctx->certasnctx, *constraints);
*constraints = gs;
gs = NULL;
}
}
if (nc->excludedSubtrees) {
if (*exclude == NULL) {
*exclude = nc->excludedSubtrees;
nc->excludedSubtrees = NULL;
}
else {
/* find the union of the two trees */
status = tc_general_subtrees_union (gs,
nc->excludedSubtrees,
*exclude,
ctx);
PKIFreeGeneralSubtrees (ctx->certasnctx, *exclude);
*exclude = gs;
gs = NULL;
}
}
error:
if (gs)
PKIFreeGeneralSubtrees (ctx->certasnctx, gs);
if (nc)
PKIFreeNameConstraints (ctx->certasnctx, nc);
return status;
}
static int
tc_process_policy_constraints (TC_CERT *cert,
int i,
int *explicit,
int *mapping,
TC_CONTEXT *ctx)
{
PKIPolicyConstraints *pc;
PKIExtension *ext;
int status;
status = tc_find_extension (&ext,
cert->tbsCertificate->extensions,
PKIid_ce_policyConstraints_OID,
PKIid_ce_policyConstraints_OID_LEN,
ctx);
if (status)
return 0;
PKIUnpackPolicyConstraints (ctx->certasnctx,
&pc,
ext->extnValue.val,
ext->extnValue.len,
&status);
if (status)
return (compiler2tc_error (status));
if (pc->requireExplicitPolicy)
{
int r = PKIGetIntVal (ctx->certasnctx, pc->requireExplicitPolicy, &status);
if (status)
{
status = compiler2tc_error (status);
goto error;
}
if (i + r < *explicit)
*explicit = i + r;
}
if (pc->inhibitPolicyMapping)
{
int q = PKIGetIntVal (ctx->certasnctx, pc->inhibitPolicyMapping, &status);
if (status)
{
status = compiler2tc_error (status);
goto error;
}
if (i + q < *mapping)
*mapping = i + q;
}
error:
PKIFreePolicyConstraints (ctx->certasnctx, pc);
return status;
}
static int
tc_process_key_usage (TC_CERT *cert, TC_CONTEXT *ctx)
{
PKIKeyUsage *ku;
PKIExtension *ext;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -