From d88c16b873d02522c865cb140f2afe8c5df749bd Mon Sep 17 00:00:00 2001 From: Odinmylord Date: Tue, 9 Apr 2024 17:40:28 +0200 Subject: [PATCH 1/4] Add signature_algorithms_cert extension to the "_serverTLS13Handshake" function --- tlslite/handshakesettings.py | 8 ++++++++ tlslite/tlsconnection.py | 8 +++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/tlslite/handshakesettings.py b/tlslite/handshakesettings.py index 38e560a2..2ae2b5ca 100644 --- a/tlslite/handshakesettings.py +++ b/tlslite/handshakesettings.py @@ -396,6 +396,10 @@ def _init_misc_extensions(self): # resumed connections (as tickets are single-use in TLS 1.3 self.ticket_count = 2 self.record_size_limit = 2**14 + 1 # TLS 1.3 includes content type + # data needed for the signature algorithms cert extension + self.more_sig_schemes_cert = [] + self.ecdsaSigHashesCert = [] + self.rsaSigHashesCert = [] def __init__(self): """Initialise default values for settings.""" @@ -675,6 +679,10 @@ def _copy_extension_settings(self, other): other.max_early_data = self.max_early_data other.ticket_count = self.ticket_count other.record_size_limit = self.record_size_limit + # signature algorithms cert + other.more_sig_schemes_cert = self.more_sig_schemes_cert + other.ecdsaSigHashesCert = self.ecdsaSigHashesCert + other.rsaSigHashesCert = self.rsaSigHashesCert @staticmethod def _remove_all_matches(values, needle): diff --git a/tlslite/tlsconnection.py b/tlslite/tlsconnection.py index 582097a7..54152ea7 100644 --- a/tlslite/tlsconnection.py +++ b/tlslite/tlsconnection.py @@ -2830,9 +2830,15 @@ def _serverTLS13Handshake(self, settings, clientHello, cipherSuite, cr_settings.dsaSigHashes = [] valid_sig_algs = self._sigHashesToList(cr_settings) assert valid_sig_algs - + cr_settings.more_sig_schemes = cr_settings.more_sig_schemes_cert + cr_settings.ecdsaSigHashes = cr_settings.ecdsaSigHashesCert + cr_settings.rsaSigHashes = cr_settings.rsaSigHashesCert + valid_sig_algs_cert = self._sigHashesToList(cr_settings) certificate_request = CertificateRequest(self.version) certificate_request.create(context=ctx, sig_algs=valid_sig_algs) + if valid_sig_algs_cert: + sig_algs_cert_ext = SignatureAlgorithmsCertExtension().create(valid_sig_algs_cert) + certificate_request.addExtension(sig_algs_cert_ext) self._queue_message(certificate_request) certificate = Certificate(CertificateType.x509, self.version) From 207aa80b5ed804a934a9f8e8517cc2477222c51e Mon Sep 17 00:00:00 2001 From: Odinmylord Date: Thu, 11 Apr 2024 11:00:36 +0200 Subject: [PATCH 2/4] Fix names and update _sigHashesToList --- tlslite/handshakesettings.py | 12 +++++++----- tlslite/tlsconnection.py | 27 ++++++++++++++++----------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/tlslite/handshakesettings.py b/tlslite/handshakesettings.py index 2ae2b5ca..ea0bbc0b 100644 --- a/tlslite/handshakesettings.py +++ b/tlslite/handshakesettings.py @@ -397,9 +397,10 @@ def _init_misc_extensions(self): self.ticket_count = 2 self.record_size_limit = 2**14 + 1 # TLS 1.3 includes content type # data needed for the signature algorithms cert extension - self.more_sig_schemes_cert = [] - self.ecdsaSigHashesCert = [] - self.rsaSigHashesCert = [] + self.more_sig_schemes_cert = list(SIGNATURE_SCHEMES) + self.ecdsa_sig_hashes_cert = list(ECDSA_SIGNATURE_HASHES) + self.rsa_sig_hashes_cert = list(RSA_SIGNATURE_HASHES) + self.rsa_sig_schemes_cert = list(RSA_SCHEMES) def __init__(self): """Initialise default values for settings.""" @@ -681,8 +682,9 @@ def _copy_extension_settings(self, other): other.record_size_limit = self.record_size_limit # signature algorithms cert other.more_sig_schemes_cert = self.more_sig_schemes_cert - other.ecdsaSigHashesCert = self.ecdsaSigHashesCert - other.rsaSigHashesCert = self.rsaSigHashesCert + other.ecdsa_sig_hashes_cert = self.ecdsa_sig_hashes_cert + other.rsa_sig_hashes_cert = self.rsa_sig_hashes_cert + other.rsa_sig_schemes_cert = self.rsa_sig_schemes_cert @staticmethod def _remove_all_matches(values, needle): diff --git a/tlslite/tlsconnection.py b/tlslite/tlsconnection.py index 54152ea7..479b6dc2 100644 --- a/tlslite/tlsconnection.py +++ b/tlslite/tlsconnection.py @@ -2830,13 +2830,11 @@ def _serverTLS13Handshake(self, settings, clientHello, cipherSuite, cr_settings.dsaSigHashes = [] valid_sig_algs = self._sigHashesToList(cr_settings) assert valid_sig_algs - cr_settings.more_sig_schemes = cr_settings.more_sig_schemes_cert - cr_settings.ecdsaSigHashes = cr_settings.ecdsaSigHashesCert - cr_settings.rsaSigHashes = cr_settings.rsaSigHashesCert - valid_sig_algs_cert = self._sigHashesToList(cr_settings) + valid_sig_algs_cert = self._sigHashesToList(cr_settings, sig_algs_cert=True) certificate_request = CertificateRequest(self.version) certificate_request.create(context=ctx, sig_algs=valid_sig_algs) - if valid_sig_algs_cert: + # if there is no difference the extension can be omitted + if set(valid_sig_algs_cert) != set(valid_sig_algs): sig_algs_cert_ext = SignatureAlgorithmsCertExtension().create(valid_sig_algs_cert) certificate_request.addExtension(sig_algs_cert_ext) self._queue_message(certificate_request) @@ -4674,7 +4672,7 @@ def _pickServerKeyExchangeSig(settings, clientHello, certList=None, @staticmethod def _sigHashesToList(settings, privateKey=None, certList=None, - version=(3, 3)): + version=(3, 3), sig_algs_cert=False): """Convert list of valid signature hashes to array of tuples""" certType = None publicKey = None @@ -4685,7 +4683,9 @@ def _sigHashesToList(settings, privateKey=None, certList=None, sigAlgs = [] if not certType or certType == "Ed25519" or certType == "Ed448": - for sig_scheme in settings.more_sig_schemes: + sig_schemes = settings.more_sig_schemes if not sig_algs_cert else \ + settings.more_sig_schemes_cert + for sig_scheme in sig_schemes: if version < (3, 3): # EdDSA is supported only in TLS 1.2 and 1.3 continue @@ -4694,7 +4694,9 @@ def _sigHashesToList(settings, privateKey=None, certList=None, sigAlgs.append(getattr(SignatureScheme, sig_scheme.lower())) if not certType or certType == "ecdsa": - for hashName in settings.ecdsaSigHashes: + hash_names = settings.ecdsaSigHashes if not sig_algs_cert else \ + settings.ecdsa_sig_hashes_cert + for hashName in hash_names: # only SHA256, SHA384 and SHA512 are allowed in TLS 1.3 if version > (3, 3) and hashName in ("sha1", "sha224"): continue @@ -4719,12 +4721,15 @@ def _sigHashesToList(settings, privateKey=None, certList=None, SignatureAlgorithm.dsa)) if not certType or certType in ("rsa", "rsa-pss"): - for schemeName in settings.rsaSchemes: + rsa_schemes = settings.rsaSchemes if not sig_algs_cert else \ + settings.rsa_sig_schemes_cert + for schemeName in rsa_schemes: # pkcs#1 v1.5 signatures are not allowed in TLS 1.3 if version > (3, 3) and schemeName == "pkcs1": continue - - for hashName in settings.rsaSigHashes: + rsa_sig_hashes = settings.rsaSigHashes if not sig_algs_cert else \ + settings.rsa_sig_hashes_cert + for hashName in rsa_sig_hashes: # rsa-pss certificates can't be used to make PKCS#1 v1.5 # signatures if certType == "rsa-pss" and schemeName == "pkcs1": From bd28f87b499907ebeb9f3eb953e120dc1e19ccf4 Mon Sep 17 00:00:00 2001 From: Odinmylord Date: Fri, 12 Apr 2024 10:56:13 +0200 Subject: [PATCH 3/4] Fix issues with linter --- tlslite/tlsconnection.py | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/tlslite/tlsconnection.py b/tlslite/tlsconnection.py index 479b6dc2..48b6b99b 100644 --- a/tlslite/tlsconnection.py +++ b/tlslite/tlsconnection.py @@ -2830,12 +2830,14 @@ def _serverTLS13Handshake(self, settings, clientHello, cipherSuite, cr_settings.dsaSigHashes = [] valid_sig_algs = self._sigHashesToList(cr_settings) assert valid_sig_algs - valid_sig_algs_cert = self._sigHashesToList(cr_settings, sig_algs_cert=True) + valid_sig_algs_cert = self._sigHashesToList(cr_settings, + sig_algs_cert=True) certificate_request = CertificateRequest(self.version) certificate_request.create(context=ctx, sig_algs=valid_sig_algs) # if there is no difference the extension can be omitted if set(valid_sig_algs_cert) != set(valid_sig_algs): - sig_algs_cert_ext = SignatureAlgorithmsCertExtension().create(valid_sig_algs_cert) + sig_algs_cert_ext = SignatureAlgorithmsCertExtension() + sig_algs_cert_ext.create(valid_sig_algs_cert) certificate_request.addExtension(sig_algs_cert_ext) self._queue_message(certificate_request) @@ -4684,7 +4686,7 @@ def _sigHashesToList(settings, privateKey=None, certList=None, if not certType or certType == "Ed25519" or certType == "Ed448": sig_schemes = settings.more_sig_schemes if not sig_algs_cert else \ - settings.more_sig_schemes_cert + settings.more_sig_schemes_cert for sig_scheme in sig_schemes: if version < (3, 3): # EdDSA is supported only in TLS 1.2 and 1.3 @@ -4696,9 +4698,9 @@ def _sigHashesToList(settings, privateKey=None, certList=None, if not certType or certType == "ecdsa": hash_names = settings.ecdsaSigHashes if not sig_algs_cert else \ settings.ecdsa_sig_hashes_cert - for hashName in hash_names: + for hash_name in hash_names: # only SHA256, SHA384 and SHA512 are allowed in TLS 1.3 - if version > (3, 3) and hashName in ("sha1", "sha224"): + if version > (3, 3) and hash_name in ("sha1", "sha224"): continue # in TLS 1.3 ECDSA key curve is bound to hash @@ -4706,38 +4708,38 @@ def _sigHashesToList(settings, privateKey=None, certList=None, curve = publicKey.curve_name matching_hash = TLSConnection._curve_name_to_hash_name( curve) - if hashName != matching_hash: + if hash_name != matching_hash: continue - sigAlgs.append((getattr(HashAlgorithm, hashName), + sigAlgs.append((getattr(HashAlgorithm, hash_name), SignatureAlgorithm.ecdsa)) if not certType or certType == "dsa": - for hashName in settings.dsaSigHashes: + for hash_name in settings.dsaSigHashes: if version > (3, 3): continue - sigAlgs.append((getattr(HashAlgorithm, hashName), + sigAlgs.append((getattr(HashAlgorithm, hash_name), SignatureAlgorithm.dsa)) if not certType or certType in ("rsa", "rsa-pss"): rsa_schemes = settings.rsaSchemes if not sig_algs_cert else \ settings.rsa_sig_schemes_cert - for schemeName in rsa_schemes: + for scheme_name in rsa_schemes: # pkcs#1 v1.5 signatures are not allowed in TLS 1.3 - if version > (3, 3) and schemeName == "pkcs1": + if version > (3, 3) and scheme_name == "pkcs1": continue rsa_sig_hashes = settings.rsaSigHashes if not sig_algs_cert else \ settings.rsa_sig_hashes_cert - for hashName in rsa_sig_hashes: + for hash_name in rsa_sig_hashes: # rsa-pss certificates can't be used to make PKCS#1 v1.5 # signatures - if certType == "rsa-pss" and schemeName == "pkcs1": + if certType == "rsa-pss" and scheme_name == "pkcs1": continue try: # 1024 bit keys are too small to create valid # rsa-pss-SHA512 signatures - if schemeName == 'pss' and hashName == 'sha512'\ + if scheme_name == 'pss' and hash_name == 'sha512'\ and privateKey and privateKey.n < 2**2047: continue # advertise support for both rsaEncryption and RSA-PSS OID @@ -4745,14 +4747,14 @@ def _sigHashesToList(settings, privateKey=None, certList=None, if certType != 'rsa-pss': sigAlgs.append(getattr(SignatureScheme, "rsa_{0}_rsae_{1}" - .format(schemeName, hashName))) + .format(scheme_name, hash_name))) if certType != 'rsa': sigAlgs.append(getattr(SignatureScheme, "rsa_{0}_pss_{1}" - .format(schemeName, hashName))) + .format(scheme_name, hash_name))) except AttributeError: - if schemeName == 'pkcs1': - sigAlgs.append((getattr(HashAlgorithm, hashName), + if scheme_name == 'pkcs1': + sigAlgs.append((getattr(HashAlgorithm, hash_name), SignatureAlgorithm.rsa)) continue return sigAlgs From c2272eeefae99bb1f35dd2eb51e688a4d980fb2f Mon Sep 17 00:00:00 2001 From: Odinmylord Date: Fri, 12 Apr 2024 10:59:42 +0200 Subject: [PATCH 4/4] fix long lines --- tlslite/tlsconnection.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tlslite/tlsconnection.py b/tlslite/tlsconnection.py index 48b6b99b..38e12ae1 100644 --- a/tlslite/tlsconnection.py +++ b/tlslite/tlsconnection.py @@ -4747,11 +4747,13 @@ def _sigHashesToList(settings, privateKey=None, certList=None, if certType != 'rsa-pss': sigAlgs.append(getattr(SignatureScheme, "rsa_{0}_rsae_{1}" - .format(scheme_name, hash_name))) + .format(scheme_name, + hash_name))) if certType != 'rsa': sigAlgs.append(getattr(SignatureScheme, "rsa_{0}_pss_{1}" - .format(scheme_name, hash_name))) + .format(scheme_name, + hash_name))) except AttributeError: if scheme_name == 'pkcs1': sigAlgs.append((getattr(HashAlgorithm, hash_name),