Dark Mode

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8ec7ebb

Browse files
authored
Merge pull request #84 from ojarva/dependabot/pip/cryptography-3.3.2
Bump cryptography from 3.2 to 3.3.2
2 parents bb8c9aa + 8b0ee23 commit 8ec7ebb

File tree

4 files changed

+39
-50
lines changed
  • .github/workflows
    • python-tests.yml
  • requirements.txt
  • sshpubkeys
    • keys.py
  • tests
    • __init__.py

4 files changed

+39
-50
lines changed

.github/workflows/python-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
runs-on: ubuntu-latest
99
strategy:
1010
matrix:
11-
python-version: [3.5, 3.6, 3.7, 3.8]
11+
python-version: [3.6, 3.7, 3.8, 3.9]
1212

1313
steps:
1414
- uses: actions/checkout@v2

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
cryptography==3.2
1+
cryptography==3.3.2
22
yapf==0.21.0

sshpubkeys/keys.py

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,11 @@
1818
MalformedDataError, MissingMandatoryOptionValueError, TooLongKeyError, TooShortKeyError, UnknownOptionNameError
1919
)
2020
from cryptography.hazmat.backends import default_backend
21+
from cryptography.hazmat.primitives import hashes
22+
from cryptography.hazmat.primitives.asymmetric import ec
2123
from cryptography.hazmat.primitives.asymmetric.dsa import DSAParameterNumbers, DSAPublicNumbers
2224
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers
23-
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed
2425
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
25-
from cryptography.hazmat.primitives.asymmetric import ec
26-
from cryptography.hazmat.primitives import hashes
2726
from urllib.parse import urlparse
2827

2928
import base64
@@ -40,6 +39,7 @@
4039
class _ECVerifyingKey:
4140
"""ecdsa.key.VerifyingKey reimplementation
4241
"""
42+
4343
def __init__(self, pubkey, default_hashfunc):
4444
self.pubkey = pubkey
4545
self.default_hashfunc = default_hashfunc
@@ -52,20 +52,17 @@ def curve(self):
5252
def __repr__(self):
5353
pub_key = self.to_string("compressed")
5454
self.to_string("raw")
55-
return "VerifyingKey({0!r}, {1!r}, {2})".format(
56-
pub_key, self.curve.name, self.default_hashfunc.name
57-
)
55+
return f"VerifyingKey({pub_key!r}, {self.curve.name!r}, {self.default_hashfunc.name})"
5856

5957
def to_string(self, encoding="raw"):
6058
"""Pub key as bytes string"""
6159
if encoding == "raw":
6260
return self.pubkey.public_numbers().encode_point()[1:]
63-
elif encoding == "uncompressed":
61+
if encoding == "uncompressed":
6462
return self.pubkey.public_numbers().encode_point()
65-
elif encoding == "compressed":
63+
if encoding == "compressed":
6664
return self.pubkey.public_bytes(Encoding.X962, PublicFormat.CompressedPoint)
67-
else:
68-
raise ValueError(encoding)
65+
raise ValueError(encoding)
6966

7067
def to_pem(self, point_encoding="uncompressed"):
7168
"""Pub key as PEM"""
@@ -83,10 +80,6 @@ def verify(self, signature, data):
8380
"""Verify signature of provided data"""
8481
return self.pubkey.verify(signature, data, ec.ECDSA(self.default_hashfunc))
8582

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-
9083

