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

📄 x509createcertificaterequest.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 3 页
字号:
			&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,
	PGPKeyDBObjRef      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 = PGPPeekContextMemoryMgr (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 (format, 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)
	{
		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 (formatData[i].value.pointervalue, "end-user",
							  formatData[i].size))
					certType = VRI_CERT_PERSONAL;
				else if (!strncmp (formatData[i].value.pointervalue, "ipsec",
								   formatData[i].size))
					certType = VRI_CERT_IPSEC;
				else if (!strncmp (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;
		}
	}

	/* we only use the PKCSReq structure with VeriSign.  Entrust and Netscape
		both just use the raw PKCS10 request inside the message */
	if (format == kPGPExportFormat_VerisignV1_CertReq)
	{
		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 = PGPPeekContextMemoryMgr (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;


}


/* Create a distinguished name buffer from a PGPAttributeValue array */
PGPError
X509CreateDistinguishedNameFromAV (
	PGPContextRef       context,
	PGPAttributeValue const  *formatData,
	PGPUInt32			formatDataCount,
	PGPByte           **dname,    /* Output buffer */
	PGPSize            *dnamesize /* Output buffer size */
)
{
	char					*str = NULL;
	PGPMemoryMgrRef			mem = PGPPeekContextMemoryMgr (context);
	PGPError				err = kPGPError_NoErr;

	*dname = NULL;
	*dnamesize = 0;

	err = x509CreateDistinguishedName ( mem, kPGPExportFormat_X509Cert,
										formatData, formatDataCount,
										&str );
	if( IsPGPError( err ) )
		return err;


	err = X509CreateDistinguishedName ( context, str, dname, dnamesize );
	PGPFreeData( str );
	return err;
}

/* Create a distinguished name buffer */
PGPError
X509CreateExtensionsFromAV (
	PGPContextRef       context,
	PGPAttributeValue const  *formatData,
	PGPUInt32			formatDataCount,
	PGPByte           **exts,    /* Output buffer */
	PGPSize            *extssize /* Output buffer size */
)
{
	TC_CONTEXT				*tcContext = NULL;
	PKICONTEXT				asnContext;
	PGPMemoryMgrRef			mem = PGPPeekContextMemoryMgr (context);
	PKIExtensions			*ext = NULL;
	PGPError				err = kPGPError_NoErr;


	*exts = NULL;
	*extssize = 0;

	/* 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;

	ext = PKINewExtensions (&asnContext);
	err = x509AddCertExtensions( formatData, formatDataCount, tcContext, ext );
	if (err)
		return err;

	/* If no extensions specified, return with null buffers */
	if ( ext->n == 0 )
		goto ERROR;			// Return with no error, cleaning up memory

	*extssize = PKISizeofExtensions (&asnContext, ext, TRUE);
	*exts = PKIAlloc (asnContext.memMgr, *extssize);
	if (!*exts)
	{
		err = kPGPError_OutOfMemory;
		goto ERROR;
	}
	PKIPackExtensions (&asnContext, *exts, *extssize, ext, &err);
	if (err)
	{
		err = kPGPError_ASNPackFailure;
		goto ERROR;
	}


ERROR:

	if (ext)
		PKIFreeExtensions (&asnContext, ext);
	if (tcContext)
		tc_free_context (tcContext);

	if (IsPGPError (err))
	{
		if (*exts)
		{
			PGPFreeData(*exts);
			*exts=NULL;
		}
		*extssize = 0;
	}
	return err;
}



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

⌨️ 快捷键说明

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