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;
}
2 answers
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".
Há duas partes lógicas para o OpenSSL. A primeira é a biblioteca SSL,E qual é a diferença entre SSL_get_error e ERR_get_error?
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.