Skip to content

Commit 829a264

Browse files
committed
Fix string formatting
1 parent 87a80c7 commit 829a264

2 files changed

Lines changed: 33 additions & 41 deletions

File tree

sshpubkeys/keys.py

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
from cryptography.hazmat.backends import default_backend
2121
from cryptography.hazmat.primitives.asymmetric.dsa import DSAParameterNumbers, DSAPublicNumbers
2222
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers
23-
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed
2423
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
2524
from cryptography.hazmat.primitives.asymmetric import ec
2625
from cryptography.hazmat.primitives import hashes
@@ -52,20 +51,17 @@ def curve(self):
5251
def __repr__(self):
5352
pub_key = self.to_string("compressed")
5453
self.to_string("raw")
55-
return "VerifyingKey({0!r}, {1!r}, {2})".format(
56-
pub_key, self.curve.name, self.default_hashfunc.name
57-
)
54+
return f"VerifyingKey({pub_key!r}, {self.curve.name!r}, {self.default_hashfunc.name})"
5855

5956
def to_string(self, encoding="raw"):
6057
"""Pub key as bytes string"""
6158
if encoding == "raw":
6259
return self.pubkey.public_numbers().encode_point()[1:]
63-
elif encoding == "uncompressed":
60+
if encoding == "uncompressed":
6461
return self.pubkey.public_numbers().encode_point()
65-
elif encoding == "compressed":
62+
if encoding == "compressed":
6663
return self.pubkey.public_bytes(Encoding.X962, PublicFormat.CompressedPoint)
67-
else:
68-
raise ValueError(encoding)
64+
raise ValueError(encoding)
6965

7066
def to_pem(self, point_encoding="uncompressed"):
7167
"""Pub key as PEM"""
@@ -83,10 +79,6 @@ def verify(self, signature, data):
8379
"""Verify signature of provided data"""
8480
return self.pubkey.verify(signature, data, ec.ECDSA(self.default_hashfunc))
8581

86-
def verify_digest(self, signature, digest):
87-
"""Verify signature over prehashed digest"""
88-
return self.pubkey.verify(signature, data, ec.ECDSA(Prehashed(digest)))
89-
9082

