📄 certmng.cpp
字号:
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 + -