2015-01-20 188 views
8

上SSL_shutdown OpenSSL的文檔指出: 因此建議,要再次檢查SSL_shutdown(返回值),並調用SSL_shutdown(),如果雙向停機還不是第一個完整的(返回值呼叫是0)。處理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); 

回答

11

openssl是有點暗藝術。

首先,您引用的頁面有HTML-if返回值很糟糕。這裏的男人頁實際上說什麼:

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. 

如果您具有阻斷BIOS,東西都比較簡單。第一次通話時爲0意味着如果您需要雙向關機,則需要再次撥打SSL_shutdown。 1意味着你完成了。 -1意味着一個錯誤。在第二次通話中(只有當您返回0時才這樣做),然後啓動雙向關機。邏輯決定你不能再回到0(因爲它是一個阻塞的BIO並且已經完成了第一步)。 -1表示錯誤,1表示完成。

如果你有無阻塞BIOS,同樣適用,節省您需要經過整個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,但是如果在以正常方式繞過select()循環後得到SSL_ERROR_WANT_READSSL_ERROR_WANT_WRITE,並且只會按照如果您收到非SSL_ERROR_WANT_錯誤代碼(在這種情況下它會計算第一個SSL_shutdown)失敗),或者您獲得01返回。如果你得到1回報,你已經完成了。如果您得到0回報,並且您想要雙向關機,那麼您必須進行第二次呼叫,在該呼叫上您將再次檢查SSL_ERROR_WANT_READSSL_ERROR_WANT_WRITE並重試選擇;那應該不會返回1,但可能會返回0或出現錯誤。

不簡單。

+0

謝謝!非常感謝幫助。 – cmidi 2015-01-20 22:51:19