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

📄 ca.cpp

📁 小型CA的完整代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	{
		ret = 0;
		goto err;
	}
	
	if (!X509_check_private_key(x509,prkey))
	{
		sprintf(outMsg,"CA certificate and CA private key do not match\n");
		ret = 0;
		goto err;
	}

	if(!mkReq(&(sCERT->SUBJECT),&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,x509,dgst,//公钥证书out,请求,根私钥,根公钥,
		serial,"today",enddate,days,&(sCERT->KUSAGE),&(sCERT->EKUSAGE),outMsg);
	if (ok <= 0) 
	{
		ret=0;
		goto err;
	}
/*	if (type==DER)
	{
		i=i2d_X509_bio(memcert,x);
		j=i2d_PrivateKey_bio(memkey,pkey);//生成的结果错误!?????????????
	}
	else if(type==PEM)
*/	{
		i=PEM_write_bio_X509(memcert,x);
		j=PEM_write_bio_PrivateKey(memkey,pkey,NULL,NULL,0,NULL, NULL);
	}

	if(!i||!j)
	{
		strcpy(outMsg,"Get Mem Cert or Key File Error");
		ret=0;
		goto err;
	}

	BIO_get_mem_ptr(memcert, &bptrcert);
	*certl=bptrcert->length;
	memcpy(cert,bptrcert->data,*certl);

	BIO_get_mem_ptr(memkey, &bptrkey);
	*keyl=bptrkey->length;
	memcpy(key,bptrkey->data,*keyl);

err:
	BIO_free_all(memcert);
	BIO_free_all(memkey);
	EVP_PKEY_free(pkey);
	EVP_PKEY_free(prkey);
	X509_free(x509);
	X509_free(x);
	if (req != NULL) X509_REQ_free(req);
	EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
	return ret;
}
//////////////////////////////////////////////////////////////////////
///////////////////////// begin //////////////////////////////////////
/*添加链表节点*/
void AddRevoke(stuREVOKE *& Head,int index,time_t time)
{
	stuREVOKE * End=new stuREVOKE(index,time);//钥增加的节点
	if(Head==NULL)
	{
		Head=End;
	}
	else 
	{
		stuREVOKE * p=Head;
		while(p->Link!=NULL)  
			p=p->Link;
		p->Link=End; 
	}

	return;
}

int Add_ExtCrl(X509_CRL *crl/*正被添加的证书*/,X509 * root/*根证书(从中得到信息)*/, 
			   int nid, char *value)
{
	X509V3_CTX ctx;
	X509_EXTENSION *ex;

	/* This sets the 'context' of the extensions. */
	/* No configuration database */
//	X509V3_set_ctx_nodb(&ctx);
    X509V3_set_ctx(&ctx, root, NULL, NULL, crl, 0);
//	issuerAltName  authorityKeyIdentifier
	ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
	if (!ex)
		return 0;
	X509_CRL_add_ext(crl,ex,-1);
	X509_EXTENSION_free(ex);
	return 1;
}


