Skip to main content
added 756 characters in body
Source Link
dave_thompson_085
  • 11.1k
  • 1
  • 31
  • 31

Aside: after not having a cert/key at all, this is probably the thing server admins, operators, and programmers screw up most often. You can find lots of Qs on several Stacks about 'TLS doesn't work' which turns out to be the server not correctly sending chain certs, usually because it's configured wrong. Because it is so common some clients, especially web browsers, try to work around it and often succeed, which causes people to misunderstand and even disbelieve the problem: "My server can't be wrong, because $thing works!" "Yes $thing works AND your server is still wrong". TLS1.3 (RFC8446) relaxes this slightly -- the server is still supposed to send the full chain optionally omitting root, but is not required to do so in strict sequence.

Aside: after not having a cert/key at all, this is probably the thing server admins, operators, and programmers screw up most often. You can find lots of Qs on several Stacks about 'TLS doesn't work' which turns out to be the server not correctly sending chain certs, usually because it's configured wrong. Because it is so common some clients, especially web browsers, try to work around it and often succeed, which causes people to misunderstand and even disbelieve the problem: "My server can't be wrong, because $thing works!" "Yes $thing works AND your server is still wrong". TLS1.3 (RFC8446) relaxes this slightly -- the server is still supposed to send the full chain optionally omitting root, but is not required to do so in strict sequence.

Source Link
dave_thompson_085
  • 11.1k
  • 1
  • 31
  • 31

First, 7.4.1.1 states: Each cipher suite defines a key exchange algorithm, a bulk encryption algorithm (including secret key length), a MAC algorithm, and a PRF. ....

My naive understanding is that all the algorithms required are right here in this exchange.

No. A (pre-TLS1.3) ciphersuite defines many of the algorithms used, but not all. It defines the ones that are in the list you quoted, and it doesn't define the ones that aren't in that list. That's rather the point of explicitly stating the list of things that are defined.

But then comes section 7.4.1.4.1 talking about "Signature Algorithms" extension. So, a signature algorithm can be specified through an extension. But a paragraph later in the same section states:

The semantics of this extension are somewhat complicated because the cipher suite indicates permissible signature algorithms but not hash algorithms. Sections 7.4.2 and 7.4.3 describe the appropriate rules.

So, does it mean that the Signature-algorithms extension is used to specify the Signature Algorithm from a set of signature algorithms selected by the server from a possibly bigger set offered by the client in the Client Hello?

Kind of. There can be and often is more than one signature used, and thus possibly more than one signature algorithm used. Each signature must meet both the constraints given by the ciphersuite, where applicable, and the sigalgs extension, if present. As it says, these are detailed in 7.4.2 and 7.4.3.

What does 7.4.2 refer to, in relevant part? It gives permissible mappings between Key Exchange Algo and Certificate Key Type.

So it does, and immediately afterward it says

   If the client provided a "signature_algorithms" extension, then all
   certificates provided by the server MUST be signed by a
   hash/signature algorithm pair that appears in that extension.  Note
   that this implies that a certificate containing a key for one
   signature algorithm MAY be signed using a different signature
   algorithm (for instance, an RSA key signed with a DSA key).  This is
   a departure from TLS 1.1, which required that the algorithms be the
   same.  Note that this also implies that the DH_DSS, DH_RSA,
   ECDH_ECDSA, and ECDH_RSA key exchange algorithms do not restrict the
   algorithm used to sign the certificate.  Fixed DH certificates MAY be
   signed with any hash/signature algorithm pair appearing in the
   extension.  The names DH_DSS, DH_RSA, ECDH_ECDSA, and ECDH_RSA are
   historical.

(You quoted part of this as being in 7.4.3, but it's not, it's in 7.4.2.)

Thus the keyexchange in the ciphersuite controls the type of key in the server (EE, leaf) cert, but not the signature on that cert by the CA, which depends primarily on the type of key used by the CA and not the type of key used by the server. In addition, the simplified model often presented that the server cert is issued/signed by a CA trusted by the client is just that, simplified. In practice there are nearly always two levels of CA and sometimes more; this is indicated, though not really explained, in the description of certificate_list about a page earlier in the same section:

      This is a sequence (chain) of certificates.  The sender's
      certificate MUST come first in the list.  Each following
      certificate MUST directly certify the one preceding it.  
      ... the root ... MAY be omitted ....

