我已经开发了将消息发送到服务器的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 Server套接字:

            /* 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套接字向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);


一旦执行了以上语句,服务器就会读取适当的消息长度并等待来自客户端的实际消息。
但是,当我尝试使用相同的上述语句发送消息时,则Server SSL_read函数将失败,返回值为-1。

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

最佳答案

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

我早在2002年就为《 Dobbs Journal》撰写了有关此内容的文章,请参见here。本文重点介绍将OpenSSL与MFC的异步套接字一起使用,但是如果您想将其与IOCP代码一起使用,则想法是相同的。

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

关于windows - 在IOCP客户端应用程序中添加OpenSSL支持,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35698891/

10-09 13:48