Subject: [TLS] First TLS cached information draft posted

From: Stefan Santesson <[email-masked]>
Date: Thu, 04 Jun 2009 19:41:07 +0200

I have finally incorporated the agreed changes to what previously was called
the cached certs extension, now changed to the cached information extension,
and submitted the first (00) TLS draft.

The draft is available from the following staging URL until it¹s made
available as a TLS draft.
http://www.ietf.org/proceedings/staging/draft-ietf-tls-cached-info-00.txt

I hope I didn¹t miss any agreed changes.

/Stefan

---

From: Simon Josefsson <[email-masked]>
Date: Fri, 05 Jun 2009 13:38:24 +0200

> http://www.ietf.org/proceedings/staging/draft-ietf-tls-cached-info-00.txt

I support this.  I've seen 40kb handshakes due to the server return a
list of acceptable CAs, and that has generated some interop problems
with GnuTLS [1].

The document appears to be in good shape.  I believe I could implement
the document if two (minor) concerns were resolved.

First, this paragraph:

   Servers that receive an extended client hello containing a
   "cached_information" extension, MAY indicate that they support one or
   more of the cached information objects by including an extension of
   type "cached_information" in the (extended) server hello, which SHALL
   contain at least one CachedObject received from the client.

The intention here appears under-specified.  What does it mean if the
client sent two CachedObject's and the server just returned one of them?
One plausible interpretation would be that the server did not support
the hash/type-combination that were not returned.  Enforcing that
interpretation is needed to resolve my second concern.

I suggest to add a sentence:

   The CachedObject's returned by the server MUST include the types the
   server supports and has accepted to replace with cached data.

Secondly, this paragraph:

   After negotiation of the use of cached certificates has been
   successfully completed (by exchanging hello messages including
   "cached_certs" extensions), the server MAY replace the cached
   information objects in its handshake messages with a corresponding
   hash_value from CachedInformationHash that was included in the
   cached_information extension of the server hello message.

Why a MAY here?  How would a client distinguish whether the server did
replace the data or not?  Why not use the extended server hello to
return the supported types (as suggested above)?  This appears to add
complexity for no particular reason, at least as far as I can
understand.

I suggest to replace MAY with MUST here.

Thanks,
/Simon

[1] GnuTLS refuses large handshakes due to DoS concerns, and we had to
increase the limit.

---

From: Stefan Santesson <[email-masked]>
Date: Fri, 05 Jun 2009 14:29:10 +0200

Thank's Simon,

Good comments and I agree to both of them.

1) Yes the intension is that if the server returns only 1 out of 2 objects,
only the object returned will be replaced

2) If the server has indicated support of a cached object in the server
hello, the requirement to replace that object with a hash should be a MUST.

It turns out that it was not to late to cancel the submission, so I have
already incorporated this in the 00 draft and resubmitted.

If you follow the same link and hit "refresh" you will see the changes.

/Stefan

---

From: Simon Josefsson <[email-masked]>
Date: Fri, 05 Jun 2009 14:36:05 +0200

> If you follow the same link and hit "refresh" you will see the changes.

Looks fine, thank you.

A minor discussion would be whether adding support for SHA-256/384/512
is worthwhile, but I don't feel strongly either way.

If someone is looking into implementing this specification, I'm
interested in performing interop testing.

/Simon

---

From: Stefan Santesson <[email-masked]>
Date: Fri, 05 Jun 2009 19:04:22 +0200

Simon,

The specification allows you to specify and use any hash algorithm that is
supported by the TLS hash algorithm registry.

SHA-1 is the only MUST support algorithm, and I think that is correct.

/Stefan

---

From: Martin Rex <[email-masked]>
Date: Fri, 5 Jun 2009 22:55:53 +0200 (MEST)

>    server supports and has accepted to replace with cached data.

I don't know whether I correctly understand the suggestion
that you're making.  But I'm very unhappy with one possible
interpretation that I see in your poposal.

Having the TLS server indicate for which objects its TLS implementation
supports the caching _in_principle_ is fine with me.

Requiring the server to already know the hash values of
parts the contents of future SSL handshake messages, specifically
the to-be-cached data at the time when composing the ServerHello
handshake message is something I would definitely not like.

The impact on implementations of TLS should be as small as possible.
To me, a requirement for a TLS server to precompute hashes over
parts of future handshake messages during ServerHello looks like
a significant additional burden, and personally, I do not yet see
any benefit this might provide.

-Martin

---

From: Stefan Santesson <[email-masked]>
Date: Sat, 06 Jun 2009 03:17:08 +0200

Martin,

I liked Simon's suggestion as he expressed my original thought that the
Server would know beforehand the hashes for acceptable information objects.

However, what you suggest actually makes sense to me.

I also found another minor error as the draft refer to hash_value (single
hash) when I should refer to the "hashes" (multiple hash) element.

