Bug 40381 - newtls SslStream
Summary: newtls SslStream
Status: RESOLVED FIXED
Alias: None
Product: Class Libraries
Classification: Mono
Component: Mono.Security ()
Version: master
Hardware: PC Linux
: --- normal
Target Milestone: Untriaged
Assignee: Martin Baulig
URL:
Depends on:
Blocks:
 
Reported: 2016-04-14 07:34 UTC by gen
Modified: 2016-11-03 16:29 UTC (History)
8 users (show)

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

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:
Status:
RESOLVED FIXED

Description gen 2016-04-14 07:34:50 UTC
I am testing newtls.
This is my test program

------------------------------------------------------------

using System;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;

namespace TlsTest
{
    class Program
    {
        public static void Main()
        {
            try
            {
                Console.WriteLine("SslStream test");
                TcpClient client = new TcpClient("google.com", 443);
                SslStream sslStream = new SslStream(
                                client.GetStream(),
                                false,
                                new RemoteCertificateValidationCallback(ValidateServerCertificate),
                                null
                                );
                sslStream.AuthenticateAsClient("google.com", new X509CertificateCollection(), SslProtocols.Tls, false);
                Console.WriteLine("success [protocol={0}]", sslStream.SslProtocol);
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.ToString());
            }
        }

        static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
    }
}

------------------------------------------------------------

oldtls is working as intended:

/sv5$ MONO_TLS_PROVIDER=oldtls
/sv5$ export MONO_TLS_PROVIDER
/sv5$ mono TlsTest.exe
SslStream test
success [protocol=Tls]

But newtls failed with an exception:

/sv5$ MONO_TLS_PROVIDER=newtls
/sv5$ export MONO_TLS_PROVIDER
/sv5$ mono TlsTest.exe
SslStream test
System.ArgumentNullException: Value cannot be null.
Parameter name: type
  at System.Activator.CreateInstance (System.Type type, BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object[] args, System.Globalization.CultureInfo culture, System.Object[] activationAttributes) <0x7fa1f0ee87e0 + 0x001fc> in <filename unknown>:0 
  at System.Activator.CreateInstance (System.Type type, System.Object[] args) <0x7fa1f0ee8a60 + 0x00023> in <filename unknown>:0 
  at Mono.Security.Providers.NewTls.TlsProviderFactory.CreateInstance (System.String typeName, System.Object[] args) <0x405421a0 + 0x00048> in <filename unknown>:0 
  at Mono.Security.Providers.NewTls.TlsProviderFactory.CreateTlsConfiguration (System.String hostname, Boolean serverMode, TlsProtocols protocolFlags, System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, Boolean remoteCertRequired, Mono.Security.Interface.MonoTlsSettings settings) <0x40541d70 + 0x002b3> in <filename unknown>:0 
  at Mono.Security.Providers.NewTls.NewTlsProvider.CreateTlsContext (System.String hostname, Boolean serverMode, TlsProtocols protocolFlags, System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, Boolean remoteCertRequired, MonoEncryptionPolicy encryptionPolicy, Mono.Security.Interface.MonoTlsSettings settings) <0x40541ce0 + 0x00037> in <filename unknown>:0 
  at Mono.Net.Security.Private.MonoTlsProviderWrapper.CreateTlsContext (System.String hostname, Boolean serverMode, TlsProtocols protocolFlags, System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, Boolean remoteCertRequired, Boolean checkCertName, Boolean checkCertRevocationStatus, MonoEncryptionPolicy encryptionPolicy, Mono.Security.Interface.MonoTlsSettings settings) <0x40541c10 + 0x000ae> in <filename unknown>:0 
  at System.Net.Security.GlobalSSPI.Create (System.String hostname, Boolean serverMode, SchProtocols protocolFlags, System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, Boolean remoteCertRequired, Boolean checkCertName, Boolean checkCertRevocationStatus, EncryptionPolicy encryptionPolicy, System.Net.Security.LocalCertSelectionCallback certSelectionDelegate, System.Net.Security.RemoteCertValidationCallback remoteValidationCallback, SSPIConfiguration userConfig) <0x40541aa0 + 0x000bf> in <filename unknown>:0 
  at System.Net.Security.SecureChannel..ctor (System.String hostname, Boolean serverMode, SchProtocols protocolFlags, System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, Boolean remoteCertRequired, Boolean checkCertName, Boolean checkCertRevocationStatus, EncryptionPolicy encryptionPolicy, System.Net.Security.LocalCertSelectionCallback certSelectionDelegate, System.Net.Security.RemoteCertValidationCallback remoteValidationCallback, SSPIConfiguration config) <0x40541110 + 0x0025b> in <filename unknown>:0 
  at System.Net.Security.SslState.ValidateCreateContext (Boolean isServer, System.String targetHost, SslProtocols enabledSslProtocols, System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, Boolean remoteCertRequired, Boolean checkCertRevocationStatus, Boolean checkCertName) <0x40540be0 + 0x002bf> in <filename unknown>:0 
  at System.Net.Security.SslState.ValidateCreateContext (Boolean isServer, System.String targetHost, SslProtocols enabledSslProtocols, System.Security.Cryptography.X509Certificates.X509Certificate serverCertificate, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, Boolean remoteCertRequired, Boolean checkCertRevocationStatus) <0x40540b70 + 0x0005f> in <filename unknown>:0 
  at System.Net.Security.SslStream.AuthenticateAsClient (System.String targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation) <0x40540af0 + 0x0004f> in <filename unknown>:0 
  at System.Net.Security.SslStream.AuthenticateAsClient (System.String targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation) <0x40540950 + 0x00078> in <filename unknown>:0 
  at TlsTest.Program.Main () <0x4050bd70 + 0x00131> in <filename unknown>:0 



