A JavaScript Implementation of TLS (Part 1/2)

Digital Bazaar has written a pure JavaScript TLS client implementation and released it as open source software. The project is called Forge.

To our knowledge a JavaScript implementation of TLS has never been done before. But, if you are a developer, you might be thinking: Wow, that sounds completely inane. Is this just another case of a bored developer engaged in an esoteric demonstration that something crazy is possible? It is useful. We promise.

If you are not a developer, you might be wondering what TLS is and what JavaScript has to do with it at all. Well, first, TLS stands for Transport Layer Security and is just the fancy name behind what makes “https” websites secure. You may have heard of SSL (Secure Socket Layer) before. TLS is the latest version of SSL and is more appropriately named because data does not have to travel over a “socket”; it can be transported in many different ways. So why would someone think a JavaScript TLS implementation is useful?

An Analogy

TLS makes it possible to go to “https” websites in a secure way. Your web browser already provides you with the ability to go to secure websites that start with “https”. Most browsers do it very quickly because they are written in much faster languages than JavaScript. Many browsers are so fast at TLS that it is very difficult to notice that communicating with an “https” website might be a bit slower than doing so with a non-secure website (“http”). If someone were to implement TLS in JavaScript, then not only would they be reinventing the wheel, but the end product just wouldn’t perform as well as your web browser’s native implementation. So, why would a developer do this?

Suppose a mechanic offered to replace the engine in your car. He is going to cut you a great deal on replacing the engine. However, not only is your current engine running just fine, but the engine he is offering will also be less powerful than the one you currently have. Sounds like a bum deal, right? But then he goes on to say that while the new engine might be a little less powerful, you will probably not notice the difference. The big advantage is that the new engine can run on renewable energy sources such as ethanol, hydrogen, or solar. So, while the engine is less powerful, it has some advantages that are economically beneficial to you and environmentally beneficial in general. Of course, at this point in history you might just write the guy off as a snake oil salesman, but the point is that there is a real benefit to this new approach.

Accessing Your Home When You are Away From Home

So, how is this related to JavaScript and TLS?

There are a large number of native applications that we run at home on our personal computers. Some of them, like Word, TextMate, and Photoshop, allow you to interact with them using a window on your desktop. Some applications are a little different and will present an interface to you via a web browser. These applications are often called web applications. The application you might use to configure your home Internet router is a good example of a web application. To access a web application, you start up web browser like Firefox or Google Chrome and go to a web address specified in the application’s manual. These kinds of web applications are currently less common, but they are out there and may become more prevalent in the future. A big advantage to having web applications like this is that you can often access your application using a different computer when you are away from home. Some popular examples include Gmail, Yahoo Maps, Twitter, or Facebook. While those applications are not on your computer at home, it is pretty clear how easy it is for you to use those applications from any device that has a web browser.

This access-from-anywhere interface is not useful for all applications, but it is not difficult to imagine scenarios where it would be a nice feature. Imagine any situation where you keep some personal information at home that you want to be able to access while you are out. For instance, maybe you want to be able to stream your personal music collection to your phone or to another computer when you are at work. These sorts of problems are often solved by companies that create websites that will store your personal information for you so that you can access it from anywhere. The downside to storing private data away from your home is that it can be costly for companies to do so and some people prefer to keep their data a little more private. You may notice that the scenarios we are discussing here are focused on private data. This means that even if you could access an application that is running at home while you are away from home, you would want to do it in a secure manner. This is where our JavaScript TLS implementation comes into play.

Securing the Connection to Your Home Application

So how do you communicate securely, when you are away from home, with an application running on your home computer? How could Google Docs allow you to access documents on your home computer from another computer without allowing attackers to see your documents as you retrieve and edit them? One way to accomplish this would be to require you to download a program from your application provider’s website that enabled you to communicate with your application at home. But these days we expect something much more seamless. We should not have to install programs just to get a web page from our home computer over the Internet. You might not even be able to install a program on the computer that you are using while away from home. You should be able to use the tools that are available in 95% of the browsers out there: JavaScript and Flash. Ideally, we would like to depend purely on JavaScript and the browser, but Flash does some neat things that the browser just doesn’t do yet, so we need it for the foreseeable future.

Implementing TLS and Raw Sockets Using Only JavaScript and Flash

How could an application provider, such as Google, enable you to securely access your home computer using just JavaScript and Flash? They could write a custom protocol, something very specific to the application they have created, to handle the communication. This would require them to spend a significant amount of time getting the security issues worked out and audited. Implementing secure communication protocols is very difficult. The other downside to implementing a new secure communications protocol is that it would only work within their company and their products. In other words, it would reduce the ability to reuse the solution to enable broader adoption of the technology, and their efforts will have to be duplicated by other companies.

If you recall from the beginning of this article, there is already a secure communication protocol in wide use on the Internet; it is called SSL, with the latest version bearing the TLS moniker. However, TLS is implemented natively in your web browser, not in JavaScript. Why would we want to implement TLS in JavaScript? The issue boils down to the unfortunate fact that you cannot access the underpinnings of the TLS protocol from JavaScript. To access your home computer in a secure and noninvasive way, the application provider must have access to the TLS layer.

