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
SSL Validation #108
Comments
|
Thank you for raising this issue, I have never been confident in the |
|
I tried this but none of the ca certs seem to match anything in the chain: defp partial_chain(certs) do
cacerts = Hex.API.Certs.cacerts()
trusted_cert =
Enum.find_value(cacerts, fn cacert ->
if cacert in certs, do: cacert
end)
if trusted_cert do
{:trusted_ca, trusted_cert}
else
:unknown_ca
end
end |
|
@benmmurphy Ping? I would very much like this fixed. |
|
i was thinking something like this (not tested. not even sure it compiles) to make sure the trusted_ca cert is one returned from the store. also, it is important to note that this breaks the use case where a client doesn't include the CA certificate which worked before. for example if your valid cert path is: CA->User Cert and you just send in 'User Cert' and no chain then before it would have set trusted_ca to the 'User Cert' and then in the chain rebuilding it would have found 'User Cert' == trusted_ca cert and returned the {TrustedCert, Chain} tuple as {'User Cert', []}. so this would have validated correctly but it would have incorrectly flagged 'User Cert' as being a trusted ca certificate. However, now it will set trusted_ca as the certificate that signed 'User Cert' and when it tries to rebuild the chain it won't be able to find a certificate in the chain which is identical to trusted_ca so it will fail to rebuild the chain with an unknown_ca error. however, one problem with this implementation is it depends on the equality check when rebuilding the chain. if the cert in the store is not exactly equal with the cert in the chain then it won't work (which i think is maybe the problem you were having). i'm not sure if they can differ. also, looking at your fix i think the following would be a better solution than my first thoughts assuming no equality problem: (EDIT: just realized it is basically the same code as your proposed solution.) you can have a look at how erlang uses the partial chain function here; https://github.com/erlang/otp/blob/maint/lib/ssl/src/ssl_certificate.erl#L305 i'll update the issue once i have a proper tested solution it is also interesting the the otp code handles the case where the issuer |
|
Yes, the issue seems to be this check https://github.com/erlang/otp/blob/maint/lib/ssl/src/ssl_certificate.erl#L315-L320. It only allows you to return a certificate in the given chain. The equality persists even when comparing OTP records it seems. |
|
i'll try and confirm that this is an actual security issue. if this is an actual issue then it limits the usefulness of the partial chain function a lot. |
|
Thank you for investing time in this @benmmurphy. I appreciate the help. |
|
yeah. i'm definitely sure this is an issue now. i have a test case here that illustrates it: |
|
i've updated the code to fix the effective ca bit problem but i may have introduced other security bugs. i believe it is significantly better than the current code tho. master...benmmurphy:invalid_ca_bit so the previous partial chain code effectively we fix this by making sure the trusted_ca return so erlang partial_chain requires the trusted_ca it is important to note that this creates |
|
Thanks for the code and the thorough explanation. We should go with this for now since it's a definitive improvement and I will ask the OTP team for guidance about properly implementing I applied your patch but the tests are not running, I needed to change |
|
i've added a pull here: #111 |
I'm fairly sure you have the same verification problem that just hit openssl.
hex/lib/hex/api.ex
Lines 59 to 81 in 8794c59
Looks like it returns the first certificate in the chain that is trusted by a certificate in the trust store as trusted_ca. but, this certificate is not necessarily a ca certificate. i think you should be returning the issuer . I suspect a chain like this will lead to accepting bad certificates:
The text was updated successfully, but these errors were encountered: