Ok, I hope that it will help in your case.
Accept self-signed certificates
Just my few cents to this topic:
a) I also like to keep stuff in the places where they belong. Simply trusting untrusted connections is a bad thing and should not be made available. You simply compromise the connection because you simply allow man in the middle attacks. So the core feature that is missing is the trusting of a certificate and that is something that simply does not belong in this app. And I am really wondering why this isn ot part of the browser in andorid. And I didn’t find an app for it. (There was an app but that was build to accept man in the middle certificates when using a proxy and it simply required a poxy! WTF???) So it is really a doing of google and not of the maintainer of this application.
b) The solution is quite simple in my eyes - once you found it: Just export the (public key of the) certificate in DER Format as .crt file and put it on your webserver server. (The export can be done with firefox on a pc easily - just open the page, click on the lock and view the certificate!) Then open the certificate in the browser of your device and android directly asks you for the name which should be used to install it.
But when we are talking about android: At the moment I am a little confused. It seems that android is thinking that these certificates are client certificates used to authenticate the system/user? That is the reason that you are forced to protect your device e.g. with a pin! And that is simply nonsense in my eyes. I think that the google developers missed something here and simply produced something crazy (Maybe I am wrong but that is what I understood so far!)
@kneitzel As you say, the way Android handles certificates is decidedly stupid. It should be simple enough to import a certificate and not deal with creating a PIN or getting warning messages. Your explanation is reasonably accurate, I think, though in some sense it doesn’t really matter why Android handles certificates so badly, because regardless of the reason, this is the current state of affairs.
so I finally bought a STARTSSL class 2 certificate for the wildcard *.perso.fr, now it’s “green” when I connect with my browser
but still I have this annoying message when trying to connect DAVDROID: “cannot verify hostname”
Note : I imported the class 2 client certificate of STARTSSL into android cert manager:
Did I miss something?
@kneitzel No one is asking for DAVdroid to “simply trust untrusted connections”. We generated the certificates on our servers, and know their fingerprint. Confirming the hash on the first connect and pinning the certificate is not a security issue - if someone tried a MITM, the fingerprint mismatch will make it obvious.
Yes, I saw that a little later when I checked out the library linked. It shows the certificate in a way people are used to from browsers on computers. But if I understood it correctly, the trust is a per application trust and not a trust of a certificate on the whole device? So yes: I see that it is a workaround and I can understand the request.
But I am not sure that implementing such a workaround is required because it is straight forward to import the certificate on your device. (Doing such workarounds might seem to be a nice thing for a user but the other side is the developer who simply has to maintain the code which simply get more complex with such workarounds. And that includes a lot of things e.g. development time to create, test and maintain it, greater chance for a failure/bug, …) So I would prefer to stick to an installation of the certificate. But of course that is my personal opinion only.
Instead of such an workaround I would like to have an application that gets a certificate and installs it. That way users could easily install required certificates.
@sulliwane: Are you sure that the certificate is installed correctly? You show the certificate on blog… but you connect to cloud… And you talked about a *.perso.fr certificate but it seems that there is no cloud.perso.fr at all (or I misspelled something when checking it.)
@kneitzel Yes, the trust is per-application.
And as mentioned above, importing my certificate to the user storage is a straightforward solution in Android 4.3. With the upgrade to 4.4, Android permanently displays a warning when importing such a self-signed cert, both in the notifications and in the settings until you remove the cert.
Now when I try to connect with DAVDROID, I have the error “Cannot Verify Hostname”.
There already is STARTCOM cert in the system trusted credential (you can check on your droid) but still I added another one.
Could it be related to the wildcard cert, or to the CA cert imported in Android?
@sulliwane: Maybe it is a name resolution error? Just wondering, because I cannot get an ip for cloud.perso.fr (Or is it just an server in your internal network?)
And the wildcard certificates work fine here. I have a certificate (self signed) for *.konrad-neitzel.de and it works fine for www.konrad-neitzel.de.
So I am running out of ideas regarding your problem,.
@brb-at: This warning is such a stupid thing. I just imported the certificate of my server and not my “CA” certificate. So yes: I know this annoying message and I also know all the discussions about it and that google simply wants to keep it this way.
@kneitzel : it seems I didn’t completly follow the installation instructions on startssl website (https://www.startssl.com/?app=20) So now I don’t have the message anymore. But I have have an “HTTP error : 405” instead…
Thank you for your help.
PS : perso.fr was just an example.
Thank you for your help
OK, problem solved ! this time it was that I didn’t read conscientiously enough the DAVDROID instructions (mea culpa) Here are the URL one must fill for DAVDROID (separatly for each kind of account):
Thank you for your help, I can start enjoying davdroid!
Hi, I just registered to post my issues here.
First of all I’d like to say that I really like DAVdroid and it works like a charm with my owncloud… but unfortunately not with https I have a domain “domain.tld” and installed owncloud on it’s own subdomain “owncloud.domain.tld”. The owncloud is hosted on a virtual server at Hosteurope (German hosting provider) and is managed via Plesk. Additionally I have a CaCert.org Account and I created a Class 3 wildcard certificate for my domain “*.domain.tld”.
I’ve never had any issues with this configuration but DAVdroid refuses the connection: cannot verify hostname. I already installed the Class 1 and Class 3 CaCert.org root certificates on my phone (http://www.cacert.org/?id=3). I can see them in my certificate safe on the phone (not sure about the correct English translation).
Do you have any advice for me? Anything else I can check? My issue seems very related to @sulliwane’s problems, but unfortunately I haven’t found any solution for my CaCert.org certificates yet.
@mrclschstr: I’d like to try this out personally because it might be interesting for others, too. Can you send me the FQDN and your public certificate to email@example.com?
@rfc2822 Hi and thanks for the offer but I finally solved my issue today I’ll try to explain it as reproduceable as possible.
At first I read the FAQ carefully again and saw this little sentence: DAVdroid 0.4+ supports SNI on Android 4.2+ devices. My Andoid is 4.1.x so it doesn’t support SNI which basically means that DAVdroid is not able to recieve the correct certificate from the subdomain. Furthermore I read another issue and stumbled across the post of @jeekajoo: https://github.com/rfc2822/davdroid/issues/9#issuecomment-26223814. So I checked my domain with the openssl-command and found out that my domain was returning a self signed Plesk certificate instead of my CaCert.org certificate!
In the end it was just a configuration fix in Plesk to deliver the CaCert.org certificate instead of the self signed Plesk certificate for the main domain (like jeekajoo already mentioned in his comment linked above). So my real issue was not reading the FAQ carefully enough
@mrclschstr Glad to hear that it works now. In case that you have got DAVdroid via Play/Samsung Store, we’d be happy about a review/rating.
I have now read some documentation about services in Android and this approach opens some new questions:
Should it be possible to use any “Custom Certificate Service”, for instance using an intent filter? In this case, users could theoretically choose between multiple certificate manager apps, but there’s also the possibility that some malware installs a malicious certificate manager app that just accepts all connections (meaning that this solution is only secure when users carefully choose what they install).
Should the service provide “connect(hostname)” call that returns either a connected, verified socket (or null) or just “verifyConnection(SSLSession)” like a hostname verifier? In both cases, it would by very useful if Java objects could be passed to/taken back from the service because neither connections nor SSLSessions can’t be marshalled without some efforts.
There are several service/IPC types in Android.
- Started services communicate via Intent/Bundle; Sockets or SSLSession can’t be passed and everything must be marshalled manually.
- When using Binder or Messenger, custom objects like Sockets or SSLSessions could be passed. However, binder only allows local services (thus making the certificate manager not reusable). Messenger has no easy two-way communication (two messengers are needed, one for each direction) and doesn’t allow multi-threading.
- When using AIDL, Sockets or SSLSession can’t be passed and everything must be marshalled manually.
I think the best approach would be AIDL if there was an acceptable way how to marshal SSLSession information (all information should be passed because the service could decide, for instance, that only connections with a certain cipher suite are accepted).
Given that raw objects should be passed, the best approach would be a Messenger service:
- The client (DAVdroid) would pass a MSG_CONNECT message including host name/port to the service and goes into “wait” mode. (If the service is not present, the normal connection routines are used.)
- The service connects, verifies certificate and host name (possibly showing a notification to the user and waiting for user interaction), and passes OK + socket handle or an error message to the client’s messenger.
- DAVdroid receives the result and either uses the returned socket or aborts.
Of course, a light-weight alternative would still be a .jar library that can be embedded – and upgraded! – easily.
Wow, this is a long thread for sure. Hi, I’m the author of MemorizingTrustManager, and I would like to provide my 2¢ as well.
- MTM is an Android Library, you should not merge it into your source, but you are free to add it as a git submodule, making future upgrades easy. You can do the same with ActionBarSherlock and other library projects.
- At the time of its creation, MTM was a sensible tradeoff between “buy expensive CA cert” and “disable all security on HTTPS”. In the light of last year’s revelations, a combination of MTM and cert pinning for sure seems urgently needed. Still, MTM provides additional value over refusal to work without an official CA certificate.
- Implementing MTM/pinning as a “remote” service in Android does not seem as promising to me, especially when point 1 from above and the security implications are considered.
- The Guardian Project, maintaining ChatSecure, are working on a unified proposal to handle chained TLS verification in client code. In my eyes, this is the way to go, and I would be glad to see it implemented as a future development of MTM, provided some help from The GP or other interested parties.
Edit: I’m using MTM as a git submodule in yaxim, and it works very well.
Another related question: Do you use the default Android email client? (I do.) And as far as I know, it has no support for custom certificates but only allows SSL or “SSL (all certificates)” which is totally unsecure and unusable. So, if you want to use your secure CalDAV/CardDAV server as an email server too, you’d always have to install the certificate into the trust store. Is this correct?
I think most people with self-hosted email use K9 mail, which has support for self-signed certificates.
- Android issue: Allow users to install CA certificates
- Android issue: Allow “Network may be monitored” warning to be permanently dismissed
- Android issue: Email app vulnerable for MITM attacks (not public, I wrote that the “allow all certificates” in the default email app allow MITM attacks and are not secure)
- Android issue: HttpClient with same certificate/https acceptance as the browser
Is this comment a response to my pull request? I agree that an infrastructure-level solution is preferable, but until that happens I think the MemorizingTrustManager is actually a pretty good solution. It does give you full security against MitM attacks, since you have to manually accept self-signed certificates.