Skip to content

Provide more information in certificate validation failures and other exceptions #494

Description

@lf-

Hi! We have been debugging an issue in production where a certificate validation fails on a connection. It would be really helpful to be able to have the contents of the offending certificate in the logs as PEM or so, so that we don't have to reproduce the problem to be able to get any more ideas as to why the validation is failing.

Currently what the library does is this:

InternalException (HandshakeFailed (Error_Protocol “certificate has unknown CA” UnknownCa))

This is generated by this code, which is called by other code that does have the certificate in question. However, the error types don't have more than the TLS RFC's error code number in them. This is reasonable enough and ensures errors are nice and consistent with other libraries, but it does mean that it's hard to add contextual metadata for specific error types:

throwCore $ Error_Protocol "certificate has unknown CA" UnknownCa

I would like to fix this issue so that future issues with TLS connections can return richer diagnostics when they are reported. It seems like it might be reasonable to implement a way of adding flexible contextual information to exceptions where available. Currently it seems that TLSException is intended to store some idea of what state the connection was in when the exception occurred, but the state of the connection is not the only meaningful information that could be reported; the contents of failing certificates are just one example of contextual information that could be meaningfully available. Also, changing TLSException to add more context is an API break, and it seems prudent to use some kind of solution here that allows for improving errors without breaking API for each improvement.

One possible approach API-wise is to do something similar to annotated-exception where exceptions have a list of Show e, Typeable e => e existentials which can then be either printed or pulled out in a structured manner, while not having strict constraints of what must be present or not.

In particular, my idea is to extend TLSException with such an annotations list on variants where there is a TLSError, though it could also be reasonable to do it inside of TLSError itself. This could, I think, be done without breaking API by using PatternSynonyms.

Alternatively, it would be possible to just depend on annotated-exception and change things to throw AnnotatedException containing TLSException (which also would not be an API break due to the compatible fromException of AnnotatedException).

Would this approach be acceptable? I could schedule implementing this at work in the next few weeks if it's workable.

cc @parsonsmatt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions