[Mono-dev] HTTPS - MS .NET Client - Linux Mono Server - Interoperability

Sebastien Pouliot sebastien.pouliot at gmail.com
Wed Sep 28 08:12:15 EDT 2005


Hello Yngve,

On Wed, 2005-28-09 at 11:42 +0200, Yngve Zackrisson wrote:
> Hello Sebastien,
> 
> Things seems to go better for me, 

great :)

> but I still have problems 
> with my server side (Mono) authentication and decryption.
> I now use a PKCS#12 file on my server side.
> Se below for more info.

...

> > > For the authentication probably an custom channel have to be used.
> > 
> > I don't see why this would be required (for client-side certificates) as
> > the authentication is part of the protocol itself.
> > 
> 
> OK. Maybe I do not need this.
> I just read some articles/samples at msdn about 
> .NET Remoting Authentication 
> and those articles suggested a custom channel.
> (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/remsspi.asp and http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/remsec.asp
> and
> http://msdn.microsoft.com/msdnmag/issues/03/06/NETRemoting/default.aspx
> ). 
> The examples was about other forms of authentication (Kerberos etc) 
> and encryption so these references may not apply?.

I don't think you'll need that unless you have some additional (more
than the client certificate) authentication data.

...

> We intend to sign both our server and client certificates 
> with our own root CA.
> There is already unix scripts for this using openssl, 
> hence the preference for openssl.

Ok, so you'll have a single root CA signing both your server and client
certificate. This root certificate will have to be in the Mono's Trusted
store on the server.

...

> > > Binary formating shall be used.
> > 
> > Was there a specific reason for using https and a binary formatting ? If
> > I understand correctly you'll be supplying your own server software ? so
> > you _could_ use SSL without using HTTP(S).
> 
> Firewalls.

Ok, so it's a port issue (not a protocol issue).

> > > The server is in house and should be a Linux one.
> > > We use latest version on Mono (1.1.9).
> > 
> > Is the server software using Mono.Security.dll ? 
> > or is it using (vanilla or custom) XSP ?
> 
> Currently Mono.Security.dll.
> 
> The intention is to run the services as "Windows services" in Mono,
> if that works.

Remember that if the Mono service runs under another identity then the
trusted root certificate must either be (a) in that user Trust store or
(b) in the machine Trust store.

