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

📄 ca.cpp

📁 minica2的第2个版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added
	OBJ_cleanup();	
	if (!X509_REQ_sign(x,pk,EVP_sha1()))//用自己的公钥签名私钥
		goto err;
	
	*req=x;
	*pkeyp=pk;
	return(1);
err:
	return(0);
}

BOOL MakeReq(const stuSUBJECT * reqInfo,/*请求信息IN*/
			 const int bits/*位数IN*/,
			 const char * priPwd/*私钥密码,IN*/,
			 char * reqMem/*证书请求文件OUT*/,
			 UINT * reqLen/*证书请求文件长度OUT*/,
			 char * priMem/*私钥文件OUT*/,
			 UINT * priLen/*私钥文件文件长度OUT*/,
			 char * outMsg/*操作结果OUT*/,
			 const int iType/*类型pem-der*/)
{
	X509_REQ * req=NULL;
	EVP_PKEY * pkey=NULL;

	BIO * breq = NULL,
		* bkey = NULL;

	int i = 0,
		j = 0;

	breq = BIO_new(BIO_s_mem());
	bkey = BIO_new(BIO_s_mem());
	BIO_set_close(breq, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */
	BIO_set_close(bkey, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */

/*	if(((breq = BIO_new_file(reqFile, "w"))== NULL)||((bkey = BIO_new_file(priFile, "w")) == NULL))
	{
		strcpy(outMsg,"Create File Error");
		return FALSE;
	}
	*/
	if(!mkReq(reqInfo,&req,&pkey,bits,outMsg))
	{
		strcpy(outMsg,"Make CertReq Error");
		return FALSE;
	}

	if(iType == PEM)
	{
		i = PEM_write_bio_X509_REQ(breq,req);		//写入公钥
		if(NULL == priPwd || strlen(priPwd) == 0)
			j = PEM_write_bio_PrivateKey(bkey,pkey,NULL,NULL,0,NULL, NULL); //私钥不加密
		else
			j = PEM_write_bio_PrivateKey(bkey,pkey,EVP_des_ede3_cbc(),NULL,0,NULL, (void *)priPwd); //私钥加密
	}
	else if(iType == DER)
	{
		i = i2d_X509_REQ_bio(breq,req);	//写入公钥

		if(NULL == priPwd || strlen(priPwd) == 0)			//写入私钥
			j = i2d_PrivateKey_bio(bkey,pkey);//私钥未加密
		else
		{
			//添加加密链
			unsigned char key[EVP_MAX_KEY_LENGTH] = "";//算法最长的KEY长度
			unsigned char iv[EVP_MAX_IV_LENGTH] = "";//算法最长的IV长度
			BIO * bEnc = NULL;
			bEnc = BIO_new(BIO_f_cipher());
			const EVP_CIPHER * cipher = NULL;
			cipher = EVP_des_ede3_cbc(); // 3DES-EDE-CBC 
			if(EVP_BytesToKey(cipher,EVP_sha1(),NULL,(unsigned char *)priPwd,
				strlen(priPwd),1,key,iv))
			{
				BIO_set_cipher(bEnc,cipher,key,iv, 1);//1-加密、0-解密
				bkey = BIO_push(bEnc, bkey); 
				j = i2d_PrivateKey_bio(bkey,pkey);//私钥加密
				BIO_flush(bkey);
				bkey = BIO_pop(bkey);
				BIO_free(bEnc);
			}
			else
				strcpy(outMsg,"初始化key or iv 失败,");
		}
	}
	//转换BIO->MEM
	if(i&&j)
	{
		i = Bio2Mem(breq, reqMem, reqLen);
		j = Bio2Mem(bkey, priMem, priLen);
	}

	BIO_free(breq);
	BIO_free_all(bkey);
	X509_REQ_free(req);
	EVP_PKEY_free(pkey);
	if(!i||!j)
	{
		strcat(outMsg,"Save Cert or Key File Error");
		return FALSE;
	}
	return TRUE;
}
////////////////////////// end //////////////////////////////////////
////////////////////////////////////////////////////////////////////
/////////////////////////// begin ////////////////////////////////////////
int copy_extensions(X509 *x, X509_REQ *req, const int copy_type)//在证书中加入req自带扩展信息
{
	STACK_OF(X509_EXTENSION) * exts = NULL;
	X509_EXTENSION * ext = NULL,
		           * tmpext = NULL;
	ASN1_OBJECT * obj = NULL;
	int i = 0,
		idx = 0,
		ret = 0;
	if (!x || !req || (copy_type == EXT_COPY_NONE))
		return 1;

	exts = X509_REQ_get_extensions(req);
	
	for(i = 0; i < sk_X509_EXTENSION_num(exts); i++)
	{
		ext = sk_X509_EXTENSION_value(exts, i);
		obj = X509_EXTENSION_get_object(ext);
		idx = X509_get_ext_by_OBJ(x, obj, -1);
		/* Does extension exist? */
		if (idx != -1) 
		{
			/* If normal copy don't override existing extension */
			if (copy_type == EXT_COPY_ADD)
				continue;
			/* Delete all extensions of same type */
			do
			{
				tmpext = X509_get_ext(x, idx);
				X509_delete_ext(x, idx);
				X509_EXTENSION_free(tmpext);
				idx = X509_get_ext_by_OBJ(x, obj, -1);
			} while (idx != -1);
		}
		if (!X509_add_ext(x, ext, -1))
			goto end;
	}
	
	ret = 1;
	
end:
	
	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
	
	return ret;
}


int do_body(X509 **xret, EVP_PKEY *pkey, X509 *px509, 
			const EVP_MD *dgst,const long serial,
			const char *startdate, const char *enddate,
			const int days,X509_REQ * req,const char * kusage,
			const char * ekusage,const stuCERTEXT * pCertExt,char * outMsg)
{
	X509_NAME * name = NULL, * CAname = NULL;
	X509 * ret = NULL;
	X509_CINF * ci = NULL;
	EVP_PKEY * pktmp = NULL;
	int ok= -1,
		i=0;
//	STACK_OF (X509_EXTENSION) * req_exts;//如何释放??
	name = X509_REQ_get_subject_name(req);
	if ((ret = X509_new()) == NULL) 
	{
		ok=0;
		goto err;
	}
	ci = ret->cert_info;

	/* Make it an X509 v3 certificate. 版本1扩展*/
	if (!X509_set_version(ret,2L)) //版本
	{
		ok=0;
		goto err;
	}
	
	ASN1_INTEGER_set(X509_get_serialNumber(ret),serial);//序列号

	if (!X509_set_issuer_name(ret,X509_get_subject_name(px509)))//发行者
	{
		ok=0;
		goto err;
	}

	//X509_gmtime_adj(X509_get_notBefore(x),0);//起始时间
	//X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);//结束时间

	if (strcmp(startdate,"today") == 0)
		X509_gmtime_adj(X509_get_notBefore(ret),0);//开始日期
	else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),(char *)startdate);
	
	if (enddate == NULL)
		X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);//结束日期
	else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),(char *)enddate);