BOOL MakeCrl(char *certfile/*根证书公钥*/,int certlen,/*为0则certfile为磁盘文件,否则为内存区域*/
			  char *keyfile/*根证书私钥*/,int keylen,
			  stuREVOKE * Head/*作废链表*/,PNewCrlMem NewCrlMem/*回调函数*/,char *& outCrl,int * crll,char * outfile/*crl文件*/,
			  char * outMsg/*操作结果*/)
{
	X509_CRL_INFO *ci = NULL;
	X509_CRL *crl = NULL;
	int ret=1,i=0;
	char *key=NULL;
	char *md=NULL;
	EVP_PKEY *pkey=NULL;
	X509 *x509=NULL;
	BIO *in=NULL,*out=NULL;
	const EVP_MD *dgst=NULL;
	X509_REVOKED *r=NULL;
	long crldays=30;
	long crlhours=0;
	stuREVOKE * temp =NULL;
	BIO * memcrl=NULL;
	BUF_MEM *bptrcrl=NULL;

	OpenSSL_add_all_algorithms();

	pkey=LoadKey(keyfile,keylen,NULL,outMsg);
	if (pkey == NULL)
	{
		ret = 0;
		goto err;
	}
	x509=LoadCert(certfile,certlen,outMsg);
	if (x509 == NULL)
	{
		ret = 0;
		goto err;
	}
	
	if (!X509_check_private_key(x509,pkey))
	{
		sprintf(outMsg,"CA certificate and CA private key do not match\n");
		ret = 0;
		goto err;
	}
	md="md5";//////////!!!!!!!!!!!!!!!!!////////////////////////////
	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;
	}
	
	if ((crl=X509_CRL_new()) == NULL)
	{
		ret = 0;
		goto err;
	}
	ci=crl->crl;
	X509_NAME_free(ci->issuer);
	ci->issuer=X509_NAME_dup(x509->cert_info->subject);
	if (ci->issuer == NULL)
	{
		ret = 0;
		goto err;
	}
	X509_gmtime_adj(ci->lastUpdate,0);
	if (ci->nextUpdate == NULL)
		ci->nextUpdate=ASN1_UTCTIME_new();
	X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);

	if(!ci->revoked)
		ci->revoked = sk_X509_REVOKED_new_null();

	
	while(Head!=NULL)//遍历链表
	{
	    temp=Head;
		X509_REVOKED *r = NULL;
        BIGNUM *serial_bn = NULL;
        r = X509_REVOKED_new();
		ASN1_TIME_set(r->revocationDate,Head->time);//时间
		char index[100];
        BN_hex2bn(&serial_bn,itoa(Head->Index,index,10));//序号
        BN_to_ASN1_INTEGER(serial_bn,r->serialNumber);
        sk_X509_REVOKED_push(ci->revoked,r);
		Head=Head->Link;
		delete temp;
	}
//	sk_X509_REVOKED_sort(ci->revoked);
	for (i=0; i<sk_X509_REVOKED_num(ci->revoked); i++)
	{
		r=sk_X509_REVOKED_value(ci->revoked,i);
		r->sequence=i;
	}

    if (ci->version == NULL)
    if ((ci->version=ASN1_INTEGER_new()) == NULL)
	{
		ret = 0;
		goto err;
	}
    ASN1_INTEGER_set(ci->version,1);
	//	issuerAltName  authorityKeyIdentifier
//	Add_ExtCrl(crl,x509,NID_subject_alt_name,"DNS:hpxs,email:hpxs@hotmail.com,RID:1.2.3.4,URI:https://hpxs,IP:192.168.0.22");
	Add_ExtCrl(crl,x509,NID_issuer_alt_name, "DNS:hpxs,email:hpxs@hotmail.com,RID:1.2.3.4,URI:https://hpxs,IP:192.168.0.22");
	Add_ExtCrl(crl,x509,NID_authority_key_identifier, "keyid,issuer:always");
	if (!X509_CRL_sign(crl,pkey,dgst))
	{
		ret = 0;
		goto err;
	}
	if(NewCrlMem)//输出内存
	{
		memcrl= BIO_new(BIO_s_mem());
		BIO_set_close(memcrl, BIO_CLOSE); /*  BIO_free() free BUF_MEM  */
		PEM_write_bio_X509_CRL(memcrl,crl);
		BIO_get_mem_ptr(memcrl, &bptrcrl);
		*crll=bptrcrl->length;
		outCrl=NewCrlMem(*crll);
		memcpy(outCrl,bptrcrl->data,*crll);
	}
	if(outfile)//输出文件
	{
		out=BIO_new_file(outfile, "w");
		if(out==NULL)
		{
			sprintf(outMsg,"%s is error",outfile);
			ret = 0;
			goto err;
		}
		PEM_write_bio_X509_CRL(out,crl);
	}

	X509V3_EXT_cleanup();//cleanup the extension code if any custom extensions have been added
