Subject: [TLS] Questions about TLS Server Name Indication extension

From: Nelson B Bolyard <[email-masked]>
Date: Tue, 27 Oct 2009 20:37:24 -0700

A few years ago, I implemented the SNI extension in a client-only TLS
library and it was really simple because I only ever sent one host name
to the server.  Now I'm implementing the server side of SNI and I realize
that the RFC appears to allow clients to do much more complex things than
my client ever did.  So, I have some questions seeking clarification about
the definition of SNI.  I hope someone here can help me by answering some
of these questions.

Q1)  A client hello's SNI extension is defined such that it may contain
multiple names.  Perhaps the intent was to allow the same server to be
named in multiple different name spaces (DNS and others), but I saw nothing
in RFC 4366 that precludes the client from naming multiple different hosts
in a single ServerNameList.  If a client names multiple host names in a
single client hello SNI extension (let's call them A.foo.com, B.foo.com and
C.foo.com) how does the client learn which one of those has been chosen by
the server?  RFC 4366 requires the "extension_data" field of the SNI
extension in the server hello to be empty.  The server may respond with a
"wildcard" certificate ("*.foo.com"), or with a certificate with multiple
Subject Alternative Names that include more than one of the names given by
the client.  In that case, how does the client know which FQDN is the one
that the physical server has chosen/identified?

I can think of lots of possible answers here, including

a) It is an error to include multiple names in the same name space, e.g.
multiple DNS names. (but the RFC doesn't say that.)

b) If multiple names are included, they must be logically synonymous, all
alternative names for the same host.  (What if they're not?)

Q2) if multiple non-synonymous names are included, is the server free to
pick any one that it wants?

Q3) Consider the "renegotiation" case, where a client and server negotiate
an initial SSL handshake ("in the clear") and then negotiate a second
handshake over the encrypted channel established by the first handshake.
Are there any special requirements or prohibitions on the use and contents
of the client hello's SNI extension in the renegotiation case?

Q3a) Is SNI permitted in that case?
Q3b) Is it required to match the SNI of the original handshake, if any?
Q3c) If it contains multiple non-synonymous host names, is the server
allowed to choose a different one than the one chosen in the first
handshake?

The next questions have to do with the "resumption" or "restart" of a TLS
session that has been previously established using an SNI extension that
named one or more virtual hosts in a connection to a physical server on
an IP address and port.

Q4) In that context, is the scope of a TLS session ID that of the physical
server, or that of a virtual server?  When attempting to restart a TLS
session on a new connection, does the TLS session ID in the client hello
uniquely identify the virtual host and its session to the physical server,
even in the absence of an SNI extension?  Or is it possible that each of
the virtual servers within the physical host may have used that same
session ID, in which case it would be necessary for the client to supply the
virtual host's FQDN in an SNI extension to uniquely identify the session?

Q5) When an SNI extension was used to establish a TLS session, it is
required that an SNI extension bearing the same host name be used in the
client hello that attempts to "restart" or "resume" the session on a new
connection?

(Obviously Q3, Q4 and Q5 overlap.)

I eagerly await your answers and comments.

/Nelson Bolyard

---

From: Michael D'Errico <[email-masked]>
Date: Wed, 28 Oct 2009 16:19:19 -0700

In my TLS implementation, I have created an object called a ServerIdentity
which is more general than a domain name.  A TLS server can be set up
with any number of server identites, each of which can have any number of
domain names and certificate chains, and you can also specify a few server
options on a per-identity basis.

When the Server Name Indication extension is received, the server goes
through the list of domain names in order and searches for the ServerIdentity
object containing the domain name.  The first match is chosen and the
handshake continues using the most appropriate certificate chain and also
the options set for that identity.

If none of the SNI names match, the server checks to see if a default
ServerIdentity has been configured.  If it has, the default identity is
used, but an UnrecognizedName alert is sent to the client (level = warning).
If no default identity has been configured, then a fatal UnrecognizedName
alert is sent and the connection fails.

