Better error handling for SSL

This commit is contained in:
2022-05-06 18:25:15 -04:00
parent c3e4588afc
commit d6aa216505
4 changed files with 33 additions and 41 deletions

View File

@@ -278,7 +278,9 @@ class Driver {
} else if (error == SSL_ERROR_WANT_WRITE) { } else if (error == SSL_ERROR_WANT_WRITE) {
chan.ready_on_pollout = true; chan.ready_on_pollout = true;
} else { } else {
close_channel(chan, drvssl::errors_string()); std::string error = drvssl::error_string();
if (error == "") error = "unknown error";
close_channel(chan, error);
} }
} }
@@ -349,7 +351,7 @@ class Driver {
} }
void advance_channel(ChanInfo &chan) { void advance_channel(ChanInfo &chan) {
drvssl::assert_errors_empty(); drvssl::clear_all_errors();
switch (chan.state) { switch (chan.state) {
case CHAN_PLAINTEXT: case CHAN_PLAINTEXT:
advance_plaintext(chan); advance_plaintext(chan);
@@ -367,7 +369,6 @@ class Driver {
assert(false); assert(false);
break; break;
} }
drvssl::assert_errors_empty();
} }
void handle_socket_input_output() { void handle_socket_input_output() {
@@ -527,7 +528,6 @@ class Driver {
ssl_client_insecure_ctx_.reset(drvssl::new_context(SSL_VERIFY_NONE)); ssl_client_insecure_ctx_.reset(drvssl::new_context(SSL_VERIFY_NONE));
ssl_load_certificate_authorities(ssl_client_secure_ctx_.get()); ssl_load_certificate_authorities(ssl_client_secure_ctx_.get());
drvssl::ctx_load_dummy_cert(ssl_server_ctx_.get()); drvssl::ctx_load_dummy_cert(ssl_server_ctx_.get());
drvssl::assert_errors_empty();
handle_lua_source(); handle_lua_source();
recorder_.drv_invoke_event_init(argc, argv); recorder_.drv_invoke_event_init(argc, argv);

View File

@@ -92,6 +92,7 @@ static SOCKET open_connection(const char *host, const char *port, std::string &e
if (sock <= 0) goto error_errno; if (sock <= 0) goto error_errno;
set_nonblocking(sock); set_nonblocking(sock);
status = connect(sock, goodaddr->ai_addr, goodaddr->ai_addrlen); status = connect(sock, goodaddr->ai_addr, goodaddr->ai_addrlen);
if ((status != 0) && (errno != EINPROGRESS)) goto error_errno; if ((status != 0) && (errno != EINPROGRESS)) goto error_errno;
@@ -220,7 +221,7 @@ static int console_read(char *bytes, int nbytes) {
} }
static void ssl_load_certificate_authorities(SSL_CTX *ctx) { static void ssl_load_certificate_authorities(SSL_CTX *ctx) {
SSL_CTX_set_default_verify_paths(ctx); assert(SSL_CTX_set_default_verify_paths(ctx) == 1);
} }
static void disable_randomization(int argc, char *argv[]) { static void disable_randomization(int argc, char *argv[]) {
@@ -259,7 +260,8 @@ int main(int argc, char **argv)
{ {
disable_randomization(argc, argv); disable_randomization(argc, argv);
enable_tty_raw(); enable_tty_raw();
OPENSSL_init_ssl(0, NULL); assert(OPENSSL_init_ssl(0, NULL) == 1);
drvssl::clear_all_errors();
SourceDB::register_lua_builtins(); SourceDB::register_lua_builtins();
Driver driver; Driver driver;
return driver.drive(argc, argv); return driver.drive(argc, argv);

View File

@@ -61,46 +61,36 @@ const char *dummy_key =
"HcKc9a4WXhC7yu79e5BnKWltHXY=\n" "HcKc9a4WXhC7yu79e5BnKWltHXY=\n"
"-----END PRIVATE KEY-----\n"; "-----END PRIVATE KEY-----\n";
std::string errors_string(bool lastonly) { std::string error_string() {
std::string err; // Get the last code.
const char *file, *data; int code = 0;
int line, flags;
// const char *func;
while (true) { while (true) {
// Newer versions of the SSL API support this. int icode = ERR_get_error();
// unsigned long code = if (icode == 0) break;
// ERR_get_error_all(&file, &line, &func, &data, &flags); code = icode;
// Older versions of the SSL API support this. }
unsigned long code =
ERR_get_error_line_data(&file, &line, &data, &flags); // Fetch and clear errno.
if (code == 0) break; int terrno = errno;
std::string reason; errno = 0;
if (code != 0) {
const char *rc = ERR_reason_error_string(code); const char *rc = ERR_reason_error_string(code);
if (rc != nullptr) { if (rc != nullptr) {
reason = rc; return rc;
} else { } else {
reason = "sys:" + strerror_str(ERR_GET_REASON(code)); return strerror_str(ERR_GET_REASON(code));
}
if (err.empty() || lastonly) {
err = reason;
} else {
err = err + ", " + reason;
}
if ((data != nullptr) && (data[0] != 0)) {
err = err + " " + data;
} }
} else if (terrno != 0) {
return strerror_str(terrno);
} else {
return "";
} }
return err;
} }
void assert_errors_empty() { void clear_all_errors() {
int code = ERR_peek_error(); ERR_clear_error();
if (code != 0) { errno = 0;
std::cerr << "SSL should not have errors at this point." << std::endl;
ERR_print_errors_fp(stderr);
exit(1);
}
} }
SSL_CTX *new_context(int verify) { SSL_CTX *new_context(int verify) {

View File

@@ -46,14 +46,14 @@ struct ErrClearErrorOnExit {
} }
}; };
std::string errors_string(bool lastonly = true); // Return the OpenSSL error as a string.
void assert_errors_empty(); std::string error_string();
void clear_all_errors();
SSL_CTX *new_context(int verify); SSL_CTX *new_context(int verify);
void ctx_load_dummy_cert(SSL_CTX *ctx); void ctx_load_dummy_cert(SSL_CTX *ctx);
void ctx_load_cert_from_directory(SSL_CTX *ctx, const std::string &dir); void ctx_load_cert_from_directory(SSL_CTX *ctx, const std::string &dir);
} // namespace drvssl } // namespace drvssl
#endif // DRIVER_SSL_HPP #endif // DRIVER_SSL_HPP