📄 extensions.c
字号:
/****************************************************************************
*
* Copyright (c) 1998, Network Associates, Inc. and its affiliated Companies
*
****************************************************************************/
#include "cert.h"
#include "tc.h"
#include "cms_proto.h"
#include "cms.h"
#include "cert_asn.h"
#include "cert_oid.h"
#include "extensions.h"
typedef struct
{
unsigned char *oid;
size_t oidlen;
tc_handler_t *handler;
} TC_HANDLER;
void tc_free_handlers (TC_LIST **db, TC_MemoryMgr *mgr)
{
TC_LIST *t;
while (*db)
{
TC_Free(mgr, ((TC_HANDLER *)(*db)->data)->oid );
TC_Free(mgr, (*db)->data);
t = *db;
*db = (*db)->next;
TC_Free(mgr, t);
}
}
int tc_create_extlist(TC_ExtensionList **list, TC_CONTEXT *ctx)
{
if (list == NULL)
return TC_E_INVARGS;
*list = PKINewExtensions(ctx->certasnctx);
if (*list == NULL)
return TC_E_NOMEMORY;
return 0;
}
void tc_free_extlist(TC_ExtensionList *list, TC_CONTEXT *ctx)
{
if (list != NULL)
PKIFreeExtensions(ctx->certasnctx, list);
return;
} /* tc_free_extlist */
static TC_HANDLER *find_handler (unsigned char *oid, size_t oidlen, TC_LIST *db)
{
while (db)
{
if (oidlen == ((TC_HANDLER *) db->data)->oidlen &&
memcmp (oid, ((TC_HANDLER *) db->data)->oid, oidlen) == 0)
return ((TC_HANDLER *) db->data);
db = db->next;
}
return NULL;
}
/*****
*
* Register a handler to use during extension processing. The handler
* can be NULL if you do not want to actually process the data in the
* extension but want to indicate that a critical extension is "handled".
* Non-critical extensions do not need to have a handler registered.
*
* If this is called and the extension already exists in the context,
* the current handler will be replaced with the provided one.
*
* parameters
* input
* oid - the extension oid
* oidlen - length of oid
* func - a pointer to an extension handler, it's prototype
* is ???
* ctx - a pointer to a CMS context to add the extension data to
*
* return
* TC_E_INVARGS
* TC_E_NOMEMORY
* 0 - okay
*
*****/
int tc_register_handler (const unsigned char *oid,
size_t oidlen,
tc_handler_t *func,
TC_CONTEXT *ctx)
{
TC_LIST *l;
TC_HANDLER *h = NULL;
if (ctx == NULL || oid == NULL || oidlen == 0)
return TC_E_INVARGS;
/* see if OID is already registered and update its handler if
so, otherwise create a new handler entry in list */
if ((h = find_handler((unsigned char *)oid, oidlen,
ctx->handlers)) != NULL) {
h->handler = func;
}
else {
if ( (h = TC_Alloc(ctx->memMgr, sizeof(TC_HANDLER)) ) == NULL)
return TC_E_NOMEMORY;
if ((h->oid = TC_Alloc(ctx->memMgr, oidlen)) == NULL) {
TC_Free(ctx->memMgr, h);
return TC_E_NOMEMORY;
}
(void)memcpy(h->oid, oid, oidlen);
h->oidlen = oidlen;
h->handler = func;
if ((l = TC_Alloc(ctx->memMgr, sizeof (TC_LIST))) == NULL) {
TC_Free(ctx->memMgr, h->oid);
TC_Free(ctx->memMgr, h);
return TC_E_NOMEMORY;
}
l->data = (void *) h;
l->next = ctx->handlers;
ctx->handlers = l;
}
return 0;
}
/*****
* run through the extensions on a X.509 v3 certificate
*
* return
* 0 - okay
* TC_E_CRITICAL
* TC_E_EXTENSION
*****/
int tc_process_extensions (PKIExtensions *pExt, void *cert, TC_CONTEXT *ctx)
{
TC_HANDLER *tmp;
int i;
TC_LIST *db = ctx->handlers;
if (!pExt)
return 0; /* nothing to do! */
/* `->n' is the number of extensions present in the list */
for (i = 0 ; i < pExt->n ; i++)
{
tmp = find_handler(pExt->elt[i]->extnID.val, pExt->elt[i]->extnID.len, db);
if (tmp)
{
if (tmp->handler && (tmp->handler(pExt->elt[i], cert, ctx) != 0) )
return TC_E_EXTENSION;
}
else if (pExt->elt[i]->critical && pExt->elt[i]->critical->val)
{
return TC_E_CRITICAL; /* unhandled critical flag */
}
}
return 0; /* no errors occurred */
}
int tc_find_extension (
TC_Extension **ext,
const TC_ExtensionList *extList,
const unsigned char *oid, /* DER-encoded OID */
size_t oidLen,
TC_CONTEXT *ctx)
{
int i;
(void)ctx; /* for future use */
if (ext == NULL || extList == NULL || oid == NULL)
return TC_E_INVARGS;
for (i = 0; i < extList->n; i++) {
if ((size_t)extList->elt[i]->extnID.len == oidLen &&
memcmp (extList->elt[i]->extnID.val, oid, oidLen) == 0) {
*ext = extList->elt[i];
return 0;
}
}
return TC_E_NOTFOUND;
}
/*****
*
* tc_add_extension
*
* parameters
* input
* oid - the extention's oid (in DER format)
* oidlen -
* critical - a flag indicating whether this extension is critical (1)
* or not (0)
* der - the ASN.1 DER encoded data for the extension
* derlen -
* output
* exts - an extension list, the new extension is added to the
* end of the list
*
* return
* TC_E_INVARGS
* TC_E_EXTENSION
* TC_E_NOMEMORY
*
*****/
int tc_add_extension (
TC_ExtensionList *extList,
const unsigned char *oid,
size_t oidlen,
int critical,
unsigned char *der,
size_t derlen,
TC_CONTEXT *ctx)
{
PKIExtension *localext;
if (extList == NULL || oid == NULL || der == NULL || oidlen == 0)
return TC_E_INVARGS;
if (extList->n == PKIMAX_Extensions)
return TC_E_EXTENSION;
localext = PKINewExtension(ctx->certasnctx);
if (localext == NULL)
return TC_E_NOMEMORY;
localext->extnID.len = oidlen;
localext->extnID.val = TC_Alloc(ctx->memMgr, oidlen);
if (localext->extnID.val == NULL) {
PKIFreeExtension(ctx->certasnctx, localext);
return TC_E_NOMEMORY;
}
(void)memcpy(localext->extnID.val, oid, oidlen);
/* only fill in the critical field if its not the DEFAULT of FALSE */
if (critical != 0) {
localext->critical = PKINewBOOLEAN(ctx->certasnctx);
if (localext->critical == NULL) {
TC_Free(ctx->memMgr, localext->extnID.val);
PKIFreeExtension(ctx->certasnctx, localext);
return TC_E_NOMEMORY;
}
if (PKIPutBoolVal(ctx->certasnctx, localext->critical, 1) != 0) {
PKIFreeBOOLEAN(ctx->certasnctx, localext->critical);
TC_Free(ctx->memMgr, localext->extnID.val);
PKIFreeExtension(ctx->certasnctx, localext);
return TC_E_NOMEMORY;
}
}
localext->extnValue.len = derlen;
localext->extnValue.val = TC_Alloc(ctx->memMgr, derlen);
if (localext->extnValue.val == NULL) {
PKIFreeBOOLEAN(ctx->certasnctx, localext->critical);
TC_Free(ctx->memMgr, localext->extnID.val);
PKIFreeExtension(ctx->certasnctx, localext);
return TC_E_NOMEMORY;
}
(void)memcpy(localext->extnValue.val, der, derlen);
extList->elt[extList->n] = localext;
(extList->n)++;
return 0;
}
/******************************************************************/
/* Prototypes */
/******************************************************************/
static int AddKeyUsageExt(TC_ExtensionList *ext,
const void *keyU,
int criticality,
TC_CONTEXT *ctx);
static int AddBasicConstraintsExt(TC_ExtensionList *ext,
const void *simpleBCons,
int criticality,
TC_CONTEXT *ctx);
static int AddSubjectAltNameExt(TC_ExtensionList *ext,
const void *genNames,
int criticality,
TC_CONTEXT *ctx);
static int AddIssuerAltNameExt(TC_ExtensionList *ext,
const void *genNames,
int criticality,
TC_CONTEXT *ctx);
static int AddPrivateKeyUsagePeriod (TC_ExtensionList *ext,
const void *privKeyUsagePeriod,
int critical,
TC_CONTEXT *ctx);
static int AddCertificatePolicies (TC_ExtensionList *ext,
const void *certPolicies,
int critical,
TC_CONTEXT *ctx);
static int AddPolicyMappings (TC_ExtensionList *ext,
const void *policyMap,
int critical,
TC_CONTEXT *ctx);
static int AddNameConstraints (TC_ExtensionList *ext,
const void *,
int critical,
TC_CONTEXT *ctx);
static int AddSubjectKeyIdentifier (TC_ExtensionList *ext,
const void *,
int critical,
TC_CONTEXT *ctx);
static int AddExtKeyUsageSyntax (TC_ExtensionList *ext,
const void *,
int critical,
TC_CONTEXT *ctx);
static int CreateKeyUsageDER(unsigned int bits,
unsigned char **buf,
size_t *size,
TC_CONTEXT *ctx);
static int AddSubjectDirectoryAttributes (TC_ExtensionList *ext,
const void *,
int critical,
TC_CONTEXT *ctx);
static int AddPolicyConstraints (TC_ExtensionList *ext,
const void *,
int critical,
TC_CONTEXT *ctx);
static int AddAuthorityInfoAccess (TC_ExtensionList *ext,
const void *,
int critical,
TC_CONTEXT *ctx);
static int AddCRLDistributionPoints (TC_ExtensionList *ext,
const void *,
int critical,
TC_CONTEXT *ctx);
static int CreateBasicConstraintsDER(const TC_BASIC_CONSTRAINT *simpleBCons,
unsigned char **buf,
size_t *size,
TC_CONTEXT *ctx);
static int GetBasicConstraints(void **returnBCons,
const PKIExtension *ext,
TC_CONTEXT *ctx);
static int GetKeyUsage (void **returnKeyU,
const PKIExtension *ext,
TC_CONTEXT *ctx);
static int GetAlternativeNameExt(void **genNames,
const PKIExtension *ext,
TC_CONTEXT *ctx);
int GetOctetStringExt(void **pos, /* OUT */
const PKIExtension *ext, /* IN */
TC_CONTEXT *ctx);/* IN */
static int GetPrivateKeyUsagePeriod (void **ret, /* OUT */
const PKIExtension *ext, /* IN */
TC_CONTEXT *ctx); /* IN */
static int GetCertificatePolicies (void **ret, /* OUT */
const PKIExtension *ext, /* IN */
TC_CONTEXT *ctx); /* IN */
static int GetPolicyMappings (void **ret, /* OUT */
const PKIExtension *ext, /* IN */
TC_CONTEXT *ctx); /* IN */
static int GetSubjectDirectoryAttributes (void **ret, /* OUT */
const PKIExtension *ext, /* IN */
TC_CONTEXT *ctx); /* IN */
static int GetNameConstraints (void **ret, /* OUT */
const PKIExtension *ext, /* IN */
TC_CONTEXT *ctx); /* IN */
static int GetPolicyConstraints (void **ret, /* OUT */
const PKIExtension *ext, /* IN */
TC_CONTEXT *ctx); /* IN */
static int GetExtKeyUsageSyntax (void **ret, /* OUT */
const PKIExtension *ext, /* IN */
TC_CONTEXT *ctx); /* IN */
static int GetCRLDistributionPoints (void **ret, /* OUT */
const PKIExtension *ext, /* IN */
TC_CONTEXT *ctx); /* IN */
static int GetAuthorityInfoAccess (void **ret, /* OUT */
const PKIExtension *ext, /* IN */
TC_CONTEXT *ctx); /* IN */
/******************************************************************/
/* Static structures */
/******************************************************************/
static struct
{
int (* ExtensionSetter) ( TC_ExtensionList *ext, /* set ext. fn ptr */
const void *simpleExtValue,
int crit,
TC_CONTEXT *ctx);
int (* ExtensionGetter) ( void **simpleExtValue, /* get ext. fn ptr */
const PKIExtension *ext,
TC_CONTEXT *ctx);
unsigned char *oid; /* oid */
size_t oidlen; /* oid length */
} supportedExtensions[] =
{
{
AddKeyUsageExt,
GetKeyUsage,
PKIid_ce_keyUsage_OID, /* key usage */
PKIid_ce_keyUsage_OID_LEN
},
{
AddBasicConstraintsExt,
GetBasicConstraints,
PKIid_ce_basicConstraints_OID, /* basic constraints */
PKIid_ce_basicConstraints_OID_LEN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -