views:

962

answers:

8

I have a desktop product which uses an embedded webserver which will use self-signed certs.

Is there something that I can put in a web page that would detect that they haven't added the root CA to their trusted list, and display a link or DIV or something directing them how to do it?

I'm thinking maybe a DIV that has instructions on install the CA, and a Javascript that runs some test (tries to access something without internal warnings??), and hides the DIV if the test succeeds. Or something like that...

Any ideas from the brilliant SO community ? :)

+1  A: 

Assuming you know C# and you want to install a pfx file.Create a exe that will be run from a url.Follow this URL

abmv
I don't want to install the cert for them -- I want to detect that they haven't done it yet, and point them to help (and possibly to an app that would do it for them). Also don't want to depend on all clients having the .NET framework installed so would need to write the app with Win32 :(
DougN
http://www.codeproject.com/KB/IP/winhttpssl.aspx coulde help
abmv
+2  A: 

The only idea I have is to use frames and some javascript.

The first element of the frame will act as a watchdog waiting x amount of time (javascript setTimeout) before showing your custom ssl failure message to the user with hyperlinks or instructions to download the self-signed cert.

The second frame element attempts the https connection and if successful resets the watchdog frame so that it never fires. If it fails (assume https cert validation failed) the watchdog message would then fire and be presented to the user.

Depending on your browser you will most likely still see some security warning with the approach but you would at least be able to push your own content without requiring users to run untrusted code with no proper trust chain (This would be much much worse from a security POV than accepting the cert validation errors and establishing an untrusted ssl session)

Improvements to the concept may be possible using other testing methods such as XMLHttpRequest et al.

Einstein
Not a bad approach, but I can't have any non-HTTPS (ie simple HTTP) pages -- it's all HTTPS. But I'm trying to think of something along the same lines you mention...
DougN
A: 

You might try to add some (hidden) Flex element or Java Applet once per user session. It will just download any https page of your server and will get all information about connection:

com.sun.deploy.security.CertificateHostnameVerifier.verify()
or
javax.security.cert.X509Certificate.checkValidity()

I suppose Flex (which is more common to users) shoul have similar ways of validating https certificate from user's point of view. It should also share OS' trusted cert. store while Java might have its own.

Alexander Kosenkov
+7  A: 

Why do you want to do this? It is a bad idea to train users to indiscriminately install root CA certificates just because a web site tells them to. You are undermining the entire chain of trust. A security conscious user would ignore your advice to install the certificate, and might conclude that you are not taking security seriously since you did not bother to acquire a certificate from an existing CA.

Do you really need HTTPS? If so, you should probably bite the bullet and make a deal with a CA to facilitate providing your customers with proper CA signed server certificates. If the web server is only used for local connections from the desktop app, you should either add the self-signed certificate to the trusted list as part of the installation process, or switch to HTTP instead.

markusk
I appreciate the concern for security. This is an IT app, and passwords will get passed. So HTTPS is absolutely required. In addition, the users are (mostly) security saavy, so they'll understand what they're doing. They have the option of providing their own CA-signed cert if they want. But some won't so we have the backup option of a self-signed cert. And though the customers work in IT, they won't necessarily know the steps to install a cert. So we'd like to help -- but only when necessary.
DougN
I'm sitting here considering what you said some more. Do CA's offer any kind of bulk server-certs? I can't believe they would, but I'm looking around, and would appreciate any pointers you might have.
DougN
Here are some possibilities at Verisign and Thawte: http://www.verisign.com/authentication/enterprise-authentication/processing-center-pki/index.html, http://www.verisign.com/authentication/enterprise-authentication/vertical-service-provider-pki/index.html, http://www.thawte.com/digital-certificate-resellers/reseller-partners/index.html. I do not have personal experience with any of these, but I would assume most major CAs would be open to some sort of reselling agreement.
markusk
Also, if you find you cannot get around self-signed certificates, perhaps something on the lines of https://developer.mozilla.org/en/nsITransportSecurityInfo and https://developer.mozilla.org/En/How_to_check_the_security_state_of_an_XMLHTTPRequest_over_SSL might help. Note that the last URL describes a solution that requires special elevated privileges to run. Not sure if there is any way to access nsITransportSecurityInfo without privileges, and I do not know what the corresponding properties is called in other browsers, but perhaps it might help you out.
markusk
Given the number and wide use of CAs, greed/laziness and some fairly disturbing incidents that have occured over the years -- It is my opinion self-signed certs are more trustworthy than CAs if the public keys are distributed properly (sneakernet?) ... (ususally not feasable)Anyway for instances where you have an application and a massive audience purchase a wild-card SSL cert with a generic domain name. companya.ontheearth.com, companyb.ontheearth.com .. This way you can have as many companies as you want on as many servers as you want with the single cert.
Einstein
+2  A: 

You should not do this. Root certificates are not something you just install, since adding one could compromise any security given to you by https.

However if you are making a desktop app then just only listen to 127.0.0.1. That way the traffic never leaves the users computer and no attacker can listen in.

tomjen
I hear you. This is an app that people will access over the LAN, and possibly over the Internet. My competitors don't support SSL at all -- they send credentials, etc in the clear. I'm trying to take it to the next level with encryption -- but I have to work with browsers :( And since anyone can use this app (even for free) I can't shoulder the cost of real-CA signed certs... So I'm looking for the most secure middle ground I can find. Not much middle ground here though (like standing on the tip of a needle)
DougN
A: 

Since the server is running on the client machine (desktop product) can it not check the supported browsers for installed certs using winapi/os functions? I know Firefox has a cert database in the user's profile directory and IE probably keeps information in the registry. It wouldn't be reliable for all browsers but if the server simply chooses between "Certificate Found" and "Please ensure you have installed the cert before continuing" then no harm is done as the user can choose to continue either way.

You could also simplify matters by providing an embedded browser as well (ie, gecko), this way you only have 1 browser to deal with which simplifies a lot of things (including pre-installing the root CA).

SpliFF
A: 

To recap: you are setting up webservers on desktop apps; each desktop will have its own webserver, but you want to use SSL to secure the connection to that webserver.

I guess there are several problems here with certificates, one being that the hostname used to access the desktop has to match the certificate. In this case you have little choice but to generate certificates on the client. You'll need to allow the user some way to specify the host name in case the name used by outsiders can't be detected from the host itself.

I'd also suggest allowing for an admin to install a trusted cert, for those who don't want to rely on self-signed certs. This way you can also offload the cost of trusted cert maintenance to the admins who really want it.

Finally, in my experience browsers either allow or refuse the self-signed cert and there is no way for the server to know if the cert is denied, or temporarily accepted, or permanently accepted. I assume there must be a mechanism somewhere to handle SSL failures but typical web programming doesn't operate at that layer. In any case, the only thing a webserver can do if SSL fails is to fallback to non-SSL, and you've indicated in a comment that you can't have anything non-SSL. I think you should try to have that restriction lifted; a non-SSL start page would be extremely helpful in this situation: it can test (using frames or images or JSON or AJAX) the https connection, and it can link to documentation about how to set up the certificate, or where to download an installer for the cert.

If the browser won't connect because of a self-signed cert, and you're not allowed to use plain HTTP at all, by what other means could you communicate with the user? There are no other channels and you can't establish one because you don't have any communication.

You mentioned in a comment writing a win32 app for installing the cert. You could install a cert at the time you install the application itself, but that doesn't help any remote browsers, and a local browser doesn't need SSL to access localhost.

Mr. Shiny and New
A: 

We've been working on an opensource JavaScript project, called Forge, that's related to this problem. Do you have a website that your users could access? If so, then you could provide a secure connection to those desktop apps via your website using a combination of Flash for cross-domain + JavaScript for TLS. It will require you to implement some web services on your website to handle signing certificates the desktop app certificates (or having your desktop apps upload the self-signed certs so they can be accessed via JavaScript). We describe how it works here:

http://blog.digitalbazaar.com/2010/07/20/javascript-tls-1/

An alternative to setting up a website, but is less secure because it allows for a MiTM attack is to host the JavaScript+Flash directly on the desktop app server. You could have your users hit your desktop app over regular http to download the JS+Flash+SSL cert, but then start using TLS afterwards via the JS. If you're on a localhost connection the MiTM attack might be a little less worrisome -- perhaps enough for you to consider this option.

dlongley