Example #1
0
def test_encode_decode():
    key1 = bitjws.PrivateKey()
    pubkey1 = bitjws.pubkey_to_addr(key1.pubkey.serialize())
    key2 = bitjws.PrivateKey()
    pubkey2 = bitjws.pubkey_to_addr(key2.pubkey.serialize())

    ser = bitjws.multisig_sign_serialize([key1, key2])
    headers, payload = bitjws.multisig_validate_deserialize(ser)

    rawpayload = json.loads(ser)['payload']
    origpayload = bitjws.base64url_decode(rawpayload.encode('utf8'))

    keys_found = {pubkey1: False, pubkey2: False}
    assert len(headers) == 2
    for h in headers:
        assert len(h) == 3
        assert h['typ'] == 'JWT'
        assert h['alg'] == 'CUSTOM-BITCOIN-SIGN'
        assert h['kid'] in keys_found
        assert keys_found[h['kid']] == False
        keys_found[h['kid']] = True
    assert all(keys_found.values())

    assert isinstance(payload.get('exp', ''), (float, int))
    assert payload['aud'] is None
    assert len(payload) == 2
    assert payload == json.loads(origpayload.decode('utf8'))
Example #2
0
def test_encode_decode():
    key1 = bitjws.PrivateKey()
    pubkey1 = bitjws.pubkey_to_addr(key1.pubkey.serialize())
    key2 = bitjws.PrivateKey()
    pubkey2 = bitjws.pubkey_to_addr(key2.pubkey.serialize())

    ser = bitjws.multisig_sign_serialize([key1, key2])
    headers, payload = bitjws.multisig_validate_deserialize(ser)

    rawpayload = json.loads(ser)['payload']
    origpayload = bitjws.base64url_decode(rawpayload.encode('utf8'))

    keys_found = {pubkey1: False, pubkey2: False}
    assert len(headers) == 2
    for h in headers:
        assert len(h) == 3
        assert h['typ'] == 'JWT'
        assert h['alg'] == 'CUSTOM-BITCOIN-SIGN'
        assert h['kid'] in keys_found
        assert keys_found[h['kid']] == False
        keys_found[h['kid']] = True
    assert all(keys_found.values())

    assert isinstance(payload.get('exp', ''), (float, int))
    assert payload['aud'] is None
    assert len(payload) == 2
    assert payload == json.loads(origpayload.decode('utf8'))
Example #3
0
def test_invalid_algorithm():
    key1 = bitjws.PrivateKey()

    # Invalid algorithm name for signing.
    with pytest.raises(AssertionError):
        bitjws.sign_serialize(key1, algorithm_name='test')
    with pytest.raises(AssertionError):
        bitjws.multisig_sign_serialize([key1], algorithm_name='test')

    # Invalid algorithm name for verifying.
    ser = bitjws.sign_serialize(key1)
    with pytest.raises(AssertionError):
        bitjws.validate_deserialize(ser, algorithm_name='test')
    ser = bitjws.multisig_sign_serialize([key1])
    with pytest.raises(AssertionError):
        bitjws.multisig_validate_deserialize(ser, algorithm_name='test')
Example #4
0
def test_payload_expired():
    key = bitjws.PrivateKey()
    print(bitjws.privkey_to_wif(key.private_key))

    # expire_after must be greater than 0 or None.
    with pytest.raises(bitjws.jws.InvalidPayload):
        bitjws.sign_serialize(key, expire_after=0)

    ser = bitjws.sign_serialize(key, expire_after=0.01)
    time.sleep(0.02)
    with pytest.raises(bitjws.jws.InvalidPayload):
        # payload expired.
        bitjws.validate_deserialize(ser)

    # But the signature can still be verified and the msg decoded
    # if expiration checks are disabled.
    h, p = bitjws.validate_deserialize(ser, check_expiration=False)
    assert h and p

    # Check with multisig.
    ser = bitjws.multisig_sign_serialize([key], expire_after=0.01)
    time.sleep(0.02)
    with pytest.raises(bitjws.jws.InvalidPayload):
        # payload expired.
        bitjws.multisig_validate_deserialize(ser)
Example #5
0
def test_payload_nojson():
    key = bitjws.PrivateKey()

    # Use a payload that is not JSON encoded.
    ser = json.loads(bitjws.multisig_sign_serialize([key]))
    ser['payload'] = bitjws.base64url_encode(b'test').decode('utf8')

    # Sign the new payload.
    signdata = '{}.{}'.format(ser['signatures'][0]['protected'], ser['payload'])
    sig = bitjws.ALGORITHM_AVAILABLE['CUSTOM-BITCOIN-SIGN'].sign(
        key, signdata)
    sig64 = bitjws.base64url_encode(sig).decode('utf8')
    ser['signatures'][0]['signature'] = sig64

    serenc = json.dumps(ser)
    with pytest.raises(bitjws.InvalidMessage):
        # The new payload was not JSON encoded, so it cannot be
        # decoded as that.
        bitjws.multisig_validate_deserialize(serenc)
    # But we can get its raw value.
    headers, payload = bitjws.multisig_validate_deserialize(serenc,
        decode_payload=False)

    assert len(headers) == 1
    assert payload == b'test'
Example #6
0
def test_payload_nojson():
    key = bitjws.PrivateKey()

    # Use a payload that is not JSON encoded.
    ser = json.loads(bitjws.multisig_sign_serialize([key]))
    ser['payload'] = bitjws.base64url_encode(b'test').decode('utf8')

    # Sign the new payload.
    signdata = '{}.{}'.format(ser['signatures'][0]['protected'],
                              ser['payload'])
    sig = bitjws.ALGORITHM_AVAILABLE['CUSTOM-BITCOIN-SIGN'].sign(key, signdata)
    sig64 = bitjws.base64url_encode(sig).decode('utf8')
    ser['signatures'][0]['signature'] = sig64

    serenc = json.dumps(ser)
    with pytest.raises(bitjws.InvalidMessage):
        # The new payload was not JSON encoded, so it cannot be
        # decoded as that.
        bitjws.multisig_validate_deserialize(serenc)
    # But we can get its raw value.
    headers, payload = bitjws.multisig_validate_deserialize(
        serenc, decode_payload=False)

    assert len(headers) == 1
    assert payload == b'test'
Example #7
0
def test_invalid_algorithm():
    key1 = bitjws.PrivateKey()

    # Invalid algorithm name for signing.
    with pytest.raises(AssertionError):
        bitjws.sign_serialize(key1, algorithm_name='test')
    with pytest.raises(AssertionError):
        bitjws.multisig_sign_serialize([key1], algorithm_name='test')

    # Invalid algorithm name for verifying.
    ser = bitjws.sign_serialize(key1)
    with pytest.raises(AssertionError):
        bitjws.validate_deserialize(ser, algorithm_name='test')
    ser = bitjws.multisig_sign_serialize([key1])
    with pytest.raises(AssertionError):
        bitjws.multisig_validate_deserialize(ser, algorithm_name='test')
Example #8
0
def test_payload_expired():
    key = bitjws.PrivateKey()
    print(bitjws.privkey_to_wif(key.private_key))

    # expire_after must be greater than 0 or None.
    with pytest.raises(bitjws.jws.InvalidPayload):
        bitjws.sign_serialize(key, expire_after=0)

    ser = bitjws.sign_serialize(key, expire_after=0.01)
    time.sleep(0.02)
    with pytest.raises(bitjws.jws.InvalidPayload):
        # payload expired.
        bitjws.validate_deserialize(ser)

    # But the signature can still be verified and the msg decoded
    # if expiration checks are disabled.
    h, p = bitjws.validate_deserialize(ser, check_expiration=False)
    assert h and p

    # Check with multisig.
    ser = bitjws.multisig_sign_serialize([key], expire_after=0.01)
    time.sleep(0.02)
    with pytest.raises(bitjws.jws.InvalidPayload):
        # payload expired.
        bitjws.multisig_validate_deserialize(ser)
Example #9
0
def test_multisig_missingkeys():
    key = bitjws.PrivateKey()

    ser = bitjws.multisig_sign_serialize([key])
    # This should work.
    headers, payload = bitjws.multisig_validate_deserialize(ser)
    assert len(headers) == 1 and payload

    serobj = json.loads(ser)

    payload = serobj.pop('payload')
    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        # Key 'payload' is missing.
        bitjws.multisig_validate_deserialize(ser)

    serobj['payload'] = payload
    signatures = serobj.pop('signatures')
    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        # Key 'signatures' is missing.
        bitjws.multisig_validate_deserialize(ser)

    serobj['signatures'] = 'hello'
    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        # 'signatures' is not a list.
        bitjws.multisig_validate_deserialize(ser)

    del serobj['signatures']
    del serobj['payload']
    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        bitjws.multisig_validate_deserialize(ser)

    # Remove a key from one of the signatures.
    serobj['signatures'] = signatures
    serobj['payload'] = payload
    sig0 = serobj['signatures'][0].copy()

    del serobj['signatures'][0]['protected']
    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        # data['signatures'][0]['protected'] is missing
        bitjws.multisig_validate_deserialize(ser)

    serobj['signatures'][0] = sig0.copy()
    del serobj['signatures'][0]['signature']
    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        # data['signatures'][0]['signture'] is missing
        bitjws.multisig_validate_deserialize(ser)

    # Remove the only signature entry.
    serobj['signatures'].pop()
    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        # No signatures.
        bitjws.multisig_validate_deserialize(ser)
Example #10
0
def test_multisig_missingkeys():
    key = bitjws.PrivateKey()

    ser = bitjws.multisig_sign_serialize([key])
    # This should work.
    headers, payload = bitjws.multisig_validate_deserialize(ser)
    assert len(headers) == 1 and payload

    serobj = json.loads(ser)

    payload = serobj.pop('payload')
    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        # Key 'payload' is missing.
        bitjws.multisig_validate_deserialize(ser)

    serobj['payload'] = payload
    signatures = serobj.pop('signatures')
    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        # Key 'signatures' is missing.
        bitjws.multisig_validate_deserialize(ser)

    serobj['signatures'] = 'hello'
    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        # 'signatures' is not a list.
        bitjws.multisig_validate_deserialize(ser)

    del serobj['signatures']
    del serobj['payload']
    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        bitjws.multisig_validate_deserialize(ser)

    # Remove a key from one of the signatures.
    serobj['signatures'] = signatures
    serobj['payload'] = payload
    sig0 = serobj['signatures'][0].copy()

    del serobj['signatures'][0]['protected']
    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        # data['signatures'][0]['protected'] is missing
        bitjws.multisig_validate_deserialize(ser)

    serobj['signatures'][0] = sig0.copy()
    del serobj['signatures'][0]['signature']
    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        # data['signatures'][0]['signture'] is missing
        bitjws.multisig_validate_deserialize(ser)

    # Remove the only signature entry.
    serobj['signatures'].pop()
    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        # No signatures.
        bitjws.multisig_validate_deserialize(ser)
Example #11
0
def test_multisig_invalidsig():
    key = bitjws.PrivateKey()

    ser = bitjws.multisig_sign_serialize([key])
    assert all(bitjws.multisig_validate_deserialize(ser))

    serobj = json.loads(ser)
    dummy = bitjws.base64url_encode(b'a' * 88)
    serobj['signatures'][0]['signature'] = dummy.decode('utf8')

    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        # Invalid signature length.
        bitjws.multisig_validate_deserialize(ser)
Example #12
0
def test_multisig_invalidsig():
    key = bitjws.PrivateKey()

    ser = bitjws.multisig_sign_serialize([key])
    assert all(bitjws.multisig_validate_deserialize(ser))

    serobj = json.loads(ser)
    dummy = bitjws.base64url_encode(b'a' * 88)
    serobj['signatures'][0]['signature'] = dummy.decode('utf8')

    ser = json.dumps(serobj)
    with pytest.raises(bitjws.jws.InvalidMessage):
        # Invalid signature length.
        bitjws.multisig_validate_deserialize(ser)
Example #13
0
def test_multisig_partiallyinvalid():
    key1 = bitjws.PrivateKey()
    key2 = bitjws.PrivateKey()
    key3 = bitjws.PrivateKey()

    ser = bitjws.multisig_sign_serialize([key1, key2, key3])
    assert all(bitjws.multisig_validate_deserialize(ser))

    serobj = json.loads(ser)
    # Swap signatures.
    sig0 = serobj['signatures'][0]['signature']
    sig1 = serobj['signatures'][1]['signature']
    sig0, sig1 = sig1, sig0
    serobj['signatures'][0]['signature'] = sig0
    serobj['signatures'][1]['signature'] = sig1

    ser = json.dumps(serobj)
    headers, payload = bitjws.multisig_validate_deserialize(ser)
    assert headers is None
    assert payload is None
Example #14
0
def test_multisig_partiallyinvalid():
    key1 = bitjws.PrivateKey()
    key2 = bitjws.PrivateKey()
    key3 = bitjws.PrivateKey()

    ser = bitjws.multisig_sign_serialize([key1, key2, key3])
    assert all(bitjws.multisig_validate_deserialize(ser))

    serobj = json.loads(ser)
    # Swap signatures.
    sig0 = serobj['signatures'][0]['signature']
    sig1 = serobj['signatures'][1]['signature']
    sig0, sig1 = sig1, sig0
    serobj['signatures'][0]['signature'] = sig0
    serobj['signatures'][1]['signature'] = sig1

    ser = json.dumps(serobj)
    headers, payload = bitjws.multisig_validate_deserialize(ser)
    assert headers is None
    assert payload is None