err:
	if(out)
		BIO_free_all(out);
	if(memcrl)
		BIO_free_all(memcrl);
	BIO_free(in);
	EVP_PKEY_free(pkey);
	X509_CRL_free(crl);
	X509_free(x509);
	EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
	if(ret==1)
		strcpy(outMsg,"CRL制作成功");
	return ret;
	
}

BOOL CertFormatConver(char * buf/*文件内容或文件名称*/,int len/*内存长度为0则buf为文件名*/,
			  char * pwd/*p12文件密码*/,char * pem/*输出文件*/,
			  int outformat,char * out/*操作结果*/)
{
	EVP_PKEY *key=NULL;
	X509 *cert=NULL;
	BIO *biout=NULL;
	int i=0;
	//输出文件
	if ((biout=BIO_new_file(pem, "w")) == NULL)
	{
		return false;
	}		
	cert = LoadCert(buf,len,out);//首先尝试公钥,bio被改写
	if(cert)//输入文件为公钥文件
	{

		if 	(outformat == DER)
			i=i2d_X509_bio(biout,cert);
		else if (outformat == PEM)
		{
		//	if (trustout) i=PEM_write_bio_X509_AUX(biout,x);
			i=PEM_write_bio_X509(biout,cert);
		}
		if(!i)//失败
			strcpy(out,"保存公钥失败");
		else
			strcpy(out,"公钥证书格式转换成功");
		
	}

	else//输入文件为私钥文件
	{
		key=LoadKey(buf,len,pwd,out);
		if(!key) 
		{
			strcpy(out,"不能识别的文件格式");
			return false;
		}
		if(outformat==PEM)
		{	
			PEM_write_bio_PrivateKey(biout, key, NULL, NULL, 0, 0, NULL);
		}
		if(outformat==DER)
		{
			i2d_PrivateKey_bio(biout,key);//得到解密后的私钥
		}
		
		strcpy(out,"私钥证书格式转换成功");
	}
	
	if (biout != NULL) BIO_free(biout);
	X509_free(cert);
	EVP_PKEY_free(key);

	return true;
}

//分解p12包
BOOL ParseDB(char * strP12/*包文件*/,char * strPwd/*私钥密码*/,char * strCert/*公钥存放*/,
			 char * strkey/*私钥存放*/,int outformat/*输出格式*/,char * out/*返回结果*/)
{
	EVP_PKEY *key=NULL;
	X509 *cert=NULL;
	STACK_OF(X509) *ca = NULL;
	BIO * bio=NULL,*bioCert=NULL,*bioKey=NULL;
	PKCS12 *p12=NULL;
	int i=0,j=0;
	
	if((bio=BIO_new_file(strP12, "r")) == NULL)
	{
		strcpy(out,"打开文件错误");
		return false;
	}
	SSLeay_add_all_algorithms();
	p12 = d2i_PKCS12_bio(bio, NULL);
	if (!PKCS12_parse(p12, strPwd, &key, &cert/*PEM*/, &ca)) 
	{
		strcpy(out,"解包失败");
		return false;
	}
	PKCS12_free(p12);

	//输出文件
	if ((bioCert=BIO_new_file(strCert, "w")) == NULL)
	{
		return false;
	}
	if ((bioKey=BIO_new_file(strkey, "w")) == NULL)
	{
		return false;
	}
	
	if(outformat == DER)
	{
		i=i2d_X509_bio(bioCert,cert);
		j=i2d_PrivateKey_bio(bioKey,key);
	}
	else if (outformat == PEM)
	{
		i=PEM_write_bio_X509(bioCert,cert);
		j=PEM_write_bio_PrivateKey(bioKey, key, NULL, NULL, 0, 0, NULL);
	}

	if (bio != NULL) BIO_free(bio);
	if (bioCert != NULL) BIO_free(bioCert);
	if (bioKey != NULL) BIO_free(bioKey);
	X509_free(cert);
	EVP_PKEY_free(key);

	EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
	if(i!=0&&j!=0)
	{
		strcpy(out,"分解P12成功");
		return true;
	}
	return false;
}

