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

📄 x509createcertificaterequest.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:

static PGPError
x509CRSToPGPError (int err)
{
	switch (err)
	{
		case VRI_E_MISSING_MANDATORY:
			return kPGPError_CRSMissingRequiredAttribute;
		case VRI_E_INVALID_CHAR:
			return kPGPError_CRSInvalidCharacter;
		case VRI_E_AVA_TYPE:
			return kPGPError_CRSInvalidAttributeType;
		case VRI_E_CERT_TYPE:
			return kPGPError_CRSInvalidCertType;
		case VRI_E_LENGTH:
			return kPGPError_CRSInvalidAttributeValueLength;
		case VRI_E_AUTHENTICATE:
			return kPGPError_CRSInvalidAuthenticateValue;
		default:
			return kPGPError_LazyProgrammer;
	}
}

#if 1
const PGPByte x509TestNameOid[] = { 0x2a, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 };
#define x509TestNameOidLen 8
#endif

static PGPError
x509AddGeneralName (
	PKICONTEXT *pki, /* [IN] */
	PGPByte tag, /* [IN] */
	const PGPByte *data, /* [IN] */
	PGPSize datasize, /* [IN] */
	PKIGeneralNames *gn) /* [OUT] */
{
	PKIAnotherName *on = NULL;

	gn->elt[gn->n] = PKINewGeneralName (pki);
	gn->elt[gn->n]->CHOICE_field_type = 0xA0 | tag;

	if (tag == 0)
	{
		on = PKINewAnotherName (pki);
		PKIPutOctVal (pki, &on->type_id, x509TestNameOid, x509TestNameOidLen);
		PKIPutOctVal (pki, &on->value, data, datasize);
		gn->elt[gn->n]->data = (void *) on;
	}
	else
	{
		PKIOCTET_STRING *os=PKINewOCTET_STRING(pki);
		PKIPutOctVal(pki,os,data,datasize);
		gn->elt[gn->n]->data = (void *) os;
	}
	gn->n++;
	return kPGPError_NoErr;
}

static PGPError
x509AddExtensionReq (
	PGPAttributeValue	*format,/* [IN] */
	PGPSize				formatcount, /* [IN] */
	TC_CONTEXT			*ctx, /* [IN] */
	TC_Attributes		*attr) /* [OUT] */
{
	int			asnerr = 0;
	PGPSize		n;
	PGPError	err;
	PGPByte *der = NULL;
	PGPSize dersize;
	PKIExtensions *ext=NULL;
	PKICONTEXT *pki = ctx->certasnctx;
	PKIGeneralNames *gn = PKINewGeneralNames (pki);
	
	ext = PKINewExtensions (pki);

	/* see if RFC822Name, DNSName, IPAddress or AnotherName are specified */
	for (n = 0; n < formatcount; n++)
	{
	  /* skip empty fields since they are not valid in ASN.1 */
	  if (format[n].size > 0)
		{
		  if (format[n].attribute == kPGPAVAttribute_RFC822Name)
			  x509AddGeneralName (pki, 1, format[n].value.pointervalue,
				  format[n].size, gn);
		  else if (format[n].attribute == kPGPAVAttribute_DNSName)
			  x509AddGeneralName (pki, 2, format[n].value.pointervalue,
				  format[n].size, gn);
#if 0 /* TODO: not finished */
		  else if (format[n].attribute == kPGPAVAttribute_AnotherName)
			  x509AddGeneralName (pki, 0, format[n].value.pointervalue,
				  format[n].size, gn);
#endif
		  else if (format[n].attribute == kPGPAVAttribute_IPAddress)
			  x509AddGeneralName (pki, 7, format[n].value.pointervalue,
				  format[n].size, gn);
		  else if (format[n].attribute == kPGPAVAttribute_CertificateExtension)
			{
			  PKIExtension *t;

			  PKIUnpackExtension (pki, &t, format[n].value.pointervalue,
				  format[n].size, &asnerr);
			  if (asnerr)
				{
				  err = kPGPError_InvalidCertificateExtension;
				  goto ERROR;
				}
			  ext->elt[ext->n] = t;
			  ext->n++;
			}
		}
	}

	if (gn->n)
	  {
		dersize = PKISizeofGeneralNames (pki, gn, TRUE);
		der = PKIAlloc (pki->memMgr, dersize);
		if (!der)
		  {
			err = kPGPError_OutOfMemory;
			goto ERROR;
		  }
		PKIPackGeneralNames (pki, der, dersize, gn, &asnerr);
		if (asnerr)
		  {
			err = kPGPError_ASNPackFailure;
			goto ERROR;
		  }

		ext->elt[ext->n] = PKINewExtension (pki);
		PKIPutOctVal (pki, &ext->elt[ext->n]->extnID,
			PKIid_ce_subjectAltName_OID, PKIid_ce_subjectAltName_OID_LEN);
		ext->elt[ext->n]->extnValue.val = der;
		ext->elt[ext->n]->extnValue.len = dersize;
		ext->n++;
	}

	if (ext->n)
	{
		dersize = PKISizeofExtensions (pki, ext, TRUE);
		der = PKIAlloc (pki->memMgr, dersize);
		if (!der)
		{
			err = kPGPError_OutOfMemory;
			goto ERROR;
		}
		PKIPackExtensions (pki, der, dersize, ext, &asnerr);
		if (asnerr)
		{
			err = kPGPError_ASNPackFailure;
			goto ERROR;
		}
		asnerr = tc_add_attribute (attr,
			PKIid_ce_rsaExtensions_OID,
			PKIid_ce_rsaExtensions_OID_LEN,
			der,
			dersize,
			ctx);
		if (asnerr)
		{
			err = kPGPError_LazyProgrammer;
			goto ERROR;
		}
	}

	err = kPGPError_NoErr;

ERROR:
	if (gn)
		PKIFreeGeneralNames (ctx->certasnctx,gn);
	if (ext)
		PKIFreeExtensions (pki,ext);
	if (der)
		PGPFreeData (der);
	return err;
}