9183
class AuthorizedKeysFile: # pylint:disable=too-few-public-methods
9284
"""Represents a full authorized_keys file.
@@ -191,7 +183,7 @@ def __init__(self, keydata=None, **kwargs):
191183
pass
192184

193185
def __str__(self):
194-
return "Key type: %s, bits: %s, options: %s" % (self.key_type.decode(), self.bits, self.options)
186+
return f"Key type: {self.key_type.decode()}, bits: {self.bits}, options: {self.options}"
195187

196188
def reset(self):
197189
"""Reset all data fields."""
@@ -235,15 +227,15 @@ def _unpack_by_int(self, data, current_position):
235227
try:
236228
requested_data_length = struct.unpack('>I', data[current_position:current_position + self.INT_LEN])[0]
237229
except struct.error as ex:
238-
raise MalformedDataError("Unable to unpack %s bytes from the data" % self.INT_LEN) from ex
230+
raise MalformedDataError(f"Unable to unpack {self.INT_LEN} bytes from the data") from ex
239231

240232
# Move pointer to the beginning of the data field
241233
current_position += self.INT_LEN
242234
remaining_data_length = len(data[current_position:])
243235

244236
if remaining_data_length < requested_data_length:
245237
raise MalformedDataError(
246-
"Requested %s bytes, but only %s bytes available." % (requested_data_length, remaining_data_length)
238+
f"Requested {requested_data_length} bytes, but only {remaining_data_length} bytes available."
247239
)
248240

249241
next_data = data[current_position:current_position + requested_data_length]
@@ -326,15 +318,15 @@ def parse_add_single_option(opt):
326318
opt_name = opt
327319
opt_value = True
328320
if " " in opt_name or not self.OPTION_NAME_RE.match(opt_name):
329-
raise InvalidOptionNameError("%s is not a valid option name." % opt_name)
321+
raise InvalidOptionNameError(f"{opt_name} is not a valid option name.")
330322
if self.strict_mode:
331323
for valid_opt_name, value_required in self.OPTIONS_SPEC:
332324
if opt_name.lower() == valid_opt_name:
333325
if value_required and opt_value is True:
334-
raise MissingMandatoryOptionValueError("%s is missing a mandatory value." % opt_name)
326+
raise MissingMandatoryOptionValueError(f"{opt_name} is missing a mandatory value.")
335327
break
336328
else:
337-
raise UnknownOptionNameError("%s is an unrecognized option name." % opt_name)
329+
raise UnknownOptionNameError(f"{opt_name} is an unrecognized option name.")
338330
if opt_name not in parsed_options:
339331
parsed_options[opt_name] = []
340332
parsed_options[opt_name].append(opt_value)
@@ -377,11 +369,11 @@ def _process_ssh_rsa(self, data):
377369
max_length = self.RSA_MAX_LENGTH_LOOSE
378370
if self.bits < min_length:
379371
raise TooShortKeyError(
380-
"%s key data can not be shorter than %s bits (was %s)" % (self.key_type.decode(), min_length, self.bits)
372+
f"{self.key_type.decode()} key data can not be shorter than {min_length} bits (was {self.bits})"
381373
)
382374
if self.bits > max_length:
383375
raise TooLongKeyError(
384-
"%s key data can not be longer than %s bits (was %s)" % (self.key_type.decode(), max_length, self.bits)
376+
f"{self.key_type.decode()} key data can not be longer than {max_length} bits (was {self.bits})"
385377
)
386378
return current_position
387379

@@ -396,7 +388,7 @@ def _process_ssh_dss(self, data):
396388
q_bits = self._bits_in_number(data_fields["q"])
397389
p_bits = self._bits_in_number(data_fields["p"])
398390
if q_bits != self.DSA_N_LENGTH:
399-
raise InvalidKeyError("Incorrect DSA key parameters: bits(p)=%s, q=%s" % (self.bits, q_bits))
391+
raise InvalidKeyError(f"Incorrect DSA key parameters: bits(p)={self.bits}, q={q_bits}")
400392
if self.strict_mode:
401393
min_length = self.DSA_MIN_LENGTH_STRICT
402394
max_length = self.DSA_MAX_LENGTH_STRICT
@@ -405,11 +397,11 @@ def _process_ssh_dss(self, data):
405397
max_length = self.DSA_MAX_LENGTH_LOOSE
406398
if p_bits < min_length:
407399
raise TooShortKeyError(
408-
"%s key can not be shorter than %s bits (was %s)" % (self.key_type.decode(), min_length, p_bits)
400+
f"{self.key_type.decode()} key can not be shorter than {min_length} bits (was {p_bits})"
409401
)
410402
if p_bits > max_length:
411403
raise TooLongKeyError(
412-
"%s key data can not be longer than %s bits (was %s)" % (self.key_type.decode(), max_length, p_bits)
404+
f"{self.key_type.decode()} key data can not be longer than {max_length} bits (was {p_bits})"
413405
)
414406

415407
dsa_parameters = DSAParameterNumbers(data_fields["p"], data_fields["q"], data_fields["g"])
@@ -422,7 +414,7 @@ def _process_ecdsa_sha(self, data):
422414
"""Parses ecdsa-sha public keys."""
423415
current_position, curve_information = self._unpack_by_int(data, 0)
424416
if curve_information not in self.ECDSA_CURVE_DATA:
425-
raise NotImplementedError("Invalid curve type: %s" % curve_information)
417+
raise NotImplementedError(f"Invalid curve type: {curve_information}")
426418
curve, hash_algorithm = self.ECDSA_CURVE_DATA[curve_information]
427419

428420
current_position, key_data = self._unpack_by_int(data, current_position)
@@ -452,7 +444,7 @@ def _process_ed25516(self, data):
452444

453445
self.bits = verifying_key_length
454446
if self.bits != 256:
455-
raise InvalidKeyLengthError("ed25519 keys must be 256 bits (was %s bits)" % self.bits)
447+
raise InvalidKeyLengthError(f"ed25519 keys must be 256 bits (was {self.bits} bits)")
456448
return current_position
457449

458450
def _validate_application_string(self, application):
@@ -463,7 +455,7 @@ def _validate_application_string(self, application):
463455
try:
464456
parsed_url = urlparse(application)
465457
except ValueError as err:
466-
raise InvalidKeyError("Application string: %s" % err) from err
458+
raise InvalidKeyError(f"Application string: {err}") from err
467459
if parsed_url.scheme != b"ssh":
468460
raise InvalidKeyError('Application string must begin with "ssh:"')
469461

@@ -494,7 +486,7 @@ def _process_key(self, data):
494486
return self._process_sk_ecdsa_sha(data)
495487
if self.key_type.strip().startswith(b"sk-ssh-ed25519"):
496488
return self._process_sk_ed25519(data)
497-
raise NotImplementedError("Invalid key type: %s" % self.key_type.decode())
489+
raise NotImplementedError(f"Invalid key type: {self.key_type.decode()}")
498490

499491
def parse(self, keydata=None):
500492
"""Validates SSH public key.
@@ -528,15 +520,15 @@ def parse(self, keydata=None):
528520
# Check key type
529521
current_position, unpacked_key_type = self._unpack_by_int(self._decoded_key, 0)
530522
if key_type is not None and key_type != unpacked_key_type.decode():
531-
raise InvalidTypeError("Keytype mismatch: %s != %s" % (key_type, unpacked_key_type.decode()))
523+
raise InvalidTypeError(f"Keytype mismatch: {key_type} != {unpacked_key_type.decode()}")
532524