//	X509_gmtime_adj(X509_get_notBefore(ret),0);//起始时间
//	X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);//结束时间

	if (!X509_set_subject_name(ret,name)) //主体 ---所有者
	{
		ok=0;
		goto err;
	}
	
	pktmp = X509_REQ_get_pubkey(req);
	i = X509_set_pubkey(ret,pktmp);//公钥
	EVP_PKEY_free(pktmp);
	if (!i) 
	{
		ok = 0;
		goto err;
	}
	
	//加入req自带扩展信息,生成REQ文件时候加入的
	if (!copy_extensions(ret, req, EXT_COPY_ALL))
	{
		strcpy("加入自带扩展信息失败",outMsg);
		goto err;
	}

	//CRL签名、仅仅加密、仅仅解密
		
	if(kusage && strlen(kusage))
		Add_ExtCert(ret,ret, NID_key_usage, kusage);

	AddExtCert(ret,px509,pCertExt);

	if(ekusage && strlen(ekusage))
		Add_ExtCert(ret,ret,NID_ext_key_usage,ekusage);

	/*
	Application			keyUsage  Values 
	SSL Client			digitalSignature 
	SSL Server			keyEncipherment 
	S/MIME Signing		digitalSignature 
	S/MIME Encryption	keyEncipherment 
	Certificate			Signing keyCertSign 
	Object Signing		digitalSignature */


	//加入自定义信息end
	X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added
	OBJ_cleanup();
	if (!X509_sign(ret,pkey,dgst))//加入签名,签名算法
	{
		ok=0;
		goto err;
	}
	ok=1;