//组合p12包
BOOL CreateDB(char * strP12/*OUT包文件*/,char * strPwd/*IN密码*/,char * strCert/*IN公钥*/,
			  char * strkey/*IN私钥*/,char * out/*返回结果*/)
{
	FILE *fp=NULL;
	EVP_PKEY *key=NULL;
	X509 *cert=NULL;
	PKCS12 *p12;
	cert =LoadCert(strCert,0,out);
	if(!cert) 
	{
		strcpy(out,"读取公钥文件失败");
		return false;
	}
	key=LoadKey(strkey,0,NULL,out);//解密后私钥
	if(!key) 
	{
		strcpy(out,"读取私钥文件失败");
		return false;
	}
   	SSLeay_add_all_algorithms();
	p12 = PKCS12_create(strPwd,"(hpxs)", key, cert, NULL, 0,0,0,0,0);
	if(!p12)
	{
		strcpy(out,"创建p12结构失败");
		return false;
	}
	if (!(fp = fopen(strP12, "wb"))) 
	{
		strcpy(out,"保存p12文件失败");
	}
	i2d_PKCS12_fp(fp, p12);
	PKCS12_free(p12);
	fclose(fp);
	strcpy(out,"合并P12成功");
	X509_free(cert);
	EVP_PKEY_free(key);
	EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
	return true;
}

//修改p12包密码
BOOL ChangePB(char * strP12/*in包文件*/,char * strPwd/*IN原密码*/,char * strPwd2/*IN新密码*/,
			  char * strOutP12/*in包文件*/,char * out/*返回结果*/)
{
	FILE *fp=NULL;
	EVP_PKEY *key=NULL;
	X509 *cert=NULL;
	STACK_OF(X509) *ca = NULL;
	PKCS12 *p12=NULL;
	int len=0,wlen=0;

	SSLeay_add_all_algorithms();
	if (!(fp = fopen(strP12, "rb")))
	{
		strcpy(out,"打开文件错误");
		return false;
	}
	p12 = d2i_PKCS12_fp(fp, NULL);
	fclose (fp);
	if (!p12) 
	{
		strcpy(out,"读取包文件错误");
		return false;
	}
	if (!PKCS12_parse(p12, strPwd, &key, &cert, &ca)) 
	{
		strcpy(out,"解包失败");
		return false;
	}
	PKCS12_free(p12);
	fclose(fp);
	p12=NULL;
	///////////////////////////////////////
	p12 = PKCS12_create(strPwd2,"(null)", key, cert, NULL, 0,0,0,0,0);
	if(!p12)
	{
		strcpy(out,"创建p12结构失败");
		return false;
	}
	if (!(fp = fopen(strOutP12, "wb"))) 
	{
		strcpy(out,"保存p12文件失败");
	}
	i2d_PKCS12_fp(fp, p12);
	PKCS12_free(p12);
	fclose(fp);
	strcpy(out,"转换P12密码成功");
	X509_free(cert);
	EVP_PKEY_free(key);
	return true;
}

BOOL CertPairCheck(char * cert,char * key,char * out)//检验公钥、私钥是否配对
{
	EVP_PKEY *pkey=NULL;
	X509 *x509=NULL;
	x509=LoadCert(cert,0,out);
	if(x509==NULL)
	{
		strcpy(out,"不能打开公钥文件");
		return FALSE;
	}
	pkey=LoadKey(key,0,NULL,out);
	if(pkey==NULL)
	{
		strcpy(out,"不能打开私钥文件");
		X509_free(x509);
		return FALSE;
	}
	if(X509_check_private_key(x509,pkey))//匹配
	{
		X509_free(x509);
		EVP_PKEY_free(pkey);
		return TRUE;
	}
	else
	{
		strcpy(out,"公私钥对不匹配");
		X509_free(x509);
		EVP_PKEY_free(pkey);
		return FALSE;
	}

}

⌨️ 快捷键说明

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