diff --git a/.travis.yml b/.travis.yml index a71e1965..736cb9cc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ matrix: include: # Linting - python: 3.6 - env: TOX_ENV=flake8 + env: TOXENV=flake8 # CPython 2.7 - python: 2.7 env: TOXENV=py27-base diff --git a/jose/backends/pycrypto_backend.py b/jose/backends/pycrypto_backend.py index cf270a88..b8f7b678 100644 --- a/jose/backends/pycrypto_backend.py +++ b/jose/backends/pycrypto_backend.py @@ -1,6 +1,7 @@ from base64 import b64encode import six +import warnings import Crypto.Hash.SHA256 import Crypto.Hash.SHA384 @@ -147,6 +148,9 @@ def sign(self, msg): raise JWKError(e) def verify(self, msg, sig): + if not self.is_public(): + warnings.warn("Attempting to verify a message with a private key. " + "This is not recommended.") try: return PKCS1_v1_5.new(self.prepared_key).verify(self.hash_alg.new(msg), sig) except Exception: diff --git a/jose/backends/rsa_backend.py b/jose/backends/rsa_backend.py index 38e42bb6..79862a3b 100644 --- a/jose/backends/rsa_backend.py +++ b/jose/backends/rsa_backend.py @@ -1,6 +1,8 @@ import binascii import six +import warnings + from pyasn1.error import PyAsn1Error import rsa as pyrsa @@ -200,6 +202,9 @@ def sign(self, msg): return pyrsa.sign(msg, self._prepared_key, self.hash_alg) def verify(self, msg, sig): + if not self.is_public(): + warnings.warn("Attempting to verify a message with a private key. " + "This is not recommended.") try: pyrsa.verify(msg, sig, self._prepared_key) return True diff --git a/jose/utils.py b/jose/utils.py index 39003ec9..e859f4c2 100644 --- a/jose/utils.py +++ b/jose/utils.py @@ -1,6 +1,5 @@ import base64 -import hmac import six import struct import sys diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 00000000..03589cf8 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,7 @@ +[pytest] +markers = + pycrypto: marks tests as applicable with PyCrypto backend + pycryptodome: marks tests as applicable with PyCryptodome backend + ecdsa: marks tests as applicable with ecdsa backend + cryptography: marks tests as applicable with cryptography backend + backend_compatibility: mark tests as testing compatibility between backends diff --git a/setup.py b/setup.py index ed196b84..984a036b 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ import os import platform -import jose +import jose # noqa: F401 from setuptools import setup diff --git a/tests/test_jws.py b/tests/test_jws.py index f543a03a..b31e0b4f 100644 --- a/tests/test_jws.py +++ b/tests/test_jws.py @@ -1,11 +1,18 @@ import json +import warnings + +import pytest from jose import jwk from jose import jws +from jose.backends import RSAKey from jose.constants import ALGORITHMS from jose.exceptions import JWSError -import pytest +try: + from jose.backends.cryptography_backend import CryptographyRSAKey +except ImportError: + CryptographyRSAKey = None @pytest.fixture @@ -291,6 +298,20 @@ def test_wrong_key(self, payload): with pytest.raises(JWSError): jws.verify(token, rsa_public_key, ALGORITHMS.HS256) + @pytest.mark.skipif(RSAKey is CryptographyRSAKey, reason="Cryptography backend outright fails verification") + def test_private_verify_raises_warning(self, payload): + token = jws.sign(payload, rsa_private_key, algorithm='RS256') + + # verify with public + jws.verify(token, rsa_public_key, algorithms='RS256') + + with warnings.catch_warnings(record=True) as w: + # verify with private raises warning + jws.verify(token, rsa_private_key, algorithms='RS256') + + assert ("Attempting to verify a message with a private key. " + "This is not recommended.") == str(w[-1].message) + ec_private_key = """-----BEGIN EC PRIVATE KEY----- MIHcAgEBBEIBzs13YUnYbLfYXTz4SG4DE4rPmsL3wBTdy34JcO+BDpI+NDZ0pqam