Bug 11487 - Server Name Indication (SNI) support is missing
Summary: Server Name Indication (SNI) support is missing
Status: RESOLVED FIXED
Alias: None
Product: Class Libraries
Classification: Mono
Component: Mono.Security ()
Version: unspecified
Hardware: PC Linux
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2013-03-30 23:49 UTC by Tobias Mueller
Modified: 2013-05-17 20:37 UTC (History)
3 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 Tobias Mueller 2013-03-30 23:49:15 UTC
I am trying to use Tomboy with a self hosted syncing service that is behind a SSL and SNI enabled HTTPd. But tomboy can't connect to it.

It seems that mono doesn't support SNI as the following testcase shows:

 $ cat  wget.cs
using System;
using System.Collections;
using System.IO;
using System.IO.IsolatedStorage;
using System.Net;
using System.Security.Cryptography.X509Certificates;
 
public class Program : ICertificatePolicy {
	private Hashtable ht;
 
	public void Load ()
	{
		if (ht == null) {
			ht = new Hashtable ();
		}
		// TODO - use isolated storage so this will work even with
		// minimal security permissions
	}
 
	public void Save (int error, string thumbprint)
	{
		// TODO
	}
 
	public bool CheckValidationResult (ServicePoint sp, 
		X509Certificate certificate, WebRequest request, int error)
	{
	    Console.WriteLine("Error " + error);
		if (error == 0)
			return true;
        if (error == -2146762481)
            return true;
		// only ask for trust failure (you may want to handle more cases)
		if (error != -2146762486)
			return false;
 
		Load ();
		string thumbprint = certificate.GetCertHashString ();
		object result = ht [thumbprint];
		if ((result is int) && ((int)result == error))
			return true;
 
		Console.WriteLine ("A trust error occured while attempting " + 
			"to access the web site. Do you wish to:");
		Console.WriteLine ("\ta) abort this untrusted session;");
		Console.WriteLine ("\tb) continue this session (only once);");
		Console.WriteLine ("\tc) trust this certificate with this " +
			"application (forever);");
 
		switch (Console.ReadLine ().ToLower ()) {
			case "b":
				return true;
			case "c":
				Save (error, thumbprint);
				return true;
			case "a":
			default:
				return false;
		}
	}
 
	public static void Main (string[] args) 
	{
		ServicePointManager.CertificatePolicy = new Program ();
		try {
			WebRequest wr = WebRequest.Create (args [0]);
			Stream stream = wr.GetResponse ().GetResponseStream ();
			Console.WriteLine (new StreamReader (stream).ReadToEnd ());
		}
		catch (WebException we) {
			// don't show the exception for trust failures
			if (we.Status != WebExceptionStatus.TrustFailure) {
			    Console.WriteLine("throuwing");
				throw;
				}
			Console.WriteLine ("Operation aborted by user.");
		}
	}
}


$ gmcs wget.cs 
wget.cs(64,37): warning CS0618: `System.Net.ServicePointManager.CertificatePolicy' is obsolete: `Use ServerCertificateValidationCallback instead'
Compilation succeeded - 1 warning(s)
$ mono ./wget.exe https://foo.sni.velox.ch
Error -2146762481
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>TLS SNI Test Site: alice.sni.velox.ch</title>
</head>
<body>
<h2>TLS SNI Test Site: alice.sni.velox.ch</h2>

