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

📄 certmng.cpp

📁 实现证书的生成和验证
💻 CPP
📖 第 1 页 / 共 4 页
字号:

	if ( is_pub_key )
	{
		if ( Out_Pubkey ( req, bio_out ) < 0 ) goto end;
	}
	if ( is_x509 )
	{
		switch ( out_fmt )
		{
		case FORMAT_ASN1:
			result = i2d_X509_bio ( bio_out, x509 );
			break;
		case FORMAT_PEM:
			result = PEM_write_bio_X509 ( bio_out, x509 );
			break;
		default:
			CError::Interface ()->Handle_Error ( 0, "输出格式不正确:%d", out_fmt );
			break;
		}
	}
	else
	{
		switch ( out_fmt )
		{
		case FORMAT_ASN1:
			result = i2d_X509_REQ_bio ( bio_out, req );
			break;
		case FORMAT_PEM:
			result = PEM_write_bio_X509_REQ ( bio_out, req );
			break;
		default:
			CError::Interface ()->Handle_Error ( 0, "输出格式不正确:%d", out_fmt );
			break;
		}
	}
	if ( ! result ) goto end;

	if ( out_type != FILE_TYPE )
	{
		int nLen = 0;
		std::string sout_put;
		char   chLen[127];

		if ( Get_BioStr( bio_out, sout_put, &nLen ) < 0 )
			goto end;

		itoa (  nLen, chLen, 10 );
		mapret.insert ( std::make_pair ( std::string ( REQ_FILE ), sout_put ) );
		mapret.insert ( std::make_pair ( std::string ( REQ_LENGTH ), std::string ( chLen ) ) );

		if ( conv_tool::Map2XML ( mapret, ppszXML, pnLen ) == -1 )
		{
			CError::Interface()->Handle_Error ( 0, "转换成XML失败" );
			goto end;
		}
	}
	ret = 0;
end:
	if ( bio_out )
		BIO_free_all ( bio_out );
	return ret;
}

int CCertMng::Verify_Request ( X509_REQ * req, EVP_PKEY * pKey )
{
	bool load_key = false;
	int  ret  = -1;

	if ( pKey == 0 )
	{
		load_key = true;
		pKey = X509_REQ_get_pubkey ( req );
	}
	if ( pKey == 0 )
		return -1;
	ret = X509_REQ_verify ( req, pKey );
	if ( load_key )
		EVP_PKEY_free ( pKey );

	return ( ret == 1 ? 0 : -1 );
}

int CCertMng::Sign_Request ( CONF * req_cnf, X509 * x509, X509_REQ * req, EVP_PKEY *pKey,
							const char * ext, ASN1_INTEGER * serial, int days, const EVP_MD *  digest )
{
	EVP_PKEY * tmpKey = 0;
	X509V3_CTX ext_ctx;

	if ( ext && !X509_set_version ( x509, 2 ) ) return -1;

	if ( serial )
	{
		if ( ! X509_set_serialNumber ( x509, serial ) ) return -1;
	}
	else
	{
		if ( ! ASN1_INTEGER_set ( X509_get_serialNumber ( x509 ), 0L ) ) return -1;
	}
	if ( ! X509_set_issuer_name ( x509, X509_REQ_get_subject_name ( req ) ) ) return -1;
	if ( ! X509_gmtime_adj ( X509_get_notBefore ( x509 ), 0 ) ) return -1;
	if ( ! X509_gmtime_adj ( X509_get_notAfter ( x509 ), (long)60*60*24*days ) ) return -1;
	if ( ! X509_set_subject_name ( x509, X509_REQ_get_subject_name ( req ) ) ) return -1;
	tmpKey = X509_REQ_get_pubkey ( req );
	if ( ! tmpKey  || ! X509_set_pubkey ( x509, tmpKey ) ) return -1;
	EVP_PKEY_free ( tmpKey );

	//设置v3_ctx 结构
	X509V3_set_ctx ( & ext_ctx, x509, x509, NULL, NULL, 0 );
	X509V3_set_nconf ( & ext_ctx, req_cnf );
	if ( ext &&
		!X509V3_EXT_add_nconf ( req_cnf, &ext_ctx, (char*)ext, x509 ) )
	{
		CError::Interface ()->Handle_Error ( 0, "增加扩展属性失败:%s", ext );
		return -1;
	}
	if ( ! X509_sign ( x509, pKey, digest ) )
	{
		CError::Interface()->Handle_Error ( 0, "自签名失败" );
		return -1;
	}
	return 0;
}

