C SSL\u连接失败,出现SSL\u错误\u系统调用错误
openssl SSLConnect与我的SSLCLIENT发生奇怪的连接故障 我们正在尝试与服务器建立ssl连接。我们注意到SSL\U连接失败,错误代码为“SSL\U error\U SYSCALL” 为了进一步深入,我们尝试打印返回“scucess”“0”的strerror(errno) 然而,我只是想了解这个问题的确切原因 添加了SSL初始化和连接的代码段:: 请求一些指导:C SSL\u连接失败,出现SSL\u错误\u系统调用错误,c,ssl,openssl,C,Ssl,Openssl,openssl SSLConnect与我的SSLCLIENT发生奇怪的连接故障 我们正在尝试与服务器建立ssl连接。我们注意到SSL\U连接失败,错误代码为“SSL\U error\U SYSCALL” 为了进一步深入,我们尝试打印返回“scucess”“0”的strerror(errno) 然而,我只是想了解这个问题的确切原因 添加了SSL初始化和连接的代码段:: 请求一些指导: int setupSSL(int server){ int retVal = 0;
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;
}
intsetupssl(intserver){
int-retVal=0;
int errorStatus=0;
int-retryMaxCount=6;
静态int-sslInitContext=0;
如果(sslInitContext==0)
{
如果(InitCTX()!=0)
{
返回-1;
}
其他的
{
sslInitContext=1;
}
}
retVal=SSL\u set\u fd(SSL,服务器);/*附加套接字描述符*/
如果(返回值!=1)
{
/*执行连接*/
sprintf(debugBuf,“系统:套接字:无法设置ssl FD:%d%s\n”,retVal,strerror(retVal));
调试日志(调试日志、跟踪日志);
CloseSocket(服务器);
返回-1;
}
做
{
retVal=SSL_connect(SSL);
errorStatus=SSL\u get\u error(SSL,retVal);
开关(错误状态)
{
案例SSL\u错误\u无:
retVal=0;
打破
案例SSL\u错误\u需要\u读取:
案例SSL\u错误\u需要\u写入:
retVal=1;
打破
违约:
sprintf(debugBuf,“系统:SSL\U套接字:无法构建SSL会话(其他错误):%d%s\n”,errorStatus,strerror(errno));
调试日志(调试日志、跟踪日志);
CloseSocket(服务器);
返回-1;
}
sprintf(debugBuf,“系统:SSL\U套接字:正在进行的SSL连接:%d,剩余重试次数为%d\n”,errorStatus,retryMaxCount);
调试日志(调试日志、跟踪日志);
如果(返回)
{
结构时间值电视;
fd_集sockReadSet;
tv.tv_sec=2;
tv.tv_usec=0;
FD_ZERO(&sockReadSet);
FD_CLR(服务器和sockReadSet);
FD_集(服务器和sockReadSet);
retVal=select(服务器+1,&sockReadSet,NULL,NULL,&tv);
如果(返回值>=1)
{
retVal=1;
}
其他的
{
retVal=-1;
}
retryMaxCount--;
if(retryMaxCount)
我们正在尝试与服务器建立ssl连接。我们注意到ssl\u连接失败,错误代码为“ssl\u error\u SYSCALL”
如果另一方只是关闭连接,通常会出现这种情况。Microsoft SChannel会在许多握手问题上执行此操作,而不是发送TLS警报。这可能发生在协议无效或没有公共密码等问题上。如果您尝试与不讲TLS的服务器进行TLS握手,也可能发生这种情况此端口上的所有日志。查看服务器端的日志以查找问题
当然,它也可能有所不同,因此您可以检查errno以获得有关问题的更多详细信息。如果您执行数据包捕获以检查线路上发生的情况,也可能会有所帮助。最好是在客户端和服务器端执行此捕获,以确保没有防火墙这样的中间包篡改连接
还建议为新连接维护SSL上下文,还是应该销毁并重新初始化SSL上下文
上下文只是设置、证书等的集合,不受SSL连接本身的影响。您可以稍后或同时将其重新用于其他连接
在附加数据包捕获后编辑:
客户端和服务器之间的文件中有多个TCP连接,只有在一个TCP连接中,客户端才会尝试发起握手,即可以看到ClientHello。服务器关闭连接。有几件有趣的事情:
- TCP握手需要很长时间。服务器仅在接收到带有SYN+ACK的SYN后1.6秒后才进行响应。另外,如果两个地址都位于专用网络(192.168.0.0)中,则其他响应也需要800毫秒。这可能表示连接或VPN(这是关于卫星链路的延迟)速度较慢,可能需要一些中间盒(防火墙)使一切变慢或服务器速度非常慢
- 客户端发送TLS 1.0请求。可能是服务器将仅执行TLS 1.1+。某些TLS堆栈(请参见上文)仅在出现此类错误时关闭连接,而不是发送不受支持的协议警报。但鉴于服务器速度较慢,它也可能是旧的,并且仅支持SSL 3.0或更低版本
- 客户端不使用SNI扩展。越来越多的服务器需要此扩展,如果没有扩展,可能会直接关闭
如果不访问服务器,就很难知道到底发生了什么。我建议在服务器端查找错误消息,并使用诸如检查服务器要求等工具,即受支持的TLS版本、密码等
除此之外,客户机还提供危险的弱密码,如各种出口密码