/sv5$ mono --version
Mono JIT compiler version 4.4.0 (Stable 4.4.0.122/a3fabf1 Ср апр 13 23:53:52 MSK 2016)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
	TLS:           __thread
	SIGSEGV:       altstack
	Notifications: epoll
	Architecture:  amd64
	Disabled:      none
	Misc:          softdebug 
	LLVM:          supported, not enabled.
	GC:            sgen
Comment 1 Guerry Semones 2016-08-17 23:24:20 UTC
I have a Console App on Mac OS X (El Capitan) that self-hosts using OWIN/Katana and SignalR. I am shifting to "newtls" to get away from the issue with the oldtls not sending intermediate certifcates. 

When I set MONO_TLS_PROVIDER=newtls, I get the same exceptions reported above whether my code is a client or a server:

1) When using AWS S3 client, I get this exception.

2) When using HttpWebRequest as a client, I get this exception.

3) When I bind my port to my own valid certificate as a server, and a browser client attempts to talk to my server using https, I get this exception.

Hopefully this helps. I'm presuming this bug manifests on OSX, but not on IOS.

Thanks,

Guerry

Mono JIT compiler version 4.4.2 (mono-4.4.0-branch-c7sr1/f72fe45 Wed Jul 27 16:20:13 EDT 2016)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
       	TLS:           normal
       	SIGSEGV:       altstack
       	Notification:  kqueue
       	Architecture:  x86
       	Disabled:      none
       	Misc:          softdebug
       	LLVM:          yes(3.6.0svn-mono-master/a173357)
       	GC:            sgen
Comment 2 Guerry Semones 2016-09-09 18:02:15 UTC
Looking at the source code I see that TlsProviderFactory is trying to load the TlsProvider from an assembly named Mono.Security.NewTls.dll. In the versions of Mono that I have parallel installed I only find Mono.Security.ProvidersNewTls.dll. The null pointer exception occurs at CreateInstance because the assembly does not exist (at least on my system). Is TlsProviderFactory an old implementation or am I supposed to compile and add a different assembly from another project?
Comment 3 Guerry Semones 2016-09-09 18:03:52 UTC
Typo above should have been Mono.Security.Providers.NewTls.dll
Comment 4 Guerry Semones 2016-09-15 20:10:00 UTC
Over on the discussion lists, Miguel pointed out to me that I might have an old runtime. I had suspected that, and so here is what I've done. I've removed all copies of mono except the Beta channel from my Xamarin Studio Enterprise. Using 'mono --version' at the command line reports: 

Mono JIT compiler version 4.6.0 (mono-4.6.0-branch/746756c Thu Sep  8 05:39:12 EDT 2016) 

Calling mono_get_runtime_build_info from within my console app, I get the same:

Mono runtime version: 4.6.0 (mono-4.6.0-branch/746756c Thu Sep  8 05:39:12 EDT 2016)

I'm compiling my console app to .NET Framework 4.6 

As far as I can tell, I only have 4.6.0 active and running. 