void CCertMng::Process_Key ( int p, int n, void * lpVoid )
{
	CCertMng * pMng = (CCertMng *)lpVoid;
	if ( pMng )
	{
		pMng->m_lpfnGenKey ( p, n, pMng->m_pVoid );
	}
}

int CCertMng::password_callback ( char * buf, int bufsiz, int verify, void * pVoid)
{
	CCertMng * pMng = (CCertMng *)pVoid;
	return pMng->m_lpfnPass_Callback ( buf, bufsiz, verify, pMng->m_pVoid );
}

EVP_PKEY * CCertMng::Load_Key ( char * pBuf, int nBufLen, int fmt, int nType )
{
	if ( pBuf == 0 )
		return NULL;

	EVP_PKEY * pKey    = 0;
	BIO      * bio_key = 0;

	if ( ( bio_key = Bio_Read ( nType, pBuf, nBufLen) ) == NULL )
	{
		CError::Interface()->Handle_Error ( 0, "读取KEY失败" );
		goto end;
	}
	
	switch ( fmt )
	{
	case FORMAT_ASN1:
		pKey = d2i_PrivateKey_bio ( bio_key, NULL );
		break;
	case FORMAT_PEM:
		pKey = PEM_read_bio_PrivateKey ( bio_key, NULL, (pem_password_cb *)password_callback, this);
		break;
	case FORMAT_PKCS12:
		{
			char chPass[BUFSIZZ];
			int  nLen = 0;
			memset ( chPass, 0, sizeof chPass );
			nLen = CCertMng::password_callback ( chPass, sizeof chPass, 1, m_pVoid );
			PKCS12 *p12 = d2i_PKCS12_bio ( bio_key, NULL );
			PKCS12_parse ( p12, chPass, &pKey, NULL, NULL);
			PKCS12_free ( p12 );
		}
		break;
	default:
		CError::Interface()->Handle_Error ( 0, "KEY类型未知:%d", fmt );
		break;
	}
end:
	if ( bio_key )
		BIO_free ( bio_key );
	return pKey;
}

int CCertMng::Load_Config ( CONF * cnf )
{
	if ( cnf == NULL )
		return -1;
	OPENSSL_load_builtin_modules();
	if ( CONF_modules_load ( cnf, NULL, 0 ) <= 0 )
	{
		CError::Interface ()->Handle_Error ( 0, "错误的配置文件:%s", m_szConfFile.c_str () );
		return -1;
	}
	return 0;
}

int CCertMng::Add_Oid_Section ( CONF * cnf )
{
	STACK_OF(CONF_VALUE) * sk_tmp = 0;
	char       * p       = 0;
	CONF_VALUE * cnf_val = 0;

	if ( ( p = NCONF_get_string ( cnf, NULL, OID_SECTION ) ) == NULL )
		return 0;
	if ( ( sk_tmp = NCONF_get_section ( cnf, p ) ) == NULL )
	{
		CError::Interface()->Handle_Error ( 0, "读取%s失败:%s", OID_SECTION, m_szConfFile.c_str() );
		return -1;
	}
	for ( int i = 0; i < sk_CONF_VALUE_num ( sk_tmp ); i++ )
	{
		cnf_val = sk_CONF_VALUE_value ( sk_tmp, i );
		if ( OBJ_create ( cnf_val->value, cnf_val->name, cnf_val->name ) == NID_undef )
		{
			CError::Interface()->Handle_Error ( 0, "创建对象失败:%s=%s", cnf_val->name, cnf_val->value );
			return -1;
		}
	}
	return 0;
}