> I have not got into this yet, so we might have to shift.
> Currently I host the remote objects in a console application.
> 
> > 
> > > The clients are Win32 clients using MS .NET 
> > > (v1.0 or v1.1 with SP enough to handle the certificates).
> > > 
> > > The clients are not connected all the time, but only during 
> > > initialization and zip file transfer.
> > > 
> > > The installation on the client side should be as simple as possible 
> > > for the clients. 
> > > Hence, preferable PKCS#12 client certificates should be used 
> > > and it should preferable be stored only in one file or in one store 
> > > (Windows store).
> > 
> > You'll either have to :
> > 
> > (a) write your own glue (p/invokes) if you want Mono.Security.dll to
> > co-exists with Windows certificate stores;
> > 
> > (b) completely skip Mono.Security.dll on the client side. I.e. once
> > installed "correctly" the MS runtime should be able to "find" the
> > private key matching the certificate you use in HttpWebRequest.
> 
> OK. I have gone for (b).
> 
> First I set the ServicePointManager.CertificatePolicy 
> to an custom class to detect any certificate errors.
> 
> Then I use a DLL from Mentalis (Org.Mentalis.Security.dll) 
> to extract the client certificates from the Windows store, 
> and then select on the IssuerName.
> Once that done, I use the Mentalis Certificate.ToX509() method 
> to convert to X509Certificate(s).
> (See: http://www.mentalis.org/ and 
> http://www.mentalis.org/soft/projects/certificates/ ).
> 
> Last I create the HttpWebRequest, 
> Add the X509Certificate(s) the requests ClientCertificates 
> and set the WebResponse to the HttpWebRequest.GetResponse().
> It seems to work (on the client side). 
> No more "Untrusted root", since the certificates 
> is in the Windows store now.

That's ok.

> Other options for extracting the certificate(s) 
> from the Windows store seems to be: 
> 
> Using CryptoAPI calls:
> http://support.microsoft.com/default.aspx?scid=kb;en-us;895971
> 
> Using a CAPICOM wrapper: 
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncapi/html/netcryptoapi.asp
> 
> Using WS-Security with the Web Service Developement Kit:
> http://www.codeproject.com/csharp/cryptography.asp

Yes, they are the other options.

> > > As a first step, I would like to have the HttpWebRequest 
> > > and HttpWebResponse to work toghther with HTTPS.
> > 
> > MS version of HttpWebRequest.ClientCertificates will "try to find"
> > private keys (in it's store) associated with the certificate(s) you're
> > supplying.
> > 
> > Note that you may have problems if the client application runs on
> > another identity (e.g. services runs as SYSTEM).
> 
> OK. (Seems no problem for me).
> 
> > 
> > Then, on the server side, you'll get this certificate (from
> > SslServerStream) and you can validate it (with your own code) and decide
> > what to do next...
> 
> Here I still have problems.
> 
> I have created a mssslserver2.exe based on your mssslserver.exe.
> The difference is that mssslserver2.exe uses 
> a PKCS#12-filename and a password as arguments, 
> instead of a .cer-filename and .pvk-filename.
> I have change the internals accordingly.
> 
> When I run this program with: 
> 
> $ mono --debug --verbose mssslserver2.exe server16-cert.p12 'password'
> 
> and call this with my client HttpWebRequest, 
> I got this error message on my server: 
> 
>     error #-2146762486
> 
> meaning a CERT_E_CHAINING problem 
> (also: X509ChainStatusFlags.UntrustedRoot 
> and AlertDescription.UnknownCA).
> 
> I am pretty sure I have the right cert, key and CA in the .p12 file.
> It seems that the root CA could not be found if it is in a PKCS#12 file.

The root can (very probably) be found in the PKCS#12 file. However it
_cannot_ be trusted *unless* it's installed in the Trust store.

> Should I add a PKCS#12 cert file to the Mono Store (Machine store) 
> (mono /.../certmgr.exe -add -c -m Trust server16-cert.p12) 
> or add only the CA to the trust store
> (mono /.../certmgr.exe -add -c -m Trust cacert16t.cer)
> or anything else to get rid of this error message?.

It must be either the user or machine Trusted store (otherwise you'll
get a trust error).

> On the server I get an exception during the client call 
> (in: reader.ReadLine ()) below: 
> >>>
> ...
> using (SslServerStream s = new SslServerStream (ns, Certificate, true, 
> false)) {
> ... 
> StreamReader reader = new StreamReader (s);
> ...
> string line;
> // Read request header 
> do {
>         line = reader.ReadLine ();
> ...
> <<<
> 
> The exception goes like this:
> >>>
> EXCEPTION handling: TlsException
> EXCEPTION handling: TlsException
> EXCEPTION handling: IOException
> EXCEPTION handling: IOException
> ---------------------------------------------------------
> System.IO.IOException: The authentication or decryption has failed. --->
> Mono.Security.Protocol.Tls.TlsException: Handshake Failure.
> in <0x00134> 
> Mono.Security.Protocol.Tls.Handshake.Server.TlsClientCertificateVerify:ProcessAsSs3  ()
> in <0x00057> 
> Mono.Security.Protocol.Tls.Handshake.HandshakeMessage:Process ()
> in (wrapper remoting-invoke-with-check) 
> Mono.Security.Protocol.Tls.Handshake.HandshakeMessage:Process ()
> in <0x00084> 
> Mono.Security.Protocol.Tls.ServerRecordProtocol:ProcessHandshakeMessage 
> (Mono.Security.Protocol.Tls.TlsStream handMsg)
> in <0x00239> 
> Mono.Security.Protocol.Tls.RecordProtocol:InternalReceiveRecordCallBack 
> (IAsyncResult asyncResult)--- End of inner exception stack trace ---
> 
> in <0x000d4> 
> Mono.Security.Protocol.Tls.SslStreamBase:AsyncHandshakeCallback
> (IAsyncResult asyncResult)
> <<<
> 
> I guess that this has to do with the CERT_E_CHAINING problem 
> mentioned above. Possible?. Right?

Maybe but I don't think so.

Yesterday (after your previous email) I tried to use the MS runtime for
client certificate without success (same failure). Somehow MS does
something different* because the server can't verify the signature (and
it's not a key and/or decryption problem - the hash value is different
but the padding is ok).

Using IE (with the SSL2 client hello) to do the same turned out another
problem, very similar to the bug #76254 reported today.

[*] The client certificate testing is done with wget/openssl
(linux/cygwin) - which sadly doesn't seems enough :(
-- 
Sebastien Pouliot
email: sebastien at ximian.com
blog: http://pages.infinit.net/ctech/




More information about the Mono-devel-list mailing list