Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added function rustls_connection_last_error_msg #556

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

tomas-stejskal-abra
Copy link

Hello,

I'm using rustls-ffi for an experimental project to implement TLS in an ERP system written in Delphi. One challenge I've encountered is the lack of detailed error messages.

This patch allows me to obtain the last error message originating from rustl_connection_ functions.

Regards,
Tom Stejskal

@cpu
Copy link
Member

cpu commented Apr 1, 2025

Hi there, thanks for the patch.

Can you expand a little bit on the motivation? My assumption is that the various connection APIs already return a rustls_result that can be interrogated in your application at will to get an error message. I'm not clear yet on why it's helpful to have this managed as state in the connection.

@tomas-stejskal-abra
Copy link
Author

tomas-stejskal-abra commented Apr 1, 2025

Hi,

the problem is that from rustls_result or rustls_io_result you can't get the actual text of the original exception.
With the function rustls_error you can only get textual representation of the enumeration value.

The original exception message was for me very useful while debugging. It is also very useful for example in error dialogs, because instead of showing generic message like this:

invalid peer certificate: NotValidForName

I can get this message:

invalid peer certificate: certificate not valid for name "win11"; certificate is only valid for IpAddress(127.0.0.1) or DnsName("localhost")

As an example where the original exception message helped me a lot with debugging was the case of calling function rustls_connection_read_tls which returned rustls_io_result value 5.
The reason is this fragment:

            let mut reader = CallbackReader { callback, userdata };
            let n_read = match conn.read_tls(&mut reader) {
                Ok(n) => n,
                Err(e) => return rustls_io_result(e.raw_os_error().unwrap_or(EIO)),
            };

Instead of this generic EIO error I was able to get the information, that plaintext buffer is full, which was crucial for me.

@cpu
Copy link
Member

cpu commented Apr 1, 2025

the problem is that from rustls_result or rustls_io_result you can't get the actual text of the original exception.
With the function rustls_error you can only get textual representation of the enumeration value.

Ahh! Thank you, I understand now. We discussed this topic a bit in #375

I think the direction you're heading is similar to what Ctz proposed there:

I think my preferred option would for a win32-style "get last error" API, attached to each object that you could get an error from. rustls_result could continue to be an enum, but callers wanting additional information could call eg. rustls_result rustls_acceptor_last_error(struct rustls_acceptor *acceptor, rustls_str *error_string_out) or something.

@djc
Copy link
Member

djc commented Apr 1, 2025

But note that some types already store the last error (in order to fuse the state), so not sure just storing an extra field is the best solution here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants