예제 #1
0
 def parse_decrypted_message_id(decrypted_token):
     # type: (str) -> Dict[str, Any]
     """Parses a decrypted message-id into component parts"""
     topic = None
     sortkey_timestamp = None
     if decrypted_token.startswith("01:"):
         info = decrypted_token.split(":")
         if len(info) != 4:
             raise InvalidTokenException("Incorrect number of token parts.")
         api_ver, uaid, chid, topic = info
     elif decrypted_token.startswith("02:"):
         info = decrypted_token.split(":")
         if len(info) != 4:
             raise InvalidTokenException("Incorrect number of token parts.")
         api_ver, uaid, chid, raw_sortkey = info
         sortkey_timestamp = int(raw_sortkey)
     else:
         info = decrypted_token.split(":")
         if len(info) != 3:
             raise InvalidTokenException("Incorrect number of token parts.")
         kind, uaid, chid = decrypted_token.split(":")
         if kind != "m":
             raise InvalidTokenException("Incorrect token kind.")
     return dict(
         uaid=uaid,
         chid=chid,
         topic=topic,
         sortkey_timestamp=sortkey_timestamp,
     )
예제 #2
0
    def parse_endpoint(self,
                       metrics,
                       token,
                       version="v1",
                       ckey_header=None,
                       auth_header=None):
        """Parse an endpoint into component elements of UAID, CHID and optional
        key hash if v2

        :param token: The obscured subscription data.
        :param version: This is the API version of the token.
        :param ckey_header: the Crypto-Key header bearing the public key
            (from Crypto-Key: p256ecdsa=)
        :param auth_header: The Authorization header bearing the VAPID info

        :raises ValueError: In the case of a malformed endpoint.

        :returns: a dict containing (uaid=UAID, chid=CHID, public_key=KEY)

        """
        token = self.fernet.decrypt(repad(token).encode('utf8'))
        public_key = None
        if ckey_header:
            try:
                crypto_key = CryptoKey(ckey_header)
            except CryptoKeyException:
                raise InvalidTokenException("Invalid key data")
            public_key = crypto_key.get_label('p256ecdsa')
        if auth_header:
            vapid_auth = parse_auth_header(auth_header)
            if not vapid_auth:
                raise VapidAuthException("Invalid Auth token")
            metrics.increment("updates.notification.auth.{}".format(
                vapid_auth['scheme']))
            # pull the public key from the VAPID auth header if needed
            try:
                if vapid_auth['version'] != 1:
                    public_key = vapid_auth['k']
            except KeyError:
                raise VapidAuthException("Missing Public Key")
        if version == 'v1' and len(token) != 32:
            raise InvalidTokenException("Corrupted push token")
        if version == 'v2':
            if not auth_header:
                raise VapidAuthException("Missing Authorization Header")
            if len(token) != 64:
                raise InvalidTokenException("Corrupted push token")
            if not public_key:
                raise VapidAuthException("Invalid key data")
            try:
                decoded_key = base64url_decode(public_key)
            except TypeError:
                raise VapidAuthException("Invalid key data")
            if not constant_time.bytes_eq(
                    sha256(decoded_key).digest(), token[32:]):
                raise VapidAuthException("Key mismatch")
        return dict(uaid=token[:16].encode('hex'),
                    chid=token[16:32].encode('hex'),
                    version=version,
                    public_key=public_key)
예제 #3
0
파일: endpoint.py 프로젝트: oremj/autopush
    def _token_valid(self, result, func):
        """Handles valid token processing, then dispatches to supplied
        function"""
        info = result.split(":")
        if len(info) != 3:
            raise InvalidTokenException("Wrong message token components")

        kind, uaid, chid = info
        if kind != 'm':
            raise InvalidTokenException("Wrong message token kind")
        return func(kind, uaid, chid)
예제 #4
0
    def parse_endpoint(self, token, version="v0", ckey_header=None):
        """Parse an endpoint into component elements of UAID, CHID and optional
        key hash if v2

        :param token: The obscured subscription data.
        :param version: This is the API version of the token.
        :param ckey_header: the Crypto-Key header bearing the public key
        (from Crypto-Key: p256ecdsa=)

        :raises ValueError: In the case of a malformed endpoint.

        :returns: a dict containing (uaid=UAID, chid=CHID, public_key=KEY)

        """

        token = self.fernet.decrypt(token.encode('utf8'))
        public_key = None
        if ckey_header:
            try:
                crypto_key = CryptoKey(ckey_header)
            except CryptoKeyException:
                raise InvalidTokenException("Invalid key data")
            label = crypto_key.get_label('p256ecdsa')
            try:
                public_key = base64url_decode(label)
            except:
                # Ignore missing and malformed app server keys.
                pass

        if version == 'v0':
            if not VALID_V0_TOKEN.match(token):
                raise InvalidTokenException("Corrupted push token")
            items = token.split(':')
            return dict(uaid=items[0], chid=items[1], public_key=public_key)
        if version == 'v1' and len(token) != 32:
            raise InvalidTokenException("Corrupted push token")
        if version == 'v2':
            if len(token) != 64:
                raise InvalidTokenException("Corrupted push token")
            if not public_key:
                raise InvalidTokenException("Invalid key data")
            if not constant_time.bytes_eq(
                    sha256(public_key).digest(), token[32:]):
                raise InvalidTokenException("Key mismatch")
        return dict(uaid=token[:16].encode('hex'),
                    chid=token[16:32].encode('hex'),
                    public_key=public_key)
예제 #5
0
 def throw_item(*args, **kwargs):
     raise InvalidTokenException("Not found")