err:
	if (CAname != NULL)
		X509_NAME_free(CAname);
	if (ok <= 0)
	{
		if (ret != NULL) X509_free(ret);
		ret=NULL;
	}
	else
		* xret = ret;
	return(ok);
}

int certify(X509 **xret, X509_REQ *req, EVP_PKEY *pkey, 
			X509 *px509,const EVP_MD *dgst,
			const long serial, const char *startdate, const char *enddate, 
			const int days,const char * KUSAGE,
			const char * EKUSAGE,const stuCERTEXT * pCertExt,char * outMsg)
{//返回公钥证书,请求文件,根私钥,根公钥,
	EVP_PKEY *pktmp=NULL;
	int ok= -1,i=0;	
	if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)//得到公钥
	{
		sprintf(outMsg,"error unpacking public key\n");
		ok=0;
		goto err;
	}
	i=X509_REQ_verify(req,pktmp);//证书请求里面有私要签名,这里验证一下,看此公钥主人是否持有私钥
	EVP_PKEY_free(pktmp);
	if (i < 0)
	{
		ok=0;
		sprintf(outMsg,"Signature verification problems....\n");
		goto err;
	}
	if (i == 0)
	{
		ok=0;
		sprintf(outMsg,"Signature did not match the certificate request\n");
		goto err;
	}
	
	ok=do_body(xret,pkey,px509,dgst,serial,startdate, enddate,
		days,req,KUSAGE,EKUSAGE,pCertExt,outMsg);
	
err:
	return(ok);
}


