Subject: [TLS] Certificate keyUsage enforcement question (new in RFC8446 Appendix E.8)

From: Viktor Dukhovni <[email-masked]>
Date: Mon, 5 Nov 2018 21:24:26 -0500

TL;DR:  Should TLS client abort DHE-RSA handshakes with a peer
certificate that *only* lists:

            X509v3 Key Usage: 
                Key Encipherment, Data Encipherment

(which one might take to mean that only RSA key exchange is allowed,
and DHE-RSA is not, for lack of the DigitalSignature bit?

[ In the unlikely case it matters, the record the certificate
  in question is self-signed, and has a DANE TLSA "3 0 1" record. ]

-- Background:

I am somewhat sympathetic to forbidding RSA key exchange when
"Key Encipherment" is not listed, in order to reduce the risk of
Bleichenbacher-type attacks, but it is not obvious at first blush
why one might the converse restriction...

The reason I ask is that the Haskell TLS library has recently added
enforcement in both directions, and I am finding some SMTP servers
with whose STARTTLS implementation my DANE scan engine no longer
interoperates.

And yet, FWIW, OpenSSL 1.1.1 continues to connect just fine.  Is
this an oversight in OpenSSL?  Overly strict enforcement in Haskell's
Network.TLS?  Should the language in RFC8446 apply also to TLS 1.2
and earlier, where no mention of "keyUsage" is to be found in the
relevant specifications?

The text in 8446 is not crystal clear on the intent.  Is keyUsage
enforcement (absent OID filters from the peer) a MUST?  A SHOULD?
A BCP?  And which directions should it apply in?  That is, does
it make sense to require RSA key transport when DHE appears to
be disallowed?

In appendix E.8 of TLS 1.3 RFC8446 <https://tools.ietf.org/html/rfc8446#appendix-E.8>
we find:

   E.8.  Attacks on Static RSA

   Although TLS 1.3 does not use RSA key transport and so is not
   directly susceptible to Bleichenbacher-type attacks [Blei98], if TLS
   1.3 servers also support static RSA in the context of previous
   versions of TLS, then it may be possible to impersonate the server
   for TLS 1.3 connections [JSS15].  TLS 1.3 implementations can prevent
   this attack by disabling support for static RSA across all versions
   of TLS.  In principle, implementations might also be able to separate
   certificates with different keyUsage bits for static RSA decryption
   and RSA signature, but this technique relies on clients refusing to
   accept signatures using keys in certificates that do not have the
   digitalSignature bit set, and many clients do not enforce this
   restriction.

In 4.2.5 <https://tools.ietf.org/html/rfc8446#section-4.2.5> we
also find:

   This document defines matching rules for two standard certificate
   extensions defined in [RFC5280]:

   -  The Key Usage extension in a certificate matches the request when
      all key usage bits asserted in the request are also asserted in
      the Key Usage certificate extension.

But that's about explicit OID filters from the peer, not a-priori
constraints.

-- 
	Viktor.

---

From: Geoffrey Keating <[email-masked]>
Date: 05 Nov 2018 20:11:12 -0800

>                 Key Encipherment, Data Encipherment

Yes, because in DHE-RSA, the RSA key is used for signing, and this is
an encryption-only key.

It's much more important in the DHE-ECDSA case, because using an
encryption-only EC key for signing can lead to key compromise (IIRC).
As far as I know there's no similar attack on RSA, but I think this is
not a well-examined area.

---

From: Viktor Dukhovni <[email-masked]>
Date: Wed, 7 Nov 2018 02:12:34 -0500

[ Quoted text slightly reordered to put the RSA issue first, as that's
  the main thing I'm trying to get clarity on, and enabling keyUsage
  enforcement is causing some interoperability issues now... ]

> On Nov 5, 2018, at 11:11 PM, Geoffrey Keating <[email-masked]> wrote:
> 

> not a well-examined area.

Since the vast majority of certificates in the wild are RSA, and
interoperability is a concern, I'd really like to better understand
what risk if any posed if one allows a an *RSA* key with a keyUsage
of "keyEncipherment" (seen on some live servers that then do DHE-RSA)
to be used for "DigitalSignature"?  I am only aware of risks in the
converse direction.  How unreasonable would it be to be more forgiving
and allow *RSA* "DigitalSignature" when the keyUsage indicates otherwise?

> encryption-only EC key for signing can lead to key compromise (IIRC).

Does anyone have pointers to references for that?  FWIW, I've never seen an
encryption-only (ECIES?) ECDSA key, I guess could be intended for CMS...
In TLSA there's no ECDS keyEncipherment, only ECDHE and fixed ECDH (obsolete).
The first goes with a keyUsage of DigitalSignature, the second with keyAgreement.

Knowing how fragile ECDSA tends to be to key recovery on nonce re-use
or similar issues, I have no reservations enforcing keyUsage for ECDSA.

-- 
	Viktor.

---

From: [email-masked] (Martin Rex)
Date: Wed, 7 Nov 2018 15:48:26 +0100 (CET)

> Yes, because in DHE-RSA, the RSA key is used for signing, and this is

There is *ZERO* security problem associated with TLS client allowing
a TLS server to do this, but it makes it harder to catch defective
CA software and bogus CA issuing practices when clients do not complain
here -- and the TLS specification says this KeyUsage DigitalSignature
is a MUST for DHE/ECDHE key exchange:

  TLSv1.2:  https://tools.ietf.org/html/rfc5246#page-49

      DHE_RSA            RSA public key; the certificate MUST allow the
      ECDHE_RSA          key to be used for signing (the
                         digitalSignature bit MUST be set if the key
                         usage extension is present) with the signature
                         scheme and hash algorithm that will be employed
                         in the server key exchange message.
                         Note: ECDHE_RSA is defined in [TLSECC].

  TLSv1.0:  https://tools.ietf.org/html/rfc2246#page-38

CAs and CA software that issues certificates as TLS server certificates
(i.e. with ExtKeyUsage  id-kp-serverAuth, id-kp-clientAuth or both) and
forgets to assert DigitalSignature, prove their own royal brokenness.

Using an RSA key for PKCS#1 v1.5 signatures is *NO* security problem.

Do not get confused by the FUD and snake-oil that resulted in the
needless additional complexity of RSA-PSS in TLSv1.3, that adds ZERO
security value.

   https://www.schneier.com/blog/archives/2018/09/evidence_for_th.html

   https://eprint.iacr.org/2018/855

There is some security risk with using an RSA signing-only key
for PKCS#1 v1.5 encryption, i.e. the equivalent of
using a keyUsage without keyEncipherment for static-RSA key exchange 

-Martin

---

From: Viktor Dukhovni <[email-masked]>
Date: Wed, 7 Nov 2018 10:44:53 -0500

On Wed, Nov 07, 2018 at 03:48:26PM +0100, Martin Rex wrote:

> here

The interoperability issues I'm seeing are with self-signed
certificates used in opportunistic TLS and DANE in SMTP.  The CA
is some end-user, who "does not know any better", and the question
is how pedantic should the client's TLS stack be in such a case.

Perhaps the correct place to *enforce* any keyUsage requirement is
in the TLS *server*, which should limit *itself* to the algorithms
compatible with the certificate.  That would be both more effective,
and more interoperable.

> -- and the TLS specification says this KeyUsage DigitalSignature

What the RFC does not say is whose duty it is (if anyone's) to
*enforce* the restriction.  Perhaps clients should not be the ones
to do so?

-- 
	Viktor.

---

From: David Benjamin <[email-masked]>
Date: Wed, 7 Nov 2018 11:40:47 -0600

> and allow *RSA* "DigitalSignature" when the keyUsage indicates otherwise?

This seems flipped to me. Which attacks do you see enforcing
keyEncipherment blocking? If you are concerned about Bleichenbacher-type
private key oracles, it should be more important to enforce
digitalSignature, and even that's not sufficient in itself (cf. DROWN
affecting non-SSLv2 clients too).

A private key oracle allows both ciphertext decryption *and* signature
forgery, so we need clients to know which forged signatures to reject, and
for an uncompromised path to be possible. Thus, if you believe the server's
RSA key exchange implementation admits a private key oracle and that oracle
is efficient enough for online attacks[*], I believe you need all of the
following for the client to not care:

1. The server uses separate keys for RSA encryption and RSA signing. It
will never use its RSA signing key for RSA encryption.
2. The server key separation is reflected in keyUsage bits, which is
enforced by the client in (EC)DHE_RSA modes.
3. The client doesn't accept RSA key exchange at all.

If all are true, the client will never accept the encryption key and the
signing key is uncompromised, so we're fine. If any of the above are false,
I don't think it works.

If the server shares RSA and (EC)DHE_RSA keys (1), as everyone does, its
one and only key is effectively compromised and there's not a whole lot one
can do, short of fixing or disabling the RSA key exchange implementation on
the server.

If the client ignores keyUsage in (EC)DHE_RSA (2), as most do, the server's
key separation is moot. The client doesn't know to reject a
private-key-oracle-forged signature.

If the client still supports RSA key exchange (3), as most do, none of this
key separation matters, because the attacker can just negotiate RSA key
exchange anyway.

My experience is that typically none of (1), (2), or (3) happen, much less
all, so this is all kind of moot. :-)

