diff --git a/autopush/tests/test_web_validation.py b/autopush/tests/test_web_validation.py index 82a9e00b..3797c1cd 100644 --- a/autopush/tests/test_web_validation.py +++ b/autopush/tests/test_web_validation.py @@ -1,12 +1,13 @@ import time import uuid +import base64 from hashlib import sha256 import ecdsa from cryptography.fernet import InvalidToken from cryptography.exceptions import InvalidSignature -from jose import jws +from jose import jws, jwk from marshmallow import Schema, fields from mock import Mock, patch import pytest @@ -1170,3 +1171,40 @@ def test_bogus_vapid_header(self): assert cm.value.status_code == 401 assert cm.value.errno == 109 + + def test_null_vapid_header(self): + schema = self._make_fut() + schema.context["conf"].use_cryptography = True + + def b64s(content): + return base64.urlsafe_b64encode(content).strip(b'=') + + payload = b'.'.join([b64s("null"), b64s("null")]) + + # force sign the header, since jws will "fix" the invalid one. + sk256p = ecdsa.SigningKey.generate(curve=ecdsa.NIST256p) + vk = sk256p.get_verifying_key() + key = jwk.construct(sk256p, "ES256") + signature = b64s(key.sign(payload)) + token = b'.'.join([payload, signature]) + crypto_key = b64s(vk.to_string()) + + self.fernet_mock.decrypt.return_value = ( + 'a' * 32) + sha256(utils.base64url_decode(crypto_key)).digest() + info = self._make_test_data( + body="asdfasdfasdfasdf", + path_kwargs=dict( + api_ver="v2", + token="asdfasdf", + ), + headers={ + "content-encoding": "aes128gcm", + "authorization": "vapid k={},t={}".format(crypto_key, token) + } + ) + + with pytest.raises(InvalidRequest) as cm: + schema.load(info) + + assert cm.value.status_code == 401 + assert cm.value.errno == 109 diff --git a/autopush/web/webpush.py b/autopush/web/webpush.py index a4c02647..fa6f2813 100644 --- a/autopush/web/webpush.py +++ b/autopush/web/webpush.py @@ -405,6 +405,10 @@ def validate_auth(self, d): is_trusted=self.context['conf'].enable_tls_auth, use_crypto=self.context['conf'].use_cryptography ) + if not isinstance(jwt, Dict): + raise InvalidRequest("Invalid Authorization Header", + status_code=401, errno=109, + headers={"www-authenticate": PREF_SCHEME}) except tuple(crypto_exceptions): raise InvalidRequest("Invalid Authorization Header", status_code=401, errno=109,