Skip to content

Commit 708191a

Browse files
committed
fix: respect RFC6749 character set in error descriptions
1 parent eb5f55c commit 708191a

14 files changed

Lines changed: 33 additions & 32 deletions

File tree

docs/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Unreleased
2323
- Use ``ECKey.binding.register_curve`` to register new supported curves.
2424
- Use ``UnsupportedAlgorithmError`` instead of ``ValueError`` in JWS/JWE registry.
2525
- Use ``MissingKeyTypeError`` and ``InvalidKeyIdError`` for errors in JWK.
26+
- Respect RFC6749 character set in error descriptions.
2627

2728
1.0.4
2829
-----

src/joserfc/_keys.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def import_key(
6666
raise MissingKeyTypeError("Missing key type")
6767

6868
if key_type not in cls.key_types:
69-
raise InvalidKeyTypeError(f'Invalid key type: "{key_type}"')
69+
raise InvalidKeyTypeError(f"Invalid key type: '{key_type}'")
7070

7171
if isinstance(data, str):
7272
data = to_bytes(data)
@@ -93,7 +93,7 @@ def generate_key(
9393
JWKRegistry.generate_key("EC", "P-256")
9494
"""
9595
if key_type not in cls.key_types:
96-
raise InvalidKeyTypeError(f'Invalid key type: "{key_type}"')
96+
raise InvalidKeyTypeError(f"Invalid key type: '{key_type}'")
9797

9898
key_cls = cls.key_types[key_type]
9999
return key_cls.generate_key(crv_or_size, parameters, private, auto_kid) # type: ignore[arg-type]
@@ -143,7 +143,7 @@ def get_by_kid(self, kid: str | None = None) -> Key:
143143
for key in self.keys:
144144
if key.kid == kid:
145145
return key
146-
raise InvalidKeyIdError(f'No key for kid: "{kid}"')
146+
raise InvalidKeyIdError(f"No key for kid: '{kid}'")
147147

148148
def pick_random_key(self, algorithm: str) -> t.Optional[Key]:
149149
key_types = self.algorithm_keys.get(algorithm)

src/joserfc/errors.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class InvalidEncryptedKeyError(JoseError):
6161

6262
class MissingAlgorithmError(JoseError):
6363
error = "missing_algorithm"
64-
description = 'Missing "alg" value in header'
64+
description = "Missing 'alg' value in header"
6565

6666

6767
class ConflictAlgorithmError(JoseError):
@@ -74,7 +74,7 @@ class UnsupportedAlgorithmError(JoseError):
7474

7575
class MissingEncryptionError(JoseError):
7676
error = "missing_encryption"
77-
description = 'Missing "enc" value in header'
77+
description = "Missing 'enc' value in header"
7878

7979

8080
class BadSignatureError(JoseError):
@@ -99,30 +99,30 @@ class InvalidEncryptionAlgorithmError(JoseError):
9999

100100
class InvalidCEKLengthError(JoseError):
101101
error = "invalid_cek_length"
102-
description = 'Invalid "cek" length'
102+
description = "Invalid 'cek' length"
103103

104104

105105
class InvalidClaimError(JoseError):
106106
error = "invalid_claim"
107107

108108
def __init__(self, claim: str):
109-
description = f'Invalid claim: "{claim}"'
109+
description = f"Invalid claim: '{claim}'"
110110
super(InvalidClaimError, self).__init__(description=description)
111111

112112

113113
class MissingClaimError(JoseError):
114114
error = "missing_claim"
115115

116116
def __init__(self, claim: str):
117-
description = f'Missing claim: "{claim}"'
117+
description = f"Missing claim: '{claim}'"
118118
super(MissingClaimError, self).__init__(description=description)
119119

120120

121121
class InsecureClaimError(JoseError):
122122
error = "insecure_claim"
123123

124124
def __init__(self, claim: str):
125-
description = f'Insecure claim "{claim}"'
125+
description = f"Insecure claim '{claim}'"
126126
super(InsecureClaimError, self).__init__(description=description)
127127

128128

src/joserfc/registry.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,17 +184,17 @@ def validate_registry_header(
184184
check_required: bool = True) -> None:
185185
for key, reg in registry.items():
186186
if check_required and reg.required and key not in header:
187-
raise ValueError(f'Required "{key}" is missing in header')
187+
raise ValueError(f"Required '{key}' is missing in header")
188188
if key in header:
189189
try:
190190
reg.validate(header[key])
191191
except ValueError as error:
192-
raise ValueError(f'"{key}" in header {error}')
192+
raise ValueError(f"'{key}' in header {error}")
193193

194194

195195
def check_crit_header(header: Header) -> None:
196196
# check crit header
197197
if "crit" in header:
198198
for k in header["crit"]:
199199
if k not in header:
200-
raise ValueError(f'"{k}" is a critical header')
200+
raise ValueError(f"'{k}' is a critical header")

src/joserfc/rfc7515/model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ class JWSAlgModel(object, metaclass=ABCMeta):
9797

9898
def check_key_type(self, key: Any) -> None:
9999
if key.key_type != self.key_type:
100-
raise InvalidKeyTypeError(f'Algorithm "{self.name}" requires "{self.key_type}" key')
100+
raise InvalidKeyTypeError(f"Algorithm '{self.name}' requires '{self.key_type}' key")
101101

102102
@abstractmethod
103103
def sign(self, msg: bytes, key: Any) -> bytes:

src/joserfc/rfc7515/registry.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ def get_alg(self, name: str) -> JWSAlgModel:
5050
:param name: value of the ``alg``, e.g. ``HS256``, ``RS256``
5151
"""
5252
if name not in self.algorithms:
53-
raise UnsupportedAlgorithmError(f'Algorithm of "{name}" is not supported')
53+
raise UnsupportedAlgorithmError(f"Algorithm of '{name}' is not supported")
5454

5555
if self.allowed:
5656
if name not in self.allowed:
57-
raise UnsupportedAlgorithmError(f'Algorithm of "{name}" is not allowed')
57+
raise UnsupportedAlgorithmError(f"Algorithm of '{name}' is not allowed")
5858
else:
5959
if name not in self.recommended:
60-
raise UnsupportedAlgorithmError(f'Algorithm of "{name}" is not recommended')
60+
raise UnsupportedAlgorithmError(f"Algorithm of '{name}' is not recommended")
6161
return self.algorithms[name]
6262

6363
def check_header(self, header: Header) -> None:

src/joserfc/rfc7516/message.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def _perform_decrypt(obj: EncryptionData, registry: JWERegistry) -> None:
111111
raise DecodeError('Invalid recipients')
112112

113113
if len(cek_set) > 1: # pragma: no cover
114-
raise DecodeError('Multiple "cek" found')
114+
raise DecodeError("Multiple 'cek' found")
115115

116116
cek = cek_set.pop()
117117
if len(cek) * 8 != enc.cek_size: # pragma: no cover

src/joserfc/rfc7516/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ def generate_iv(self) -> bytes:
175175

176176
def check_iv(self, iv: bytes) -> bytes:
177177
if len(iv) * 8 != self.iv_size: # pragma: no cover
178-
raise ValueError('Invalid "iv" size')
178+
raise ValueError("Invalid 'iv' size")
179179
return iv
180180

181181
@abstractmethod

src/joserfc/rfc7516/registry.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,14 @@ def get_zip(self, name: str) -> JWEZipModel:
102102

103103
def _check_algorithm(self, name: str, registry: dict[str, t.Any]) -> None:
104104
if name not in registry:
105-
raise UnsupportedAlgorithmError(f'Algorithm of "{name}" is not supported')
105+
raise UnsupportedAlgorithmError(f"Algorithm of '{name}' is not supported")
106106

107107
if self.allowed:
108108
if name not in self.allowed:
109-
raise UnsupportedAlgorithmError(f'Algorithm of "{name}" is not allowed')
109+
raise UnsupportedAlgorithmError(f"Algorithm of '{name}' is not allowed")
110110
else:
111111
if name not in self.recommended:
112-
raise UnsupportedAlgorithmError(f'Algorithm of "{name}" is not recommended')
112+
raise UnsupportedAlgorithmError(f"Algorithm of '{name}' is not recommended")
113113

114114

115115
default_registry = JWERegistry()

src/joserfc/rfc7517/models.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,13 @@ def as_bytes(
5656
def validate_dict_key_registry(cls, dict_key: DictKey, registry: KeyParameterRegistryDict) -> None:
5757
for k in registry:
5858
if registry[k].required and k not in dict_key:
59-
raise ValueError(f'"{k}" is required')
59+
raise ValueError(f"'{k}' is required")
6060

6161
if k in dict_key:
6262
try:
6363
registry[k].validate(dict_key[k])
6464
except ValueError as error:
65-
raise ValueError(f'"{k}" {error}')
65+
raise ValueError(f"'{k}' {error}")
6666

6767
@classmethod
6868
def validate_dict_key_use_operations(cls, dict_key: DictKey) -> None:
@@ -71,7 +71,7 @@ def validate_dict_key_use_operations(cls, dict_key: DictKey) -> None:
7171
operations = cls.use_key_ops_registry[_use]
7272
for op in dict_key["key_ops"]:
7373
if op not in operations:
74-
raise ValueError('"use" and "key_ops" does not match')
74+
raise ValueError("'use' and 'key_ops' does not match")
7575

7676

7777
class BaseKey(t.Generic[NativePrivateKey, NativePublicKey], metaclass=ABCMeta):
@@ -200,7 +200,7 @@ def check_use(self, use: str) -> None:
200200
"""
201201
designed_use = self.get("use")
202202
if designed_use and designed_use != use:
203-
raise UnsupportedKeyUseError(f'This key is designed to be used for "{designed_use}"')
203+
raise UnsupportedKeyUseError(f"This key is designed to be used for '{designed_use}'")
204204

205205
def check_alg(self, alg: str) -> None:
206206
"""Check if this key supports the given "alg".
@@ -210,7 +210,7 @@ def check_alg(self, alg: str) -> None:
210210
"""
211211
designed_alg = self.get("alg")
212212
if designed_alg and designed_alg != alg:
213-
raise UnsupportedKeyAlgorithmError(f'This key is designed for algorithm "{designed_alg}"')
213+
raise UnsupportedKeyAlgorithmError(f"This key is designed for algorithm '{designed_alg}'")
214214

215215
def check_key_op(self, operation: str) -> None:
216216
"""Check if the given key_op is supported by this key.
@@ -220,12 +220,12 @@ def check_key_op(self, operation: str) -> None:
220220
"""
221221
key_ops = self.get("key_ops")
222222
if key_ops is not None and operation not in key_ops:
223-
raise UnsupportedKeyOperationError(f'Unsupported key_op "{operation}"')
223+
raise UnsupportedKeyOperationError(f"Unsupported key_op '{operation}'")
224224

225225
assert operation in self.operation_registry
226226
reg = self.operation_registry[operation]
227227
if reg.private and not self.is_private:
228-
raise UnsupportedKeyOperationError(f'Invalid key_op "{operation}" for public key')
228+
raise UnsupportedKeyOperationError(f"Invalid key_op '{operation}' for public key")
229229

230230
@t.overload
231231
def get_op_key(self, operation: t.Literal["verify", "encrypt", "wrapKey", "deriveKey"]) -> NativePublicKey: ...

0 commit comments

Comments
 (0)