My main confusion is that Mono.Security.Providers.NewTls.TlsProviderFactory tries to load an assembly Mono.Security.NewTls, which does not seem to exist in my copy of 4.6.0. I know this existed in the mono-tls project previously.

Thanks, 

Guerry
Comment 5 Guerry Semones 2016-09-15 20:13:27 UTC
Also reporting from my app, my TLS provider is:

TLS Provider: Mono.Security.Providers.NewTls.NewTlsProvider

I have the following included in my references:
Mono.Security
Mono.Security.Providers.NewTls

Thanks,

Guerry
Comment 6 mg 2016-09-21 15:23:25 UTC
I can also repro this issue

Mono JIT compiler version 4.6.0 (Stable 4.6.0.245/746756c Wed Sep 14 09:49:13 UTC 2016)
(on a fresh Ubuntu install, packages installed from Xamarin sources)
Comment 7 Alexander Bekrenev 2016-09-23 12:41:41 UTC
I have same issue with
Mono JIT compiler version 4.6.0 (Stable 4.6.0.245/746756c Wed Sep 21 14:16:42 UTC 2016)

Mono.Security.Providers.NewTls.TlsProviderFactory has constants
	const string assemblyName = "Mono.Security.NewTls, Version=4.0.0.0, Culture=neutral, PublicKeyToken=84e3aee7225169c2";
	const string tlsConfigTypeName = "Mono.Security.NewTls.TlsConfiguration";
	const string tlsContextTypeName = "Mono.Security.NewTls.TlsContext";
That constants use wrong namespaces or current mono release miss that classes. That classes are from mono-tls.
I do not know how to fix it on mono so cannot suggest a decision.

But I have workaround as I urgently need to use TLS 1.2 for my projects.
If you want to use "newtls" provider then you need to get sources  from github.
Get 'mono/mono-tls'. 
Then get source of 'xamarin/web-tests' to 'mono/mono-tls/external'.
You need to create new solution with next projects: 
Mono.Security.NewTls and Mono.Security.NewTls.Instrumentation from 'mono-tls/' 
and Mono.Security.Interface from 'external/web-tests/Console'
Build it and get three dlls: Mono.Security.Interface.dll, Mono.Swecurity.NewTls.dll and Mono.Security.NewTls.Instrumentation.dll
Place that dlls near your exe file and try to run.
Comment 8 Guerry Semones 2016-09-23 15:00:48 UTC
Thanks Alexander, I will try and do that. I'd attempted to build mono-tls before, but could not figure it out. With your instructions, I'll give it another go!

Thanks,

Guerry
Comment 9 Guerry Semones 2016-09-23 17:46:47 UTC
Hey Alexander, much thanks for the instructions! I was able to build mono-tls and get my app working again. I'm sure this will all get straightened out as Martin and Miguel finish up this work. It's got to be a complex effort! For the time being, this moves our project forward I think.

There are two clarifications I would add to your instructions:

1) The specific version of the Xamarin web-tests git repository that is needed is Martin's found here: https://github.com/xamarin/web-tests/tree/e7810fb86fb3facf50949b9be1aff75f7cbcdeda

I originally went to the top-level repo and it did not include what was needed.

2) From Martin's version of web-test that you have placed under external/web-tests, add the Mono.Security.Interface project from the Target platform that you need (Mac/Android/IOS/etc. In my case, what I needed was:

external/web-tests/Mac/Mono.Security.Interface/Mono.Security.Interface.csproj

Alexander's instructions mentioned getting this from external/web-tests/Console. This did not work for me.

Of course, I also had to touch the various projects to make sure their build targets were compatible. 

Thanks,

Guerry
Comment 10 Alexander Bekrenev 2016-09-23 19:53:31 UTC
Guerry, thank you for your clarification.
About Mono.Security.Interface: I build and use it under Linux/Ubuntu. Sorry, that does not have it right away.
Comment 11 James Ward 2016-10-09 16:15:18 UTC
I'm seeing the same error, on my app.   
Are there plans to include the fix or needed files into a future mono release? I thought this might happen with the release of 4.6.1 but I still see the error.
Comment 12 Miguel de Icaza [MSFT] 2016-11-03 16:29:06 UTC
The proper fix is in the upcoming Mono version, the 4.8.0 release, with that release, the code works fine, you want to use the new BTLS prpvider, like this:

$  MONO_TLS_PROVIDER=btls mono a.exe 
SslStream test
success [protocol=Tls]