My test server has two identities set up:

    Mike's Toolbox Network
    www.mikestoolbox.net + default
    RSA/SHA-1 signed RSA certificate chain
    RSA/SHA-1 signed DSA certificate chain (only works with TLS 1.2)
    RSA/SHA-256 signed RSA certificate chain
    RequestClientCertificate
    LoadDefaultRootCertificates
    Use1024BitDHParameters
    CacheSessions
    IssueSessionTickets

    Mike's Toolbox Charity
    www.mikestoolbox.org
    RSA/SHA-1 signed RSA certificate chain
    RSA/SHA-256 signed RSA certificate chain
    Use1536BitDHParameters
    CacheSessions
    IssueSessionTickets

When you connect to the test server, the information returned includes the
server identity that was negotiated.

Mike

Nelson B Bolyard wrote:
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls
>

---

From: Martin Rex <[email-masked]>
Date: Thu, 29 Oct 2009 23:46:06 +0100 (MET)

Nelson B Bolyard wrote:
> in a single ServerNameList.

It seems that it is a defect of RFC4366 to not indicate that
a ServerNameList must contain at most one entry per NameType.

> alternative names for the same host.  (What if they're not?)

If I would implement the server side, I would entirely ignore everything
besides the first entry in the List of each NameType my implementation
recognizes (i.e. Hostname).

> pick any one that it wants?

There is no such thing as a synonymous DNS name (the hostname Nametype)
-- either it is exactly the same name (case-insensitive, of course),
or it is a different name.  There is exactly _one_ name 
that goes into the opening/connect of the particular network connection
through which the ClientHello with the SNI extension is sent, and that
name ought to be put into the SNI by a sensible TLS client implementation,
if anything at all.

Btw. RFC-4366 doesn't say what to do about IP-Addresses.  Since
rfc-2818.txt indicates that Server certificates may contain
SANs of the type iPAddress, sending IP-Addresses also via SNI
sounds like the way to go when e.g. the Browser tries to open
a URL with only an IPaddress instead of a hostname..

The server is free to do whatever it wants, including ignoring the
SNI entirely (which is what most servers are doing today anyway).

The more interesting question is what is the client (and in particular
one that sends such a stupid request) going to do about all of the
possible server behaviour?

A client that sends more than one ServerName of the same type is
quite likely broken (or debugging or attacking the server).

> of the client hello's SNI extension in the renegotiation case?

A client that performs a TLS renegotiation or TLS session resumption
with a different SNI information as in the original ClientHello is
probably broken (or debugging or attacking the server).

In principle, the client should assert exactly the same TLS extensions
on a TLS session resume or TLS session renegotiation than what it
asserted on the original Client Hello.  If the client wants to
assert other TLS extensions, it should NOT try to resume a previous
SSL session (i.e. it should sent an empty TLS session id)

> Q3a) Is SNI permitted in that case?

This is definitely not a question of permission.
The issue is consistent and sensible behaviour of a TLS client.

> Q3b) Is it required to match the SNI of the original handshake, if any?

The spec doesn't make explicit requirements, it is a requirement implied
by common sense.  Clients that don't do it are quite likely broken.

> virtual host's FQDN in an SNI extension to uniquely identify the session?

There are two different angles to look at this problem: server and client.

A TLS server implementation that supports multiple different credentials
on the same communication endpoint ought to implement its behaviour in
a consistent and predictable fashion.  If the server supports credential
selection through SNI, it should keep session caches seperate per SNI--
and also per cihpersuites offered by the client.

There may be even more attributes or TLS extensions which the server
session cache should differentiate.  It entirely depends on whether
the server supports more than a single SSL credential on a 
communication endpoint, and what differences in characteristics
the supported credentials have.

If the can easily determine that the TLS session resume will result in
significantly different session characteristics than a full TLS handshake
based on the received ClientHello then it should perform a full handshake.