Re (2), historically we'd seen issues with MITM proxies minting certs
incorrectly, BoringSSL only enforces key usage for RSA starting TLS 1.3 (it
was new, so get it right from the start) and ECDSA at all versions (only
one value in practice, seems to have worked out). I started gathering more
current metrics a while back but haven't had time to follow-up on this yet.
But as most clients sadly still have to support RSA key exchange (3) and
managing two certificates (1) is onerous for most server, I doubt any
fixing that will help in practice for a while, if ever. It's more an
ecosystem health thing.

David

[*] If you believe the oracle isn't efficient enough for online attacks,
you probably can just lean on downgrade protection ratcheting you to
(EC)DHE_RSA and call it a day?

---

From: Geoffrey Keating <[email-masked]>
Date: 07 Nov 2018 15:07:53 -0800

> and allow *RSA* "DigitalSignature" when the keyUsage indicates otherwise?

Maybe I should expand on my previous answer.

There is, obviously, an attack with RSA under some circumstances.  If
you have an oracle where the attacker can see the results of any RSA
decryption, then this leads directly to the ability to forge a
signature.

In more practical situations, the attacker doesn't get to see the
results.  Instead, for example in properly-implemented TLS, the
attacker only learns whether the decryption was successful, relative
to a key chosen by the attacker, and a 'successful' decryption
includes a padding check of the output which is highly unlikely to
succeed for a fixed input.  So there doesn't seem to be a direct
attack in this situation.

However, how do you know this is the situation?

There is the obvious question about improper implementations.  How do
you know that this key wasn't configured this way because there's a
known security issue which might leak a key used for encryption, and
the key is intended only to be presented to hosts which will not
accept DHE?

This is particularly relevant because we do know of some attacks on
PKCS#1v1.5 encryption, which make the 'proper implementation' quite
complicated, and you can see the result in RFC 3218.  However these
attacks were concerned primarily with recovering the symmetric key,
and not forging a signature using the RSA key.  I don't think anyone
has deeply investigated the signature-forging issue in this context,
since typically if you can recover the symmetric key, that's bad
enough (you can just force the connection to use an encryption-based
ciphersuite).

In general, though, what you're asking is "The CA signing this key has
instructed that I do not accept signatures made with it.  Is it OK to
accept signatures made with it?" It's really hard to see how the
answer to that could generally be 'yes'.

---

From: Peter Gutmann <[email-masked]>
Date: Thu, 8 Nov 2018 02:19:56 +0000

Viktor Dukhovni <[email-masked]> writes:

>The interoperability issues I'm seeing are with self-signed certificates used
>in opportunistic TLS and DANE in SMTP.  The CA is some end-user, who "does not
>know any better", and the question is how pedantic should the client's TLS
>stack be in such a case.

My code, by default, strictly enforces keyUsage [0], so I end up seeing all
the broken certs out there, and it's complete chaos, (DH) keyAgreement set for
RSA certs, every possible key usage (includings ones the algorithm isn't
capable of) set, things like email encryption and SSL server set for CA certs
(extKeyUsage), keyEncipherment for signing keys, digitalSignature for
encryption keys, it's the Rule 34 of PKI (if you can think of it, someone's
put it in an extension).  This includes CA-issued certs, not self-signed ones.
I think a significant chunk of TLS PKI only works because implementations
don't strictly enforce keyUsage.

Peter.

[0] Which probably wasn't the best default setting.  If you think the public
    web PKI has broken certs, you should see what turns up in the SCADA 
    world...

---

From: "Blumenthal, Uri - 0553 - MITLL" <[email-masked]>
Date: Thu, 8 Nov 2018 02:58:55 +0000

Peter, 

I think your code did exactly right. The standard requires honoring KeyUsage.

Maybe if more implementations were diligent with this, the cert zoo we're observing would've been less wild...

Regards,
Uri

Sent from my iPhone

> On Nov 7, 2018, at 21:21, Peter Gutmann <[email-masked]> wrote:
> 
> _______________________________________________
> TLS mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/tls

---

