Handling signature_algorithm extension on TLS1.3 server

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Handling signature_algorithm extension on TLS1.3 server

Raja Ashok-2
Hi,

Currently has_usable_cert() function is called on tls_choose_sigalg() to find out the suitable certificate available. But currently rsa_pkcs1_xxx and rsa_pss_rsae_xxx certs are stored on same index SSL_PKEY_RSA. Because of this it may ends in choosing rsa_pkcs1_xxx cert for rsa_pss_rsae_xxx extension. Is this behaviour correct ?

As per my understanding a new index should be created like SSL_PKEY_RSA_PSS_RSAE_SIGN for rsa_pss_rsae_xxx type certs. 

Regards,
Raja Ashok


Reply | Threaded
Open this post in threaded view
|

Re: Handling signature_algorithm extension on TLS1.3 server

Matt Caswell-2


On 06/06/2019 16:15, Raja Ashok wrote:
> Hi,
>
> Currently has_usable_cert() function is called on tls_choose_sigalg() to find
> out the suitable certificate available. But currently rsa_pkcs1_xxx and
> rsa_pss_rsae_xxx certs are stored on same index SSL_PKEY_RSA. Because of this it
> may ends in choosing rsa_pkcs1_xxx cert for rsa_pss_rsae_xxx extension. Is this
> behaviour correct ?

There are two things to consider:

1) The OID in the RSA cert, which can be one of rsaEncryption or RSASSA-PSS. The
former is for "traditional" RSA certs, whilst the latter *only* allows use of
the key for signing (it cannot be used for encryption).

2) The type of signing in use, e.g. RSASSA-PKCS-v1_5 or RSASSA-PSS.

rsaEncryption certs are capable of doing *either* form of signing, whilst
RSASSA-PSS certs can only do PSS signing.

We store rsaEncryption certs under the SSL_PKEY_RSA index, and RSASSA-PSS certs
under the SSL_PKEY_RSA_PSS_SIGN index.

TLSv1.2 and below signs handshake messages using PKCS v1.5. which corresponds to
these signature algorithms:

          rsa_pkcs1_sha256(0x0401)
          rsa_pkcs1_sha384(0x0501)
          rsa_pkcs1_sha512(0x0601)

These sig algs cannot be used in TLSv1.3 for signing handshake messages,
although they may appear in a ClientHello for backwards compatibility with
TLSv1.2. You can only use these sig algs with "traditional" RSA certs (not PSS
RSA certs).

TLSv1.3 signs handshake messages using PSS which corresponds to these signature
algorithms for "traditional" (rsaEncryption) certs:

          rsa_pss_rsae_sha256(0x0804)
          rsa_pss_rsae_sha384(0x0805)
          rsa_pss_rsae_sha512(0x0806)

Or these signature algorithms for PSS certs:

          rsa_pss_pss_sha256(0x0809)
          rsa_pss_pss_sha384(0x080a)
          rsa_pss_pss_sha512(0x080b)

Therefore it is perfectly correct behaviour that a cert stored under the
SSL_PKEY_RSA index could be used for signing handshake message using either
rsa_pkcs1_xxx or for rsa_pss_rsae_xxx. The former is used in TLSv1.2 and the
latter is used in TLSv1.3.

Matt
Reply | Threaded
Open this post in threaded view
|

Re: Handling signature_algorithm extension on TLS1.3 server

Raja Ashok-2
Thanks for the detailed explanation.

So rsaEncryption cert can do both RSASSA-PKCS-v1_5 and RSASSA-PSS type signature. And also the digital signature present on the cert can be of type RSASSA-PKCS-v1_5 or RSASSA-PSS.

Currently in 1.1.1c's has_usable_cert() function, digital signature (Issuer's signature) present on rsaEncryption cert type is not checked. So if TLS1.3 client sends rsa_pss_rsae_xxx in "signature_algorithm" extension and if the server's rsaEncrypted cert has digital signature of type RSASSA-PKCS-v1_5, then it should not use that certificate but it is using currently.

And also the hash algorithm used on rsaEncryption cert's digital signature is not checked with "signature_algorithm" extension received from client. If TLS1.3 client sends rsa_pss_rsae_sha384 and rsa_pss_rsae_sha512 in "signature_algorithm" extension, and if server has a rsaEncrypted cert with signature of type rsa_pss_rsae_sha256 then it should not use that certificate, but it is using currently.


On Thu, Jun 6, 2019 at 9:11 PM Matt Caswell <[hidden email]> wrote:


On 06/06/2019 16:15, Raja Ashok wrote:
> Hi,
>
> Currently has_usable_cert() function is called on tls_choose_sigalg() to find
> out the suitable certificate available. But currently rsa_pkcs1_xxx and
> rsa_pss_rsae_xxx certs are stored on same index SSL_PKEY_RSA. Because of this it
> may ends in choosing rsa_pkcs1_xxx cert for rsa_pss_rsae_xxx extension. Is this
> behaviour correct ?

There are two things to consider:

1) The OID in the RSA cert, which can be one of rsaEncryption or RSASSA-PSS. The
former is for "traditional" RSA certs, whilst the latter *only* allows use of
the key for signing (it cannot be used for encryption).

2) The type of signing in use, e.g. RSASSA-PKCS-v1_5 or RSASSA-PSS.

rsaEncryption certs are capable of doing *either* form of signing, whilst
RSASSA-PSS certs can only do PSS signing.

We store rsaEncryption certs under the SSL_PKEY_RSA index, and RSASSA-PSS certs
under the SSL_PKEY_RSA_PSS_SIGN index.

TLSv1.2 and below signs handshake messages using PKCS v1.5. which corresponds to
these signature algorithms:

          rsa_pkcs1_sha256(0x0401)
          rsa_pkcs1_sha384(0x0501)
          rsa_pkcs1_sha512(0x0601)

These sig algs cannot be used in TLSv1.3 for signing handshake messages,
although they may appear in a ClientHello for backwards compatibility with
TLSv1.2. You can only use these sig algs with "traditional" RSA certs (not PSS
RSA certs).

TLSv1.3 signs handshake messages using PSS which corresponds to these signature
algorithms for "traditional" (rsaEncryption) certs:

          rsa_pss_rsae_sha256(0x0804)
          rsa_pss_rsae_sha384(0x0805)
          rsa_pss_rsae_sha512(0x0806)

Or these signature algorithms for PSS certs:

          rsa_pss_pss_sha256(0x0809)
          rsa_pss_pss_sha384(0x080a)
          rsa_pss_pss_sha512(0x080b)

Therefore it is perfectly correct behaviour that a cert stored under the
SSL_PKEY_RSA index could be used for signing handshake message using either
rsa_pkcs1_xxx or for rsa_pss_rsae_xxx. The former is used in TLSv1.2 and the
latter is used in TLSv1.3.

Matt
Reply | Threaded
Open this post in threaded view
|

Re: Handling signature_algorithm extension on TLS1.3 server

Matt Caswell-2


On 07/06/2019 07:27, Raja Ashok wrote:

> Thanks for the detailed explanation.
>
> So rsaEncryption cert can do both RSASSA-PKCS-v1_5 and RSASSA-PSS type
> signature. And also the digital signature present on the cert can be of type
> RSASSA-PKCS-v1_5 or RSASSA-PSS.
>
> Currently in 1.1.1c's has_usable_cert() function, digital signature (Issuer's
> signature) present on rsaEncryption cert type is not checked. So if TLS1.3
> client sends rsa_pss_rsae_xxx in "signature_algorithm" extension and if the
> server's rsaEncrypted cert has digital signature of type RSASSA-PKCS-v1_5, then
> it should not use that certificate but it is using currently.

There are two extensions to consider signature_algorithms and
signature_algorithms_cert. From RFC8446:

   TLS 1.3 provides two extensions for indicating which signature
   algorithms may be used in digital signatures.  The
   "signature_algorithms_cert" extension applies to signatures in
   certificates, and the "signature_algorithms" extension, which
   originally appeared in TLS 1.2, applies to signatures in
   CertificateVerify messages.

Looking at the code for has_usable_cert you can see it first checking to see if
it has a certificate that can sign in accordance with signature algorithms. And
then it goes on to check whether the signature in the certificate itself is
consistent with signature_algorithms_cert.

So, if signature_algorithms_cert does not contain rsa_pkcs1_* and the
certificate contains a PKCS1.5 signature, then it shouldn't be being used.

However the RFC then goes on to say:

   If no "signature_algorithms_cert" extension is
   present, then the "signature_algorithms" extension also applies to
   signatures appearing in certificates.

This was an area of some ambiguity in the TLSv1.2 spec where only
signature_algorithms exists. I believe it was common practice for
implementations to not check the signatures in certificates for conformance with
this (certainly that is the way OpenSSL behaves). The TLSv1.3 spec seems to be
more explicit about this. I would expect our TLSv1.2 implementation to continue
to operate as it did before so this additional checking of signatures in
certificates where only the signature_algorithms extensions is present should
only apply to TLSv1.3.

I don't see any code to do this in has_usable_cert so this looks like a
potential bug. Although possibly it was left out on purpose.

Ben Kaduk may have a view on this who implemented this code:

https://github.com/openssl/openssl/pull/5068/commits/e639c37bddea48334cb45d88d407c655641e1a35


Matt
Reply | Threaded
Open this post in threaded view
|

Re: Handling signature_algorithm extension on TLS1.3 server

Raja Ashok-2


This was an area of some ambiguity in the TLSv1.2 spec where only
signature_algorithms exists. I believe it was common practice for
implementations to not check the signatures in certificates for conformance with
this (certainly that is the way OpenSSL behaves). The TLSv1.3 spec seems to be
more explicit about this. I would expect our TLSv1.2 implementation to continue
to operate as it did before so this additional checking of signatures in
certificates where only the signature_algorithms extensions is present should
only apply to TLSv1.3.

I don't see any code to do this in has_usable_cert so this looks like a
potential bug. Although possibly it was left out on purpose.

Yes. Currently this check is missing for both TLSv1.2 and TLSv1.3. I feel we may need to add for both TLSv1.2 and TLSv1.3, because TLSv1.2 RFC 5246 also mandates to do this check.

   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.


Atleast we should add this check for TLSv1.3. Otherwise cert with rsa_pkcsv1_5_xxx signature getting selected even if client has not included rsa_pkcsv1_5_xxx in signature_algorithm ext, but included rsa_pss_rsae_xxx. This looks weird.

Apart from this I am having one more doubt, that TLSv1.3 RFC 8446 says certificate with legacy signature(rsa_pkcsv1_5_sha1 and ecdsa_sha1) can be selected if no other valid certificate present on TLS1.3 server. But in tls_choose_sigalgs() function for TLSv1.3 we are currently skipping all SHA1 based and RSA_PKCSv1_5 based signature algorithm. I feel instead of avoiding we should consider as a low priority in this function for selecting legacy certificates with rsa_pkcsv1_5 and ecdsa_sha1.
 
      TLS 1.3 servers MUST NOT offer a SHA-1 signed certificate unless
      no valid certificate chain can be produced without it (see
      Section 4.4.2.2).



Ben Kaduk may have a view on this who implemented this code:

https://github.com/openssl/openssl/pull/5068/commits/e639c37bddea48334cb45d88d407c655641e1a35


And also requesting Ben Kaduk to put some light on it. 
Reply | Threaded
Open this post in threaded view
|

Re: Handling signature_algorithm extension on TLS1.3 server

Hubert Kario
On Friday, 7 June 2019 14:42:26 CEST Raja Ashok wrote:

> > This was an area of some ambiguity in the TLSv1.2 spec where only
> > signature_algorithms exists. I believe it was common practice for
> > implementations to not check the signatures in certificates for
> > conformance with
> > this (certainly that is the way OpenSSL behaves). The TLSv1.3 spec seems
> > to be
> > more explicit about this. I would expect our TLSv1.2 implementation to
> > continue
> > to operate as it did before so this additional checking of signatures in
> > certificates where only the signature_algorithms extensions is present
> > should
> > only apply to TLSv1.3.
> >
> > I don't see any code to do this in has_usable_cert so this looks like a
> > potential bug. Although possibly it was left out on purpose.
>
> Yes. Currently this check is missing for both TLSv1.2 and TLSv1.3. I feel
> we may need to add for both TLSv1.2 and TLSv1.3, because TLSv1.2 RFC 5246
> also mandates to do this check.
>
>    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.

OTOH, the practice in TLS 1.2, and behaviour codified in TLS 1.3 RFC, is that
if you have just one chain, give it to client and let it sort out if it likes
it or not

--
Regards,
Hubert Kario
Senior Quality Engineer, QE BaseOS Security team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 115, 612 00  Brno, Czech Republic

signature.asc (849 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Handling signature_algorithm extension on TLS1.3 server

Viktor Dukhovni


> On Jun 7, 2019, at 12:07 PM, Hubert Kario <[hidden email]> wrote:
>
> OTOH, the practice in TLS 1.2, and behaviour codified in TLS 1.3 RFC, is that
> if you have just one chain, give it to client and let it sort out if it likes
> it or not

Absolutely.  The text in RFC5246 is a specification overreach from TLS into
X.509 that is counterproductive in practice.  We should not implement the
part of RFC5246 that would have the server fail the handshake when its
certificate chain has *potentially* unsupported signatures.  Deciding
whether the chain is OK (or even looked at all) is up to the client.

--
        Viktor.