2016-02-29 67 views
0

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

我使用

/* 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); 

初始化后,我们建立正常完成端口工作者线程初始化SSL,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

03月01日我曾尝试使用SSL套接字BIO对后 “ERR =所以SSL_connect(SSL);”作为

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

回答

0

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

我在2002年写了关于Dr. Dobbs Journal的文章,请参阅here。本文重点介绍如何将OpenSSL与MFC的异步套接字一起使用,但如果您想将它与IOCP代码结合使用,这些想法是相同的。

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

+0

感谢您的回复, 我已经通过您的示例代码,但从我没有得到如何使用SSL初始化和BIO对的确切流程。 你能指导我如何通过你的代码挖掘更好地理解它吗? 也如你所说不要使用“SSL_connect()”,它的原因是什么? 我曾尝试不使用它,但未完成到服务器的SSL连接。 –

+0

我刚刚测试了示例代码。您应该能够通过简单地使用新的IDE打开它,将VC6项目升级到任何较新的编译器。然后按照文章中的说明为您的Open SSL路径调整项目。代码然后建立。运行它并将目标服务器更改为www.google.com,因为microsoft示例服务器不再存在。点击连接,代码将连接到谷歌并执行SSL握手。点击SendRequest,你会发送一个HTTP请求。您应该能够通过在您感兴趣的Open SSL代码周围设置断点来追踪。 –