We have to think through the concept of sending over multiple hashes and
what the appropriate response from the server is.

1) The server accepts replacement in principle, but does not know at the
time of sending the server hello if any of the hashes match.

2) The server accepts one or more hashes from the client hello (for one
object type) and includes the hashes it accepts in the server hello

3) The server accepts one or more hashes from the client hello (for one
object type) but includes only 1 (the preferred one) hash for that object
type in the server hello.

Once we can agree on this, I will update and submit a new version of the
draft.

/Stefan

---

From: Stefan Santesson <[email-masked]>
Date: Sun, 07 Jun 2009 10:46:52 +0200

I think I have to try to clarify this

The client send a cached_information extension which contains a list of
CachedObject structures.

Each ChachedObject element contains:

- type identifier (CachedInformationType type)
- a list of hash values (CachedInformationHash hashes)

Each CachedInformationHash contains:

- Algorithm identifier (HashAlgorithm hash)
- Hash value (opaque hash_value)

There are a number of issues that need to be specified or clarified in the
draft:

1) Is it allowed to send over multiple CachedObject elements containing the
same type identifier?

Proposed answer = No (you can already include multiple hashes for each type)

2) What should the server return in its server hello message for each
acceptable CachedObject?

Alternative 1 = The CachedObject element, exactly as it was received by the
client (with all hashes)

Alternative 2 = The CachedObject element, but only containing the
CachedInformationHash elements that is recognize and support.

Proposed answer = Alternative 1 (This allows the server to say YES in
principle without analyzing the hash values at the time of Hello exchange)

3) Is the server REQUIRED to honor its support of a CachedObject by
replacing the identified handshake data with a received hash?

Proposed answer = NO (for reasons raised by Martin)

4) What does the server send as replacement for the replaced handshake data?

Proposed answer = One opaque hash_value (without hash type identifier) that
was received by the client, which MUST contain a valid hash over the
replaced data.

Do you agree?

/Stefan

On 09-06-06 3:17 AM, "Stefan Santesson" <[email-masked]> wrote:

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

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 09 Jun 2009 08:37:14 +0200

> SHA-1 is the only MUST support algorithm, and I think that is correct.

That's fine.

In practice, I guess client implementations are likely to send:

CachedInformation =
  {
    { certificate_chain { sha1, "..." } },
    { certificate_chain { sha2-512, "..." } },
    ...
  }

How should a server behave if it receives a HashAlgorithm it doesn't
support, for a CachedInformationType it does support?

I suggest unsupported hashes should be ignored by servers.  I think some
guidance in the document is needed to make sure algorithm agility will
work.

In other words, after:

   Hash algorithm identifiers are provided by the RFC 5246 [RFC5246]
   HashAlgorithm registry. Compliant implementations MUST support
   sha1(2) as HashAlgorithm.

add this sentence:

   Servers MUST ignore unsupported hash algorithm identifiers.

This leads to the possibly surprising behaviour that if a sha1 value is
not sent by the client, and the server only supports sha1, the extension
will not be negotiated.  But that is right, isn't it?

/Simon

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 09 Jun 2009 08:40:35 +0200

> any benefit this might provide.

Good point, but how would a client know whether a server replaced the
cached information with a hash or not if there is no signaling whether
this happened or not?

/Simon

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 09 Jun 2009 08:57:53 +0200

> - Hash value (opaque hash_value)

Right.

> Proposed answer = No (you can already include multiple hashes for each type)

Agreed.

There is a follow-on question here:

Is it allowed to send over multiple CachedObject elements containing the
same type identifier and same hash algorithm but different hash values?

The options and consequences are:

No: This is the simplest.  In this case, I don't see a reason for the
server to send back the same hash value the client sent -- so the Hash
value field would be removed in the server response, to save some more
space.

Yes: This allows clients to send hashes for multiple variants of the
cached information.  For example, the client may have received two
different server certificates in the past, and may want to offer caching
of both.

The Yes case seems complex but there could be use cases for it.  If you
didn't think of this, I'd prefer to disallow it.

> principle without analyzing the hash values at the time of Hello

I don't see any value in duplicating the hash values here though?

> Proposed answer = NO (for reasons raised by Martin)

I understand Martin's concern, but how would a client know whether data
was replaced or not?  How would the client know which hash algorithm is
used?

> was received by the client, which MUST contain a valid hash over the

I think we need to include the hash algorithm too.  You cannot infer
which hash algorithm is used based on the length only.

I don't think it is reliable to optionally replace data.  Hash values
can be made to look like valid ASN.1, and the client would have to guess
whether the server replaced the value or not.

/Simon

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 09 Jun 2009 09:02:40 +0200

Another minor point, quoting the document:

   When CachedInformationType identifies certificate_chain, then
   hash_value MUST include at least one hash value calculated over the
   certificate_list element of a server side Certificate message.
