[Mono-dev] Request for comments: mozroots, msroots, X509Chain
Edward Ned Harvey (mono)
edward.harvey.mono at clevertrove.com
Thu Jan 8 02:37:34 UTC 2015
Is Sebastien on this list? I'm just guessing he'll have an opinion, or at least a passing interest. I guess Miguel, too.
When a client application makes a SSL/TLS connection to a server, the application must validate the server cert, validate any chain of intermediate signing certs, and conclude by validating a trusted CA root cert that terminates the chain, or else the connection is considered untrusted/insecure. No matter what, the server cert (leaf cert) is provided by the server. No matter what, the root cert must exist in a predefined list of roots trusted by the client. This leaves a little bit of ambiguity around the process of building the chain of intermediates - The server may send the chain to the client, or the client may construct a chain any way it can, but if it fails to build a valid chain, the connection is considered untrusted/insecure.
It is well known that mono ships with no trusted CA roots. If a user wants to use a mono-based application to connect to any type of SSL/TLS server (including https), they are typically required to use the "mozroots" command (part of mono) to populate the root list. There are several things wrong with this -
#1, it's not user friendly to require users to manually run a command on the terminal before they can use standard internet resources.
#2, application developers are very likely to automate the mozroots process into their applications (I know I do). This is cumbersome to developers, particularly because mozroots is a console application, not a class that can be called programatically.
#3, Although people generally know about the empty mono root CA list, most people don't know there is a separate list of intermediates (also empty). Both lists are empty by default, but mozroots populates the root list by downloading from mozilla. The intermediate list remains empty. There is nothing strictly *wrong* with populating the root list and leaving the intermediate list empty, but it means the mono client is fragile. If the SSL server fails to send the chain to the client for any reason, then the client has no other recourse, and will fail to construct a chain. The client could be more robust, if the intermediate list were populated too. Then, the client could usually build a valid chain, even if the server fails to send the chain.
To validate this concept, I'd like to point out that Microsoft ships Windows with a list of roots *and* a list of intermediates populated by default.
There is a bug in mono that prevents a mono server from sending the chain to the client. This bug is being worked on independently of this email. Since a mono client has no intermediates, it means a mono client is doomed whenever it tries to connect to a mono server signed by an intermediate, which is unfortunately the real world norm. Interestingly, if you run a .Net client and mono server, then the connection succeeds because the client is able to construct the chain from the MS list of intermediates. Also, if you run a .Net server and mono client, the connection succeeds because the .Net server successfully sends the chain to the client. The incompatibility problem occurs strictly when a mono client connects to a mono server signed by intermediate. This lends even more validity to the concept of populating a list of intermediates on the client, to make the client more robust.
As a final piece of background information here, I need to point out that mono X509Chain currently does not attempt to use the intermediate store to build a chain. So even if the intermediate list were populated, the mono client would still fail to build the chain.
So finally, I get to the meat of this email:
1- I would like to introduce a new way of populating the root list. I would like to create a new MSRoots class, and corresponding "msroots" wrapper console application, that can be used instead of, or in addition to mozroots. Users can run msroots from the terminal, just as they are accustomed to do with mozroots. But application developers can also use the MSRoots class to perform the same job programatically - very easy.
MSRoots will follow the Microsoft practice of populating roots and intermediates, instead of following the mozilla practice of populating roots without intermediates. Also, MSRoots will follow the MS selection of roots (currently 43 roots) and will not follow the mozilla list (currently over 140 roots).
Copyright and license terms are a sticky subject when distributing CA certs. To avoid any difficulty, I support the current approach of *not* distributing certs, but instead, automating the download. It is absolutely legal (fair use) to distribute URL's that refer to potentially copyrighted material; since the URL is only a reference, the URL is legal to distribute under fair use. I hereby volunteer to maintain a list of references, and to automate the process of updating that list, so any random schmo or monkey could trivially take over the job at any time. I can establish some way of automating a periodic comparison on a fully updated windows system, versus the published list, and generating an alert whenever Microsoft's list deviates. Upon alert, an unskilled human or monkey such as myself would then manually apply a change to the URL list, so literally no information (and hence no copyrighted information) gets copied from either Microsoft or the CA, and yet the list will adapt over time to follow Microsoft's practices of root & intermediate selections.
I think it's ok for the list of URL's to be hard-coded into mono, or distributed from a particular URL, or even a completely separate open source project. If it's hard-coded into mono, it will have the advantage of always working, but users would only get updates when they update mono. If you think about it, that's actually a pretty reasonable constraint, because updates to that list *are* security updates, and users *should* be updating mono regularly for bugfixes and security updates. Also, there are well established precedents - for example in Windows, you only get updates to your root list if you run Windows Updates. And in linux, you only get updates to your root list if you run yum or apt updates, etc. In OSX, you only get updates if you run Software Updates. So it seems reasonable that users would only get updates to the mono MSRoots cert lists when they run system updates on mono. I endorse the idea of distributing the URL's hard-coded into mono MSRoots class, but ultimately, this is a question for somebody of authority in mono. (Miguel? Sebastien? Someone else?)
2- I would like to put effort into X509Chain.Build(), to make it smarter. Obviously, since it currently doesn't even think about using the intermediate store, that's some obvious room for improvement. All of the above talk about MSRoots is for naught until X509Chain.Build utilizes the intermediates store. I am pretty sure, but I'd like to discuss in a separate email, that there are some other flaws in how X509Chain.Build() chooses to build the chain. I wouldn't be able to specifically say right now - I'll need to look close and scrutinize first.
More information about the Mono-devel-list