From: Viktor Dukhovni <[email-masked]>
Date: Wed, 7 Nov 2018 23:26:40 -0500

> On Nov 7, 2018, at 6:07 PM, Geoffrey Keating <[email-masked]> wrote:
> 
> n general, though, what you're asking is "The CA signing this key has

Thanks for everyone's input, this has been very helpful.  The approach
I'm inclined to take is as follows:

1. Always enforce key usage for your own certificate, ensuring key
   separation as provisioned at the time of key/certificate creation.
   This also maximizes opportunities for problems to be detected early
   and fixed.

2. Always enforce peer certificate key usage (separation) for ECDSA.
   ECDSA keys are more brittle when misused.

3. Enforce RSA peer certificate key usage when RSA key transport is locally
   disabled, allowing only (EC)DHE-RSA.  This is always the case with TLS 1.3,
   but for TLS <= 1.2 subject to the enabled ciphers.

The rationale for 3 is as follows:

   * The primary responsibility for doing key separation right falls on the
     key holder (as in 1).  If that's always done correctly, the peer has
     nothing to second-guess.

   * If the key holder has no key separation, and makes key recovery
     possible through some sort of side-channel, then the attacker who
     recovers the key can always misuse that key via whichever key
     exchange is allowed by the certificate, when all are accepted by
     the client.

     Therefore, if the client supports both RSA key exchange and (EC)DHE-RSA,
     the attacker wins regardless of any effort by the client to enforce key
     usages.

     Which leaves the case where the client only accepts (EC)DHE-RSA (as with
     TLS 1.3 or TLS 1.2 with the RSA key exchange features disabled).  In that
     case, if the attacker is able to compromise a server key constrained to
     "keyEncipherment", but cannot obtain a fraudulent certificate, then he'd have
     a certificate for just "keyEncipherment" which the client will refuse to
     honour for "digitalSignature".  And so the client actually gets some measure
     of protection by doing keyUsage enforcement.

This approach also has the advantage that legacy cases continue to (mis)behave
like they always did, but the strictness rises to match the client's protocol
preferences wether through use of TLS 1.3 (fresh start, fresh constraints) or
by restricting TLS 1.2 ciphers in a way that makes keyUsage enforcement a
practical counter-measure to at least some potential attacks.

-- 
	Viktor.

---

From: "Blumenthal, Uri - 0553 - MITLL" <[email-masked]>
Date: Thu, 8 Nov 2018 14:37:21 +0000

Yes to what Viktor proposed.

    

    

    

    
    
    -- 
    	Viktor.

---

From: Peter Gutmann <[email-masked]>
Date: Thu, 8 Nov 2018 22:27:24 +0000

Blumenthal, Uri - 0553 - MITLL <[email-masked]> writes:

>Always enforce peer certificate key usage (separation) for ECDSA. ECDSA keys
>are more brittle when misused.

Since ECDSA can only do signing, isn't this a bit redundant?  In other words
you can't really not enforce keyUsage for a signature-only algorithm.

Peter.

---

From: Viktor Dukhovni <[email-masked]>
Date: Thu, 8 Nov 2018 18:31:35 -0500

> On Nov 8, 2018, at 5:27 PM, Peter Gutmann <[email-masked]> wrote:
> 

Well, ECDH keys (not really ECDSA) can do key agreement, and EC keys
can be used for encryption with ECIES.  In any case, it seems that
other libraries are already requiring digitalSignature in keyUsage
(when present) for ECDSA that don't yet do so for RSA, and I'm willing
to go along with that.  Trying to make a pragmatic choice...

-- 
	Viktor.

---

From: Peter Gutmann <[email-masked]>
Date: Fri, 9 Nov 2018 06:19:32 +0000

Viktor Dukhovni <[email-masked]> writes:

>Well, ECDH keys (not really ECDSA) can do key agreement, and EC keys can be
>used for encryption with ECIES.

Sure, in theory, but in practice I've never seen an (EC)DH cert used in TLS
(despite actively looking for one, since it'd be a collectors item for the
cert collection [0]), and I doubt most implementations could even deal with
one if they saw one.  Also, I don't think any TLS implementation, or
specification, does ECIES.  So it's pretty much self-regulating...

Peter.

[0] I know some test certs were generated about 20 years ago to demonstrate
    X9.42 use in S/MIME, but that's all I'm aware of.

---

From: Viktor Dukhovni <[email-masked]>
Date: Fri, 9 Nov 2018 01:40:21 -0500

> On Nov 9, 2018, at 1:19 AM, Peter Gutmann <[email-masked]> wrote:
> 
> (despite actively looking for one,

Nor have I, and I rather think that introducing fixed-(EC)DH ciphers into
TLS was a mistake, and glad to see them gone in TLS 1.3.

> since it'd be a collectors item for the

And yet I guess the possibility exists that some poor slob deploys a TLS server
with an exotic EC key, that's supposed to be used for fixed-ECDH or CMS key
envelopment.  Does that risk key compromise given how fragile EC signatures
when misused?

I guess I am willing to risk failing a tiny fraction of handshakes in this
case; and rumour has it I'd have some company, so the Haskell TLS library
(where I'm helping the maintainers at the moment) won't stand out from the
pack in being overly strict wrt. ECDSA keyUsage.

The idea is to actually relax the rules a bit from what they've recently
become, as based on the specs they're presently a bit too strict, and I
am trying to dial them back to more practical choices.  If you think that
ECDSA keyUsage enforcement does more harm than good, I could reconsider,
but I am inclined to be more cautious with EC than with RSA.

-- 
-- 
	Viktor.

---

From: Yoav Nir <[email-masked]>
Date: Fri, 9 Nov 2018 23:52:56 +0700

> On 9 Nov 2018, at 13:40, Viktor Dukhovni <[email-masked]> wrote:
> 

FWIW RFC 8422 also deprecates them for TLS 1.2 and earlier.

Yoav

---

From: Viktor Dukhovni <[email-masked]>
Date: Fri, 9 Nov 2018 12:25:32 -0500

> On Nov 9, 2018, at 11:52 AM, Yoav Nir <[email-masked]> wrote:
> 

Great!  Thanks.  I see that in:

   5.5.  Certificate Request

   https://tools.ietf.org/html/rfc8422#section-5.5

Mind you, as that text is in the context of "Certificate Request" some
might not read to understand that they're also deprecated for the server
certificate, but we can hope that'll be understood implicitly.

-- 
	Viktor.

---

From: Tony Putman <[email-masked]>
Date: Mon, 12 Nov 2018 09:45:09 +0000

Victor,

> TLS was a mistake, and glad to see them gone in TLS 1.3.

Can you please explain to me the problem with (EC)DH ciphers? If it's the
lack of forward secrecy, then I understand. If there are other problems, 
then I would be keen to understand them.

Thanks,
Tony

Dyson Technology Limited, company number 01959090, Tetbury Hill, Malmesbury, SN16 0RP, UK.
This message is intended solely for the addressee and may contain confidential information. If you have received this message in error, please immediately and permanently delete it, and do not use, copy or disclose the information contained in this message or in any attachment.
Dyson may monitor email traffic data and content for security & training.

---

From: Viktor Dukhovni <[email-masked]>
Date: Mon, 12 Nov 2018 08:57:01 -0500

> On Nov 12, 2018, at 4:45 AM, Tony Putman <[email-masked]> wrote:
> 

As much as it was lack of forward-secrecy, it was unnecessary bloat.
Few if any users actually needed these, and they did not get used.

The question is not so much what problem they introduced, but rather
what problem they were supposed to solve, and whether that problem
warranted the added complexity in the protocol.  I think we've had
the answer for some time now...

-- 
	Viktor.

---

From: Andrei Popov <[email-masked]>
Date: Tue, 13 Nov 2018 20:18:57 +0000

> Nor have I, and I rather think that introducing fixed-(EC)DH ciphers into TLS was a mistake, and glad to see them gone in TLS 1.3.

I agree with the sentiment, but there is a concerted effort to bring fixed (EC)DH to TLS 1.3:
https://www.etsi.org/deliver/etsi_ts/103500_103599/10352303/01.01.01_60/ts_10352303v010101p.pdf

It seems that a client that is not willing to participate has to actively look for and reject server certs with "VisibilityInformation" in them.
Except this won't always help, because "In some essential circumstances, the visibility information field may be omitted."

Cheers,

Andrei

---

From: Nikos Mavrogiannopoulos <[email-masked]>
Date: Thu, 15 Nov 2018 16:48:32 +0100

On Mon, 2018-11-05 at 21:24 -0500, Viktor Dukhovni wrote:
> Network.TLS?

gnutls has been enforcing that rule for quite some time. That had
generated quite some bug reports from application developers in the
past. The main argument was, but other implementations work.
Nevertheless the last few years the trend has changed and I think that
strictness is not only tolerated by developers/end-users but actually
promoted. That's only my impression though.

regards,
Nikos