【问题标题】:Add OpenSSL Support in IOCP Client application在 IOCP 客户端应用程序中添加 OpenSSL 支持
【发布时间】:2016-02-29 11:54:45
【问题描述】:

我开发了向服务器发送消息的 IOCP 客户端应用程序。现在我想在其中添加 SSL 支持,以便使用 OpenSSL 连接启用 SSL 的服务器应用程序。

我已经使用

初始化 SSL
/* Load encryption & hashing algorithms for the SSL program */
SSL_library_init();

/* Load the error strings for SSL & CRYPTO APIs */
SSL_load_error_strings();

/* Create an SSL_METHOD structure (choose an SSL/TLS protocol version) */
meth = TLSv1_2_method();

/* Create an SSL_CTX structure */
ctx = SSL_CTX_new(meth);

if(ctx == NULL)
    return false;

SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, nullptr);

SSL_CTX_set_verify_depth(ctx,1);

初始化后,我们创建普通的 IOCP 工作线程,IOCP 套接字然后连接到 SSL 服务器套接字

            /* An SSL structure is created */
            ssl = SSL_new (ctx);

            RETURN_NULL(ssl);

            /* Assign the socket into the SSL structure (SSL and socket without BIO) */
            SSL_set_fd(ssl, Socket);

            /* Perform SSL Handshake on the SSL client */
            int     err;
            err = SSL_connect(ssl);
            if (err<1) 
            {
                err=SSL_get_error(ssl,err);
                printf("SSL error #%d in accept,program terminated\n",err);
            }

            RETURN_SSL(err);

            /* Informational output (optional) */
            printf ("SSL connection using %s\n", SSL_get_cipher (ssl));

            /* Get the server's certificate (optional) */
            X509            *server_cert;
            server_cert = SSL_get_peer_certificate (ssl);    

            if (server_cert != NULL)
            {
                printf ("Server certificate:\n");

                char  *str;
                str = X509_NAME_oneline(X509_get_subject_name(server_cert),0,0);
                //RETURN_NULL(str);
                printf ("\t subject: %s\n", str);
                free (str);

                str = X509_NAME_oneline(X509_get_issuer_name(server_cert),0,0);
                //RETURN_NULL(str);
                printf ("\t issuer: %s\n", str);
                free(str);

                X509_free (server_cert);

            }
            else
                printf("The SSL server does not have certificate.\n");

到服务器的 SSL 连接正常工作,我能够正确检索服务器证书详细信息。 现在我想通过 SSL Socket 向 SSL 服务器发送消息并接收来自服务器的响应。但是在我们的 IOCP 客户端应用程序中,我们使用 WSASend 和 WSARecv 进行数据交换。 如何使用 SSL_write/SSL_read 函数在 SSL 服务器上执行此操作?

请指导我这样做。


编辑日期:2016 年 3 月 1 日

我尝试在“err = SSL_connect(ssl);”之后为 SSL 套接字使用 BIO 对作为

bioIn = BIO_new_socket(this->Socket, BIO_NOCLOSE);
bioOut = BIO_new_socket(this->Socket, BIO_NOCLOSE);
SSL_set_bio(ssl, bioIn, bioIn);

然后尝试将消息长度发送到服务器

int err = SSL_write(ssl, PerIOHandle->Buffer, PerIOHandle->BufferLength);

一旦上述语句执行,服务器读取正确的消息长度并等待来自客户端的实际消息。 但是当我尝试使用上述相同的语句发送消息时,服务器 SSL_read 函数失败并返回 -1 代码。

请任何人帮我添加完整的 SSL 支持。

【问题讨论】:

    标签: windows ssl openssl winsock2 iocp


    【解决方案1】:

    正如您所发现的,您需要使用 OpenSSL IO 抽象 BIO。这使您可以将 OpenSSL 代码与套接字分开。您只需通过 BIO 推送数据,然后获取它们提供给您的数据并将您自己的写入操作发送到异步/IOCP 套接字。

    我早在 2002 年就为 Dr. Dobbs Journal 写过这篇文章,请参阅 here。本文重点介绍将 OpenSSL 与 MFC 的异步套接字一起使用,但如果您想将其与 IOCP 代码一起使用,思路是相同的。

    本文附带完整且有效的代码,您可以将其用作 IOCP 代码的基础。你一开始就连接 BIO 对,根本不使用 SSL_connect()。

    【讨论】:

    • 感谢您的回复,我已经浏览了您的示例代码,但从中我没有得到关于如何使用 SSL 初始化和 BIO 对的确切流程。您能否指导我如何挖掘您的代码以更好地理解它?另外,正如您所说,不要使用“SSL_connect()”,这是什么原因?我试过不使用它,但是与服务器的 SSL 连接没有完成。
    • 我刚刚测试了示例代码。您应该能够将 VC6 项目升级到任何更新的编译器,只需使用新的 IDE 打开它。然后按照文章中的说明为您的 Open SSL 路径调整项目。然后构建代码。运行它并将目标服务器更改为 www.google.com,因为 microsoft 示例服务器不再存在。单击连接,代码将连接到 google 并进行 SSL 握手。单击 SendRequest,您将发送一个 HTTP 请求。您应该能够通过在您感兴趣的 Open SSL 代码周围设置断点来进行跟踪。
    猜你喜欢
    • 2015-04-08
    • 2016-04-21
    • 2010-10-03
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-05
    相关资源
    最近更新 更多