PGPError x509CreateSubjectPublicKeyInfo (
	PGPKeyRef keyref,
	PKICONTEXT *asnContext,
	X509SubjectPublicKeyInfo *info)
{
	PGPError err;
	PGPInt32 keyAlgID;
	PGPMemoryMgrRef mem = PGPGetContextMemoryMgr (PGPGetKeyContext (keyref));
	const PGPByte rsaparm[2] = { 0x05, 0x00 };

	memset (info, 0, sizeof (X509SubjectPublicKeyInfo));

	/* determine which type of key we have */
	err = PGPGetKeyNumber (keyref, kPGPKeyPropAlgID, &keyAlgID);
	if (IsPGPError (err))
		return err;

	/* format the key and any parameters for PKCS-10 */
	if (keyAlgID == kPGPPublicKeyAlgorithm_DSA)
	{
		err = x509FormatDSAKey (mem,
			asnContext,
			keyref,
			&info->keyData,
			&info->keyDataSize,
			&info->keyParm,
			&info->keyParmSize);

		info->keyAlg = TC_ALG_DSA;
		info->keyAlgSize = TC_ALG_DSA_LEN;
		info->sigAlg = TC_ALG_DSA_SHA1;
		info->sigAlgSize = TC_ALG_DSA_SHA1_LEN;
	}
	else if (keyAlgID == kPGPPublicKeyAlgorithm_RSA  ||
		keyAlgID == kPGPPublicKeyAlgorithm_RSAEncryptOnly ||
		keyAlgID == kPGPPublicKeyAlgorithm_RSASignOnly)
	{
		err = x509FormatRSAKey (mem,
			asnContext,
			keyref,
			&info->keyData,
			&info->keyDataSize,
			&info->keyParm,
			&info->keyParmSize);

		info->keyAlg = TC_ALG_RSA;
		info->keyAlgSize = TC_ALG_RSA_LEN;
		info->sigAlg = TC_ALG_RSA_MD5;
		info->sigAlgSize = TC_ALG_RSA_MD5_LEN;
		info->sigParmSize = sizeof rsaparm;
		info->sigParm = PGPNewData (mem, info->sigParmSize, 0);
		memcpy (info->sigParm, rsaparm, info->sigParmSize);
	}
	else
	{
		/* we don't support whatever type of key this is */
		err = kPGPError_UnknownPublicKeyAlgorithm;
	}

	return err;
}

void
x509FreeSubjectPublicKeyInfo (X509SubjectPublicKeyInfo *info)
{
	if (info->keyData)
		PGPFreeData (info->keyData);
	if (info->keyParm)
		PGPFreeData (info->keyParm);
	if (info->sigParm)
		PGPFreeData (info->sigParm);
}