<p><strong>Unfortunately, your client  
did not send a TLS server name indication extension
(<a href="http://www.ietf.org/rfc/rfc4366.txt">RFC 4366</a>)
in its ClientHello </strong>(negotiated protocol: TLSv1)<strong>, so you're
probably getting warnings about certificate name mismatches.</strong></p>
<p>In your request, this header was included:</p>
<pre>  Host: foo.sni.velox.ch</pre>
<p>
This Web server is running <a href="http://httpd.apache.org/">Apache httpd</a>'s mod_ssl,
linked against a version of <a href="http://www.openssl.org/source/">OpenSSL</a>
with support for TLS extensions. Apache httpd 2.2.12 was the first official release
featuring TLS SNI capabilities.
</p>
<p><em>
Für deutschsprachige Leser ist eine PDF-Version eines im Oktober 2009 erschienenen
<strong><a href="http://sni.velox.ch/ct_2309_Apache_TLS_SNI.pdf">c’t-Artikels</a></strong>
verfügbar, mit ausführlichen Erläuterungen zu einem SNI-Setup mit Apache und mod_ssl.
</em></p>
<p>
For the current connection (established at Sun Mar 31 03:41:03 UTC 2013),
<code>httpd</code> is assuming that the certificate
with <strong>CN=alice.sni.velox.ch</strong> is the correct one.
Apache is configured as shown below and uses three certificates,
(kindly provided by <a href="http://www.quovadisglobal.com/" target="_blank">QuoVadis</a>),
where CN=alice.sni.velox.ch, CN=bob.sni.velox.ch, and CN=*.sni.velox.ch.
Based on the information your client submitted, the highlighted
<code>VirtualHost</code> has been selected for your viewing pleasure:
</p>
<pre>
  Listen 443
  NameVirtualHost *:443

  &lt;VirtualHost *:443&gt;
    SSLEngine On
    ServerName <a href="https://alice.sni.velox.ch/">alice.sni.velox.ch</a>:443
    ServerAlias <a href="https://carol.sni.velox.ch/">carol.sni.velox.ch</a>
    DocumentRoot /var/www/html/alice
    SSLCertificateFile /etc/pki/tls/certs/alice.sni.velox.ch.crt
    SSLCertificateKeyFile /etc/pki/tls/private/alice.sni.velox.ch.key
    # <a href="/misc/certs/alice.sni.velox.ch.crt.pem">alice.sni.velox.ch.crt</a> has a subjectAltName extension
    # with two dNSName entries: alice.sni.velox.ch and
    #                           carol.sni.velox.ch
    # Since this VirtualHost is listed first, it's also
    # the default one and will get selected if none
    # of the others match
  &lt;/VirtualHost&gt;

  &lt;VirtualHost *:443&gt;
    SSLEngine On
    ServerName <a href="https://bob.sni.velox.ch/">bob.sni.velox.ch</a>:443
    ServerAlias <a href="https://dave.sni.velox.ch/">dave.sni.velox.ch</a>
    DocumentRoot /var/www/html/bob
    SSLCertificateFile /etc/pki/tls/certs/bob.sni.velox.ch.crt
    SSLCertificateKeyFile /etc/pki/tls/private/bob.sni.velox.ch.key
    # <a href="/misc/certs/bob.sni.velox.ch.crt.pem">bob.sni.velox.ch.crt</a> has a subjectAltName extension
    # with two dNSName entries: bob.sni.velox.ch and
    #                           dave.sni.velox.ch
  &lt;/VirtualHost&gt;

  <strong style="font-size:120%;">&lt;VirtualHost *:443&gt;
    SSLEngine On
    ServerName <a href="https://mallory.sni.velox.ch/">mallory.sni.velox.ch</a>:443
    ServerAlias <a href="https://www.sni.velox.ch/">*.sni.velox.ch</a>
    ServerAlias <a href="https://sni.velox.ch/">sni.velox.ch</a>
    DocumentRoot /var/www/html/mallory
    SSLCertificateFile /etc/pki/tls/certs/mallory.sni.velox.ch.crt
    SSLCertificateKeyFile /etc/pki/tls/private/mallory.sni.velox.ch.key
    # <a href="/misc/certs/mallory.sni.velox.ch.crt.pem">mallory.sni.velox.ch.crt</a> has a subjectAltName extension
    # with two dNSName entries: *.sni.velox.ch and
    #                           sni.velox.ch
    # Since it has a wildcard DNS name, it will match for any
    # VirtualHost below .sni.velox.ch which is not explicitly configured
  &lt;/VirtualHost&gt;</strong>