Sigalgs constrains the signatures on all the certs in the chain -- possibly excepting the root, because the root signature is a dummy self-signature that needn't be checked -- and the keyexchange/ciphersuite does not.

To make things more confusing for me comes Section 7.4.3:

The ServerKeyExchange message is sent by the server only when the server Certificate message (if sent) does not contain enough data to allow the client to exchange a premaster secret.

What exactly is this "enough data"? Does a standard (whatever that implies!) certificate not have "enough data" any way? Will the server not have picked the key-exchange-algo, when sending the Server Hello, to match the server Certificate it sent?

Literally the next lines answer your question.

      ... This is true [more data is needed]
      for the following key exchange methods:

         DHE_DSS
         DHE_RSA
         DH_anon

     [plus ECDHE_RSA ECDHE_ECDSA ECDH_anon in RFC4492, 
     referenced in the next paragraph]

These key exchanges are 'ephemeral' keyexchanges -- they use a newly-created keypair for each handshake, which cannot be in the certificate because the certificate was created in advance -- often far in advance (like years). Thus the ServerKeyExchange message is needed to convey (and validate) the publickey. The server will indeed choose a keyexchange and cert-plus-static-key that are compatible with each other, as well as being permitted by the client, but most clients today will list as preferred, and most servers will choose (either on their own bat or following client preference) an ephemeral keyexchange over one that isn't, because it provides the valuable feature Forward Secrecy aka Perfect Forward Secrecy (PFS).

      It is not legal to send the ServerKeyExchange message for the
      following key exchange methods:

         RSA
         DH_DSS
         DH_RSA

      [plus ECDH_RSA ECDH_ECDSA in RFC4492]

because those keyexchanges use (and need) only the publickey in the certificate. Only the first, RSA, is commonly used; the 'static' aka 'fixed' (non-ephemeral) DH and ECDH keyexchanges are mostly useless, and the former (static-DH) require a cert that can't be obtained from any known CA.

In addition to the publickey (and mostly certificate) based keyexchanges defined in RFC5246 (and 4346 and 2246) and RFC4492, there are some other keyexchanges defined in other RFCs like PSK (Pre-Shared Key), SRP (Secure Remote Password), and Kerberos which use ServerKeyExchange (and ClientKeyExchange as well) in substantially different ways. These are not used on the public network, and only rarely even on private networks. Consult those other RFCs for details; they can be found via the IANA registry.

In TLS1.0 (and SSL3) there were 'export' ciphersuites some of which used a keyexchange called RSA_EXPORT, which for legal reasons had the restriction that an RSA key over 512 bits could be used for signing but not encryption. This meant that if the server RSA cert key was 512 bits (or less) it simply sent the cert and the client used it, but if the cert key was longer it sent ServerKeyExchange containing a 'temporary' RSA key of 512 bits (or less) to be used for encrypting the premaster secret, signed by the (longer) key in the cert. This 'export' feature had other, also very detrimental, effects as well. See RFC2246 for the awful details.

The 'appropriate rules' in 7.4.3 are on page 52, and describe the signature in the ServerKeyExchange message, which covers the body of that message plus the session nonces, and uses the publickey in the server cert:

   If the client has offered the "signature_algorithms" extension, the
   signature algorithm and hash algorithm MUST be a pair listed in that
   extension.  ....

   In addition, the hash and signature algorithms MUST be compatible
   with the key in the server's end-entity certificate.  RSA keys MAY be
   used with any permitted hash algorithm, subject to restrictions in
   the certificate, if any.

   Because DSA signatures do not contain any secure indication of hash
   algorithm, there is a risk of hash substitution if multiple hashes
   may be used with any key.  Currently, DSA [DSS] may only be used with
   SHA-1.  Future revisions of DSS [DSS-3] are expected to allow the use
   of other digest algorithms with DSA, as well as guidance as to which
   digest algorithms should be used with each key size.  In addition,
   future revisions of [PKIX] may specify mechanisms for certificates to
   indicate which digest algorithms are to be used with DSA.

As predicted, FIPS186-3 in 2009 (and -4 in 2013) define DSA with larger sizes and SHA-2 hashes, and RFC5758 in 2010 allows them in PKIX (technically modifying 3279, not 3280 or 5280).