使用我的SSLCLIENT与openssl SSLConnect发生奇怪的连接失败。
我们正在尝试与服务器建立ssl连接。我们注意到SSL_CONNECT失败,错误代码为“SSL_ERROR_SYSCALL”。
为了进一步深入,我们尝试打印strerror(errno),返回“scuccess”“0”。
但我只是想了解这个问题的确切原因
为SSL init和connect ::
添加了代码段请求一些指导:
int setupSSL(int server){
int retVal = 0;
int errorStatus = 0;
int retryMaxCount = 6;
static int sslInitContext=0;
if(sslInitContext == 0)
{
if(InitCTX() != 0)
{
return -1;
}
else
{
sslInitContext=1;
}
}
retVal = SSL_set_fd(ssl, server); /* attach the socket descriptor */
if ( retVal != 1 )
{
/* perform the connection */
sprintf(debugBuf,"SYSTEM:SOCKET:Could not set ssl FD: %d %s\n",retVal,strerror(retVal));
debug_log(debugBuf,TRACE_LOG);
CloseSocket(server);
return -1;
}
do
{
retVal = SSL_connect(ssl);
errorStatus = SSL_get_error (ssl, retVal);
switch (errorStatus)
{
case SSL_ERROR_NONE:
retVal = 0;
break;
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
retVal = 1;
break;
default:
sprintf(debugBuf,"SYSTEM:SSL_SOCKET:Could not build SSL session(Other error): %d %s\n",errorStatus,strerror(errno));
debug_log(debugBuf,TRACE_LOG);
CloseSocket(server);
return -1;
}
sprintf(debugBuf,"SYSTEM:SSL_SOCKET:SSL CONNECTION Under PROGRESS: %d with remaining retries %d\n",errorStatus,retryMaxCount);
debug_log(debugBuf,TRACE_LOG);
if (retVal)
{
struct timeval tv;
fd_set sockReadSet;
tv.tv_sec = 2;
tv.tv_usec = 0;
FD_ZERO(&sockReadSet);
FD_CLR(server, &sockReadSet);
FD_SET(server,&sockReadSet);
retVal = select(server+1, &sockReadSet, NULL, NULL, &tv);
if (retVal >= 1)
{
retVal = 1;
}
else
{
retVal = -1;
}
retryMaxCount--;
if (retryMaxCount <= 0 )
break;
}
}while(!SSL_is_init_finished (ssl) && retVal == 1);
cert = SSL_get_peer_certificate(ssl);
if(cert == NULL)
{
debug_log("SYSTEM:SSL_SOCKET:Unable to retrive server certificate\n",TRACE_LOG);
CloseSocket(server);
return -1;
}
if(SSL_get_verify_result(ssl)!=X509_V_OK)
{
debug_log("SYSTEM:SSL_SOCKET:Certificate doesn't verify\n",TRACE_LOG);
CloseSocket(server);
return -1;
}
/*X509_NAME_get_text_by_NID (X509_get_subject_name (cert), NID_commonName, peer_CN, 256);
if(strcasecmp(peer_CN, cnName)){
debug_log("SYSTEM:SSL_SOCKET:Common name doesn't match host name\n",TRACE_LOG);
return -1;
}*/
return 0;
// LoadCertificates(ctx, CertFile, KeyFile);
}
int InitCTX(void)
{
int errorStatus = 0;
static int isSslInit = 1;
if(isSslInit)
{
OpenSSL_add_all_algorithms();/* Load cryptos, et.al. */
SSL_load_error_strings();/* Bring in and register error messages */
if(SSL_library_init() < 0)
{
debug_log("SYSTEM:SSL_SOCKET:Could not initialize the OpenSSL library\n",TRACE_LOG);
return -1;
}
method = TLSv1_client_method();
isSslInit=0;
}
ctx = SSL_CTX_new(method);/* Create new context */
if ( ctx == NULL)
{
debug_log("SYSTEM:SSL_SOCKET:Unable to create a new SSL context structure\n",TRACE_LOG);
//sprintf(debugBuf,"SYSTEM:SSL_SOCKET:Unable to create a new SSL context structure: %d %s\n",errorStatus,strerror(retVal));
//debug_log(debugBuf,TRACE_LOG);
return -1;
}
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
if (SSL_CTX_use_certificate_file(ctx,CertFile, SSL_FILETYPE_PEM) <= 0)
{
SSL_CTX_free(ctx);
ctx = NULL;
debug_log("SYSTEM:SSL_SOCKET:Error setting the certificate file.\n",TRACE_LOG);
return -1;
}
/* Set the list of trusted CAs based on the file and/or directory provided*/
if(SSL_CTX_load_verify_locations(ctx,CertFile,NULL)<1)
{
SSL_CTX_free(ctx);
ctx = NULL;
debug_log("SYSTEM:SSL_SOCKET:Error setting verify location.\n",TRACE_LOG);
return -1;
}
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);
SSL_CTX_set_timeout (ctx, 300);
ssl = SSL_new(ctx); /* create new SSL connection state */
if(ssl == NULL)
{
sprintf(debugBuf,"SYSTEM:SOCKET:SSL:Unable to create SSL_new context\n");
debug_log(debugBuf,DEBUG_LOG);
if(ctx != NULL)
SSL_CTX_free(ctx);
return -1;
}
return 0;
}
还建议为新连接维护SSL上下文,还是应该销毁并重新启动ssl上下文?
添加了PCAP信息:
https://drive.google.com/file/d/0B60pejPe6yiSUk1MMmI1cERMaFU/view?usp=sharing
客户:198.168.51.10(198.168.51.10),服务器:192.168.96.7(192.168.96.7)
答案 0 :(得分:5)
我们正在尝试与服务器建立ssl连接。我们注意到SSL_CONNECT失败并显示错误代码&#34; SSL_ERROR_SYSCALL&#34;。
如果另一方只是关闭连接,通常就是这种情况。 Microsoft SChannel在许多类型的握手问题上执行此操作,而不是发回TLS警报。对于无效协议或没有通用密码等问题,可能会发生这种情况。如果您尝试与此端口上根本不说TLS的服务器进行TLS握手,也会发生这种情况。查看服务器端的日志以查找问题。
当然它也可以是不同的东西,所以你可以检查errno以获得有关问题的更多细节。如果您进行数据包捕获以检查线路上发生了什么,这也可能有所帮助。最好是在客户端和服务器端进行此捕获,以确保没有像防火墙这样的中间件篡改连接。
还建议为新连接维护SSL上下文,还是应该销毁并重新启动ssl上下文?
上下文只是设置,证书等的集合,不受SSL连接本身的影响。您可以稍后或同时将其重新用于其他连接。
在附加数据包捕获后编辑:
客户端和服务器之间的文件中有多个TCP连接,并且只有一个客户端尝试启动握手,即可以看到ClientHello。服务器关闭连接。一些有趣的事情:
如果没有访问服务器,很难知道到底发生了什么。我建议在服务器端查找错误消息,并使用SSLyze等工具检查服务器的要求,即支持的TLS版本,密码等。
除了客户端提供危险的弱密码,如各种EXPORT密码。这看起来像是一个相当古老的OpenSSL版本的默认值。