tcp_connect 中的 gSoap SSL/TLS 证书主机名不匹配
gSoap SSL/TLS certificate host name mismatch in tcp_connect
我的 soap 客户端不接受我必须连接到的服务的证书。它给出了错误:SSL/TLS certificate host name mismatch in tcp_connect
。但是 chrome 确实接受证书。我检查了 chrome 中的证书,发现它是 *.domain.nl 形式的通配符证书。是否需要额外的配置步骤才能让 gSoap/openssl 接受这个?
ssl 初始化:
soap_ssl_client_context(&proxy,
SOAP_SSL_DEFAULT, /* use SOAP_SSL_DEFAULT in production code */
NULL, /* keyfile (cert+key) */
NULL, /* password to read the keyfile */
"c:\test\cacert.pem",
NULL, /* optional capath to directory with trusted certificates */
NULL
)
我正在测试的 cacert.pem 是 http://curl.haxx.se/ca/cacert.pem
当我将 SOAP_SSL_SKIP_HOST_CHECK
添加到选项时,一切正常。
我在使用 gSOAP 2.8.22 时遇到了同样的问题。在寻找解决方案时,我发现了您的问题……但没有答案。所以我下载、构建和调试 "OpenSSL 1.0.2d 9 Jul 2015"(当前最新版本)。
我尝试访问 https://outlook.office365.com/ews/exchange.asmx。证书包含在 "Certificate Subject Alt Name" 通配符名称中,例如“*.office365.com”。我在 stdsoap2.cpp 中找到了处理此字段的代码,但 它不检查通配符名称 :
names = (GENERAL_NAMES*)X509_get_ext_d2i(peer, NID_subject_alt_name, NULL, NULL);
if (names)
{ val = i2v_GENERAL_NAMES(NULL, names, val);
sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
}
if (val)
{ int j;
for (j = 0; j < sk_CONF_VALUE_num(val); j++)
{ CONF_VALUE *nval = sk_CONF_VALUE_value(val, j);
if (nval && !strcmp(nval->name, "DNS") && !strcmp(nval->value, host))
{ ok = 1;
break;
}
}
sk_CONF_VALUE_pop_free(val, X509V3_conf_free);
}
然后我把代码改成了
names = (GENERAL_NAMES*)X509_get_ext_d2i(peer, NID_subject_alt_name, NULL, NULL);
if (names)
{ val = i2v_GENERAL_NAMES(NULL, names, val);
sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
}
if (val)
{ int j;
for (j = 0; j < sk_CONF_VALUE_num(val); j++)
{ CONF_VALUE *nval = sk_CONF_VALUE_value(val, j);
if (nval && !strcmp(nval->name, "DNS"))
{
if ( !strcmp( nval->value, host))
{
ok = 1;
break;
}
else if ( *nval->value == '*')
{
const char* const t = nval->value + 1;
if ( *t == '.')
{
const char* const h = strchr( host, '.');
if ( h && !strcmp( t, h))
{
ok = 1;
break;
}
}
}
}
}
sk_CONF_VALUE_pop_free(val, X509V3_conf_free);
}
此修复不处理 UTF-8 名称。为此,您可以查看处理通用名称的代码(搜索 NID_commonName)。
我的 soap 客户端不接受我必须连接到的服务的证书。它给出了错误:SSL/TLS certificate host name mismatch in tcp_connect
。但是 chrome 确实接受证书。我检查了 chrome 中的证书,发现它是 *.domain.nl 形式的通配符证书。是否需要额外的配置步骤才能让 gSoap/openssl 接受这个?
ssl 初始化:
soap_ssl_client_context(&proxy,
SOAP_SSL_DEFAULT, /* use SOAP_SSL_DEFAULT in production code */
NULL, /* keyfile (cert+key) */
NULL, /* password to read the keyfile */
"c:\test\cacert.pem",
NULL, /* optional capath to directory with trusted certificates */
NULL
)
我正在测试的 cacert.pem 是 http://curl.haxx.se/ca/cacert.pem
当我将 SOAP_SSL_SKIP_HOST_CHECK
添加到选项时,一切正常。
我在使用 gSOAP 2.8.22 时遇到了同样的问题。在寻找解决方案时,我发现了您的问题……但没有答案。所以我下载、构建和调试 "OpenSSL 1.0.2d 9 Jul 2015"(当前最新版本)。
我尝试访问 https://outlook.office365.com/ews/exchange.asmx。证书包含在 "Certificate Subject Alt Name" 通配符名称中,例如“*.office365.com”。我在 stdsoap2.cpp 中找到了处理此字段的代码,但 它不检查通配符名称 :
names = (GENERAL_NAMES*)X509_get_ext_d2i(peer, NID_subject_alt_name, NULL, NULL);
if (names)
{ val = i2v_GENERAL_NAMES(NULL, names, val);
sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
}
if (val)
{ int j;
for (j = 0; j < sk_CONF_VALUE_num(val); j++)
{ CONF_VALUE *nval = sk_CONF_VALUE_value(val, j);
if (nval && !strcmp(nval->name, "DNS") && !strcmp(nval->value, host))
{ ok = 1;
break;
}
}
sk_CONF_VALUE_pop_free(val, X509V3_conf_free);
}
然后我把代码改成了
names = (GENERAL_NAMES*)X509_get_ext_d2i(peer, NID_subject_alt_name, NULL, NULL);
if (names)
{ val = i2v_GENERAL_NAMES(NULL, names, val);
sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
}
if (val)
{ int j;
for (j = 0; j < sk_CONF_VALUE_num(val); j++)
{ CONF_VALUE *nval = sk_CONF_VALUE_value(val, j);
if (nval && !strcmp(nval->name, "DNS"))
{
if ( !strcmp( nval->value, host))
{
ok = 1;
break;
}
else if ( *nval->value == '*')
{
const char* const t = nval->value + 1;
if ( *t == '.')
{
const char* const h = strchr( host, '.');
if ( h && !strcmp( t, h))
{
ok = 1;
break;
}
}
}
}
}
sk_CONF_VALUE_pop_free(val, X509V3_conf_free);
}
此修复不处理 UTF-8 名称。为此,您可以查看处理通用名称的代码(搜索 NID_commonName)。