int CCertMng::Make_Request ( CONF * req_cnf, X509_REQ * req, EVP_PKEY *pKey,
							int nAttribs, unsigned long nCharset )
{
	char *    pszDnSect   = 0, * pszAttr_Sect = 0;
	STACK_OF(CONF_VALUE) * dn_sk = 0, * attr_sk = 0;

	pszDnSect = NCONF_get_string ( req_cnf, REQ_SECTION, DIST_NAME );
	if ( pszDnSect == 0 )
	{
		CError::Interface()->Handle_Error ( 0, "不能读取%s,配置文件%s", DIST_NAME, m_szConfFile.c_str() );
		return -1;
	}
	dn_sk = NCONF_get_section ( req_cnf, pszDnSect );
	if ( dn_sk == 0 )
	{
		CError::Interface ()->Handle_Error ( 0, "不能得到%s,配置文件%s", pszDnSect, m_szConfFile.c_str() );
		return -1;
	}
	pszAttr_Sect = NCONF_get_string ( req_cnf, REQ_SECTION, ATTRIBUTES );
	if ( pszAttr_Sect )
	{
		attr_sk = NCONF_get_section ( req_cnf, pszAttr_Sect );
		if ( attr_sk == 0 )
		{
			CError::Interface()->Handle_Error ( 0, "不能得到%s,配置文件%s", pszAttr_Sect, m_szConfFile.c_str() );
			return -1;
		}
	}
	if ( ! X509_REQ_set_version ( req, 0L ) )
	{
		CError::Interface ()->Handle_Error ( 0, "设置版本号失败" );
		return -1;
	}
	if ( -1 == Prompt_Info ( req_cnf, req, dn_sk, pszDnSect, attr_sk, pszAttr_Sect, nAttribs, nCharset ) )
		return -1;
	if ( ! X509_REQ_set_pubkey ( req, pKey ) )
		return -1;
	return 0;
}

int CCertMng::Prompt_Info ( CONF * req_cnf, X509_REQ * req, STACK_OF(CONF_VALUE) * dn_sk, char * dn_sect,
						   STACK_OF(CONF_VALUE) * attr_sk, char * attr_sect,
						   int nAttribs, unsigned long nCharset )
{
	int   i = 0;
	int   nid;
	long  n_min = -1, n_max = -1;

	char * type = 0, * p = 0;
	std::string def, value;

	CONF_VALUE * cnf_val = 0;
	X509_NAME  * subj;

	subj = X509_REQ_get_subject_name ( req );

	if ( ! sk_CONF_VALUE_num ( dn_sk ) )
	{
		CError::Interface()->Handle_Error ( 0, "在配置文件没有设置证书属性信息" );
		return -1;
	}
	for ( ; ; ) 
	{
		if ( sk_CONF_VALUE_num ( dn_sk ) <= i )
			break;
		cnf_val = sk_CONF_VALUE_value ( dn_sk, i++ );
		type = cnf_val->name;
		if ( !Check_End ( type, MIN_POSTFIX ) ||
			!Check_End ( type, MAX_POSTFIX ) || 
			!Check_End ( type, DEF_POSTFIX ) || 
			!Check_End ( type, VAL_POSTFIX ) )
		{
			continue;
		}
		for ( p = cnf_val->name; *p ; p++ )
		{
			if ( ( *p == ':' ) || ( *p == ',' ) || ( *p == '.' ) )
			{
				p++;
				if ( *p ) type = p;
				break;
			}
		}
		if ( ( nid = OBJ_txt2nid ( type ) ) == NID_undef )
			continue;
		if ( Get_Section ( req_cnf, cnf_val, dn_sect, def, value, &n_min, &n_max ) == -1 )
			return -1;
		if ( -1 == Add_DN_Object ( subj, cnf_val->value, def.c_str(), value.c_str(), nid, n_min,n_max, nCharset ) )
			return -1;
	}
	if ( X509_NAME_entry_count ( subj ) == 0 )
	{
		CError::Interface()->Handle_Error ( 0, "在配置文件%s中没有指定对象", m_szConfFile.c_str() );
		return -1;
	}
	if ( nAttribs )
	{
		i = 0;
		for ( ; ; )
		{
			if ( attr_sk == NULL || (sk_CONF_VALUE_num ( attr_sk ) <= i ))
				break;
			cnf_val = sk_CONF_VALUE_value ( attr_sk, i++ );
			type = cnf_val->name;
			if ( ( nid = OBJ_txt2nid ( type ) ) == NID_undef )
				continue;
			if ( Get_Section ( req_cnf, cnf_val, attr_sect, def, value, &n_min, &n_max ) == -1 )
				return -1;
			if ( -1 == Add_DN_Attribute ( req, cnf_val->value, def.c_str(), value.c_str(), nid, n_min, n_max, nCharset) )
				return -1;
		}
	}
	return 0;
}

