【发布时间】:2017-10-30 18:39:51
【问题描述】:
为了理解SSL/TLS,我在Windows-7上下载了OpenSSL-1.0.2k,并用Cygwingcc64 bit编译器编译。我从OpenSSL server/client example in c 中获取了off-the-shelf 的服务器/客户端示例,并使用cygwin gcc 编译。第一次编译就成功了。我使用以下命令从cmd 执行服务器和客户端。
(Server) D:\>ssl-server.exe 5000
(Client) D:\>ssl-client.exe 127.0.0.1 5000
客户端没有任何响应就退出,但另一方面,服务器显示它已建立连接,例如;
Connection: 127.0.0.1:50475
并无限等待下一行。
然后我开始调试服务器端,发现过程void Servlet(SSL* ssl)中的SSL_accept()返回了-1的值,这是意料之外的。我从OpenSSLopenSSL DOC咨询了文档;
TLS/SSL 握手不成功,因为在协议级别发生了致命错误或发生了连接失败。关机不干净。也可能发生需要继续非阻塞 BIO 操作的操作。使用返回值 ret 调用 SSL_get_error() 以找出原因。
SSL_get_error() 返回SSL_ERROR_SYSCALL。我在这个电话之后检查了errno 的值,我看到了no error。 Servlet 方法的完整代码如下。其余代码与链接相同。
void Servlet(SSL* ssl) /* Serve the connection -- threadable */
{ char buf[1024];
char reply[1024];
int sd, bytes;
const char* HTMLecho="<html><body><pre>%s</pre></body></html>\n\n";
int ret;
ret = SSL_accept(ssl); /* do SSL-protocol accept */
if ( ret == -1 )
{
// printf(" SSL_accept() returned -1\n");
switch(SSL_get_error(ssl, ret) )
{
case SSL_ERROR_SYSCALL:
perror("errno");
break;
default:
printf( "default" );
break;
}
exit(-1);
}
else if ( ret == 0)
{
printf(" SSL_accept() returned 0\n");
exit(-1);
}
else if ( ret == 1) // The TLS/SSL connection has been established.
{
ShowCerts(ssl); /* get any certificates */
bytes = SSL_read(ssl, buf, sizeof(buf)); /* get request */
if ( bytes > 0 )
{
buf[bytes] = 0;
printf("Client msg: \"%s\"\n", buf);
sprintf(reply, HTMLecho, buf); /* construct reply */
SSL_write(ssl, reply, strlen(reply)); /* send reply */
}
else
ERR_print_errors_fp(stderr);
}
sd = SSL_get_fd(ssl); /* get socket connection */
SSL_free(ssl); /* release SSL state */
close(sd); /* close connection */
}
【问题讨论】:
-
那么
SSL_get_error()的值是多少? -
switch-case进入默认情况。printf("default\n");从我的代码中执行。printf("ret: %i\n", ret);switch之前的行输出-1 -
所以你得到了SSL_ERROR_SYCALL,现在你必须找到
errno的值,或者调用perror()。这都是有据可查的。所有这些信息都应该已经包含在问题中了。 -
你已经用你能想到的一切编辑了你的问题除了我现在问了三四次,从一个多小时前开始。现在是您停止猜测和胡闹的时候了,开始注意这里告诉您的内容以及要求您提供的内容。
-
您正在运行您无休止且毫无意义地摆弄的代码,因此与原始代码相比,它可能无法识别。您需要为 SSL_ERROR_SYSCALL 添加一个案例并在其中调用
perror("SSL_accept")。我认为这也是微不足道的。我注意到,两个小时后,我们仍然没有比两个小时前更接近解决实际问题。