533525
self.key_type = unpacked_key_type
534526

535527
key_data_length = self._process_key(self._decoded_key[current_position:])
536528
current_position = current_position + key_data_length
537529

538530
if current_position != len(self._decoded_key):
539-
raise MalformedDataError("Leftover data: %s bytes" % (len(self._decoded_key) - current_position))
531+
raise MalformedDataError(f"Leftover data: {len(self._decoded_key) - current_position} bytes")
540532

541533
if self.disallow_options and self.options:
542534
raise InvalidOptionsError("Options are disallowed.")

tests/__init__.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -105,17 +105,17 @@ def ch(option, parsed_option):
105105
return lambda self: self.check_valid_option(option, parsed_option)
106106

107107
for i, items in enumerate(options):
108-
prefix_tmp = "%s_%s" % (items[0], i)
109-
setattr(TestOptions, "test_%s" % prefix_tmp, ch(items[1], items[2]))
108+
prefix_tmp = f"{items[0]}_{i}"
109+
setattr(TestOptions, f"test_{prefix_tmp}", ch(items[1], items[2]))
110110

111111

112112
def loop_invalid_options(options):
113113
def ch(option, expected_error):
114114
return lambda self: self.check_invalid_option(option, expected_error)
115115

116116
for i, items in enumerate(options):
117-
prefix_tmp = "%s_%s" % (items[0], i)
118-
setattr(TestOptions, "test_%s" % prefix_tmp, ch(items[1], items[2]))
117+
prefix_tmp = f"{items[0]}_{i}"
118+
setattr(TestOptions, f"test_{prefix_tmp}", ch(items[1], items[2]))
119119

120120

121121
def loop_valid(keyset, prefix):
@@ -126,7 +126,7 @@ def ch(pubkey, bits, fingerprint_md5, fingerprint_sha256, options, comment, **kw
126126

127127
for items in keyset:
128128
modes = items.pop()
129-
prefix_tmp = "%s_%s" % (prefix, items.pop())
129+
prefix_tmp = f"{prefix}_{items.pop()}"
130130
for mode in modes:
131131
if mode == "strict":
132132
kwargs = {"strict": True}
@@ -138,7 +138,7 @@ def ch(pubkey, bits, fingerprint_md5, fingerprint_sha256, options, comment, **kw
138138
else:
139139
pubkey, bits, fingerprint_md5, fingerprint_sha256, options, comment = items
140140
setattr(
141-
TestKeys, "test_%s_mode_%s" % (prefix_tmp, mode),
141+
TestKeys, f"test_{prefix_tmp}_mode_{mode}",
142142
ch(pubkey, bits, fingerprint_md5, fingerprint_sha256, options, comment, **kwargs)
143143
)
144144

@@ -151,32 +151,32 @@ def ch(pubkey, expected_error, **kwargs):
151151

152152
for items in keyset:
153153
modes = items.pop()
154-
prefix_tmp = "%s_%s" % (prefix, items.pop())
154+
prefix_tmp = f"{prefix}_{items.pop()}"
155155
for mode in modes:
156156
if mode == "strict":
157157
kwargs = {"strict": True}
158158
else:
159159
kwargs = {"strict": False}
160160
pubkey, expected_error = items
161-
setattr(TestKeys, "test_%s_mode_%s" % (prefix_tmp, mode), ch(pubkey, expected_error, **kwargs))
161+
setattr(TestKeys, f"test_{prefix_tmp}_mode_{mode}", ch(pubkey, expected_error, **kwargs))
162162

163163

164164
def loop_authorized_keys(keyset):
165165
def ch(file_str, valid_keys_count):
166166
return lambda self: self.check_valid_file(file_str, valid_keys_count)
167167

168168
for i, items in enumerate(keyset):
169-
prefix_tmp = "%s_%s" % (items[0], i)
170-
setattr(TestAuthorizedKeys, "test_%s" % prefix_tmp, ch(items[1], items[2]))
169+
prefix_tmp = f"{items[0]}_{i}"
170+
setattr(TestAuthorizedKeys, f"test_{prefix_tmp}", ch(items[1], items[2]))
171171

172172

173173
def loop_invalid_authorized_keys(keyset):
174174
def ch(file_str, expected_error, **kwargs):
175175
return lambda self: self.check_invalid_file(file_str, expected_error, **kwargs)
176176

177177
for i, items in enumerate(keyset):
178-
prefix_tmp = "%s_%s" % (items[0], i)
179-
setattr(TestAuthorizedKeys, "test_invalid_%s" % prefix_tmp, ch(items[1], items[2]))
178+
prefix_tmp = f"{items[0]}_{i}"
179+
setattr(TestAuthorizedKeys, f"test_invalid_{prefix_tmp}", ch(items[1], items[2]))
180180

181181

182182
loop_valid(list_of_valid_keys, "valid_key")

0 commit comments

Comments
 (0)