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

📄 ca.cpp

📁 minica2的第2个版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			   const char * strPwd2/*IN新密码*/,
			   const char * strOutP12/*in新包文件*/,
			   char * outMsg/*返回结果*/)
{
	BIO *bin = NULL;
	BIO *biout = NULL;
	EVP_PKEY *key = NULL;
	X509 *pCert = NULL;
	PKCS12 *p12 = NULL;
	int len = 0,
		wlen = 0;

	BOOL bRet = TRUE;


	OpenSSL_add_all_algorithms();
	//输入文件 
	if ((bin=BIO_new_file(strP12, "rw")) == NULL)
	{
		strcpy(outMsg,"加载PFX文件错误");
		bRet = FALSE;
		goto err;
	}		
	p12 = d2i_PKCS12_bio(bin, NULL);
	if (!p12) 
	{
		strcpy(outMsg,"加载包文件失败");
		bRet = FALSE;
		goto err;
	}
	if (!PKCS12_parse(p12, strPwd, &key, &pCert, NULL)) 
	{
		strcpy(outMsg,"解包失败");
		bRet = FALSE;
		goto err;
	}
	///////////////////////////////////////
	if(p12)
		PKCS12_free(p12);

	p12 = NULL;

	p12 = PKCS12_create((char *)strPwd2,"MiniCA", key, pCert, NULL, 0,0,0,0,0);
	if(!p12)
	{
		strcpy(outMsg,"创建p12结构失败");
		bRet = FALSE;
		goto err;
	}
	//输出文件
	if ((biout = BIO_new_file(strP12, "w")) == NULL)
	{
		strcpy(outMsg,"创建输出文件失败");
		bRet = FALSE;
		goto err;
	}
	i2d_PKCS12_bio(biout, p12);

err:
	if(p12)
		PKCS12_free(p12);
	if(pCert)
		X509_free(pCert);
	if(key)
		EVP_PKEY_free(key);
	if (bin)
		BIO_free(bin);
	if (biout)
		BIO_free(biout);
//	EVP_cleanup();//frees all three stacks and sets their pointers to NULL ---- EVP_CIPHER
	return bRet;
}

//检验公钥、私钥是否配对
BOOL CertPairCheck(const char * pCert,
				   const char * key,
				   char * outMsg,
				   const char * priPwd )//检验公钥、私钥是否配对
{
	EVP_PKEY *pkey=NULL;
	X509 *px509=NULL;
	px509=LoadCert(pCert,0,"",outMsg);
	if(px509==NULL)
	{
		strcpy(outMsg,"不能加载公钥文件");
		return FALSE;
	}
	pkey=LoadKey(key,0,priPwd,outMsg);
	if(pkey==NULL)
	{
		strcpy(outMsg,"不能加载私钥文件");
		X509_free(px509);
		return FALSE;
	}
	if(X509_check_private_key(px509,pkey))//匹配
	{
		X509_free(px509);
		EVP_PKEY_free(pkey);
		return TRUE;
	}
	else
	{
		strcpy(outMsg,"公私钥对不匹配");
		X509_free(px509);
		EVP_PKEY_free(pkey);
		return FALSE;
	}

}

int HexToTen(const char * pHex)
{
    DWORD dwHexNum=0;
    for (; *pHex!=0 ; pHex++)
    {
        dwHexNum *= 16;
        if ((*pHex>='0') && (*pHex<='9'))
            dwHexNum += *pHex-'0';
        else if ((*pHex>='a') && (*pHex<='f'))
            dwHexNum += *pHex-'a'+10;
        else if ((*pHex>='A') && (*pHex<='F'))
            dwHexNum += *pHex-'A'+10;
        else
            -1;
    }
	return dwHexNum;
}

void Utf8ToAnsi(const UCHAR * lpsrc,const int srclen, LPSTR lpdst, int& dstlen)
{
	WCHAR * Unicode;
    int len = MultiByteToWideChar ( CP_UTF8 , 0 ,(char*) lpsrc ,-1 ,NULL,0);
    Unicode = new WCHAR[len * sizeof(WCHAR)];
    MultiByteToWideChar ( CP_UTF8 , 0 ,( char * ) lpsrc, -1, Unicode , len );
    len = WideCharToMultiByte(CP_ACP,0,Unicode,-1,NULL,0,NULL,NULL);
    dstlen = WideCharToMultiByte (CP_ACP,0,Unicode,-1,lpdst,len,NULL,NULL);
    delete []Unicode;
}



