在IOCP客户端应用程序中添加OpenSSL支持

时间:2016-02-29 11:54:46

标签: windows ssl openssl winsock2 iocp

我开发了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日

在&#34; err = SSL_connect(ssl);&#34;&#34; err = SSL_connect(ssl)之后,我尝试将BIO对用于SSL套接字;&#34;如

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支持。

1 个答案:

答案 0 :(得分:0)

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

我在2002年为Dobbs Journal博士写过这篇文章,见here。本文重点介绍如何将OpenSSL与MFC的异步套接字一起使用,但如果要将其与IOCP代码一起使用,这些想法是相同的。

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