2016-02-29 104 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代碼周圍設置斷點來追蹤。 –