⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 extensions.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************
 *
 * 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 + -