Bug 6843 - Missing protocol in SslStream
Summary: Missing protocol in SslStream
Alias: None
Product: Class Libraries
Classification: Mono
Component: Mono.Security ()
Version: 2.10.x
Hardware: PC Linux
: --- normal
Target Milestone: Untriaged
Assignee: Sebastien Pouliot
: 11736 ()
Depends on:
Reported: 2012-09-02 10:25 UTC by Peter Hultqvist
Modified: 2014-08-07 00:48 UTC (History)
7 users (show)

Is this bug a regression?: ---
Last known good build:

Wireshark capture of the failed attempts (8.41 KB, application/vnd.tcpdump.pcap)
2012-09-02 10:25 UTC, Peter Hultqvist
patch/proof following RFC compatibility for version > TLSv1.0 (1004 bytes, patch)
2013-08-16 08:53 UTC, Olivier

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Peter Hultqvist 2012-09-02 10:25:06 UTC
This was originally posted on the Mono-list where Sebastien Pouliot had a look at it but unfortunately did not have time to find a fix at the time.

I'm writing an IMAP server that will accept SSL connections.

It is tested using openssl:
    openssl s_client -connect localhost:1993

On connection an IOException is thrown with an inner
NotSupportedException: "Unsupported security protocol type"

I have tried using two methods:

With the System.Net.Security.SslStream:

            ssl = new SslStream(tcp.GetStream(), false);
                AuthenticateSslCallback, null);

And with the Mono.Security.Protocol.Tls.SslServerStream:

                ssl = new SslServerStream(
                    true, SecurityProtocolType.Tls);

Both are generating the same exception mentioned above.

This was all tested on Ubuntu, mono
When the first example was tried on windows it worked.

Further the output from the openssl s_client was:
from the output of openssl, the client, I get:
    Protocol  : TLSv1
    Protocol  : SSLv3
Matching the SslProtocols.Tls/Ssl3 that I put in the
AuthenticateAsServer() call in the server code.

Using Wireshark I got from the client:

SSLv3 Record Layer: Handshake Protocol: Client Hello
Version: TLS 1.0 (0x0301)

but the next packet from my server is:

SSLv3 Record Layer: Alert (Level: Warning, Description: Internal Error)
Version: TLS 1.0 (0x0301)

I got it working using a third option, the OpenSSL.NET wrapper.

Attached file is a wireshark trace of:

the 1993.pcap file is a wireshark/libpcap(I added the pcap suffix
myself) type containing 5 attempts
1,2: openssl s_client
3: (failed)
4,5: using the following code:

TcpClient tcp = new TcpClient();
            tcp.Connect(IPAddress.Loopback, 1993);

            SslStream ssl = new SslStream(tcp.GetStream(), false, Validate);

Using the client code works against the server code.

I installed the mono-dbg package to get filename and line in the

{System.IO.IOException: The authentication or decryption has failed.
---> System.NotSupportedException: Unsupported security protocol type
  at Mono.Security.Protocol.Tls.Context.DecodeProtocolCode (Int16 code)
[0x00026] in
(Int16 protocol) [0x00000] in
() [0x00000] in
  at Mono.Security.Protocol.Tls.Handshake.HandshakeMessage.Process ()
[0x00037] in
  at (wrapper remoting-invoke-with-check)
Mono.Security.Protocol.Tls.Handshake.HandshakeMessage:Process ()
(Mono.Security.Protocol.Tls.TlsStream handMsg) [0x0002a] in
(IAsyncResult asyncResult) [0x00127] in
  --- End of inner exception stack trace ---
  at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback
(IAsyncResult asyncResult) [0x00044] in

The openssl version was: OpenSSL 1.0.1 14 Mar 2012 (from the default ubuntu repo of 12.04)
Comment 1 Peter Hultqvist 2012-09-02 10:25:44 UTC
Created attachment 2446 [details]
Wireshark capture of the failed attempts
Comment 2 Victor Nicollet 2013-05-28 12:22:21 UTC
The problem appears to come from Mono.Security.Protocol.Tls.Context.DecodeProtocol code, which sees the protocol version 0x0302 (TLS 1.1) in the Client Hello message, and breaks. 

This would be correct at any other point, but the version number sent during the Client Hello message should be interpreted as "this is the highest version I can use". So, for that message in particular, Mono should accept values greater than 0x301 (TLS 1.0) from the client, and respond with 0x301 itself.
Comment 3 Olivier 2013-08-16 08:53:23 UTC
Created attachment 4646 [details]
patch/proof following RFC compatibility for version > TLSv1.0
Comment 4 Olivier 2013-08-16 09:00:32 UTC
According to rfc5246 (E.1.Compatibility with TLS 1.0/1.1 and SSL 3.0), when a hello, version > TLSv1.0 id received, the client/server must reply with the highest supported version.

The patch attached solve the issue, however I'm not sure it does not introduce new biais
Comment 5 Sebastien Pouliot 2014-01-22 20:51:48 UTC
*** Bug 11736 has been marked as a duplicate of this bug. ***
Comment 6 Sebastien Pouliot 2014-01-22 20:53:39 UTC
Thanks Olivier. The patch is not quite right (it affects both client and server code) but close. I'll test the changes soon (along with other SSL/TLS fixes).
Comment 7 Sebastien Pouliot 2014-01-24 08:47:40 UTC
Fixed in mono/master 5048ce7bd9c9127e69006986ed66b2380e0b2f8b
Comment 8 alex 2014-08-06 20:06:36 UTC
What version of Mono has the fix been deployed in (if it has)? It is still present in 3.4 across all platforms (Ubuntu, Windows and Mac).
Comment 9 alex 2014-08-07 00:48:27 UTC
Disregard previous. One of the team noticed that the specific Npgsql.dll we use was pulling in an older version of Mono.Security.dll
Deleting the old dll from the bin, and referencing the gac version resolved the error.