This repository has been archived by the owner on Jul 13, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 29
feature: allow channels to register with public key #382
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,10 @@ | |
import datetime | ||
import socket | ||
|
||
from hashlib import sha256 | ||
|
||
from cryptography.fernet import Fernet, MultiFernet | ||
from cryptography.hazmat.primitives import constant_time | ||
from twisted.internet import reactor | ||
from twisted.internet.defer import ( | ||
inlineCallbacks, | ||
|
@@ -232,6 +235,7 @@ def update_rotating_tables(self): | |
self.current_msg_month = message_table.table_name | ||
self.message_tables[self.current_msg_month] = \ | ||
Message(message_table, self.metrics) | ||
|
||
returnValue(True) | ||
|
||
def update(self, **kwargs): | ||
|
@@ -248,7 +252,57 @@ def update(self, **kwargs): | |
else: | ||
setattr(self, key, val) | ||
|
||
def make_endpoint(self, uaid, chid): | ||
""" Create an endpoint from the identifiers""" | ||
return self.endpoint_url + '/push/' + \ | ||
self.fernet.encrypt((uaid + ':' + chid).encode('utf8')) | ||
def make_endpoint(self, uaid, chid, key=None): | ||
"""Create an v1 or v2 endpoint from the indentifiers. | ||
|
||
Both endpoints use bytes instead of hex to reduce ID length. | ||
v0 is uaid.hex + ':' + chid.hex and is deprecated. | ||
v1 is the uaid + chid | ||
v2 is the uaid + chid + sha256(key).bytes | ||
|
||
:param uaid: User Agent Identifier | ||
:param chid: Channel or Subscription ID | ||
:param key: Optional provided Public Key | ||
:returns: Push endpoint | ||
|
||
""" | ||
root = self.endpoint_url + '/push/' | ||
base = (uaid.replace('-', '').decode("hex") + | ||
chid.replace('-', '').decode("hex")) | ||
|
||
if key is None: | ||
return root + 'v1/' + self.fernet.encrypt(base).strip('=') | ||
|
||
return root + 'v2/' + self.fernet.encrypt(base + sha256(key).digest()) | ||
|
||
def parse_endpoint(self, token, version="v0", public_key=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 public_key: the public key (from Encryption-Key: p256ecdsa=) | ||
|
||
:raises ValueError: In the case of a malformed endpoint. | ||
|
||
:returns: a tuple containing the (UAID, CHID) | ||
|
||
""" | ||
|
||
token = self.fernet.decrypt(token.encode('utf8')) | ||
|
||
if version == 'v0': | ||
if ':' not in token: | ||
raise ValueError("Corrupted push token") | ||
return tuple(token.split(':')) | ||
if version == 'v1' and len(token) != 32: | ||
raise ValueError("Corrupted push token") | ||
if version == 'v2': | ||
if len(token) != 64: | ||
raise ValueError("Corrupted push token") | ||
if not public_key: | ||
raise ValueError("Invalid key data") | ||
if not constant_time.bytes_eq(sha256(public_key).digest(), | ||
token[32:]): | ||
raise ValueError("Key mismatch") | ||
return (token[:16].encode('hex'), token[16:32].encode('hex')) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😮 🏆 |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not going to be great to do at scale....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're prolly going to have to file a separate issue to replace the uaid lookup with a lookup that does a set membership test in dynamodb, so that we're not pulling the entire list of channels then checking them.
We can ensure the channels are normalized, by updating the migration code to normalize them on monthly rotation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. We're kinda stuck at the moment because of legacy records. Eventually, they should expire out, but for now, we have to account for them.