Mono Frustrations: “The authentication or decryption has failed.”

Often calling the AuthenticateAsClient method of an SslStream results in the “The authentication or decryption has failed.” error, because Mono cannot verify the certificate. As a last resort, the error can be circumvented by disabling the certificate validation by adding the following line to the code:

ServicePointManager.ServerCertificateValidationCallback += (o, certificate, chain, errors) => true;

If you are creating the SslStream in a using block, you can do this instead:

using (SslStream s = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback((o, certificate, chain, errors) => true)))
{
s.AuthenticateAsClient(uri.Host, null, SslProtocols.Tls, false);
...
}

Mono Frustrations: WebRequest

The WebRequest class has many issues, especially in Mono. A major problem occurs when the response code is an HTTP error (e.g. 4xx), for which the class throws an Exception, causing a Runtime Error if it goes unhandled. This is not a big deal in .NET, because the request.GetResponse() call can be surrounded by a try/catch block that catches the thrown WebException, which still contains the response in its Response property. However, a bug in Mono makes it impossible to retrieve the response from a WebException, as the Response property is always null.

Solution: It is a better idea to use a TcpClient instead and manually generate an HTTP request using it.