So where does Flash come into play? No matter what protocol is used, you need to be able to communicate across domains. This means that you will go to your application provider’s website, the first domain, to get access to your home computer, the second domain. Normally a web browser can only easily communicate with a single domain. There are some upcoming technologies (e.g. WebSockets) that will ease that restriction, but for right now, Flash makes communicating across domains possible.

Verifying Certificates

In order for your web browser to talk to an “https” website, that website needs to have what is called a trusted SSL certificate. This means that there is a digital document on the Web that you can trust that proves that your web browser is actually talking to the website you typed into the location bar of your browser. When you type “‘https://www.mybank.com” into your web browser, you expect to be talking to your bank’s secure website. However, there are attackers out there who would like to trick you into thinking you are going to your bank’s website. If the security measures in place are poor then your web browser will fail to warn you about an attacker-forged website. If you don’t know that a website is forged then you may send them your username and password without knowing that anything bad has happened. An SSL certificate that is trusted by your web browser provides you with the peace of mind to enter your username and password on your bank’s webpage without having to worry about forgeries. If you receive an SSL certificate that is not trusted then your web browser will warn you and suggest that you leave the website.

Trust

So how does your web browser know who to trust? By default, your browser will trust certificates provided by large, well-established companies like VeriSign. These large companies issue SSL certificates to other companies that have proven that they are real businesses by verifying their business phone number and address. This background check ensures that when an SSL certificate says that it belongs to “www.mybank.com”, you know that you are really talking to your bank instead of a forged site that looks like your bank. However, that’s the problem with communicating with an application in your home. You’re probably not a business, so how can you get an SSL certificate that any web browser you want to use will trust?

Getting a trusted SSL certificate can be expensive. Most importantly, the cost to you is not zero dollars. In addition, SSL certificates are typically signed for a particular domain (ie: www.mybank.com). This means that the certificate cannot be used for a different domain and that one would need to purchase a domain to go along with the SSL certificate. You might also need to purchase a static IP address from your Internet Service Provider to ensure that your newly purchased personal website consistently redirects to your home computer. There is a significant cost for purchasing all of the things that you need, and sorting through all of the details is tedious. Ultimately, this process is too costly and time consuming for the average person. Most people are simply more willing to store their private data on a public website than they are to dredge through these issues.

You could generate your own SSL certificate for free. But as previously mentioned, when you try to visit the website, your web browser will display bright red warning signs that it is untrusted. Many people don’t know when to explicitly trust an SSL certificate or what it even means to do so. Usually when a person sees a certificate warning in their browser they will either simply leave the site or do something potentially dangerous and outright ignore it.

So your home application could generate an SSL certificate for you, but when you tried to access your application from a web browser it would complain. However, there is a way around this problem. The application could upload an SSL certificate to your application provider’s website where you could download it at a later time. You could then add the certificate to your browser as a trusted certificate. Unfortunately, most people would agree that this interaction is still too complicated.

How It Works

As you can see, there are a large number of difficulties when attempting to solve this problem. We expect that most people would rather walk away from these kinds of details than try to navigate them. Accessing applications that are running at home needs to be as simple as accessing Facebook and as secure as accessing a banking website. In order to achieve both of these goals, we have no choice but to abandon the native SSL/TLS support in the web browser and implement it in JavaScript.

With that goal in mind, here is an example of how you could communicate with an application in your home using our TLS implementation:

You go to your application provider’s “https” website (e.g. Google Docs) and log in. From there, you click “Access my Home Computer”. From that web page, your browser downloads the JavaScript TLS code we’ve written and the Flash file to access your server at home. Your browser also automatically downloads the SSL certificate for your application at home so that it knows who to trust. From that point forward you can communicate directly with your application at home from a web page on your application provider’s website. You can access your application provider’s website from any computer, mobile phone, or web-connected device that has JavaScript and Flash support.

If you’re a developer and you don’t want to store the self-signed certificates uploaded by home applications, an alternative is to create your own Certificate Authority that can sign the home application certificates using an appropriate common or subject alternative name. Then you can have the JavaScript code check for the appropriate name when connecting to a particular home application. An additional interface for enabling or disabling a home application’s SSL certificate can be provided to deal with compromised certificates.

Possibilities

With this mechanism, a number of very useful scenarios are enabled. Some examples include managing a web-connected thermostat in your home, monitoring your home’s security system, streaming music from a home computer, or adding items to a grocery list that is tracked by your fridge. There are many pieces of personal information that we would like to have access to in our homes. Hopefully this helps to explain why the idea isn’t so crazy after all.

In the next article, we’ll discuss the design and implementation of this system. Getting this system working was not only challenging but is also of great interest to web developers who would like to write web applications that can be installed in the home and accessed from anywhere.

Trackbacks/Pingbacks