2015-01-20 9 views
8

La documentazione di openssl su SSL_shutdown afferma che: Si consiglia pertanto di verificare il valore restituito di SSL_shutdown() e richiamare SSL_shutdown() di nuovo, se lo spegnimento bidirezionale non è ancora completo (valore di ritorno del primo la chiamata è 0).Gestione SSL_shutdown correttamente

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

Ho un frammento di codice sotto dove controlla la presenza di valore restituito 0 da SSL_shutdown e chiamo ancora, che ho utilizzato. La mia domanda è, va bene ignorare il valore di ritorno di SSL_shutdown nella seconda chiamata o dovremmo continuare a riprovare SSL_shutdown fino a quando non viene restituito 1 (spegnimento bidirezionale completo).

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

risposta

11

openssl è un po 'un arte oscura.

In primo luogo, la pagina a cui si fa riferimento ha un valore HTML restituito male. Ecco ciò che l'uomo-page realtà dice:

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. 

Se è stato il blocco del BIOS, le cose sono relativamente semplici. Uno 0 alla prima chiamata significa che è necessario chiamare di nuovo SSL_shutdown se si desidera uno spegnimento bidirezionale. A 1 significa che hai finito. A -1 indica un errore. Alla seconda chiamata (che si fa solo se si ha uno 0 indietro), viene avviato uno spegnimento bidirezionale. La logica impone di non riuscire a ottenere di nuovo lo 0 (perché è un BIO bloccante e avrà completato il primo passo). Un -1 indica un errore e un 1 indica il completamento.

Se si dispone di BIOS non-bloccanti, lo stesso vale, salvo per il fatto che devi passare attraverso l'intero SSL_ERROR_WANT_READ e SSL_ERROR_WANT_WRITE trafila, cioè .:

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. 

in modo da avere due livelli di ripetizione. Chiama SSL_shutdown la "prima" volta, ma ripeti se ricevi SSL_ERROR_WANT_READ o SSL_ERROR_WANT_WRITE dopo aver aggirato il ciclo select() nel modo normale, e conta solo il "primo" SSL_shutdown come fatto se ottieni un codice di errore non SSL_ERROR_WANT_ (nel qual caso non riuscito), o si ottiene un ritorno 0 o 1. Se ottieni un ritorno 1, hai finito. Se si ottiene un ritorno 0 e si desidera uno spegnimento bidirezionale, è necessario effettuare la seconda chiamata, sulla quale sarà necessario verificare per SSL_ERROR_WANT_READ o SSL_ERROR_WANT_WRITE e riprovare selezionare; che non dovrebbe restituire 1, ma potrebbe restituire 0 o un errore.

Non semplice.

+0

Grazie! aiuto molto apprezzato. – cmidi

Problemi correlati