我使用OpenSSL来加密一些硬件发送的电子邮件。但是,每当我尝试调用SSL_connect()时,我得到: SSL例程:SSL23_GET_SERVER_HELLO:未知协议
发送" EHLO"和" STARTTLS"我调用以下函数:
SSL_CTX *ctx = NULL;
SSL *ssl = NULL;
void CreateTLSSession(int sockfd)
{
printf("///////////////creating TLS Session/////////////////////\n");
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
ctx = SSL_CTX_new(SSLv23_client_method());
if (ctx == NULL)
{
printf("failed to initialize context\n");
return;
}
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
ssl = SSL_new(ctx);
if (!SSL_set_fd(ssl, sockfd))
{
printf("failed to bind to socket fd\n");
return;
}
if (SSL_connect(ssl) < 1)
{
ERR_print_errors_fp(stdout);
fflush(stdout);
printf("SSL_connect failed\n");
return;
}
}
我已尝试连接到:
我尝试过不同的端口,因为有关此SO的类似问题表明,此类错误通常与使用错误的SSL端口有关。
我在这里错过了什么吗?
更新:
所有其他方法(即TLSv1_1_method(),SSLv3_method()...)导致SSL3_GET_RECORD:版本号错误
更新:
我能够在wireshark上观察以下内容:
&#34; EHLO&#34;
&#34;在您的服务&#34;
&#34; STARTTLS&#34;
&#34;准备开始&#34;
- &gt;现在我调用上面的函数
无法读取的请求(已加密)
无法回复(加密)
- &GT; ERROR
答案 0 :(得分:3)
端口587和25上的SMTP服务器通常是纯文本,只有在初始SMTP对话框和客户端的STARTTLS命令之后才会切换到TLS。在纯文本套接字上尝试SSL_connect将失败。
答案 1 :(得分:1)
解决此问题的另一种方法可能是在Scott Gifford的sslclient
下运行您的C程序(请参阅http://www.superscript.com/ucspi-ssl/sslclient.html)。 sslclient将生成您的程序并打开到服务器的tcp连接,并将程序的标准输出管道传送到服务器,并将服务器的输出管道输出到您的程序的标准输入。他有一个用于TLS的修补版本,它将以纯文本方式启动连接,然后一旦双方同意STARTTLS,您的程序就可以通过向文件描述符写入命令来向sslcient发出信号以启用连接上的SSL加密目的。这样做的好处是你可以让sslclient完成所有繁重的工作,只要设置套接字和ssl等,你就可以专注于程序的核心功能。
答案 2 :(得分:0)
潜在的袜子是非阻塞的。通过使用select
并等待TLS握手完成,问题得以解决。