In SSL/TLS, the server is supposed to send a certificate chain to the client, to make the client easily validate the authenticity of the server from one of the client's trusted root CA's. If the server doesn't send a chain, the client can make some level of effort trying to construct the chain, but each client implementation might perform that effort differently.
I'm digging into this some more, but the observed behavior is:
I'm using SslStream. When I connect a mono client to a mono server, I can step through mono source on the client and I can see the server doesn't send the chain. The client therefore checks root CA's but no intermediates, and therefore fails. (To be technically accurate, the server incorrectly sends a chain with zero items in it, which causes the client to only check root CA's with no intermediates. The behavior would be different if the server had sent a "null" chain, in which case the mono client will execute different code, attempting to construct a chain, but I don't actually know if that other code would succeed or not.)
My test program, with the exact same C# code with the exact same cert, running on windows server, actually sends the chain to the client, including a single item, which is the intermediate, and therefore, both windows & mono clients are able to authenticate the windows server with no problem.
The mono server, connected with a windows client, presumably does not send the chain to the client (but I can't step through MS code to confirm this assumption), but the client is able to authenticate the server, so presumably the windows client makes more effort to construct the chain, or perhaps the client has some sort of pre-built chain in its list to check... All I know is that it works.
So the problem only exists with a mono server, connected to a mono client, when the server cert is signed by an intermediate.
I'm rather amazed that I'm the first person to observe this, as every CA that I know of actually signs certs with intermediate authorities. I'd like to ask the community:
Do you run any mono SSL server, connected with mono SSL clients? Does your server certificate include an intermediate chain? Did you make your clients override a cert that the client would naturally reject from the server? Did you tweak your client trusts, more than simply running mozroots, in order to make your intermediate chain work?