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

Fix SSL certificate error / better support for libgit2 SSL certificate check callbacks #414

Closed
jaanus opened this issue Oct 15, 2014 · 12 comments · Fixed by #430
Closed

Comments

@jaanus
Copy link
Contributor

jaanus commented Oct 15, 2014

I have a specific problem with a test app I have written with ObjectiveGit. When my users try to clone a remote repo, they get the error The SSL certificate is invalid. Oddly enough, this happens when trying to clone from https://github.com. I saw that a few months ago, there were some Github/Digicert certificate chain issues. Haven’t yet figured out if this is causing my users problems, but even so, I can’t require all my end users to manipulate the certificate chains.

So. I may need to do a fix on my side. I noticed that in libgit2, there is the callback certificate_check_cb available, which currently is not exposed. Should that be wrapped by ObjectiveGit? Or any other ideas about how to first debug such cert errors, and then how to fix them?

@jspahrsummers
Copy link
Contributor

Haven’t yet figured out if this is causing my users problems, but even so, I can’t require all my end users to manipulate the certificate chains.

It would probably be worth investigating this. Even if it's not very user-friendly, they shouldn't have invalid certificates in their keychain, and they might be silently affecting other sites too.

I noticed that in libgit2, there is the callback certificate_check_cb available, which currently is not exposed. Should that be wrapped by ObjectiveGit?

We used to wrap the previous version of that API, so I wouldn't be opposed to wrapping the new one in general.

However, I'm concerned that it's not the right solution to the particular problem that you're encountering right now. If you would just use that callback to skip certificate checks, you're exposing users to MITM attacks on their Git data (which is very valuable data to many people).

Or were you thinking of doing something else with the callback?

@jaanus
Copy link
Contributor Author

jaanus commented Oct 15, 2014

Yep, I was thinking of just using the cert check callbacks to skip the certificate checks as a last resort, I don’t have any other use case for it. (I wouldn’t just skip all the checks, more likely just hardcode a few certs if there really is no other way.)

But, I have installed a stock copy of OS X Mavericks in a virtual machine, and I can now reproduce the problem locally. With everything of the system at default settings, it is saying “The SSL certificate is invalid” for a repo on https://github.com. I guess I’ll try debugging it and maybe isolate the offending cert or some such. Sadly I can’t just fire up the debugger and do it live, since I can’t install any dev tools on the VM. So I’ll build a small test app and I guess patch libgit2 and Objective-Git to log me info about the fails. I’ll report back here if I find out something.

@jspahrsummers
Copy link
Contributor

Thanks for digging into it! We (GitHub for Mac) still shell out to git for cloning—mostly because of inertia—so unfortunately we haven't run into these kinds of issues yet.

@jaanus
Copy link
Contributor Author

jaanus commented Oct 20, 2014

Looked into this a little. I can consistently reproduce this on vanilla Yosemite and Mavericks without any developer tools installed. Cloning with objective-git is not working at all on these machines. It is not working because the following line in netops.c verify_server_cert

if (SSL_get_verify_result(ssl->ssl) != X509_V_OK) {

returns error 20, which according to OpenSSL documentation is…

20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate
       the issuer certificate could not be found: this occurs if the issuer certificate of an untrusted
       certificate cannot be found.

So for some reason, the SSL subsystem works differently on developer and non-developer machines.

@jspahrsummers
Copy link
Contributor

@vmg @arrbee Have either of you seen anything like this before? I don't see any past issues about OS X certificate validation in libgit2/libgit2.

@zetachang
Copy link

Running on iOS (simulator and real device), cloning a simple repo from github using https will failed for the same "Certificate is invalid" error.

I am using Xcode 6 and build upon current master.

@zetachang
Copy link

I've fixed the issue by manually setting the SSL certificate location using libgit2 API (https://libgit2.github.com/libgit2/#HEAD/group/libgit2/git_libgit2_opts)

Also, I've tried providing a callback using certificate_check_cb which resulted in the same The SSL certificate is invalid error.

@jaanus
Copy link
Contributor Author

jaanus commented Nov 5, 2014

Does this mean that out of the box, libgit2 is not picking up the certs it should pick? What certs/locations did you use?

@zetachang
Copy link

I think since openssl doesn't come with any root CA certificates. And the app is running in sandbox, so the only possible way to make it work is providing our own certificate package.

For the certificate to make cloning from github work, I just export the DigiCert one github.com use with Keychain Access.app in pem format and make it bundled in the app.

Related libgit2 PR: libgit2/libgit2#2583

@jaanus
Copy link
Contributor Author

jaanus commented Nov 6, 2014

@zetachang thanks, makes a lot of sense. Sounds like objective-git could use some options to do this so you wouldn’t have to drop down to libgit2 API. I’ll try reproducing this problem and your fix and maybe make a objective-git PR with this feature sometime.

@phatblat
Copy link
Member

Thanks @zetachang. I was able to get past this error with the same approach.

Seems like the Security framework should provide a way to extract all the root CA certificates from the system and build a PEM file for libgit2. I looked into this briefly, but it looks like the Sec* APIs are different between iOS and OS X so this approach may not be portable.

@petetak
Copy link

petetak commented Nov 18, 2014

Thanks - very useful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants