Skip to content

Commit

Permalink
Make challenge signing reusable (#1501)
Browse files Browse the repository at this point in the history
* Make challenge signing reusable

* bring back comment

* add type hinting

* add missing docstrings

* CI: fix deploy step
  • Loading branch information
om26er committed Nov 18, 2021
1 parent f4c9450 commit 99794e8
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 27 deletions.
68 changes: 44 additions & 24 deletions autobahn/wamp/cryptosign.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import binascii
import struct
from typing import Callable

import txaio

Expand Down Expand Up @@ -354,7 +355,15 @@ def _verify_signify_ed25519_signature(pubkey_file, signature_file, message):

if HAS_CRYPTOSIGN:

def format_challenge(session, challenge, channel_id_type) -> bytes:
def format_challenge(challenge: Challenge, channel_id_raw: bytes, channel_id_type: str) -> bytes:
"""
Format the challenge based on provided parameters
:param challenge: The WAMP-cryptosign challenge object for which a signature should be computed.
:param channel_id_raw: The channel ID when channel_id_type is 'tls-unique'.
:param channel_id_type: The type of the channel id, currently handles 'tls-unique' and
ignores otherwise.
"""
if not isinstance(challenge, Challenge):
raise Exception(
"challenge must be instance of autobahn.wamp.types.Challenge, not {}".format(type(challenge)))
Expand All @@ -375,8 +384,6 @@ def format_challenge(session, challenge, channel_id_type) -> bytes:
challenge_raw = binascii.a2b_hex(challenge_hex)

if channel_id_type == 'tls-unique':
# get the TLS channel ID of the underlying TLS connection
channel_id_raw = session._transport.get_channel_id()
assert len(
channel_id_raw) == 32, 'unexpected TLS transport channel ID length (was {}, but expected 32)'.format(
len(channel_id_raw))
Expand All @@ -392,6 +399,36 @@ def format_challenge(session, challenge, channel_id_type) -> bytes:

return data

def sign_challenge(data: bytes, signer_func: Callable):
"""
Sign the provided data using the provided signer.
:param data: challenge to sign
:param signer_func: The callable function to use for signing
:returns: A Deferred/Future that resolves to the computed signature.
:rtype: str
"""
# a raw byte string is signed, and the signature is also a raw byte string
d1 = signer_func(data)

# asyncio lacks callback chaining (and we cannot use co-routines, since we want
# to support older Pythons), hence we need d2
d2 = txaio.create_future()

def process(signature_raw):
# convert the raw signature into a hex encode value (unicode string)
signature_hex = binascii.b2a_hex(signature_raw).decode('ascii')

# we return the concatenation of the signature and the message signed (96 bytes)
data_hex = binascii.b2a_hex(data).decode('ascii')

sig = signature_hex + data_hex
txaio.resolve(d2, sig)

txaio.add_callbacks(d1, process, None)

return d2

class SigningKeyBase(object):

def __init__(self, signer, can_sign: bool) -> None:
Expand Down Expand Up @@ -422,28 +459,11 @@ def sign_challenge(self, session, challenge, channel_id_type='tls-unique'):
:returns: A Deferred/Future that resolves to the computed signature.
:rtype: str
"""
data = format_challenge(session, challenge, channel_id_type)

# a raw byte string is signed, and the signature is also a raw byte string
d1 = self.sign(data)

# asyncio lacks callback chaining (and we cannot use co-routines, since we want
# to support older Pythons), hence we need d2
d2 = txaio.create_future()

def process(signature_raw):
# convert the raw signature into a hex encode value (unicode string)
signature_hex = binascii.b2a_hex(signature_raw).decode('ascii')

# we return the concatenation of the signature and the message signed (96 bytes)
data_hex = binascii.b2a_hex(data).decode('ascii')

sig = signature_hex + data_hex
txaio.resolve(d2, sig)

txaio.add_callbacks(d1, process, None)
# get the TLS channel ID of the underlying TLS connection. Could be None.
channel_id_raw = session._transport.get_channel_id()
data = format_challenge(challenge, channel_id_raw, channel_id_type)

return d2
return sign_challenge(data, self.sign)

@util.public
def sign(self, data):
Expand Down
7 changes: 4 additions & 3 deletions deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ aws s3 rm s3://${AWS_S3_BUCKET_NAME}/wheels/autobahn-${AUTOBAHN_VERSION}-${AUTOB
aws s3 rm s3://${AWS_S3_BUCKET_NAME}/wheels/autobahn-${AUTOBAHN_VERSION}-py2.py3-none-any.whl
aws s3 rm s3://${AWS_S3_BUCKET_NAME}/wheels/autobahn-latest-py2.py3-none-any.whl

aws s3 cp --acl public-read ./dist/autobahn-${AUTOBAHN_VERSION}-py2.py3-none-any.whl s3://${AWS_S3_BUCKET_NAME}/wheels/autobahn-${AUTOBAHN_VERSION}-${AUTOBAHN_BUILD_ID}-py2.py3-none-any.whl
aws s3 cp --acl public-read ./dist/autobahn-${AUTOBAHN_VERSION}-py2.py3-none-any.whl s3://${AWS_S3_BUCKET_NAME}/wheels/autobahn-${AUTOBAHN_VERSION}-py2.py3-none-any.whl
aws s3 cp --acl public-read ./dist/autobahn-${AUTOBAHN_VERSION}-py2.py3-none-any.whl s3://${AWS_S3_BUCKET_NAME}/wheels/autobahn-latest-py2.py3-none-any.whl
aws s3 cp --acl public-read ./dist/autobahn-${AUTOBAHN_VERSION}-cp310-cp310-linux_x86_64.whl s3://${AWS_S3_BUCKET_NAME}/wheels/autobahn-${AUTOBAHN_VERSION}-${AUTOBAHN_BUILD_ID}-py2.py3-none-any.whl
aws s3 cp --acl public-read ./dist/autobahn-${AUTOBAHN_VERSION}-cp310-cp310-linux_x86_64.whl s3://${AWS_S3_BUCKET_NAME}/wheels/autobahn-${AUTOBAHN_VERSION}-py2.py3-none-any.whl
aws s3 cp --acl public-read ./dist/autobahn-${AUTOBAHN_VERSION}-cp310-cp310-linux_x86_64.whl s3://${AWS_S3_BUCKET_NAME}/wheels/autobahn-latest-py2.py3-none-any.whl
aws s3 cp --acl public-read ./dist/autobahn-${AUTOBAHN_VERSION}-cp310-cp310-linux_x86_64.whl s3://${AWS_S3_BUCKET_NAME}/wheels/autobahn-latest-cp310-cp310-linux_x86_64.whl

#aws s3api copy-object --acl public-read \
# --copy-source wheels/autobahn-${AUTOBAHN_VERSION}-py2.py3-none-any.whl --bucket ${AWS_S3_BUCKET_NAME} \
Expand Down

0 comments on commit 99794e8

Please sign in to comment.