Closed elf-bot closed 3 years ago
Imagine we had a flag on each trust anchor indicating whether it was supposed to be a normal CA certificate or a self-signed end-entity certificate. Then on any such trust anchors, we could skip this check. I would be happy to review a PR that adds such a mechanism with appropriate tests.
I sent a PR (#127) adding support for self-signed certificates using the mechanism proposed by @briansmith
@briansmith Have you got any feedback, or is there anything I can do to help #127 get merged?
wow I blocked here, what the hell, I just want a TLS tunnel with full self signed certificate... I really need to make a root and sign it for nothing ?
One of the original ideas I had for webpki was to support self-signed certificates as described above. The idea was implement roughly what web browsers do with respect to "certificate error exceptions." However, given all the other things that need to be done, I think we have to be realistic about the prioritization of this feature. In particular, I think we should first focus on correctly implementing and verifying the correctness of the real, correct (web) PKI semantics, and de-prioritize other things. So, I'm just going to close this. Once we're past 1.0 we might reconsider.
Also, as far as I know, most users of this webpki crate are using it through Rustls. If you look in the Rustls issue tracker, you can see a relatively recent discussion about making it possible to implement alternate certificate validation that doesn't depend on webpki, and such an alternative mechanism was implemented in Rustls. So now you can use Rustls and plug in your own certificate processing to get the semantics you need.
We're running into this with self-signed certificates generated by LND that are accepted by OpenSSL, but not rustls
/webpki
. We don't have an in-depth understanding of the relevant specs, and don't fully understand why exactly webpki
rejects the certificates.
We'd like to understand the situation better so we can make LND generate certificates that work with both rustls
and OpenSSL. Is the cause of the different behavior of webpki
and OpenSSL that OpenSSL will accept a self-signed end-entity certificate to be added as a root certificate, which makes it trust servers that present that certificate, but this isn't spec-complaint, so webpki
doesn't do this?
I created an issue in the lnd
repo, and they mentioned that they had run into similar problems in the past, which they had fixed by adding the Extended Key Usage value serverAuth
to the certificate. Is this a spec-complient way of getting this to work, or is it OpenSSL-specific?
@casey using webpki with LND was the original motivation for the PR I made which is linked above. It was never merged.
LND's self-signed certs are not invalid in any way according to any spec that I'm aware of. webpki just doesn't support trusting self signed certs.
You can apply the linked patch to webpki, or you can replace LND's certs with certs from a CA (and add that CA as a root for webpki if it's not an existing trusted one). The latter approach is what I ended up doing since I don't want to maintain a fork of webpki.
You can also bypass webpki. For example, if using rustls, set your own certificate verifier.
@jbg Ahhh, I see. Thank you for clarifying!
LOL, I had the same problem also with lnd
and I managed to figure it out. I have published my own lnd
client library based on tonic
.
Not sure if just bytewise comparing of the certificate is good idea but at least I don't see any way it could be insecure. If anyone has pointers I'd appreciate any advice.
@Kixunil Great minds think alike!
We were doing the same thing, just making sure that the certificate that the server presented was the same certificate that the user presented. Aside from not handling certificate expiration, we don't know of any security issues when doing so, but to be cautious, we switched to using OpenSSL instead of webpki
.
This is the issue we opened in the rustls
repo: https://github.com/ctz/rustls/issues/772#issue-933122221
In case you're interested, here's where we use OpenSSL with tonic.
Thanks for hints! Depending on what exactly you do, not checking hostname and expiration may be completely OK. In case of LND, I believe it's usually used on the same machine and the certificate is on the same FS or securely transferred to a different machine. There's no good reason to care about hostname if you consider the certificate to be authoritative proof of identity.
To put it differently, it works more like onion domains - you only have the key and if the key is correct, nobody can MITM you. You don't care which IP they are on, there's no domain name.
Expiration is also somewhat funny. It assumes that rotating certificates mitigates key compromise. But TLS key is stored on filesystem with much more sensitive stuff: admin macaroon. Basically the security model is reversed here - certificate protects the server, not the client. If the server is compromised, you're already screwed and MITM is no longer needed.
The only reason expiration might be interesting is cryptography break that takes a long time. If it ever happens I guess we will have bigger problems. But perhaps worth adding the check. As I said, I'm more concerned with it stopping working than with it being unsecure.
Anyway it seems our libraries are quite similar. Do you think we could join our forces?
This issue was closed 6 months ago. I locked the conversation here to avoid distracting people. I am open to making webpki more flexible but doing things that are just flat-out wrong and dangerous is out of scope of this project, so I'd rather not discuss such solutions here. I know this sounds harsh; not trying to be. I just want to keep discussion here focused on implementing correct certificate validation. I hope you understand.
Hello, I'm trying to connect to a gRPC server that provides a self-signed certificate. However I'm getting the following error
WebPKIError(CAUsedAsEndEntity)
. If I understand correctly WebPKI wants the CA to issue an end entity certificate instead of using just the self-signed CA cert itself. Unfortunately I don't control the server software that generates the certificate, so I was wondering if there is a way to allow a self-signed CA cert to be used as an End Entity cert?https://github.com/briansmith/webpki/blob/0573c1ec3fa4da14d74b9c6ee52087b80dadf16e/src/verify_cert.rs#L234 (fwiw removing this line passes the validation of the cert and the connection happens on rustls tlsclient example)
Here is an example of the certificate used in case it helps: Thank you