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

WebSocket server only sends the first certificate in a certificate chain #1189

Closed
ptesavol opened this issue May 20, 2024 · 2 comments · Fixed by #1195
Closed

WebSocket server only sends the first certificate in a certificate chain #1189

ptesavol opened this issue May 20, 2024 · 2 comments · Fixed by #1195

Comments

@ptesavol
Copy link

Hi

This bug is preventing us from taking the node-datachannel WebSockets into use at Streamr.

The WebSocketServer of libdatachannel currently only sends the first certificate in the certificate chain to the client. This usually works in the case of browser clients, but causes the error "Error: unable to verify the first certificate" on nodejs clients, as the intermediate certificates of the chain are not sent.

Looking at the code, it seems that in the case of OpenSSL the reason for the bug is at

SSL_CTX_use_certificate(mCtx, x509);
where only one certificate is loaded into the context. According to the OpenSSL documentation "The rest of the certificates needed to form the complete certificate chain can be specified using the SSL_CTX_add_extra_chain_cert()" function.

@paullouisageneau
Copy link
Owner

This is not exactly a bug, only a limitation of how the WebSocket server certificate setting is currently designed: it loads the provided certificate and key with the Certificate generic wrapper and loads it in the context. The limitation is that it loads a single certificate if the file contains a certificate chain.

Therefore, it is not possible to simply call SSL_CTX_add_extra_chain_cert() because the certificate chain needs to be loaded first. Also SSL_CTX_add1_chain_cert() or SSL_CTX_set1_chain() should be use instead because SSL_CTX_add_extra_chain_cert() takes ownership of the certificate so it would crash as soon as the connection deletes it (the OpenSSL API is a huge mess).

Loading certificate chain with SSL_CTX_use_certificate_chain_file could be another option but performance wouldn't be good as the certificates would be reloaded for each incoming connection. This would require sharing the context, which comes at the cost of thread synchronization.

I think the correct way is to introduce a different wrapper to load the entire certificate chain into a STACK_OF(X509), while keeping the compatibility with other crypto libraries. I'll look into into it, but this is definitely more complicated than replacing a function call by another.

@paullouisageneau
Copy link
Owner

I added support for loading the chain with OpenSSL in the existing Certificate wrapper on #1195, since GnuTLS should support loading the chain out of the box with the existing code.

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 a pull request may close this issue.

2 participants