diff options
| author | robot-piglet <[email protected]> | 2026-07-12 16:29:08 +0300 |
|---|---|---|
| committer | robot-piglet <[email protected]> | 2026-07-12 16:43:51 +0300 |
| commit | 63aff3789e8f93814a0d9f4068981b7397f70232 (patch) | |
| tree | d8e05dd1dea8bfb10148a53c2e61703fdea706f9 /contrib/python | |
| parent | 63c45db5cce8b82897f37967cd4af196de67e1e7 (diff) | |
Intermediate changes
commit_hash:28321331c1969bd72d182c9fadb787e0b1601554
Diffstat (limited to 'contrib/python')
| -rw-r--r-- | contrib/python/scramp/.dist-info/METADATA | 12 | ||||
| -rw-r--r-- | contrib/python/scramp/README.md | 10 | ||||
| -rw-r--r-- | contrib/python/scramp/scramp/core.py | 25 | ||||
| -rw-r--r-- | contrib/python/scramp/scramp/utils.py | 2 | ||||
| -rw-r--r-- | contrib/python/scramp/ya.make | 2 |
5 files changed, 41 insertions, 10 deletions
diff --git a/contrib/python/scramp/.dist-info/METADATA b/contrib/python/scramp/.dist-info/METADATA index d3b2cda4342..eb6b3e790f8 100644 --- a/contrib/python/scramp/.dist-info/METADATA +++ b/contrib/python/scramp/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.4 Name: scramp -Version: 1.4.9 +Version: 1.4.10 Summary: An implementation of the SCRAM protocol. Project-URL: Homepage, https://codeberg.org/tlocke/scramp Author: The Contributors @@ -54,6 +54,7 @@ Scramp supports the following mechanisms: * [OpenSSF Scorecard](#openssf-scorecard) * [Doing A Release Of Scramp](#doing-a-release-of-scramp) * [Release Notes](#release-notes) + * [Version 1.4.10, 2026-06-27](#version-1410-2026-06-27) * [Version 1.4.9, 2026-06-19](#version-149-2026-06-19) * [Version 1.4.8, 2026-01-06](#version-148-2026-01-06) * [Version 1.4.7, 2026-01-04](#version-147-2026-01-04) @@ -384,6 +385,15 @@ Run `tox` to make sure all tests pass, then update the release notes, then do: ## Release Notes +### Version 1.4.10, 2026-06-27 + +- Implement max and min guards for iteration count. +- The xor() function should fail if the two values are of unequal lengths +- Handle the case of an error in first server message +- Fix formatting in channel binding error message +- SHA3-512 didn't work, but it should do now + + ### Version 1.4.9, 2026-06-19 - Fix typo in error message. diff --git a/contrib/python/scramp/README.md b/contrib/python/scramp/README.md index 1ccdd745c56..652f8f590d0 100644 --- a/contrib/python/scramp/README.md +++ b/contrib/python/scramp/README.md @@ -33,6 +33,7 @@ Scramp supports the following mechanisms: * [OpenSSF Scorecard](#openssf-scorecard) * [Doing A Release Of Scramp](#doing-a-release-of-scramp) * [Release Notes](#release-notes) + * [Version 1.4.10, 2026-06-27](#version-1410-2026-06-27) * [Version 1.4.9, 2026-06-19](#version-149-2026-06-19) * [Version 1.4.8, 2026-01-06](#version-148-2026-01-06) * [Version 1.4.7, 2026-01-04](#version-147-2026-01-04) @@ -363,6 +364,15 @@ Run `tox` to make sure all tests pass, then update the release notes, then do: ## Release Notes +### Version 1.4.10, 2026-06-27 + +- Implement max and min guards for iteration count. +- The xor() function should fail if the two values are of unequal lengths +- Handle the case of an error in first server message +- Fix formatting in channel binding error message +- SHA3-512 didn't work, but it should do now + + ### Version 1.4.9, 2026-06-19 - Fix typo in error message. diff --git a/contrib/python/scramp/scramp/core.py b/contrib/python/scramp/scramp/core.py index 7bfd362914a..7ab1a5703a7 100644 --- a/contrib/python/scramp/scramp/core.py +++ b/contrib/python/scramp/scramp/core.py @@ -77,6 +77,8 @@ CHANNEL_TYPES = ( "tls-unique-for-telnet", ) +MAX_ITERATION_COUNT = 10_000_000 # DoS guard + def _make_cb_data(name, ssl_socket): if name == "tls-unique": @@ -137,6 +139,10 @@ class ScramMechanism: def make_auth_info(self, password, iteration_count=None, salt=None): if iteration_count is None: iteration_count = self.iteration_count + if iteration_count < self.iteration_count: + raise ScramException( + f"The iteration count must be at least {self.iteration_count}" + ) salt, stored_key, server_key = _make_auth_info( self.hf, password, iteration_count, salt=salt ) @@ -175,8 +181,8 @@ def _validate_channel_binding(channel_binding): channel_type, channel_data = channel_binding if channel_type not in CHANNEL_TYPES: raise ScramException( - "The channel_binding parameter must either be None or a tuple with the " - "first element a str specifying one of the channel types {CHANNEL_TYPES}." + f"The channel_binding parameter must either be None or a tuple with the " + f"first element a str specifying one of the channel types {CHANNEL_TYPES}." ) if not isinstance(channel_data, bytes): @@ -207,6 +213,7 @@ class ScramClient: mech = sorted(mechs, key=attrgetter("strength"))[-1] self.hf, self.use_binding = mech.hf, mech.use_binding self.mechanism_name = mech.name + self.iterations = mech.iteration_count self.c_nonce = _make_nonce() if c_nonce is None else c_nonce self.username = username @@ -229,7 +236,7 @@ class ScramClient: self._set_stage(ClientStage.set_server_first) self.server_first = message self.nonce, self.salt, self.iterations = _set_server_first( - message, self.c_nonce + message, self.c_nonce, self.iterations ) def get_client_final(self): @@ -351,8 +358,7 @@ def _make_auth_message(client_first_bare, server_first, client_final_without_pro def _make_salted_password(hf, password, salt, iterations): - hash_name = hf.__name__.split("_")[-1] - return hashlib.pbkdf2_hmac(hash_name, uenc(saslprep(password)), salt, iterations) + return hashlib.pbkdf2_hmac(hf().name, uenc(saslprep(password)), salt, iterations) def _c_key_stored_key_s_key(hf, salted_password): @@ -518,14 +524,19 @@ def _get_server_first(nonce, salt, iterations): return ",".join((f"r={nonce}", f"s={salt}", f"i={iterations}")) -def _set_server_first(server_first, c_nonce): - msg = _parse_message(server_first, "server first", {"r", "s", "i"}) +def _set_server_first(server_first, c_nonce, min_iteration_count): + msg = _parse_message(server_first, "server first", {"r", "s", "i"}, {"e"}) if "e" in msg: raise ScramException(f"The server returned the error: {msg['e']}") nonce = msg["r"] salt = msg["s"] iterations = int(msg["i"]) + if not (min_iteration_count <= iterations <= MAX_ITERATION_COUNT): + raise ScramException( + f"Server iteration count must be between {min_iteration_count} " + f"and {MAX_ITERATION_COUNT} inclusive" + ) if not nonce.startswith(c_nonce): raise ScramException("Client nonce doesn't match.", SERVER_ERROR_OTHER_ERROR) diff --git a/contrib/python/scramp/scramp/utils.py b/contrib/python/scramp/scramp/utils.py index da864d2fe2f..da991644090 100644 --- a/contrib/python/scramp/scramp/utils.py +++ b/contrib/python/scramp/scramp/utils.py @@ -14,7 +14,7 @@ def h(hf, msg): def xor(bytes1, bytes2): - return bytes(a ^ b for a, b in zip(bytes1, bytes2)) + return bytes(a ^ b for a, b in zip(bytes1, bytes2, strict=True)) def b64enc(binary): diff --git a/contrib/python/scramp/ya.make b/contrib/python/scramp/ya.make index 9453f63f0af..f5d6699f70a 100644 --- a/contrib/python/scramp/ya.make +++ b/contrib/python/scramp/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(1.4.9) +VERSION(1.4.10) LICENSE(MIT-0) |