int CCertMng::Get_Section ( CONF * req_cnf, CONF_VALUE * cnf_val,
						   const char * section,
						   std::string & def, std::string & val,
						   long * min, long * max)
{
	char   buf[255];
	char   * p = 0;

	if ( BIO_snprintf ( buf, sizeof buf, "%s_default", cnf_val->name ) >= sizeof buf )
	{
		CError::Interface ()->Handle_Error ( 0, "参数名称太长:%s", cnf_val->name );
		return -1;
	}
	p = NCONF_get_string ( req_cnf, section, buf );
	if ( p == NULL )
		ERR_clear_error();
	else
		def = p;

	BIO_snprintf ( buf, sizeof buf, "%s_value", cnf_val->name );
	p = NCONF_get_string ( req_cnf, section, buf );
	if ( p == NULL )
		ERR_clear_error();
	else
		val = p;

	BIO_snprintf(buf,sizeof buf,"%s_min", cnf_val->name);
	if ( ! NCONF_get_number ( req_cnf, section, buf, min ) )
	{
		ERR_clear_error();
		*min = -1;
	}
	BIO_snprintf(buf,sizeof buf,"%s_max", cnf_val->name);
	if ( ! NCONF_get_number ( req_cnf, section, buf, max ) )
	{
		ERR_clear_error();
		*max = -1;
	}
	return 0;
}

int CCertMng::Check_End ( char * src, char * end )
{
	int src_len = strlen ( src );
	int end_len = strlen ( end );
	if ( end_len > src_len )
		return 1;
	char * tmp = src + src_len - end_len;
	return strcmp ( tmp, end );
}

int CCertMng::Add_DN_Object ( X509_NAME * x509_name, char * text,
							 const char * def, const char * value,
							 int nid, long n_min, long n_max, unsigned long char_set )
{
	int  nLen = 0;
	char buf[BUFSIZZ];

	memset ( buf, 0, sizeof buf );
	if ( strlen( value ) > 0 )
	{
		BUF_strlcpy ( buf, value, sizeof buf );
	}
	else
	{
		if ( m_lpfnGet_Dn_Value == NULL )
		{
			CError::Interface()->Handle_Error ( 0, "回调函数指针不能为NULL" );
			return -1;
		}
		if ( m_lpfnGet_Dn_Value ( text, def, buf, n_min, n_max, m_pVoid ) == -1 && buf[0] == '\n' )
		{
			BUF_strlcpy ( buf, def, sizeof  buf );
		}
		else if ( buf[0] == '.' && buf[1] == '\n' )
			return 0;
	}
	if ( buf[0] == '\0' ) return 0;
	if ( ( buf[0] == '.' ) && ( buf[1] == '\n' || buf[1] == '\0' ) )
		return 0;
	nLen = strlen ( buf );
	buf[nLen] = '\0';
	if ( ! X509_NAME_add_entry_by_NID ( x509_name, nid, char_set, (unsigned char *) buf, -1, -1, 0 ) )
		return -1;
	return 0;
}

int CCertMng::Add_DN_Attribute ( X509_REQ * req, char * text,
								const char * def, const char * value,
						 int nid, long n_min, long n_max, unsigned long char_set )
{
	int  nLen = 0;
	char buf[BUFSIZZ];

	memset ( buf, 0, sizeof buf );
	if ( strlen ( value ) > 0 )
	{
		BUF_strlcpy ( buf, value, sizeof buf );
	}

⌨️ 快捷键说明

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