Tratamento de erros do OpenSSL

Esta é a forma correcta de lidar com erros no OpenSSL? E qual é a diferença entre SSL_get_error e ERR_get_error? Os documentos são bastante vagos a este respeito.

int ssl_shutdown(SSL *ssl_connection)
{
    int rv, err;
    ERR_clear_error();
    rv = SSL_shutdown(ssl_connection);

    if (rv == 0)
        SSL_shutdown(ssl_connection);

    if (rv < 0)
    {
        err = SSL_get_error(ssl_connection, rv);

        if (err == SSL_ERROR_SSL)
            fprintf(stderr, "%s\n", ERR_error_string(ERR_get_error(), NULL));

        fprintf(stderr, "%s\n", SSL_state_string(ssl_connection));

        return 1;
    }

    SSL_free(ssl_connection);
    return 0;
}
Author: Red, 2016-06-23

2 answers

Ssl_get_ Erro:

O Ssl_get_ Error () devolve um código do resultado (adequado para o botão C "switch" declaração) para uma chamada anterior para SSL_connect (), Ssl_acept (), Ssl_ do_ handshake(), SSL_read(), SSL_peek (), ou SSL_write () no ssl. O o valor devolvido por essa função TLS/SSL I / O deve ser passado para Ssl_get_ error () no parâmetro ret.

Erro:

Err_get_ Error () devolve o código de erro mais antigo do tópico erro coloca em fila e remove o item. Esta função pode ser chamada repetidamente até que não haja mais códigos de erro para retornar.

Então este último é para uso mais geral e aqueles não devem ser usados em conjunto, porque:

A fila de erros do tópico actual deverá estar vazia antes de a operação TLS/SSL I / O ser tentada, ou o Ssl_get_ Error() não irá funcionar de forma fiável.

Por isso, terá de ler todos os erros usando o Err_get_ ERROR e lidar com eles (ou ignorá-los pela remoção como você fez na sua amostra de código com {[[0]}) e, em seguida, executar a operação IO. A sua abordagem parece correcta, embora não possa verificar todos os aspectos por mim neste momento.

Consulte esta resposta e Este post para mais informações.

Editar: de acordo com este tutorial, as rotinas BIO_ podem gerar um erro e afectar a fila de erros:

O terceiro campo é o nome do pacote que gerou o erro, tais como " BIO routines " or "bignum routines".

 2
Author: Jezor, 2017-05-23 12:16:26

E qual é a diferença entre SSL_get_error e ERR_get_error?

Há duas partes lógicas para o OpenSSL. A primeira é a biblioteca SSL, libssl.a (e libssl.so), e inclui as coisas relacionadas com a comunicação. A segunda é a biblioteca de criptografia, libcrypto.a (e libcrypto.so), e inclui grandes números, configuração, entrada/saída, etc.

libssl.a depende de libcrypto.a, e é por isso que o comando link é ordenado como -lssl -lcrypto.

Usa SSL_get_error para recuperar a maioria erros da biblioteca de porção SSL, e você usa ERR_get_error para obter erros não na Parte SSL da biblioteca.


Esta é a forma correcta de lidar com erros no OpenSSL?

O código que mostraste está mais próximo de "Como é que se desliga um 'socket' de SSL " {[[28]}. Em última análise, as girações controlam dois casos. A primeira é uma conexão meio aberta, quando o cliente desliga sem enviar a mensagem de notificação de Fecho. O segundo é o comportamento do seu programa ao enviar a mensagem de notificação de Fecho.

É difícil responder "está correcto" porque não sabemos o comportamento que quer. Se você não se importa se a notificação for enviada, então acredito que você só precisa ligar uma vez, independentemente do que o cliente faz.
 4
Author: jww, 2016-06-23 06:52:14