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
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:
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:
hs-tls/tls/Network/TLS/Handshake/Certificate.hs
Line 24 in 4cdbf9a
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 => eexistentials 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-exceptionand change things to throwAnnotatedExceptioncontaining TLSException (which also would not be an API break due to the compatiblefromExceptionofAnnotatedException).Would this approach be acceptable? I could schedule implementing this at work in the next few weeks if it's workable.
cc @parsonsmatt