/////////////////////////////////////////////////////////////////////////////
// 通过黑名单验证证书,验证通过返回真,否则返回假
BOOL CheckCertWithCrl(const char *pubCert,const int pubCertLen,
					  const char *crlData,const int crlLen,char * outMsg)
{
	BOOL bRet = TRUE;
	int i = 0;
	BOOL bf = TRUE;
	int num;
	ASN1_INTEGER *serial = NULL;
	STACK_OF(X509_REVOKED) *revoked = NULL;
	X509_REVOKED *rc;
	X509_CRL * crl = NULL;
	BIO * in=NULL;

	X509 *x509 = LoadCert(pubCert,pubCertLen,NULL,outMsg);
	if (x509 == NULL)
	{
		strcpy(outMsg,"加载证书失败");
		bRet = FALSE;
		goto end;
	}
	if(crlLen==0)
	{
		if((in=BIO_new_file(crlData, "r"))==NULL)
		{		
			strcpy(outMsg,"Create File Error");
			bRet = FALSE;
			goto end;
		}
	}
	else
	{
		if((in=BIO_new_mem_buf((void *)crlData,crlLen))== NULL)
		{		
			strcpy(outMsg,"GlobalLock mem Error");
			bRet = FALSE;
			goto end;
		}
	}
	crl = d2i_X509_CRL_bio(in,NULL); //DER 格式?
	if(crl == NULL)
	{
		BIO_reset(in);//恢复bio
		crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); //PEM格式?
	}
	if(crl == NULL)
	{		
		strcpy(outMsg,"加载 crl 失败");
		bRet = FALSE;
		goto end;
	}
	revoked = crl->crl->revoked;

    
	serial = X509_get_serialNumber(x509);
	num = sk_X509_REVOKED_num(revoked);
	for(i=0;i<num;i++)
	{
		rc=sk_X509_REVOKED_pop(revoked);	//leak
		if(ASN1_INTEGER_cmp(serial,rc->serialNumber)==0)
		{
			strcpy(outMsg,"证书已作废");
			bf = FALSE;
		}
		X509_REVOKED_free(rc);	//leak
	}
    
end:
	if(crl)
		X509_CRL_free(crl);
	if(x509)
		X509_free(x509);
	if(in)
		BIO_free(in);
	if(bRet)
	{
		if(bf)
			strcpy(outMsg,"证书有效");
	}
	return bf;
}
    
/////////////////////////////////////////////////////////////////////////////
// 通过根证书验证证书ENGINE_load_private_key
BOOL CheckCertWithRoot(const char *pubCert,const int pubCertLen,
					   const char *rootCert,const int rootCertLen,char * outMsg)
{
	OpenSSL_add_all_algorithms();
	BOOL bRet = TRUE;
	EVP_PKEY * pcert = NULL;
	X509 *pRoot = NULL;
	int ret =0;

	X509 *x509 = LoadCert(pubCert,pubCertLen,NULL,outMsg);
	if (x509 == NULL)
	{
		strcpy(outMsg,"加载证书失败");
		bRet =  FALSE;
		goto end;
	}

	pRoot = LoadCert(rootCert,rootCertLen,NULL,outMsg);
	if (pRoot == NULL)
	{
		strcpy(outMsg,"加载根证书失败");
		bRet =  FALSE;
		goto end;
	}
    
	pcert = X509_get_pubkey(pRoot);
	if (pcert == NULL)
	{
		strcpy(outMsg,"读取根证书公钥信息失败");
		bRet =  FALSE;
		goto end;
	}
	
	ret = X509_verify(x509,pcert);

end:
	if(pcert)
		EVP_PKEY_free (pcert); 
    if(x509)
		X509_free(x509);
	if(pRoot)
		X509_free(pRoot);
//	EVP_cleanup();
	if(bRet)
	{
		if(ret==1)
		{
			strcpy(outMsg,"证书与根证书匹配");
			return TRUE;
		}
		else
		{
			strcpy(outMsg,"证书与根证书不匹配");
			return FALSE;
		}
	}
	else
		return FALSE;
}
    
/////////////////////////////////////////////////////////////////////////////
// 检查证书有效期,在有效期内返回真,否则返回假
BOOL CheckCertLife(const char *pubCert,const int pubCertLen,char * outMsg)
{
	X509 *x509 = LoadCert(pubCert,pubCertLen,NULL,outMsg);
	if (x509 == NULL)
	{
		strcpy(outMsg,"加载证书失败");
		return FALSE;
	}
	time_t ct;
	time( &ct );
	asn1_string_st *before=X509_get_notBefore(x509),
		*after=X509_get_notAfter(x509);
	ASN1_UTCTIME *be=ASN1_STRING_dup(before),
		*af=ASN1_STRING_dup(after);
	BOOL bf;
	if(ASN1_UTCTIME_cmp_time_t(be,ct)>=0||ASN1_UTCTIME_cmp_time_t(af,ct)<=0)
	{
		strcpy(outMsg,"证书超出有效期");
		bf = FALSE;
	}
	else
	{
		strcpy(outMsg,"证书有效");
		bf = TRUE;
	}
	M_ASN1_UTCTIME_free(be);
	M_ASN1_UTCTIME_free(af);
	X509_free(x509);
	return bf;
}
 

/*组合P7包*/
BOOL CreateP7b(std::list<std::string> * pCertList,
			   const char * lpszCrl,
			   const char * outP7b,
			   const int outformat,
			   char * outMsg/*返回结果*/)
{
	int i = 0;
	BIO *in = NULL,
		*out = NULL;
	PKCS7 *p7 = NULL;
	PKCS7_SIGNED *p7s = NULL;
	X509_CRL *crl = NULL;
	STACK *certflst = NULL;
	STACK_OF(X509_CRL) *crl_stack = NULL;
	STACK_OF(X509) *cert_stack = NULL;
	in = BIO_new(BIO_s_file());
	if(lpszCrl && strlen(lpszCrl) != 0)	//有黑名单文件
	{
		//加载CRL结构
		if (BIO_read_filename(in,lpszCrl) <= 0)
		{
			sprintf(outMsg, "加载CRL%s失败", lpszCrl);
			goto end;
		}
		crl = d2i_X509_CRL_bio(in,NULL); //DER 格式?
		if(crl == NULL)
		{
			BIO_reset(in);//恢复bio
			crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); //PEM格式?
		}
	}
	if ((p7 = PKCS7_new()) == NULL) goto end;
	if ((p7s = PKCS7_SIGNED_new()) == NULL) goto end;
	p7->type = OBJ_nid2obj(NID_pkcs7_signed);
	p7->d.sign = p7s;
	p7s->contents->type = OBJ_nid2obj(NID_pkcs7_data);
	
	if (!ASN1_INTEGER_set(p7s->version,1))
		goto end;
	if ((crl_stack=sk_X509_CRL_new_null()) == NULL)
		goto end;
	p7s->crl = crl_stack;
	if (crl != NULL)
	{
		sk_X509_CRL_push(crl_stack,crl);
		crl = NULL; /* now part of p7 for OPENSSL_freeing */
	}
	
	if ((cert_stack = sk_X509_new_null()) == NULL) goto end;
	p7s->cert = cert_stack;
	if(pCertList)
	{
		std::list<std::string>::const_iterator pos;
		for(pos = pCertList->begin(); pos != pCertList->end(); ++pos)
		{
			std::string strCert = *pos;
			X509 * pX509 = LoadCert(strCert.c_str(), 0, 0, outMsg);
			if(pX509)
			{
				sk_X509_push(cert_stack, pX509);
			}
		}
	}
	out = BIO_new(BIO_s_file());
	if (BIO_write_filename(out, const_cast<char *>(outP7b)) <= 0)
	{
		goto end;
	}

	if(outformat == DER)
		i=i2d_PKCS7_bio(out,p7);
	else if(outformat == PEM)
		i=PEM_write_bio_PKCS7(out,p7);
	
end:
	if (in != NULL) BIO_free(in);
	if (out != NULL) BIO_free_all(out);
	if (p7 != NULL) PKCS7_free(p7);			//free cert_stack
	if (crl != NULL) X509_CRL_free(crl);
	return i;
}


/*分解P7包*/
BOOL ParseP7b(const char * lpszInP7b/*包文件或内存*/,
			  const UINT iP12Len/* 如果包为文件,则为0,否则为内存长度*/,
			  const int outformat/*输出格式*/,
			  const char * lpszCert/*公钥存放*/,
			  const char * lpszCrl/*CRL存放*/,
			  const char * lpszOutP7b/*用于转换P7格式的输出文件名*/,
			  char * outMsg/*返回结果*/)
{
	PKCS7 *p7 = NULL;
	int i,badops=0;
	BIO *in = NULL,
		*out = NULL;
	int ret = 1;
	STACK_OF(X509) *certs=NULL;
	STACK_OF(X509_CRL) *crls=NULL;

	in=BIO_new(BIO_s_file());
	out=BIO_new(BIO_s_file());
	if ((in == NULL) || (out == NULL))
	{
		ret = 0;
        goto end;
    }

	if (BIO_read_filename(in, lpszInP7b) <= 0)
	if (in == NULL)
	{
		sprintf(outMsg, "读取P7B%s失败", lpszInP7b);
		ret = 0;
		goto end;
	}

	p7 = d2i_PKCS7_bio(in,NULL);
	if(!p7)
	{
		BIO_reset(in);//恢复bio
		p7=PEM_read_bio_PKCS7(in,NULL,NULL,NULL);
	}
	if (p7 == NULL)
	{
		sprintf(outMsg, "加载P7B%s失败", lpszInP7b);
		ret = 0;
		goto end;
	}
	
	i=OBJ_obj2nid(p7->type);
	switch (i)
	{
	case NID_pkcs7_signed:
		certs=p7->d.sign->cert;
		crls=p7->d.sign->crl;
		break;
	case NID_pkcs7_signedAndEnveloped:
		certs=p7->d.signed_and_enveloped->cert;
		crls=p7->d.signed_and_enveloped->crl;
		break;
	default:
		break;
	}
	
	if (certs != NULL && lpszCert && strlen(lpszCert) !=0 )
	{
		X509 *x;
		for (i=0; i<sk_X509_num(certs); i++)
		{
			BIO * bioCert = NULL;
			char buf[256] = {0};
			sprintf(buf, "%s-%d.Cer", lpszCert, i);
			if((bioCert = BIO_new_file(buf, "w")) == NULL)
			{
				goto end;
				ret = 0;
			}
			x = sk_X509_value(certs,i); //保存证书公钥
			if (outformat == DER)
			{
				i2d_X

⌨️ 快捷键说明

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