/* Create the payload */
PGPError
X509CreateCertificateRequest (
	PGPContextRef       context,
	PGPKeyRef           keyref,     /* Key to export */
	PGPExportFormat     format,     /* Export format (CA) */
	PGPAttributeValue  *formatData, /* Formatting data */
	PGPUInt32           formatDataCount,
	PGPOptionListRef    passphrase, /* Passphrase if signing */
	PGPByte           **certReq,    /* Output buffer */
	PGPSize            *certReqSize /* Output buffer size */
							 )
{
	TC_CONTEXT				*tcContext;
	PKICONTEXT				asnContext;
	TC_CertificationRequest	*certRequest = NULL;
	TC_Name					*subjectName = NULL;
	PGPMemoryMgrRef			mem = PGPGetContextMemoryMgr (context);
	X509CMSCallbackData		callbackData;
	char					*dnString = NULL;
	int						tcError;
	PGPError				err;
	X509SubjectPublicKeyInfo	spki;

	TC_Attributes			*attr = NULL;
	char					*reginfo = NULL;

	/* clear outputs */
	*certReq = NULL;
	*certReqSize = 0;

	/* initialize callback data */
	memset (&callbackData, 0, sizeof (callbackData));
	callbackData.passphrase = passphrase;
	callbackData.context = context;
	callbackData.key = keyref;

	/* initialize ASN.1 compiler */
	memset (&asnContext, 0, sizeof (asnContext));
	asnContext.memMgr = &X509CMSMemoryMgr;
	asnContext.memMgr->customValue = (void *) mem;

	memset (&spki, 0, sizeof spki);

	/* initialize CMS */
	tcError = tc_init_context (&tcContext,
		asnContext.memMgr,
		x509CMSSignCallback,
		&callbackData,
		NULL,
		NULL);
	if (tcError)
		return kPGPError_CMSInitialization;

	/* convert AVA array into printable string suitable for input to CMS */
	err = x509CreateDistinguishedName (mem,
		format,
		formatData,
		formatDataCount,
		&dnString);
	if (IsPGPError (err))
		goto error;

	tcError = tc_create_dname (&subjectName, tcContext);
	if (tcError)
	{
		err = kPGPError_LazyProgrammer;
		goto error;
	}
	tcError = tc_make_dname_fromstring (subjectName, dnString, tcContext);
	PGPFreeData (dnString);
	if (tcError)
	{
		err = kPGPError_InvalidDistinguishedName;
		goto error;
	}

	err = x509CreateSubjectPublicKeyInfo (keyref, &asnContext, &spki);
	if (IsPGPError (err))
		goto error;

	/* some CAs will barf on pkcs-10 with no attributes, so add a signing-time
	   to ensure we have at least one present */
	tcError = tc_create_attrlist (&attr, tcContext);
	tcError = tc_set_signing_time (attr, tcContext);

	/* determine if we need to add the ExtensionReq attribute */
	err = x509AddExtensionReq (formatData, formatDataCount, tcContext, attr);
	if (IsPGPError (err))
		goto error;

	tcError = tc_create_request (&certRequest,
		0, /* pkcs-10 1.5 requires version number 0 */
		spki.sigAlg,
		spki.sigAlgSize,
		spki.sigParm,
		spki.sigParmSize,
		subjectName,
		spki.keyAlg,
		spki.keyAlgSize,
		spki.keyData,	/* public key material */
		spki.keyDataSize,
		spki.keyParm,	/* key parameters.*/
		spki.keyParmSize,
		attr,	/* attributes */
		tcContext);

	if (tcError)
	{
		/* TODO: should this return a finer grain of error code? */
		err = kPGPError_CertRequestCreationFailure;
		goto error;
	}

	tcError = tc_pack_request (certReq, certReqSize, certRequest, tcContext);
	if (tcError)
	{
		err = kPGPError_CertRequestCreationFailure;
		goto error;
	}

	/* since we could have more than one crypto operation, the callbacks
	   make a copy of this, so free the master copy now */
	PGPFreeOptionList (passphrase);

	/* create CRS wrapper */
	if (format == kPGPExportFormat_VerisignV1_CertReq) /* jason */
	{
		vri_ava_t	*av;
		int			certType = -1;
		size_t		i;

		/* determine what type of certificate we are requesting */
		for (i = 0; i < formatDataCount; i++)
			if (formatData[i].attribute == kPGPAVAttribute_CertType)
			{
				if (!strncmp ((char *) formatData[i].value.pointervalue, "end-user",
							  formatData[i].size))
					certType = VRI_CERT_PERSONAL;
				else if (!strncmp ((char *) formatData[i].value.pointervalue, "ipsec",
								   formatData[i].size))
					certType = VRI_CERT_IPSEC;
				else if (!strncmp ((char *) formatData[i].value.pointervalue, "server",
								   formatData[i].size))
					certType = VRI_CERT_SECURE_SERVER;
				break;
			}
		if (certType == -1)
		{
			/* missing or bad cert_type */
			err = kPGPError_CRSInvalidCertType;
			goto error;
		}

		x509CompileRegInfo (&asnContext, formatData, formatDataCount, &av);
		tcError = vri_GenerateRegInfo (&asnContext,
			VRI_ENTITY_EE,
			certType,
			av, 
			&reginfo);
		PGPFreeData (av);
		if (tcError)
		{
			err = x509CRSToPGPError (tcError);
			goto error;
		}
	}

	if (format == kPGPExportFormat_VerisignV1_CertReq ||
		format == kPGPExportFormat_EntrustV1_CertReq) /* jason */
	{
		PGPByte *p10 = *certReq;
		PGPSize p10len = *certReqSize;

		tcError = vri_GeneratePKCSReq (&asnContext, 
			p10,
			p10len,
			reginfo,
			certReq,
			certReqSize);
		if (reginfo)
			PGPFreeData (reginfo);
		PGPFreeData (p10);
		if (tcError)
		{
			err = kPGPError_LazyProgrammer;
			goto error;
		}
	}
	err = kPGPError_NoErr;
error:
	x509FreeSubjectPublicKeyInfo (&spki);

	if (certRequest)
		tc_free_request (certRequest, tcContext);
	if (subjectName)
		tc_free_dname (subjectName, tcContext);
	if (attr)
		tc_free_attrlist (attr, tcContext);
	if (tcContext)
		tc_free_context (tcContext);

	if (IsPGPError (err))
	{
		if (*certReq)
		{
			PGPFreeData(*certReq);
			*certReq=NULL;
		}
		*certReqSize = 0;
	}
	return err;
}



