[Mono-aspnet-list] WebRequest POST with client certificate
Stefan Kadow
stefan.kadow at cervis.de
Sun Jan 13 23:36:54 UTC 2013
Hello,
I have a MVC2 web application running on Debian squeeze with Apache
2.2.16, OpenSSL 0.9.8 and mono 2.6.7. I want to secure the access with
SSL client certificates, for identification and authorization.
The client programm running on another machine uses the HttpWebRequest
class for accessing the server with HTTP methods "GET" and "POST". On
windows machines the client program runs fine using .NET 3.5.
On Linux machines the client program runs only with HTTP method "GET". A
WebRequest with HTTP method "POST" throws an exception. I tried the
following code on client machines with Debian squeeze (mono 2.6.7) and
Debian wheezy (mono 2.10.8).
The following code (HTTP "GET") runs successful on Windows and Linux:
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create("https://server.net/mvc/contr/action");
X509Certificate2Collection certColl =
new X509Certificate2Collection();
certColl.Import("certfile.p12", "123",
X509KeyStorageFlags.Exportable);
request.ClientCertificates.AddRange(certColl);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(response.StatusDescription);
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
Console.WriteLine(reader.ReadToEnd());
The following code (HTTP "POST") runs successful on Windows, but throws
an excpection on Linux:
HttpWebRequest request = (HttpWebRequest)
WebRequest.Create("https://server.net/mvc/contr/action");
X509Certificate2Collection certColl =
new X509Certificate2Collection();
certColl.Import("certfile.p12", "123",
X509KeyStorageFlags.Exportable);
request.ClientCertificates.AddRange(certColl);
string postData = @"<?xml version=\"1.0\" encoding=\"utf-8\"?>
<message/>";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.Method = "POST";
request.ContentType = "text/xml";
request.ContentLength = byteArray.Length;
request.KeepAlive = false; // needed for POST-requests(?)
Stream requestStream = request.GetRequestStream();
requestStream.Write(byteArray, 0, byteArray.Length); // exception
requestStream.Close();
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(response.StatusDescription);
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
Console.WriteLine(reader.ReadToEnd());
The exception thrown is:
System.Net.WebException: Error getting response stream (ReadDone1):
ReceiveFailure ---> System.IO.IOException: The authentication or
decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: The
authentication or decryption has failed.
Apache error log lists:
[error] Re-negotiation handshake failed: Not accepted by client!?
Apache configuration:
# mono.security needs old/insecure re-negotiation:
SSLInsecureRenegotiation on
<Directory /var/www/bin/mvc>
SSLVerifyClient require
SSLVerifyDepth 1
SSLUserName SSL_CLIENT_S_DN_CN
SSLOptions +StdEnvVars +ExportCertData +OptRenegotiate
</Directory>
The server certificate is signed by GeoTrust, the GeoTrust root
certificate is installed with certmgr.exe in Trust store. The
self-signed CA certificate, which signed the client certificates is part
of the pkcs12-file and additionally installed in Trust store, too.
But, the certificates can not be the problem, because the WebRequests
with HTTP method GET are running fine on Linux client machines.
More information about the Mono-aspnet-list
mailing list