...
   When CachedInformationType identifies trusted_cas, then hash_value
   MUST include at least one hash value calculated over the
   certificate_authorities element of a server side CertificateRequest
   message.

And quoting RFC 5246 for the definitions of certificate_list and
certificate_authorities:

      opaque ASN.1Cert<1..2^24-1>;

      struct {
          ASN.1Cert certificate_list<0..2^24-1>;
      } Certificate;
...
      opaque DistinguishedName<1..2^16-1>;

      struct {
          ClientCertificateType certificate_types<1..2^8-1>;
          SignatureAndHashAlgorithm
            supported_signature_algorithms<2^16-1>;
          DistinguishedName certificate_authorities<0..2^16-1>;
      } CertificateRequest;

Q: Should the length bytes be included in the hash input or not?

/Simon

---

From: Martin Rex <[email-masked]>
Date: Tue, 9 Jun 2009 12:02:37 +0200 (MEST)

Simon Josefsson wrote:
> Martin Rex wrote: 

The client knows which Hash it would find, if the server would sent
the hash, so it could check for that.  Even a collision of the
hash and the original handshake data would not cause a problem
with this "heuristical" determination.

I'm wondering about the following: we should give a strong recommendation
about the minimum size of an object in order for caching to make any
sense at all, like >= 2x the size of the hash.

At least 2x, because the hash appears (at least) twice in a full SSL
handshake (ClientHello and the actual handshake message with the
cached information).

For a SSL session resume, the extension will create an unconditional
burden, because the ClientHello extension would need to be present
in every ClientHello, in order to actually save on the full handshake
in case the server decides to require one (e.g. session expired on
server side).

Maybe the minimum size should be rather 3x hash size, considering
the rest of the protocol overhead.

-Martin

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 09 Jun 2009 12:59:52 +0200

> the rest of the protocol overhead.

This seems like a good idea -- and it solves the problem in the client
to identify whether the server replaced the data or not.  If the minimum
size is 3x hash size, the client can look at the length of the data.  If
it is longer than 3x hash size, it knows the server opted out from
sending the hash.  If it is shorter than 3x hash size, it knows the
server actually did replace the data with a hash value.

It seems wasteful that the same hash value is sent back and forth
_three_ times during a handshake, and possibly that could be optimized.
But that would add complexity.

/Simon

---

From: Martin Rex <[email-masked]>
Date: Tue, 9 Jun 2009 14:23:52 +0200 (MEST)

> server actually did replace the data with a hash value.

Not quite.