/* Create a distinguished name buffer */
PGPError
X509CreateDistinguishedName (
	PGPContextRef       context,
	char const			*str,		/* LDAP format string */
	PGPByte           **dname,    /* Output buffer */
	PGPSize            *dnamesize /* Output buffer size */
)
{
	TC_CONTEXT				*tcContext = NULL;
	PKICONTEXT				asnContext;
	PKIName					*name = NULL;
	PGPMemoryMgrRef			mem = PGPGetContextMemoryMgr (context);
	PGPError				err = kPGPError_NoErr;

	*dname = NULL;

	/* initialize ASN.1 compiler */
	memset (&asnContext, 0, sizeof (asnContext));
	asnContext.memMgr = &X509CMSMemoryMgr;
	asnContext.memMgr->customValue = (void *) mem;

	/* initialize CMS */
	err = tc_init_context (&tcContext,
		asnContext.memMgr,
		NULL,
		NULL,
		NULL,
		NULL);
	if (err)
		return kPGPError_CMSInitialization;

	err = tc_create_dname (&name, tcContext);
	if (err)
	{
		err = kPGPError_LazyProgrammer;
		goto error;
	}
	err = tc_make_dname_fromstring (name, str, tcContext);
	if (err)
	{
		err = kPGPError_InvalidDistinguishedName;
		goto error;
	}

	*dnamesize = PKISizeofName (&asnContext, name, 1);
	*dname = PKIAlloc (asnContext.memMgr, *dnamesize);
	if( *dname == NULL )
	{
		err = kPGPError_OutOfMemory;
		goto error;
	}
	PKIPackName (&asnContext, *dname, *dnamesize, name, &err);
	PKIFreeName (&asnContext, name);
	name = NULL;
	if (err)
	{
		err = kPGPError_InvalidDistinguishedName;
		goto error;
	}

 error:

	if (name)
		PKIFreeName (&asnContext, name);
	if (tcContext)
		tc_free_context (tcContext);

	if (IsPGPError (err))
	{
		if (*dname)
		{
			PGPFreeData(*dname);
			*dname=NULL;
		}
		*dnamesize = 0;
	}
	return err;


}


/* vim:ts=4:sw=4:
 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -