certificate compression: unsolicited CompressedCertificate is accepted
I've discovered two related cases of non-compliance with RFC8879, specifically with this requirement:
The algorithm MUST be one of the algorithms listed in the peer's compress_certificate extension.
Both have been discovered with my yet currently WIP tlslite/tlsfuzzer merge requests.
Case 1: Consider a GnuTLS server compiled with certificate compression, but without any certificate compression enabled in runtime. Receiving a CompressedCertificate in reply to CertificateRequest despite not sending a compress_certificate extension beforehand leads to decompressing and validating the certificate. An appropriate alert for this case would be unexpected_message.
Case 2: Consider a GnuTLS server compiled with a certificate compression, with some, but not all certificate compression algorithms enabled in runtime. Receiving a CompressedCertificate in reply to CertificateRequest using a not-enabled compression algorithm leads to decompressing and validating the certificate. An appropriate alert for this case would be illegal_parameter.
Both should be addressed by adding the following checks as the peer's CompressedCertificate is about to be decompressed:
- compress_certificate extension has indeed been received
- the specific algorithm selected by the peer has been negotiated beforehand
I anticipate that symmetric issues might also be in place for clients decompressing unsolicited server certificates.
CC @ZoltanFridrich, @dueno.
Invocation I've used for 1:
$ gnutls-serv --x509certfile ~/.certs/server/cert.pem --x509keyfile ~/.certs/server/key.pem --x509cafile ~/.certs/ca/cert.pem --port 4433 -d9 --verify-client-cert &
$ scripts/test-tls13-certificate-nocompression-verify.py -c ~/.certs/client/cert.pem -k ~/.certs/client/key.pem -E "signature_algorithms status_request 47" --algorithms zstd,zlib,brotli'
...
brotli-compressed certificate aborts ...
Error encountered while processing node ExpectAlert(level=2, description=10) (child: None) with last message being: None
Invocation I've used for 2:
$ gnutls-serv --x509certfile ~/.certs/server/cert.pem --x509keyfile ~/.certs/server/key.pem --x509cafile ~/.certs/ca/cert.pem --port 4433 -d9 --compress-cert zstd --compress-cert zlib --verify-client-cert &
scripts/
$ test-tls13-certificate-compression-verify.py -c ~/.certs/client/cert.pem -k ~/.certs/client/key.pem -E "signature_algorithms status_request 47" --algorithms zstd,zlib --disabled brotli
...
brotli client cert rejected ...
Error encountered while processing node ExpectAlert(level=2, description=47) (child: None) with last message being: None