The caching extension is supposed to be generic, and the to-be-cached
real data may in some situations be quite short or even the same size
than the hash value (probably not for the server certificate caching,
but maybe for the list of certification authorities in the certificate
request message, which consists of distinguished names only, and
there could be just one very short DName (or none at all with TLS v1.1+)

> But that would add complexity.

There are several conceivable approaches, so we might want to weigh
the pros and cons for them.

 - out-of-band signalling, i.e. in the Server-Hello extension
    (++)  no ambiguity about what is sent, no matter what is acutually
          used as replacement in the encoded handshake message
    (---) would require server to pre-compute hashes over parts of future
          tls handshake messages when composing Server-Hello

 - in-band-signalling, i.e. a combination of the Server-Hello acknowledgement
   for principle support of caching a particular piece of information of
   the (full) SSL handshake plus a replacement tag that the client can
   recognize for the cached piece of information within the SSL handshake
   message in case the hash provided by the client matches the hash over
   the data that the server would normally send.

    (++) smaller impact on the overall architecture of the TLS
         implementation, because there is no requirement to precompute
         a hash over parts of a future tls handshake message

    (-) requires a sort-of heuristic determination whether the data
        encoded in a handshake message is real data or the replacement
        tag--be it a fixed short tag or the hash (pre-requisite: the
        client asserted the hash for cached information in ClientHello
        and the server acknowledged support for this in ServerHello)

-Martin

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 09 Jun 2009 15:41:27 +0200

> there could be just one very short DName (or none at all with TLS v1.1+)

Then why use the extension?  The point of the extension, as I understood
it, is to replace large data with a small hash of the same data.  If the
data is small, the extension doesn't serve any purpose and should not be
used.  That is why I liked your suggestion to limit the use of the
extension when the data is larger than 3x hash size.

/Simon

---

From: Martin Rex <[email-masked]>
Date: Tue, 9 Jun 2009 15:47:34 +0200 (MEST)

> was replaced or not?  How would the client know which hash algorithm is

The Server can reliably signal in the ServerHello extension whether
it supports Caching for an object for which the Client asserted
a Hash value in the ClientHello extension, and the Server ought
to be able to decide upfront which Hash algorithms it supports.

Allowing the client to supply different hashes for different
incarnations of the same tls handshake data would significantly
increase the protocol complexity.  Suddenly, the hash values
of different algorithms might refer to different cached data.

I would suggest to limit the client to announce only one cached
value (possibly with different hash algorithms, but then the server
should not have to check each hash value for a mach, but only the
hash algorithm selected by the server).

It might be sensible for the client to manage cache entries based
on several attributes, and in particular distuigish also by the
"server name" as used in the TLS extension "Server name indication"
in order to support TLS-compatible virtual hosting.

> whether the server replaced the value or not.

The Server Hello Extension should indicate whether the server will
try to use the caching extension, and which hash algorithm it is
going to use (from those proposed by the client).

So the "heuristic" of the client is to match the potentially cached
data (length first, then data) against the one hash value that the
client originally proposed in the ClientHelloExtension and that the server
agreed to support in the ServerHelloExtension.

Personally, I'm not concerned about a potential collision of the
clients proposed hash with the real data that the server is going
to send.  Such a collision would not affect the data that the server
is going to send, it could only affect how the client would
interpret it (using the cached data instead of parsing the
real data that looks like its proposed hash).

What are possible alternatives?
- Send other data that could be ambiguous in other scenarios
- Send data in a specifically invalid fashion, i.e. a maximum-value
  length field that exceeds the outer container size.

-Martin

---

From: Martin Rex <[email-masked]>
Date: Tue, 9 Jun 2009 15:52:33 +0200 (MEST)

> extension when the data is larger than 3x hash size.

Look at this:

Server supports caching of certificate_authorities list and runs with
a large list

Client connects, caches the long list and announces the hash of the
cached information on future reconnects

Server configuration is updated, certificate_authorities list
is cut down and now only contains one very short name.

Client connects again (having still cached the previous long list),
server indicates to support caching of that value in principle,
but returns the real data since the hash proposed by the client
no longer matches.

Client should now realize that the short data is the new real
data, should probably drop the cached value, and refrain from
further caching of the short value.

-Martin

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 09 Jun 2009 15:55:49 +0200

Here is a modified idea.  Replace the CachedInformationHash with this
structure:

struct {
           HashAlgorithm hash;
           uint32 datasize;       /* NEW.  Size of hashed data.
                                     MUST be >= 4 * hashsize(hash) */
           opaque hash_value<0..255>;
      } CachedInformationHash;

The server respond by indicating whether it supports cached data in
principle, but defers until later in the handshake to decide whether to
replace data or not.  This addresses Martin's concern.

Then add text to say that datasize MUST be >= 4 * hashsize(hash) where
hashsize is the hash output size, i.e., 20 for SHA-1.  Smaller objects
cannot be cached with this extension.

The server can decide, when constructing later handshake packets,
whether to replace the generated data with a hash or not.  Typically,
the server would generate the data as normal.  Then if the client
provided a cache extension type for the object, it will compare a hash
of the generated data with the hash provided by the client.  If they
match, it will send the CachedInformationHash value instead of the
generated data.

The client parses the response, and can by looking at the size of each
object decide whether it is a hash or real data.

This runs into a problem if the server instead of returning a hash
returned data that was considerably smaller than the value cached by the
client.  The client could then be confused whether the returned data is
real data or a hash value.  A type-specific tag could be constructed
here -- for both certificate_list and certificate_authorities it could
be some invalid ASN.1 followed by the CachedInformationHash.

This is a compromise, but it seems difficult to solve both Martin's
concern and my concern that clients needs to reliably be able to decode
incoming data.  Better ideas welcome.

/Simon

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 09 Jun 2009 16:00:21 +0200

> further caching of the short value.

Right.  That is how I think it should work as well.

I believe that adding a limit of 4x hash size (or similar) is still
useful, though, since it would be pointless for the client in your
example to update its cached hash with a hash of the new string, and
send that hash in the future.  Doing so would result in a handshake that
is potentially _larger_ than if the cached data were sent.

/Simon

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 09 Jun 2009 16:19:26 +0200

> in order to support TLS-compatible virtual hosting.

That is a good point, and it would help implementers to make this
explicit.  Stefan, how about adding a sentence to explain this?  After
this paragraph

   Clients MAY include an extension of type "cached_information" in the
   (extended) client hello, which SHALL contain at least one
   CachedObject as specified in section 2.

you could add

   Clients MAY need the ability to cache different values depending on
   other information in the Client Hello that modify what values the
   server uses, in particular the Server Name Indication [RFC4366]
   value.

If XML source is available, I could send you a patch. ;)

Thanks,
/Simon

---

From: Stefan Santesson <[email-masked]>
Date: Tue, 16 Jun 2009 16:59:44 +0200

Simon,

This is a good suggestion. I have added this text in the edit pool of next
version.

Unfortunately I'm an nroff hacker :)

/Stefan