Monday, 30. April 2007, 11:04:30
April 30th, 1997 (give or take a few days; remembering exact days can be hard) was the first time Opera's SSL implementation completed a full transaction.
The four months prior to this largely unnoticed (but for Opera significant) event, had been very busy. I had to study and learn about SSL and general cryptography, then do intense design and development work, followed by a lot of testing and debugging.
The SSL support in Opera was my first assignment when I started working at Opera. You might say that I was thrown in at the deep end. The benefit, of course, was that my hands weren't tied by a pre-exisiting design.
Geir
1,2, who was then developing the network code, as well as the rendering engine, had been looking at the SSLeay crypto-library (it's now known as
OpenSSL), which had an SSL implementation, but hadn't gotten much further than starting to look at the specification and download SSLeay by the time I started at Opera.
After looking at SSLeay's interfaces and code I reached the conclusion that the SSL implementation would not work well with our network code and decided that an independent implementation of the protocol would be better, although I kept SSLeay around for the crypto support, which was independent of the protocol.
A couple of other decisions were:
- Avoid implementing the basic crypto functions myself. It is far too easy to get something wrong in that code, both with respect to performance and correctness (and security). Also, it would take far too long to implement all the necessary functionality. So we used SSLeay for the encryption and certificate support.
- Isolate the encryption and certificate handling code from the rest of the protocol implementation so that we could, if necessary, replace the crypto support library without major changes to the rest of the code.
- Isolate atomic structures as much possible, as well, in object oriented classes, because it made coding easier. This is very easy in C++, and I could do this using techniques I learned during my masters thesis work.
I started by implementing SSL v3, since it was then the most recent definition, and also quite well defined. I still hold the SSL v3 and TLS specifications as some of the best written protocol specifications I have seen (with PKCS #7 and S/MIME as some of the worst ones). SSL v2 I postponed until later.
Implementing something from scratch is hard work, and you often have to backtrack as you find that the current solution design did not work out as expected. But it is, of course, this challenge that is a large part of what attracts many to software development.
After a couple of months, and having integrated the new protocol with the network code, we were ready to make it work.
This also involved a lot of work, and some situations can be a little bizarre. One time I got to the point where I had sent the encrypted keymaterial (used to calculate the encryption keys) to the server, and the server slammed the door in my face (which is what it almost always did when I made a mistake).
All right, that indicated (of course) that something was wrong with the data we sent.
So, I checked that we encrypted correctly, that we encoded the message correctly according to the specification. Everything checks out. OK, let's take a look at what the competition is doing: Huh, it's *not* following the spec?! I test that "method", and it works to get me to the next stage.
I send off an email to the specification authors, and ask what is going on? The answer: It looks like Netscape (who wrote the spec) implemented it wrong in their clients and servers, and so it stuck (but they said TLS 1.0 was going to do it right).
This incident has an amusing follow up story. Almost two years later I was testing against the newest SSLeay development version which was going to support TLS 1.0, and ran into the same problem. I double checked with the TLS spec authors, but the spec had not changed, so I told Eric Young he had made a mistake, and to be sure I had it right he put the question to the TLS work group mailing list, and got the same answer I got.
Finally though, April 30th the code worked well enough that we could actually get a web page back.
The implementation was by no means finished, and work would continue for the rest of the year to get the SSL implementation into a shape fit to be shipped in Opera 3.0. But just to "round" that day off, I spent two or three hours implementing the TLS 1.0 version, even though I wasn't able to test it until early 1999, at which time it took just a week to get it working properly and mostly ready for Opera 3.50.
The SSL implementation wasn't static (and still isn't). Work on improving it continued, and is continuing:
- In 1999 we added TLS 1.0 support, as one of the first clients to do so.
- A while ago I started a complete rewrite of the protocol control engine
because I was encountering more trouble with adding new functionaliy. Part of what I did was to take the design methods I had used earlier and go even further along that route (I get the impression a few colleagues would say I went too far
, I suspect they just got caught up in the details). This new engine became active in 9.0.
- We have regularly updated the version of SSLeay and later OpenSSL, although the first major upgrade was the worst, due to the major internal changes in the certificate system made in the 0.8.x compared to the 0.6.x version we were using at the time.
- We have added new encryption methods as they became available.
- We have improved the security related information we show users.
- We were among the first (if not the first) to deploy a client supporting TLS 1.1 and TLS Extensions, in fact so early we had to disable it and develop a workaround before we could enable it by default (I actually got a question from Microsoft
, about them having the same problems with TLS Extensions that we had).
What is in the future of Opera's SSL/TLS implementation?
[*]We are adding support for
Extended Validation certificates.
[*]There are some big changes coming in the certificate management system.
[*]In Kestrel we are planning to completely remove support for SSL v2 and the weak 40 and 56 bit ciphers.
Some may wonder why we are still using our own implementation of SSL and TLS when there are several implementations around. After all, some of the original reasons for the choice no longer exist.
Well, while we do use other implementations on some platforms, for technological reasons, one major reason is that it gives us more control of what functionality we support. For example, we implemented TLS 1.1 and TLS Extension 3 years ago, and we are actually still the only major TLS 1.1 client around, and other TLS Extension clients did not show up until second half of 2006 (although that is a chicken and egg situation). We are also more at liberty to integrate the code better with our own processes and techniques.
Having our own implementation also makes it easier to move the functionality to a new platform, although Open Source implementations have the same benefit.
Another reason may be a bit more philosophical, as Opera's engine is one of only four major SSL/TLS clients deployed, and at least two of the other three are also developed with the server side. This means that Opera's client may be able to keep the others from implementing mistakes that then get turned into de-facto standards (which is what happened with the above mentioned specification). Diversity is what will keep the net working.
But, that question is also similar to a few other questions: Why develelop our own HTML parser, webpage rendering engine, our own browser, and so on? In this context, another obvius reason becomes clear, we think we can implement these things better ourselves.
Although we have hit the occasional troublespot, I think (if I may be so bold) that the design I chose in 1997 has worked out quite well. While there has been some big changes in parts, the basic design and functionality of Opera's SSL implementation are still quite similar to the original implementation.