BOOL MakeCert(const stuCertPair & RootPair/*根证书对*/,
			  const long serial/*序列号*/,
			  const char *enddate/*作废日期*/,
			  const int days/*有效期*/, 
			  const char * reqMem/*请求文件或内存*/,
			  const int reqLen/*请求的长度,0-标示文件*/,
			  const char * KUSAGE/*密钥用法*/,
			  const char * EKUSAGE/*增强密钥用法*/,
			  const stuCERTEXT * pCertExt,/*证书扩展*/
			  char * outMem/*结果公钥文件*/,
			  UINT * MemLen/*结果长度*/,
			  char * outMsg/*操作结果*/,
			  const int type/*结果类型DER,PEM*/)//通过证书请求,得到证书
{
	int ret=1;
	char * md=NULL;
	EVP_PKEY *pkey=NULL;
	X509 * px509=NULL;
	X509_REQ *req=NULL;
	X509 * x=NULL;
	BIO * bcert=NULL,* reqbio=NULL;
	int j;
	const EVP_MD *dgst=NULL;

	OpenSSL_add_all_algorithms();//加入签名算法
	X509 * x509 = NULL;

	if(reqLen == 0)//输入为磁盘文件
	{
		if((reqbio=BIO_new_file(reqMem, "r")) == NULL)
		{
			strcpy(outMsg,"找不到证书请求文件");
			ret=0;
			goto err;
		}
	}
	else//输入为内存中文件
	{
		if((reqbio = BIO_new_mem_buf((void *)reqMem, reqLen)) == NULL)//只读类型
		{
			sprintf(outMsg,"Make Mem Bio Error");
			ret=0;
			goto err;
		}
	}

	
	if ((req=PEM_read_bio_X509_REQ(reqbio,NULL,NULL,NULL)) == NULL)//PEM_read_X509_REQ 
	{
		BIO_reset(reqbio);
		if ((req=d2i_X509_REQ_bio(reqbio,NULL)) == NULL)
		{
			sprintf(outMsg,"Error get certificate request");
			ret=0;
			goto err;
		}
	}

	if(!CertPair2XE(RootPair,px509,pkey,outMsg))
	{
		ret = 0;
		goto err;
	}

	md="sha1";//////////!!!!!!!!!!!!!!!!!////////////////////////////
	if ((dgst=EVP_get_digestbyname(md)) == NULL)//return an EVP_MD structure when passed a digest name
	{
		sprintf(outMsg,"%s is an unsupported message digest type\n",md);
		ret = 0;
		goto err;
	}
	j=certify(&x,req,pkey,px509,dgst,//公钥证书out,请求文件,根私钥,根公钥,
		serial,"today",enddate,days,KUSAGE,EKUSAGE,pCertExt,outMsg);
	if (j <= 0) 
	{
		ret=0;
		goto err;
	}

	bcert = BIO_new(BIO_s_mem());
	BIO_set_close(bcert, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */

	if (type==DER)
	{
		ret = i2d_X509_bio(bcert,x); 
	}
	else if(type==PEM)
	{
		ret = PEM_write_bio_X509(bcert,x);
	}

	//转换BIO->内存
	if(ret)
	{
		ret = Bio2Mem(bcert, outMem, MemLen);
	}
err:
	if (reqbio != NULL) BIO_free(reqbio);
	BIO_free_all(bcert);
	EVP_PKEY_free(pkey);
	X509_free(px509);
	X509_free(x);
	if (req != NULL) X509_REQ_free(req);
//	EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
//	CRYPTO_cleanup_all_ex_data();
	return ret;

}

///////////////////////// end ////////////////////////////////////////
BOOL DirectCert(const stuCertPair & RootPair/*根证书对*/,
				const int bits/*[IN]*/,
				const long serial/*[IN]序列号*/,
				const char * enddate/*[IN]作废日期*/,
				const int days/*[IN]有效期*/,
				const char * priPwd /*私钥加密密码,IN*/,
				const stuSUBJECT * sSUBJECT/*[IN]用户信息*/,
				const char * friendlyName/*好记的名称*/,
				const char * keyUsage/*密钥用法*/,
				const char * ekeyUsage/*扩展密钥用法*/,
				const stuCERTEXT * pCertExt,/*证书扩展结构*/
				char * pCert/*[OUT]输出证书公钥*/,
				UINT * certl/*[OUT]长度*/,
				char * key/*[OUT]输出证书私钥*/,
				UINT * keyl/*[OUT]长度*/,
				char * p12/*[OUT]输出证书私钥*/,
				UINT * p12l/*[OUT]长度*/,
				char * outMsg/*[OUT]返回错误信息*/,
				const int iType/*结果类型DER,PEM*/)
{
	X509_REQ * req=NULL;
	EVP_PKEY * pkey=NULL, * prkey=NULL;//证书私钥,//根私钥
	X509 * px509=NULL,* x=NULL;//根公钥,证书公钥
	int ret=1;
	char * md=NULL;
	int i=0,j=0,ok=0;
	const EVP_MD *dgst=NULL;

	OpenSSL_add_all_algorithms();//加入签名算法

	if(!CertPair2XE(RootPair,px509,prkey,outMsg))
	{
		ret = 0;
		goto err;
	}

	if(!mkReq(sSUBJECT,&req,&pkey, bits,outMsg))
	{
		sprintf(outMsg,"Make CertReq error");
		ret = 0;
		goto err;
	}

	md = "sha1";//////////!!!!!!!!!!!!!!!!!////////////////////////////
	if ((dgst = EVP_get_digestbyname(md)) == NULL)//return an EVP_MD structure when passed a digest name
	{
		sprintf(outMsg,"%s is an unsupported message digest type\n",md);
		ret = 0;
		goto err;
	}
	ok = certify(&x,req,prkey,px509,dgst,//公钥证书out,请求,根私钥,根公钥,
		serial,"today",enddate,days,keyUsage,ekeyUsage,pCertExt,outMsg);
	if (ok > 0) 
	{
		X5092Mem(x,iType,pCert,certl);
		Key2Mem(pkey,iType,priPwd,key,keyl);
		CreateMemPfx(x, pkey, priPwd, friendlyName, p12, p12l);
	}

err:
	EVP_PKEY_free(pkey);
	EVP_PKEY_free(prkey);
	X509_free(px509);
	X509_free(x);
	if (req != NULL) X509_REQ_free(req);
//	EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
//	CRYPTO_cleanup_all_ex_data();
	return ret;
}

⌨️ 快捷键说明

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