</pre>
<p>Clicking on the <code>ServerName</code> and <code>ServerAlias</code> links should
get you to these VirtualHosts. The <code>.crt</code> links will show the certificates
in PEM format, preceded by an OpenSSL text dump.</p>
<p>Browsers/clients with support for TLS server name indication:</p>
<ul>
<li><a href="http://www.opera.com/browser/">Opera 8.0 and later</a> (the TLS 1.1 protocol must be enabled)</li>
<li><a href="http://www.microsoft.com/windows/internet-explorer/default.aspx">Internet Explorer 7 or later</a> (under Windows Vista and later only, not under Windows&#160;XP)</li>
<li><a href="http://www.mozilla.com/firefox/">Firefox 2.0 or later</a></li>
<li><a href="http://curl.haxx.se/">Curl 7.18.1 or later</a> (when compiled against an SSL/TLS toolkit with SNI support)</li>
<li><a href="http://www.google.com/chrome/">Chrome 6.0</a> or later (on all platforms - releases up to 5.0 only on specific OS versions)</li>
<li><a href="http://www.apple.com/safari/">Safari 3.0 or later</a> (under OS X 10.5.6 or later and under Windows Vista and later)</li>
</ul>
<p>See also <a href="http://www.outoforder.cc/projects/apache/mod_gnutls/">mod_gnutls</a>
for an alternative Apache module featuring SNI support.</p>
<p><small>Last updated 2012-04-18, Kaspar Brand (contact: sni velox ch, insert "@" before and "." after "velox")</small></p>
</body>
</html>




When you visit https://foo.sni.velox.ch with your browser, you see that it will support SNI quite well. Mono, however, does not according to the response.
Comment 1 Zoltan Varga 2013-03-31 01:19:38 UTC
-> sys.web
Comment 2 Sebastien Pouliot 2013-05-16 15:27:10 UTC
SNI was implemented a few months ago. You need a recent version of Mono to get it. E.g.

pollux:Projects sebastienpouliot$ mono --version
Mono JIT compiler version 2.10.12 (mono-2-10/c9b270d Thu Mar  7 21:38:12 EST 2013)
Copyright (C) 2002-2012 Novell, Inc, Xamarin, Inc and Contributors. www.mono-project.com
	TLS:           normal
	SIGSEGV:       normal
	Notification:  kqueue
	Architecture:  x86
	Disabled:      none
	Misc:          softdebug 
	LLVM:          yes(2.9svn-mono)
	GC:            Included Boehm (with typed GC)
pollux:Projects sebastienpouliot$ mcs wget.cs 
wget.cs(64,37): warning CS0618: `System.Net.ServicePointManager.CertificatePolicy' is obsolete: `Use ServerCertificateValidationCallback instead'
Compilation succeeded - 1 warning(s)
pollux:Projects sebastienpouliot$ mono ./wget.exe https://foo.sni.velox.ch
Error 0
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>TLS SNI Test Site: *.sni.velox.ch</title>
</head>
<body>
<h2>TLS SNI Test Site: *.sni.velox.ch</h2>

<p><strong>Great! Your client  
sent the following TLS server name indication extension
(<a href="http://www.rfc-editor.org/rfc/rfc6066.txt">RFC 6066</a>)
in its ClientHello </strong>(negotiated protocol: TLSv1, cipher suite: AES256-SHA)<strong>:</strong></p>
<pre>  <strong>foo.sni.velox.ch</strong></pre>
<p>In your request, this header was included:</p>
<pre>  Host: foo.sni.velox.ch</pre>
<p>
This Web server is running <a href="http://httpd.apache.org/">Apache httpd</a>'s mod_ssl,
linked against a version of <a href="http://www.openssl.org/source/">OpenSSL</a>
with support for TLS extensions. Apache httpd 2.2.12 was the first official release
featuring TLS SNI capabilities.
</p>
<p>
For the current connection (established at Thu May 16 19:25:08 UTC 2013),
<code>httpd</code> is assuming that the certificate
with <strong>CN=*.sni.velox.ch</strong> is the correct one.
Apache is configured as shown below and uses three certificates,
(kindly provided by <a href="http://www.quovadisglobal.com/" target="_blank">QuoVadis</a>),
where CN=alice.sni.velox.ch, CN=bob.sni.velox.ch, and CN=*.sni.velox.ch.
Based on the information your client submitted, the highlighted
<code>VirtualHost</code> has been selected for your viewing pleasure:
</p>
<pre>
  Listen 443
  # NameVirtualHost is only needed for httpd 2.2.x
  NameVirtualHost *:443

  &lt;VirtualHost *:443&gt;
    SSLEngine On
    ServerName <a href="https://alice.sni.velox.ch/">alice.sni.velox.ch</a>:443
    ServerAlias <a href="https://carol.sni.velox.ch/">carol.sni.velox.ch</a>
    DocumentRoot /var/www/html/alice
    SSLCertificateFile /etc/pki/tls/certs/alice.sni.velox.ch.crt
    SSLCertificateKeyFile /etc/pki/tls/private/alice.sni.velox.ch.key
    # <a href="/misc/certs/alice.sni.velox.ch.crt.pem">alice.sni.velox.ch.crt</a> has a subjectAltName extension
    # with two dNSName entries: alice.sni.velox.ch and
    #                           carol.sni.velox.ch
    # Since this VirtualHost is listed first, it's also
    # the default one and will get selected if none
    # of the others match
  &lt;/VirtualHost&gt;

  &lt;VirtualHost *:443&gt;
    SSLEngine On
    ServerName <a href="https://bob.sni.velox.ch/">bob.sni.velox.ch</a>:443
    ServerAlias <a href="https://dave.sni.velox.ch/">dave.sni.velox.ch</a>
    DocumentRoot /var/www/html/bob
    SSLCertificateFile /etc/pki/tls/certs/bob.sni.velox.ch.crt
    SSLCertificateKeyFile /etc/pki/tls/private/bob.sni.velox.ch.key
    # <a href="/misc/certs/bob.sni.velox.ch.crt.pem">bob.sni.velox.ch.crt</a> has a subjectAltName extension
    # with two dNSName entries: bob.sni.velox.ch and
    #                           dave.sni.velox.ch
  &lt;/VirtualHost&gt;

  <strong style="font-size:120%;">&lt;VirtualHost *:443&gt;
    SSLEngine On
    ServerName <a href="https://mallory.sni.velox.ch/">mallory.sni.velox.ch</a>:443
    ServerAlias <a href="https://www.sni.velox.ch/">*.sni.velox.ch</a>
    ServerAlias <a href="https://sni.velox.ch/">sni.velox.ch</a>
    DocumentRoot /var/www/html/mallory
    SSLCertificateFile /etc/pki/tls/certs/mallory.sni.velox.ch.crt
    SSLCertificateKeyFile /etc/pki/tls/private/mallory.sni.velox.ch.key
    # <a href="/misc/certs/mallory.sni.velox.ch.crt.pem">mallory.sni.velox.ch.crt</a> has a subjectAltName extension
    # with two dNSName entries: *.sni.velox.ch and
    #                           sni.velox.ch
    # Since it has a wildcard DNS name, it will match for any
    # VirtualHost below .sni.velox.ch which is not explicitly configured
  &lt;/VirtualHost&gt;</strong>

</pre>
<p>Clicking on the <code>ServerName</code> and <code>ServerAlias</code> links should
get you to these VirtualHosts. The <code>.crt</code> links will show the certificates
in PEM format, preceded by an OpenSSL text dump.</p>
<p>Browsers/clients with support for TLS server name indication:</p>
<ul>
<li><a href="http://www.opera.com/browser/">Opera 8.0 and later</a> (the TLS 1.1 protocol must be enabled)</li>
<li><a href="http://www.microsoft.com/windows/internet-explorer/default.aspx">Internet Explorer 7 or later</a> (under Windows Vista and later only, not under Windows&#160;XP)</li>
<li><a href="http://www.mozilla.com/firefox/">Firefox 2.0 or later</a></li>
<li><a href="http://curl.haxx.se/">Curl 7.18.1 or later</a> (when compiled against an SSL/TLS toolkit with SNI support)</li>
<li><a href="http://www.google.com/chrome/">Chrome 6.0</a> or later (on all platforms - releases up to 5.0 only on specific OS versions)</li>
<li><a href="http://www.apple.com/safari/">Safari 3.0 or later</a> (under OS X 10.5.6 or later and under Windows Vista and later)</li>
</ul>
<p><small>Last updated 2013-05-08, Kaspar Brand (contact: sni velox ch, insert "@" before and "." after "velox")</small></p>
</body>
</html>
Comment 3 Tobias Mueller 2013-05-17 08:37:25 UTC
Hm. Doesn't work for me with the latest tarball: 
 $ /tmp/mono/bin/mono --version
Mono JIT compiler version 2.11.4 (tarball Fr 17. Mai 14:04:20 CEST 2013)
Copyright (C) 2002-2012 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:            Included Boehm (with typed GC and Parallel Mark)
Comment 4 Sebastien Pouliot 2013-05-17 08:46:52 UTC
Not sure where the tarball comes from but 2.11.4 is pretty old and 2.11 was renamed to 3.0.x after that (or the next) release. Right now I'm running 3.0.10.
Comment 5 Tobias Mueller 2013-05-17 20:37:56 UTC
oh, I thought that anything > 2.10.12 would be sufficient, as it's the version you indicated. And I thought I take the last release of the 2.x series as Fedora, Debian, Ubuntu and all ship 2.10.8.

Anyway, 3.0.10 works. Thanks!