[Mono-list] Private key failure SslStream based authentication on Mono/UbuntuLinux

Chirag Patel patel.chirag.d at gmail.com
Fri May 27 14:12:04 EDT 2011


Hello Sebastien,

I also want to mention my setup.
Windows is my client.
Linux is the server - a VM on the same Windows machine above. (I have
hopefully! disabled firewall)

But please read on :)

On Fri, May 27, 2011 at 10:42 AM, Sebastien Pouliot
<sebastien.pouliot at gmail.com> wrote:
> On Fri, 2011-05-27 at 09:49 -0700, Chirag Patel wrote:
>> Hello Sebastien,
>>
>> I see some progress. The progress came out of using X509Certificate2
>> on my linux server.
>> So, private key exception is gone.
>
> Great :-)
>
>> Now I face another problem on client side (on the code that has run
>> fine on windows for 1 year).
>
> Still on Windows / .NET ?
> or running Mono ?
>
Client side: Windows + Microsoft .NET 3.5
Server side: Linux + Mono 2.6 (latest stable release)

> If the later, windows or linux ? version ? ...
>
>>                 _sslstream = new SslStream(_tcpclient.GetStream(), false,
>>                     callback, null);
>>                 _sslstream.AuthenticateAsClient("", _certs, SslProtocols.Ssl3,
>>                     false);
>> The application stalls at AuthenticateAsClient. Never goes forward.
>> And based on Debug output, I see that it has server's Remote
>> Certificate name mismatch issue.
>> (I think it has problem identifying server as what the server says it is)
>
> If you're using client certificates then you'll need to make sure they
> (the client certs) are signed by a certificate root that is trusted by
> the server.
>
My certificate is purchased and signed from Verisign.
But I change what I said. Actually, it looks like on the client it
goes further from AuthenticateAsClient (though I don't see that
clearly on serverside).
But the next step Client does is Read. As server is supposed to send a
greeting response with some server details.
           _sslstream.Read(buffer, offset, size);
If looks like this one doesn't move forward for quite a while. (This
time I am more sure because I was in debugging session on both client
and server :))
The last thing server did was BeginHandshake call.
                  SslStream :: BeginAuthenticateAsServer(serverCert, true,
 SslProtocols.Ssl3, true, callback, this);	
On top of that, when I 'stop' the client, server's EndHandshake (viz.
EndAuthenticateAsServer) is called.

>> Here's what I tried after that.
>> I ran my server on windows and linux both to get the Subject of the
>> certificate on both sides. They were exactly the same.
>
> Subject name must match the server name, e.g. DNS lookup, so the client
> can be sure its talking to the right host (e.g. avoid MitM)
2 things. I have a windows hosts file entry that points the
certificate subject name to right IP.
(though the Linux VM name is not the same as certificate subject name)
Another fact is that in the client code I allow all server cert errors
to go through temporarily. This is with the validation callback
function.
(This is where I found that RemoteCertificateNameMismatch error)

>
>>
>> Could you think of anything else?
>
> iirc old Mono releases had some limitations when subject names had
> wildcards, e.g. CN=*.mysite.com
Good to know that, but I do not have wildcard. My cert is like abc.xyz.com
>
>> I have also included some inline messages out of curiosity.
>>
>> Thanks
>>
>> On Thu, May 26, 2011 at 1:31 PM, Sebastien Pouliot
>> <sebastien.pouliot at gmail.com> wrote:
>> > Hello Chirag,
>> >
>> > On Thu, 2011-05-26 at 13:17 -0700, Chirag Patel wrote:
>> >> Hi All,
>> >>
>> >> I am working on migrating my .NET based windows service to mono and linux.
>> >>
>> >> I am using SslStream and its BeginAuthenticateServer method.
>> >>
>> >> Exception: The authentication or decryption has failed.
>> >> Inner Exception: Server certificate Private Key unavailable.
>> >> at Mono.Security.Protocol.Tls.Handshake.Server.TlsClientKeyExchange.ProcessAsSsl3
>> >> () [0x00000] in <filename unknown>:0
>> >>   at Mono.Security.Protocol.Tls.Handshake.HandshakeMessage.Process ()
>> >> [0x00000] in <filename unknown>:0
>> >>   at (wrapper remoting-invoke-with-check)
>> >> Mono.Security.Protocol.Tls.Handshake.HandshakeMessage:Process ()
>> >>   at Mono.Security.Protocol.Tls.ServerRecordProtocol.ProcessHandshakeMessage
>> >> (Mono.Security.Protocol.Tls.TlsStream handMsg) [0x00000] in <filename
>> >> unknown>:0
>> >>   at Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback
>> >> (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0
>> >>
>> >> [http://lists.ximian.com/pipermail/mono-list/2007-February/034278.html]
>> >>
>> >> I see that Sebastien has pointed out using alternate
>> >> Mono.Security.Protocol.Tls.SslServerStream class,
>> >> and its delegate to fetch private key. (because of difference between
>> >> linux vs. windows handling of certs.)
>> >
>> > That's an alternative, not the best, but it has quite a bit of source
>> > code using it (e.g. xsp) and is easy to adapt (to whatever source you're
>> > loading the private key from).
>> >
>> >> What is next? Just use the server certificate from SslServerStream
>> >> property, and dispose the stream?
>> >
>> > No, if you start using SslServerStream then you'll need to use it
>> > completely (forget SslStream).
>> >
>> >> And continue using original Microsoft SslStream?
>> >
>> > That's another choice and needs a different solution :)
>> >
>> >> Or
>> >> I just have to use Mono's SslServerStream and manually write read
>> >> "any/irrelevant" data to proceed with authentication?
>> >
>> > No
>> If I were to use SslServerStream, what Logic would replace
>> SslStream::BeginAuthenticateAsServer?
>
> I don't recall. Best to look at Mono's source code for SslStream :-)
>
>>
>> >
>> >> I am using PFX file. I did include private key. So, Do I even need to
>> >> use the delegate to load private key separately??
>> >> (How can I debug whether the loaded X509Certificate instance has the
>> >> private key loaded.)
>> >>
>> >> I have also tried this with a Verisign issued real certificate. But
>> >> since that entire thing including export was done on Windows, I tried
>> >> my code with self-signed (linux - openssl) cert.
>> >
>> > Two things comes to mind:
>> >
>> > 1. make sure Mono can read your PKCS12 file (e.g. load it using
>> > X509Certificate2 and dump its properties). This is important because
>> > Mono's ASN.1 implementation does not support "indefinite length" and
>> > some tools generates them.
>> >
>> > 2. When using SslStream + PKCS12 also make sure you're using
>> > X509Certificate2 (***2*** not X509Certificate). This will ensure the
>> > private key, if present, will be loaded in memory and will let SslStream
>> > use it.
>> >
>> I think (2) did solve the problem: Private key unavailable.
>> I mentioned I load cert from PFX file. I wonder what's the ideal way
>> to handle certificates in mono+linux?
>
> Yes, it helps for self-contained applications...
>
>> I see /etc/ssl...but that doesn't provide exact facilities like
>> microsoft certificate store. I used a tool called XCA on ubuntu, but
>> it creates its own database file.
>
> ... since there's no single standard as you found out ;-)
>
> Sebastien
>
>


More information about the Mono-list mailing list