9184
class AuthorizedKeysFile: # pylint:disable=too-few-public-methods
9285
"""Represents a full authorized_keys file.
@@ -191,7 +184,7 @@ def __init__(self, keydata=None, **kwargs):
191184
pass
192185

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

196189
def reset(self):
197190
"""Reset all data fields."""
@@ -235,15 +228,15 @@ def _unpack_by_int(self, data, current_position):
235228
try:
236229
requested_data_length = struct.unpack('>I', data[current_position:current_position + self.INT_LEN])[0]
237230
except struct.error as ex:
238-
raise MalformedDataError("Unable to unpack %s bytes from the data" % self.INT_LEN) from ex
231+
raise MalformedDataError(f"Unable to unpack {self.INT_LEN} bytes from the data") from ex
239232

240233
# Move pointer to the beginning of the data field
241234
current_position += self.INT_LEN
242235
remaining_data_length = len(data[current_position:])
243236

244237
if remaining_data_length < requested_data_length:
245238
raise MalformedDataError(
246-
"Requested %s bytes, but only %s bytes available." % (requested_data_length, remaining_data_length)
239+
f"Requested {requested_data_length} bytes, but only {remaining_data_length} bytes available."
247240
)
248241

249242
next_data = data[current_position:current_position + requested_data_length]
@@ -326,15 +319,15 @@ def parse_add_single_option(opt):
326319
opt_name = opt
327320
opt_value = True
328321
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)
322+
raise InvalidOptionNameError(f"{opt_name} is not a valid option name.")
330323
if self.strict_mode:
331324
for valid_opt_name, value_required in self.OPTIONS_SPEC:
332325
if opt_name.lower() == valid_opt_name:
333326
if value_required and opt_value is True:
334-
raise MissingMandatoryOptionValueError("%s is missing a mandatory value." % opt_name)
327+
raise MissingMandatoryOptionValueError(f"{opt_name} is missing a mandatory value.")
335328
break
336329
else:
337-
raise UnknownOptionNameError("%s is an unrecognized option name." % opt_name)
330+
raise UnknownOptionNameError(f"{opt_name} is an unrecognized option name.")
338331
if opt_name not in parsed_options:
339332
parsed_options[opt_name] = []
340333
parsed_options[opt_name].append(opt_value)
@@ -377,11 +370,11 @@ def _process_ssh_rsa(self, data):
377370
max_length = self.RSA_MAX_LENGTH_LOOSE
378371
if self.bits < min_length:
379372
raise TooShortKeyError(
380-
"%s key data can not be shorter than %s bits (was %s)" % (self.key_type.decode(), min_length, self.bits)
373+
f"{self.key_type.decode()} key data can not be shorter than {min_length} bits (was {self.bits})"
381374
)
382375
if self.bits > max_length:
383376
raise TooLongKeyError(
384-
"%s key data can not be longer than %s bits (was %s)" % (self.key_type.decode(), max_length, self.bits)
377+
f"{self.key_type.decode()} key data can not be longer than {max_length} bits (was {self.bits})"
385378
)
386379
return current_position
387380

@@ -396,20 +389,18 @@ def _process_ssh_dss(self, data):
396389
q_bits = self._bits_in_number(data_fields["q"])
397390
p_bits = self._bits_in_number(data_fields["p"])
398391
if q_bits != self.DSA_N_LENGTH:
399-
raise InvalidKeyError("Incorrect DSA key parameters: bits(p)=%s, q=%s" % (self.bits, q_bits))
392+
raise InvalidKeyError(f"Incorrect DSA key parameters: bits(p)={self.bits}, q={q_bits}")
400393
if self.strict_mode:
401394
min_length = self.DSA_MIN_LENGTH_STRICT
402395
max_length = self.DSA_MAX_LENGTH_STRICT
403396
else:
404397
min_length = self.DSA_MIN_LENGTH_LOOSE
405398
max_length = self.DSA_MAX_LENGTH_LOOSE
406399
if p_bits < min_length:
407-
raise TooShortKeyError(
408-
"%s key can not be shorter than %s bits (was %s)" % (self.key_type.decode(), min_length, p_bits)
409-
)
400+
raise TooShortKeyError(f"{self.key_type.decode()} key can not be shorter than {min_length} bits (was {p_bits})")
410401
if p_bits > max_length:
411402
raise TooLongKeyError(
412-
"%s key data can not be longer than %s bits (was %s)" % (self.key_type.decode(), max_length, p_bits)
403+
f"{self.key_type.decode()} key data can not be longer than {max_length} bits (was {p_bits})"
413404
)
414405

415406
dsa_parameters = DSAParameterNumbers(data_fields["p"], data_fields["q"], data_fields["g"])
@@ -422,14 +413,12 @@ def _process_ecdsa_sha(self, data):
422413
"""Parses ecdsa-sha public keys."""
423414
current_position, curve_information = self._unpack_by_int(data, 0)
424415
if curve_information not in self.ECDSA_CURVE_DATA:
425-
raise NotImplementedError("Invalid curve type: %s" % curve_information)
416+
raise NotImplementedError(f"Invalid curve type: {curve_information}")
426417
curve, hash_algorithm = self.ECDSA_CURVE_DATA[curve_information]
427418

428419
current_position, key_data = self._unpack_by_int(data, current_position)
429420
try:
430-
ecdsa_pubkey = ec.EllipticCurvePublicKey.from_encoded_point(
431-
curve, key_data
432-
)
421+
ecdsa_pubkey = ec.EllipticCurvePublicKey.from_encoded_point(curve, key_data)
433422
except ValueError as ex:
434423
raise InvalidKeyError("Invalid ecdsa key") from ex
435424
self.bits = curve.key_size
@@ -452,7 +441,7 @@ def _process_ed25516(self, data):
452441

453442
self.bits = verifying_key_length
454443
if self.bits != 256:
455-
raise InvalidKeyLengthError("ed25519 keys must be 256 bits (was %s bits)" % self.bits)
444+
raise InvalidKeyLengthError(f"ed25519 keys must be 256 bits (was {self.bits} bits)")
456445
return current_position
457446

458447
def _validate_application_string(self, application):
@@ -463,7 +452,7 @@ def _validate_application_string(self, application):
463452
try:
464453
parsed_url = urlparse(application)
465454
except ValueError as err:
466-
raise InvalidKeyError("Application string: %s" % err) from err
455+
raise InvalidKeyError(f"Application string: {err}") from err
467456
if parsed_url.scheme != b"ssh":
468457
raise InvalidKeyError('Application string must begin with "ssh:"')
469458

@@ -494,7 +483,7 @@ def _process_key(self, data):
494483
return self._process_sk_ecdsa_sha(data)
495484
if self.key_type.strip().startswith(b"sk-ssh-ed25519"):
496485
return self._process_sk_ed25519(data)
497-
raise NotImplementedError("Invalid key type: %s" % self.key_type.decode())
486+
raise NotImplementedError(f"Invalid key type: {self.key_type.decode()}")
498487

499488
def parse(self, keydata=None):
500489
"""Validates SSH public key.
@@ -528,15 +517,15 @@ def parse(self, keydata=None):
528517
# Check key type
529518
current_position, unpacked_key_type = self._unpack_by_int(self._decoded_key, 0)
530519
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()))
520+
raise InvalidTypeError(f"Keytype mismatch: {key_type} != {unpacked_key_type.decode()}")
532521

533522
self.key_type = unpacked_key_type
534523

535524
key_data_length = self._process_key(self._decoded_key[current_position:])
536525
current_position = current_position + key_data_length
537526

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

541530
if self.disallow_options and self.options:
542531
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)