From 1922f0972b065077404c0dafa0946f2132400a2b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Padilla?= <jpadilla@webapplicate.com>
Date: Wed, 21 Jun 2017 15:49:41 -0400
Subject: [PATCH 1/3] Throw if key is an PKCS1 PEM-encoded public key

---
 jwt/algorithms.py                | 1 +
 tests/keys/testkey_pkcs1.pub.pem | 5 +++++
 tests/test_algorithms.py         | 7 +++++++
 3 files changed, 13 insertions(+)
 create mode 100644 tests/keys/testkey_pkcs1.pub.pem

Index: PyJWT-1.4.2/jwt/algorithms.py
===================================================================
--- PyJWT-1.4.2.orig/jwt/algorithms.py
+++ PyJWT-1.4.2/jwt/algorithms.py
@@ -121,6 +121,7 @@ class HMACAlgorithm(Algorithm):
         invalid_strings = [
             b'-----BEGIN PUBLIC KEY-----',
             b'-----BEGIN CERTIFICATE-----',
+            b'-----BEGIN RSA PUBLIC KEY-----',
             b'ssh-rsa'
         ]
 
Index: PyJWT-1.4.2/tests/keys/testkey_pkcs1.pub.pem
===================================================================
--- /dev/null
+++ PyJWT-1.4.2/tests/keys/testkey_pkcs1.pub.pem
@@ -0,0 +1,5 @@
+-----BEGIN RSA PUBLIC KEY-----
+MIGHAoGBAOV/0Vl/5VdHcYpnILYzBGWo5JQVzo9wBkbxzjAStcAnTwvv1ZJTMXs6
+fjz91f9hiMM4Z/5qNTE/EHlDWxVdj1pyRaQulZPUs0r9qJ02ogRRGLG3jjrzzbzF
+yj/pdNBwym0UJYC/Jmn/kMLwGiWI2nfa9vM5SovqZiAy2FD7eOtVAgED
+-----END RSA PUBLIC KEY-----
Index: PyJWT-1.4.2/tests/test_algorithms.py
===================================================================
--- PyJWT-1.4.2.orig/tests/test_algorithms.py
+++ PyJWT-1.4.2/tests/test_algorithms.py
@@ -63,6 +63,13 @@ class TestAlgorithms:
             with open(key_path('testkey2_rsa.pub.pem'), 'r') as keyfile:
                 algo.prepare_key(keyfile.read())
 
+    def test_hmac_should_throw_exception_if_key_is_pkcs1_pem_public(self):
+        algo = HMACAlgorithm(HMACAlgorithm.SHA256)
+
+        with pytest.raises(InvalidKeyError):
+            with open(key_path('testkey_pkcs1.pub.pem'), 'r') as keyfile:
+                algo.prepare_key(keyfile.read())
+
     def test_hmac_should_throw_exception_if_key_is_x509_certificate(self):
         algo = HMACAlgorithm(HMACAlgorithm.SHA256)
 
Index: PyJWT-1.4.2/jwt/api_jws.py
===================================================================
--- PyJWT-1.4.2.orig/jwt/api_jws.py
+++ PyJWT-1.4.2/jwt/api_jws.py
@@ -107,6 +107,15 @@ class PyJWS(object):
 
     def decode(self, jws, key='', verify=True, algorithms=None, options=None,
                **kwargs):
+
+        if not algorithms:
+            warnings.warn(
+                'It is strongly recommended that you pass in a ' +
+                'value for the "algorithms" argument when calling decode(). ' +
+                'This argument will be mandatory in a future version.',
+                DeprecationWarning
+            )
+
         payload, signing_input, header, signature = self._load(jws)
 
         if verify:
Index: PyJWT-1.4.2/jwt/api_jwt.py
===================================================================
--- PyJWT-1.4.2.orig/jwt/api_jwt.py
+++ PyJWT-1.4.2/jwt/api_jwt.py
@@ -58,6 +58,15 @@ class PyJWT(PyJWS):
 
     def decode(self, jwt, key='', verify=True, algorithms=None, options=None,
                **kwargs):
+
+        if not algorithms:
+            warnings.warn(
+                'It is strongly recommended that you pass in a ' +
+                'value for the "algorithms" argument when calling decode(). ' +
+                'This argument will be mandatory in a future version.',
+                DeprecationWarning
+            )
+
         payload, signing_input, header, signature = self._load(jwt)
 
         decoded = super(PyJWT, self).decode(jwt, key, verify, algorithms,
Index: PyJWT-1.4.2/tests/test_api_jws.py
===================================================================
--- PyJWT-1.4.2.orig/tests/test_api_jws.py
+++ PyJWT-1.4.2/tests/test_api_jws.py
@@ -266,6 +266,16 @@ class TestJWS:
 
         pytest.deprecated_call(jws.decode, example_jws, verify=False)
 
+    def test_decode_with_optional_algorithms(self, jws):
+        example_secret = 'secret'
+        example_jws = (
+            b'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.'
+            b'aGVsbG8gd29ybGQ.'
+            b'SIr03zM64awWRdPrAM_61QWsZchAtgDV3pphfHPPWkI'
+        )
+
+        pytest.deprecated_call(jws.decode, example_jws, key=example_secret)
+
     def test_load_no_verification(self, jws, payload):
         right_secret = 'foo'
         jws_message = jws.encode(payload, right_secret)
Index: PyJWT-1.4.2/tests/test_api_jwt.py
===================================================================
--- PyJWT-1.4.2.orig/tests/test_api_jwt.py
+++ PyJWT-1.4.2/tests/test_api_jwt.py
@@ -479,3 +479,13 @@ class TestJWT:
                 secret,
                 verify_expiration=True
             )
+
+    def test_decode_with_optional_algorithms(self, jwt, payload):
+        secret = 'secret'
+        jwt_message = jwt.encode(payload, secret)
+
+        pytest.deprecated_call(
+            jwt.decode,
+            jwt_message,
+            secret
+        )