There are much more interesting questions: when a TLS session in the
cache was originally established with protocol version 0x03,0x01
what about a client resume proposal with a protocol version 0x03.0x00
or 0x03,0x02 in the client_version of the ClientHello?

A TLS client that has cached a TLS session should only propose to
resume it, when it connects to exactly the same Server and the
same Port (and for Web-Browsers, that means the name&port as it
appears in the URL and is independent of the ipaddr&port on
the transport layer because of client-side TLS proxies).

A TLS client should *NEVER* make assumptions about independent
servers (i.e. independent ServerNames) sharing a TLS session cache.
Sensible TLS clients should NOT assume that TLS servers on different
ports of the same host share the TLS session cache (or credentials
or any other TLS characteristics, for that matter).

We had a problem with some vendors TLS implementation that made
flawed assumptions about services on different ports of the
same machine (hostname).  We had one particular configuration
where there was a service with a RSA-credential and SSLv3-only
implementation listening on one port and a different service
with a DSA-credential and TLS-v1.0-capable.

When that vendors TLS implementation was sent from the
DSA-cred-TLS-v1.0-capable service with an URL to the
RSA-cred-SSLv3-only service on a different port of the
same host it exhibited two problems:

  - it incorrectly proposed TLS session resumption in the ClientHello

  - it failed the full SSL handhskae with a fatal error because it wasn't
    able to deal with the switch DSA->RSA ciphersuites and TLSv1.0->SSLv3
    in a full handshake resulting from a failed TLS session resume
    proposal.

In order to make the URL(redirect) work, you had to clear the SSL state
first, flushing the TLS session cache.

Consistent behaviour is really the key point here.  When and how often
a TLS session resume will fail and result in a full TLS handshake can
depend very much on the load on the server (we use a default cache
lifetime of 15 minutes for the SSL sessions on the server).

A different Server credential may result in a different ciphersuite
and in a different set of trust anchors for client cert verification,
so the server side cache should probably be tied to the server
credential, if the server supports more than one credential,
and selection should be based on SNI in case that the server
supports virtual hosting and credentials selection through SNI.

> client hello that attempts to "restart" or "resume" the session on a new

Again, this is common sense.  A client that uses different TLS extensions
here is either broken, doing fancy debugging, or attacking the server.

A server that supports more than one credential on a single communication
endpoint should really use entirely seperate session caches per credential.

If you have a server running with 30 virtual hosts and the same number
of independen SSL server credentials, and you change only one of these
credentials (like replace the existing server cert with a renewed one,
i.e. one with a longer validity), then a good server design will allow
you to update that state without server downtime, and flushing exactly
the TLS session cache related to the updated server credential while
leaving all other server credentials and cached sessions untouched and valid.

-Martin

---

From: Michael D'Errico <[email-masked]>
Date: Fri, 30 Oct 2009 19:12:55 -0700

> a URL with only an IPaddress instead of a hostname..

RFC 4366 says on page 10:

    Literal IPv4 and IPv6 addresses are not permitted in "HostName".

A new name type would need to be created for IP addresses.

> or 0x03,0x02 in the client_version of the ClientHello?

I looked at my code and found that when a cached session is
retrieved, the ClientHello.version of the new handshake is compared
to the negotiated version of the original session.  If they are not
equal, then a full handshake is performed.

But that brings up a subtle point.  What if the client originally
connected offering a higher version than I support?  When it tries
to resume a session, should it use the version it originally sent
in the ClientHello, or the lower version that was negotiated?

I would think that the client should be allowed to specify the same
version number it originally connected with.

I searched through RFC 5246 but could not find a discussion of this.
Did I miss it?  What do others think should happen?

> or any other TLS characteristics, for that matter).

A somewhat related problem I encountered is that Google's search
engine assumes that the content at http port 80 is the same as the
content at https port 443.  I was having trouble getting my site
indexed because the text/plain page from my TLS test server was
being treated as my home page by Google's bot, i.e. with no links.
I don't know if other search engines exhibit this behavior.

Mike