簡體   English   中英

正確處理 SSL_shutdown

[英]Handling SSL_shutdown correctly

SSL_shutdown上的 OpenSSL 文檔指出:

因此,如果雙向關閉尚未完成(第一次調用的返回值為 0),建議檢查SSL_shutdown()的返回值並再次調用SSL_shutdown() )。

https://www.openssl.org/docs/ssl/SSL_shutdown.html

我在下面有一個代碼片段,我在其中檢查SSL_shutdown返回值 0 並再次調用它,我一直在使用它。 我的問題是,在第二次調用時忽略SSL_shutdown的返回值是否可以,或者我們應該繼續重試SSL_shutdown直到返回 1(雙向關閉完成)。

int r = SSL_shutdown(ssl);
//error handling here if r < 0 
if(!r)
{
    shutdown(fd,1);
    SSL_shutdown(ssl); //how should I handle return value and error handling here is it required?? 
}
SSL_free(ssl);
SSLMap.erase(fd);
shutdown(fd,2);
close(fd);

openssl有點黑暗藝術。

首先,您引用的頁面對返回值進行了 HTML 化處理。 這是手冊頁的實際內容

  RETURN VALUES

   The following return values can occur:

   0   The shutdown is not yet finished. Call SSL_shutdown() for a second
       time, if a bidirectional shutdown shall be performed.  The output
       of SSL_get_error(3) may be misleading, as an erroneous
       SSL_ERROR_SYSCALL may be flagged even though no error occurred.

   1   The shutdown was successfully completed. The "close notify" alert
       was sent and the peer's "close notify" alert was received.

   -1  The shutdown was not successful because a fatal error occurred
       either at the protocol level or a connection failure occurred. It
       can also occur if action is need to continue the operation for non-
       blocking BIOs.  Call SSL_get_error(3) with the return value ret to
       find out the reason.

如果您有阻塞 BIO,事情就相對簡單了。 第一次調用時為 0 意味着如果您想要完全雙向關閉,則需要再次調用SSL_shutdown 基本上這意味着您發送了 close_notify 警報但還沒有回復)。 1 表示您之前收到了來自其他對等方的 close_notify 警報,並且您完全完成了。 -1 表示不可恢復的錯誤。 在第二次調用時(只有在返回 0 時才這樣做),然后啟動雙向關閉(即現在等待對方向您發送“close_notify”警報)。 邏輯決定你不能再次得到 0(因為它是一個阻塞的 BIO 並且已經完成了第一步)。 -1 表示錯誤,1 表示完成成功。

如果你有非阻塞 BIO,同樣的“可能 0 然后 1”返回值適用,除了你需要通過整個SSL_ERROR_WANT_READSSL_ERROR_WANT_WRITE的事實,即:

   If the underlying BIO is non-blocking, SSL_shutdown() will also return
   when the underlying BIO could not satisfy the needs of SSL_shutdown()
   to continue the handshake. In this case a call to SSL_get_error() with
   the return value of SSL_shutdown() will yield SSL_ERROR_WANT_READ or
   SSL_ERROR_WANT_WRITE. The calling process then must repeat the call
   after taking appropriate action to satisfy the needs of SSL_shutdown().
   The action depends on the underlying BIO. When using a non-blocking
   socket, nothing is to be done, but select() can be used to check for
   the required condition. When using a buffering BIO, like a BIO pair,
   data must be written into or retrieved out of the BIO before being able
   to continue.

所以你有兩個級別的重復。 你叫SSL_shutdown “第一”時間,但重復,如果你得到SSL_ERROR_WANT_READSSL_ERROR_WANT_WRITE繞來繞去后select()循環以正常的方式,只算“第一” SSL_shutdown為已完成,如果你得到一個非SSL_ERROR_WANT_錯誤代碼(其中如果失敗),或者您會得到01回報。 如果你得到1回報,你就完成了。 如果返回0 ,並且想要雙向關閉,則必須進行第二次調用,再次調用時需要檢查SSL_ERROR_WANT_READSSL_ERROR_WANT_WRITE試選擇; 不應返回1 ,但可能返回 0 或錯誤。

不簡單。

文檔中的更多注釋:在第一次調用SSL_shutdown並返回“0”之后,您可以選擇調用SSL_read而不是SSL_shutdown (以防對等方仍在該 SSL 套接字上向您發送任何數據),並且,我猜測,“希望”他們最終會從他們身邊向您發送一條關閉消息,以沖洗管道。

此外,如果您計划在關閉完成后“無論如何”關閉套接字,您可以完全跳過對SSL_shutdown的第二次調用(“0 然后 1”的“1”),然后繼續關閉套接字,內核應該注意丟棄“現在被忽略”的 close_notify 警報,大概他們應該發送......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM