Exemple #1
0
    def sign_stream_claim(self, claim, claim_address, cert_claim_id):
        validate_claim_id(cert_claim_id)
        decoded_addr = decode_address(claim_address)

        to_sign = bytearray()
        to_sign.extend(decoded_addr)
        to_sign.extend(claim.serialized_no_signature)
        to_sign.extend(binascii.unhexlify(cert_claim_id))

        digest = self.HASHFUNC(to_sign).digest()

        if not isinstance(self.private_key, ecdsa.SigningKey):
            raise Exception("Not given a signing key")
        sig_dict = {
            "version":
            V_0_0_1,
            "signatureType":
            self.CURVE_NAME,
            "signature":
            self.private_key.sign_digest_deterministic(digest,
                                                       hashfunc=self.HASHFUNC),
            "certificateId":
            binascii.unhexlify(cert_claim_id)
        }

        msg = {
            "version": V_0_0_1,
            "stream": decode_b64_fields(claim.protobuf_dict)['stream'],
            "publisherSignature": sig_dict
        }

        return Claim.load(msg)
Exemple #2
0
    def test_validate_what_cant_be_serialized_back_even_by_loading_back_from_dictionary(
            self):
        cert = ClaimDict.generate_certificate(secp256k1_private_key,
                                              curve=SECP256k1)
        self.assertDictEqual(cert.claim_dict, secp256k1_cert)
        original = ClaimDict.load_dict(example_010).serialized
        altered = original + b'\x00\x01\x02\x30\x50\x80\x99'  # pretend this extra trash is from some unknown protobuf

        # manually sign
        signer = get_signer(SECP256k1).load_pem(secp256k1_private_key)
        signature = signer.sign(
            b'example',
            decode_address(claim_address_2),
            altered,
            binascii.unhexlify(claim_id_1),
        )
        detached_sig = Signature(
            NAMED_SECP256K1(signature, binascii.unhexlify(claim_id_1),
                            altered))

        signed = detached_sig.serialized
        self.assertEqual(signed[85:], altered)
        signed_copy = ClaimDict.deserialize(signed)
        signed_copy = ClaimDict.load_dict(signed_copy.claim_dict)
        self.assertEqual(
            signed_copy.validate_signature(claim_address_2,
                                           cert,
                                           name='example'), True)
        self.assertEqual(signed, signed_copy.serialized)
Exemple #3
0
def decode_fields(claim_dictionary):
    """Decode hex and b58 encoded bytes in dictionaries given to ClaimDict"""
    claim_dictionary = deepcopy(claim_dictionary)
    claim_type = CLAIM_TYPES[claim_dictionary[CLAIM_TYPE]]
    claim_value = claim_dictionary[claim_type]
    if claim_type == CLAIM_TYPES[STREAM_TYPE]:
        claim_value['source']['source'] = binascii.unhexlify(
            claim_value['source']['source'])
        if 'fee' in claim_value['metadata']:
            try:
                address = decode_address(
                    claim_value['metadata']['fee']['address'])
            except InvalidAddress as err:
                raise DecodeError("Invalid fee address: %s" % err)
            claim_value['metadata']['fee']['address'] = address
    elif claim_type == CLAIM_TYPES[CERTIFICATE_TYPE]:
        public_key = binascii.unhexlify(claim_value["publicKey"])
        claim_value["publicKey"] = public_key
    if SIGNATURE in claim_dictionary:
        decoded_sig = binascii.unhexlify(
            claim_dictionary[SIGNATURE]['signature'])
        decoded_cert_id = binascii.unhexlify(
            claim_dictionary[SIGNATURE]['certificateId'])
        claim_dictionary[SIGNATURE]['signature'] = decoded_sig
        claim_dictionary[SIGNATURE]['certificateId'] = decoded_cert_id
    claim_dictionary[claim_type] = claim_value
    return claim_dictionary
Exemple #4
0
 def protobuf(self):
     pb = {
         "version": self.version,
         "currency": CURRENCY_MAP[self.currency],
         "address": decode_address(self.address),
         "amount": self.amount
     }
     return FeeHelper.load(pb)
Exemple #5
0
async def main(address: str):
    try:
        decode_address(address)
    except:
        print(f"'{address}' is not a valid lbrycrd address")
        return 1
    loop = asyncio.get_running_loop()

    storage = SQLiteStorage(os.path.expanduser("~/.lbrynet/lbrynet.sqlite"))
    await storage.open()
    blob_manager = BlobManager(loop, os.path.expanduser("~/.lbrynet/blobfiles"), storage)
    await blob_manager.setup()

    server = await loop.create_server(
        lambda: BlobServer(loop, blob_manager, address),
        '0.0.0.0', 4444)
    try:
        async with server:
            await server.serve_forever()
    finally:
        await storage.close()
Exemple #6
0
def migrate(fee):
    if len(list(fee.keys())) == 3 and 'currency' in fee and 'amount' in fee and 'address' in fee:
        return FeeHelper.load({
            "version": "_0_0_1",
            "currency": fee['currency'],
            "amount": fee['amount'],
            "address": decode_address(fee['address'])
        })
    if len(list(fee.keys())) > 1:
        raise Exception("Invalid fee")

    currency = list(fee.keys())[0]
    amount = fee[currency]['amount']
    address = fee[currency]['address']

    return FeeHelper.load({
        "version": "_0_0_1",
        "currency": currency,
        "amount": amount,
        "address": decode_address(address)
    })
Exemple #7
0
    def validate_claim_signature(self, claim, claim_address):
        decoded_address = decode_address(claim_address)

        # extract and serialize the stream from the claim, then check the signature
        signature = binascii.unhexlify(claim.signature)

        if signature is None:
            raise Exception("No signature to validate")

        to_sign = bytearray()
        to_sign.extend(decoded_address)
        to_sign.extend(claim.serialized_no_signature)
        to_sign.extend(binascii.unhexlify(self.certificate_claim_id))

        return self.validate_signature(self.HASHFUNC(to_sign).digest(), signature)
Exemple #8
0
    def sign_stream_claim(self,
                          claim,
                          claim_address,
                          cert_claim_id,
                          name,
                          detached=False):
        validate_claim_id(cert_claim_id)
        raw_cert_id = binascii.unhexlify(cert_claim_id)
        decoded_addr = decode_address(claim_address)
        if detached:
            assert name, "Name is required for detached signatures"
            assert self.CURVE_NAME == SECP256k1, f"Only SECP256k1 is supported, not: {self.CURVE_NAME}"
            signature = self.sign(
                name.lower().encode(),
                decoded_addr,
                claim.serialized_no_signature,
                raw_cert_id,
            )
        else:
            signature = self.sign(decoded_addr, claim.serialized_no_signature,
                                  raw_cert_id)

        if detached:
            return Claim.load(decode_b64_fields(
                claim.protobuf_dict)), Signature(
                    NAMED_SECP256K1(signature, raw_cert_id,
                                    claim.serialized_no_signature))
        # -- Legacy signer (signature inside protobuf) --

        if not isinstance(self.private_key, ecdsa.SigningKey):
            raise Exception("Not given a signing key")
        sig_dict = {
            "version": V_0_0_1,
            "signatureType": self.CURVE_NAME,
            "signature": signature,
            "certificateId": raw_cert_id
        }

        msg = {
            "version": V_0_0_1,
            "stream": decode_b64_fields(claim.protobuf_dict)['stream'],
            "publisherSignature": sig_dict
        }

        proto = Claim.load(msg)
        return proto, Signature.flagged_parse(proto.SerializeToString())
Exemple #9
0
    async def test_new_signature_model_from_unserializable_claim(self):
        address1, address2 = await self.account.receiving.get_addresses(
            limit=2, only_usable=True)
        sendtxid1 = await self.blockchain.send_to_address(address1, 5)
        sendtxid2 = await self.blockchain.send_to_address(address2, 5)
        await self.blockchain.generate(1)
        await asyncio.wait([
            self.on_transaction_id(sendtxid1),
            self.on_transaction_id(sendtxid2)
        ])

        self.assertEqual(d2l(await self.account.get_balance()), '10.0')

        cert, key = generate_certificate()
        cert_tx = await Transaction.claim('@bar', cert, l2d('1.0'), address1,
                                          [self.account], self.account)
        original = ClaimDict.load_dict(example_claim_dict).serialized
        altered = original + b'\x00\x01\x02\x30\x50\x80\x99'  # pretend this extra trash is from some unknown protobuf

        # manually sign
        signer = get_signer(SECP256k1).load_pem(key)
        signature = signer.sign(
            b'foo',
            decode_address(address1),
            altered,
            binascii.unhexlify(cert_tx.outputs[0].claim_id),
        )
        detached_sig = Signature(
            NAMED_SECP256K1(signature,
                            binascii.unhexlify(cert_tx.outputs[0].claim_id),
                            altered))
        claim_tx = await Transaction.claim('foo', detached_sig, l2d('1.0'),
                                           address1, [self.account],
                                           self.account)

        await self.broadcast(cert_tx)
        await self.broadcast(claim_tx)
        await self.ledger.wait(claim_tx)
        await self.blockchain.generate(1)
        await self.ledger.wait(claim_tx)

        response = await self.ledger.resolve(0, 10, 'lbry://@bar/foo')
        self.assertIn('lbry://@bar/foo', response)
        self.assertIn('claim', response['lbry://@bar/foo'])
Exemple #10
0
    def validate_claim_signature(self, claim, claim_address, name):
        to_sign = bytearray()
        if claim.detached_signature and claim.detached_signature.raw_signature:
            assert name is not None, "Name is required for verifying detached signatures."
            to_sign.extend(name.lower().encode())
            signature = claim.detached_signature.raw_signature
            payload = claim.detached_signature.payload
        else:
            # extract and serialize the stream from the claim, then check the signature
            signature = binascii.unhexlify(claim.signature)
            payload = claim.serialized_no_signature
        decoded_address = decode_address(claim_address)


        if signature is None:
            raise Exception("No signature to validate")

        to_sign.extend(decoded_address)
        to_sign.extend(payload)
        to_sign.extend(binascii.unhexlify(self.certificate_claim_id))

        return self.validate_signature(self.HASHFUNC(to_sign).digest(), signature)
Exemple #11
0
 def test_regtest_address_decode_error(self):
     with self.assertRaises(InvalidAddress):
         decode_address("bW5PZEvEBNPQRVhwpYXSjabFgbSw1oaHyR")
     with self.assertRaises(InvalidAddress):
         decode_address("mzGSynizDwSgURdnFjosZwakSVuZrdE8V5")
Exemple #12
0
 def test_regtest_address_encode_decode(self):
     valid_addr_hex = "6fcdac187757dbf05500f613ada6fdd953d59b9acbf3c9343f"
     self.assertEqual(encode_address(binascii.unhexlify(valid_addr_hex)),
                      b"mzGSynizDwSgURdnFjosZwakSVuZrdE8V4")
     self.assertEqual(decode_address("mzGSynizDwSgURdnFjosZwakSVuZrdE8V4"),
                      binascii.unhexlify(valid_addr_hex))
Exemple #13
0
 def test_mainnet_address_encode_decode(self):
     valid_addr_hex = "55be482f953ed0feda4fc5c4d012681b6119274993dc96bf10"
     self.assertEqual(encode_address(binascii.unhexlify(valid_addr_hex)),
                      b"bW5PZEvEBNPQRVhwpYXSjabFgbSw1oaHyR")
     self.assertEqual(decode_address("bW5PZEvEBNPQRVhwpYXSjabFgbSw1oaHyR"),
                      binascii.unhexlify(valid_addr_hex))