summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Holtermann <info@markusholtermann.eu>2017-12-01 20:11:09 +0100
committerJosé Padilla <jpadilla@webapplicate.com>2017-12-01 14:11:09 -0500
commit0c80a7119a1a82e7023ab3b0c766311de5821707 (patch)
tree374f535413b80de40fd6d3711de6d0dd98ef724f
parente0aa10ee586bf010ce9a99c5582ee8dc9293ba1e (diff)
downloadpyjwt-0c80a7119a1a82e7023ab3b0c766311de5821707.tar.gz
Fix #315: Raise InvalidSignatureError over generic DecodeError (#316)
-rw-r--r--CHANGELOG.md3
-rw-r--r--docs/api.rst5
-rw-r--r--jwt/api_jws.py7
-rw-r--r--jwt/exceptions.py4
-rw-r--r--tests/test_api_jws.py11
5 files changed, 26 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5793d70..68eb2ac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Audience parameter now supports iterables [#205][205]
+- An invalid signature now raises an `InvalidSignatureError` instead of `DecodeError` [#315][315]
+
### Fixed
### Added
@@ -204,4 +206,5 @@ rarely used. Users affected by this should upgrade to 3.3+.
[271]: https://github.com/jpadilla/pyjwt/pull/271
[277]: https://github.com/jpadilla/pyjwt/pull/277
[281]: https://github.com/jpadilla/pyjwt/pull/281
+[315]: https://github.com/jpadilla/pyjwt/pull/315
[7c1e61d]: https://github.com/jpadilla/pyjwt/commit/7c1e61dde27bafe16e7d1bb6e35199e778962742
diff --git a/docs/api.rst b/docs/api.rst
index 4bb4d3b..08b6991 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -19,6 +19,11 @@ Exceptions
Raised when a token cannot be decoded because it failed validation
+.. class:: InvalidSignatureError
+
+ Raised when a token's signature doesn't match the one provided as part of
+ the token.
+
.. class:: ExpiredSignatureError
Raised when a token's ``exp`` claim indicates that it has expired
diff --git a/jwt/api_jws.py b/jwt/api_jws.py
index ad3ff6a..b796fa7 100644
--- a/jwt/api_jws.py
+++ b/jwt/api_jws.py
@@ -7,7 +7,10 @@ from .algorithms import (
Algorithm, get_default_algorithms, has_crypto, requires_cryptography # NOQA
)
from .compat import binary_type, string_types, text_type
-from .exceptions import DecodeError, InvalidAlgorithmError, InvalidTokenError
+from .exceptions import (
+ DecodeError, InvalidAlgorithmError, InvalidSignatureError,
+ InvalidTokenError
+)
from .utils import base64url_decode, base64url_encode, force_bytes, merge_dict
@@ -203,7 +206,7 @@ class PyJWS(object):
key = alg_obj.prepare_key(key)
if not alg_obj.verify(signing_input, key, signature):
- raise DecodeError('Signature verification failed')
+ raise InvalidSignatureError('Signature verification failed')
except KeyError:
raise InvalidAlgorithmError('Algorithm not supported')
diff --git a/jwt/exceptions.py b/jwt/exceptions.py
index 31177a0..b396bf1 100644
--- a/jwt/exceptions.py
+++ b/jwt/exceptions.py
@@ -6,6 +6,10 @@ class DecodeError(InvalidTokenError):
pass
+class InvalidSignatureError(DecodeError):
+ pass
+
+
class ExpiredSignatureError(InvalidTokenError):
pass
diff --git a/tests/test_api_jws.py b/tests/test_api_jws.py
index 60671a2..4bf8d39 100644
--- a/tests/test_api_jws.py
+++ b/tests/test_api_jws.py
@@ -5,7 +5,8 @@ from decimal import Decimal
from jwt.algorithms import Algorithm
from jwt.api_jws import PyJWS
from jwt.exceptions import (
- DecodeError, InvalidAlgorithmError, InvalidTokenError
+ DecodeError, InvalidAlgorithmError, InvalidSignatureError,
+ InvalidTokenError
)
from jwt.utils import base64url_decode, force_bytes, force_unicode
@@ -178,8 +179,14 @@ class TestJWS:
bad_secret = 'bar'
jws_message = jws.encode(payload, right_secret)
- with pytest.raises(DecodeError):
+ with pytest.raises(DecodeError) as excinfo:
+ # Backward compat for ticket #315
+ jws.decode(jws_message, bad_secret)
+ assert 'Signature verification failed' == str(excinfo.value)
+
+ with pytest.raises(InvalidSignatureError) as excinfo:
jws.decode(jws_message, bad_secret)
+ assert 'Signature verification failed' == str(excinfo.value)
def test_decodes_valid_jws(self, jws, payload):
example_secret = 'secret'