Esempio n. 1
0
    def _generate_batch(self, payload):
        payload_encoded = payload.encode('utf-8')
        hasher = hashlib.sha512()
        hasher.update(payload_encoded)

        header = TransactionHeader()
        header.batcher_pubkey = self.public_key
        # txn.dependencies not yet
        header.family_name = 'test'
        header.family_version = '1'
        header.nonce = _generate_id(16)
        header.payload_encoding = "text"
        header.payload_sha512 = hasher.hexdigest().encode()
        header.signer_pubkey = self.public_key

        txn = Transaction()
        header_bytes = header.SerializeToString()
        txn.header = header_bytes
        txn.header_signature = signing.sign(header_bytes, self.signing_key)
        txn.payload = payload_encoded

        batch_header = BatchHeader()
        batch_header.signer_pubkey = self.public_key
        batch_header.transaction_ids.extend([txn.header_signature])

        batch = Batch()
        header_bytes = batch_header.SerializeToString()
        batch.header = header_bytes
        batch.header_signature = signing.sign(header_bytes, self.signing_key)
        batch.transactions.extend([txn])
        return batch
Esempio n. 2
0
def _create_config_txn(pubkey, signing_key, setting_key_value):
    """Creates an individual sawtooth_config transaction for the given key and
    value.
    """
    setting_key = setting_key_value[0]
    setting_value = setting_key_value[1]
    nonce = str(datetime.datetime.utcnow().timestamp())
    proposal = ConfigProposal(setting=setting_key,
                              value=setting_value,
                              nonce=nonce)
    payload = ConfigPayload(data=proposal.SerializeToString(),
                            action=ConfigPayload.PROPOSE).SerializeToString()

    header = TransactionHeader(
        signer_pubkey=pubkey,
        family_name='sawtooth_config',
        family_version='1.0',
        inputs=_config_inputs(setting_key),
        outputs=_config_outputs(setting_key),
        dependencies=[],
        payload_encoding='application/protobuf',
        payload_sha512=hashlib.sha512(payload).hexdigest(),
        batcher_pubkey=pubkey).SerializeToString()

    signature = signing.sign(header, signing_key)

    return Transaction(header=header,
                       header_signature=signature,
                       payload=payload)
Esempio n. 3
0
def _do_config_set(args):
    """Executes the 'set' subcommand.  Given a key file, and a series of
    key/value pairs, it generates batches of sawtooth_config transactions in a
    BatchList instance, and stores it in a file.
    """
    settings = [s.split('=', 1) for s in args.setting]

    with open(args.key, 'r') as key_file:
        wif_key = key_file.read().strip()
        signing_key = signing.encode_privkey(
            signing.decode_privkey(wif_key, 'wif'), 'hex')
        pubkey = signing.encode_pubkey(signing.generate_pubkey(signing_key),
                                       'hex')

    txns = [
        _create_config_txn(pubkey, signing_key, setting)
        for setting in settings
    ]
    txn_ids = [txn.header_signature for txn in txns]

    batch_header = BatchHeader(signer_pubkey=pubkey,
                               transaction_ids=txn_ids).SerializeToString()

    batch = Batch(header=batch_header,
                  header_signature=signing.sign(batch_header, signing_key),
                  transactions=txns)

    batch_list = BatchList(batches=[batch]).SerializeToString()

    try:
        with open(args.output, 'wb') as batch_file:
            batch_file.write(batch_list)
    except:
        raise CliException('Unable to write to {}'.format(args.output))
Esempio n. 4
0
    def _create_batches(self, batch_count, txn_count,
                        valid_batch=True, valid_txn=True,
                        valid_batcher=True):

        batch_list = []

        for i in range(batch_count):
            txn_list = self._create_transactions(txn_count, valid_txn,
                                                 valid_batcher)
            txn_sig_list = [txn.header_signature for txn in txn_list]

            batch_header = BatchHeader(signer_pubkey=self.public_key)
            batch_header.transaction_ids.extend(txn_sig_list)

            header_bytes = batch_header.SerializeToString()

            if valid_batch:
                signature = signing.sign(
                    header_bytes,
                    self.private_key)
            else:
                signature = "bad_signature"

            batch = Batch(header=header_bytes,
                          transactions=txn_list,
                          header_signature=signature)

            batch_list.append(batch)

        return batch_list
    def test_deserialized_wait_timer(self):
        wait_timer = \
            EnclaveWaitTimer(
                validator_address='1600 Pennsylvania Avenue NW',
                duration=3.14159,
                previous_certificate_id='Bond.  James Bond.',
                local_mean=2.71828)

        serialized = wait_timer.serialize()
        signing_key = self._create_random_key()
        wait_timer.signature = \
            signing.sign(serialized, signing_key)

        copy_wait_timer = \
            EnclaveWaitTimer.wait_timer_from_serialized(
                serialized,
                wait_timer.signature)

        self.assertEqual(wait_timer.validator_address,
                         copy_wait_timer.validator_address)
        self.assertAlmostEqual(wait_timer.request_time,
                               copy_wait_timer.request_time)
        self.assertAlmostEqual(wait_timer.duration, copy_wait_timer.duration)
        self.assertEqual(wait_timer.previous_certificate_id,
                         copy_wait_timer.previous_certificate_id)
        self.assertAlmostEqual(wait_timer.local_mean,
                               copy_wait_timer.local_mean)
        self.assertEqual(wait_timer.signature, copy_wait_timer.signature)

        self.assertEqual(serialized, copy_wait_timer.serialize())
Esempio n. 6
0
    def _create_blocks(self, block_count, batch_count,
                       valid_block=True, valid_batch=True):
        block_list = []

        for i in range(block_count):
            batch_list = self._create_batches(
                batch_count, 2, valid_batch=valid_batch)
            batch_ids = [batch.header_signature for batch in batch_list]

            block_header = BlockHeader(signer_pubkey=self.public_key,
                                       batch_ids=batch_ids)

            header_bytes = block_header.SerializeToString()

            if valid_block:
                signature = signing.sign(
                    header_bytes,
                    self.private_key)
            else:
                signature = "bad_signature"

            block = Block(header=header_bytes,
                          batches=batch_list,
                          header_signature=signature)

            block_list.append(block)

        return block_list
Esempio n. 7
0
    def _create_blocks(self,
                       block_count,
                       batch_count,
                       valid_block=True,
                       valid_batch=True):
        block_list = []

        for i in range(block_count):
            batch_list = self._create_batches(batch_count,
                                              2,
                                              valid_batch=valid_batch)
            batch_ids = [batch.header_signature for batch in batch_list]

            block_header = BlockHeader(signer_pubkey=self.public_key,
                                       batch_ids=batch_ids)

            header_bytes = block_header.SerializeToString()

            if valid_block:
                signature = signing.sign(header_bytes, self.private_key)
            else:
                signature = "bad_signature"

            block = Block(header=header_bytes,
                          batches=batch_list,
                          header_signature=signature)

            block_list.append(block)

        return block_list
Esempio n. 8
0
def _create_config_txn(pubkey, signing_key, setting_key_value):
    """Creates an individual sawtooth_config transaction for the given key and
    value.
    """
    setting_key = setting_key_value[0]
    setting_value = setting_key_value[1]
    nonce = str(datetime.datetime.utcnow().timestamp())
    proposal = ConfigProposal(
        setting=setting_key,
        value=setting_value,
        nonce=nonce)
    payload = ConfigPayload(data=proposal.SerializeToString(),
                            action=ConfigPayload.PROPOSE).SerializeToString()

    header = TransactionHeader(
        signer_pubkey=pubkey,
        family_name='sawtooth_config',
        family_version='1.0',
        inputs=_config_inputs(setting_key),
        outputs=_config_outputs(setting_key),
        dependencies=[],
        payload_encoding='application/protobuf',
        payload_sha512=hashlib.sha512(payload).hexdigest(),
        batcher_pubkey=pubkey
    ).SerializeToString()

    signature = signing.sign(header, signing_key)

    return Transaction(
        header=header,
        header_signature=signature,
        payload=payload)
Esempio n. 9
0
def _do_config_set(args):
    """Executes the 'set' subcommand.  Given a key file, and a series of
    key/value pairs, it generates batches of sawtooth_config transactions in a
    BatchList instance, and stores it in a file.
    """
    settings = [s.split('=', 1) for s in args.setting]

    with open(args.key, 'r') as key_file:
        wif_key = key_file.read().strip()
        signing_key = signing.encode_privkey(
            signing.decode_privkey(wif_key, 'wif'), 'hex')
        pubkey = signing.encode_pubkey(
            signing.generate_pubkey(signing_key), 'hex')

    txns = [_create_config_txn(pubkey, signing_key, setting)
            for setting in settings]
    txn_ids = [txn.header_signature for txn in txns]

    batch_header = BatchHeader(signer_pubkey=pubkey,
                               transaction_ids=txn_ids).SerializeToString()

    batch = Batch(
        header=batch_header,
        header_signature=signing.sign(batch_header, signing_key),
        transactions=txns
    )

    batch_list = BatchList(batches=[batch]).SerializeToString()

    try:
        with open(args.output, 'wb') as batch_file:
            batch_file.write(batch_list)
    except:
        raise CliException('Unable to write to {}'.format(args.output))
Esempio n. 10
0
    def _create_batches(self,
                        batch_count,
                        txn_count,
                        valid_batch=True,
                        valid_txn=True,
                        valid_batcher=True):

        batch_list = []

        for i in range(batch_count):
            txn_list = self._create_transactions(txn_count, valid_txn,
                                                 valid_batcher)
            txn_sig_list = [txn.header_signature for txn in txn_list]

            batch_header = BatchHeader(signer_pubkey=self.public_key)
            batch_header.transaction_ids.extend(txn_sig_list)

            header_bytes = batch_header.SerializeToString()

            if valid_batch:
                signature = signing.sign(header_bytes, self.private_key)
            else:
                signature = "bad_signature"

            batch = Batch(header=header_bytes,
                          transactions=txn_list,
                          header_signature=signature)

            batch_list.append(batch)

        return batch_list
Esempio n. 11
0
    def _send_xo_txn(self, name, action, space=""):

        # Serialization is just a delimited utf-8 encoded string
        payload = ",".join([name, action, str(space)]).encode()

        # Construct the address
        address = self._get_address(name)

        header = TransactionHeader(
            signer_pubkey=self._public_key,
            family_name="xo",
            family_version="1.0",
            inputs=[address],
            outputs=[address],
            dependencies=[],
            payload_encoding="csv-utf8",
            payload_sha512=_sha512(payload),
            batcher_pubkey=self._public_key).SerializeToString()

        signature = signing.sign(header, self._private_key)

        transaction = Transaction(header=header,
                                  payload=payload,
                                  header_signature=signature)

        batch_list = self._create_batch_list([transaction])

        result = self._send_request("batches", batch_list.SerializeToString(),
                                    'application/octet-stream')

        return result
    def create_wait_timer(cls,
                          validator_address,
                          previous_certificate_id,
                          local_mean,
                          minimum_wait_time):
        with cls._lock:
            # If we don't have a PoET private key, then the enclave has not
            # been properly initialized (either by calling create_signup_info
            # or unseal_signup_data)
            if cls._poet_private_key is None:
                raise \
                    ValueError(
                        'Enclave must be initialized before attempting to '
                        'create a wait timer')

            # Create some value from the cert ID.  We are just going to use
            # the seal key to sign the cert ID.  We will then use the
            # low-order 64 bits to change that to a number [0, 1]
            tag = \
                base64.b64decode(
                    signing.sign(
                        previous_certificate_id,
                        cls._seal_private_key))

            tagd = float(struct.unpack('Q', tag[-8:])[0]) / (2**64 - 1)

            # Now compute the duration with a minimum wait time guaranteed
            duration = minimum_wait_time - local_mean * math.log(tagd)

            # Create and sign the wait timer
            wait_timer = \
                EnclaveWaitTimer(
                    validator_address=validator_address,
                    duration=duration,
                    previous_certificate_id=previous_certificate_id,
                    local_mean=local_mean)
            wait_timer.signature = \
                signing.sign(
                    wait_timer.serialize(),
                    cls._poet_private_key)

            # Keep track of the active wait timer
            cls._active_wait_timer = wait_timer

            return wait_timer
Esempio n. 13
0
    def _generate_genesis_block(self):
        genesis_header = BlockHeader(previous_block_id=NULL_BLOCK_IDENTIFIER,
                                     signer_pubkey=self.public_key,
                                     block_num=0)

        block = BlockBuilder(genesis_header)
        block.add_batches([self._generate_batch("Genesis")])
        header_bytes = block.block_header.SerializeToString()
        signature = signing.sign(header_bytes, self.signing_key)
        block.set_signature(signature)
        return BlockWrapper(block.build_block())
Esempio n. 14
0
    def _create_batch_list(self, transactions):
        transaction_signatures = [t.header_signature for t in transactions]

        header = BatchHeader(
            signer_pubkey=self._public_key,
            transaction_ids=transaction_signatures).SerializeToString()

        signature = signing.sign(header, self._private_key)

        batch = Batch(header=header,
                      transactions=transactions,
                      header_signature=signature)
        return BatchList(batches=[batch])
    def test_deserialized_wait_certificate(self):
        wait_timer = \
            EnclaveWaitTimer(
                validator_address='1600 Pennsylvania Avenue NW',
                duration=3.14159,
                previous_certificate_id='Smart, Maxwell Smart',
                local_mean=2.71828)

        wait_certificate = \
            EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                wait_timer=wait_timer,
                nonce='Eeny, meeny, miny, moe.',
                block_digest='Indigestion. Pepto Bismol.')

        serialized = wait_certificate.serialize()
        signing_key = self._create_random_key()
        wait_certificate.signature = \
            signing.sign(serialized, signing_key)

        copy_wait_certificate = \
            EnclaveWaitCertificate.wait_certificate_from_serialized(
                serialized,
                wait_certificate.signature)

        self.assertAlmostEqual(
            wait_certificate.request_time,
            copy_wait_certificate.request_time)
        self.assertAlmostEqual(
            wait_certificate.duration,
            copy_wait_certificate.duration)
        self.assertEqual(
            wait_certificate.previous_certificate_id,
            copy_wait_certificate.previous_certificate_id)
        self.assertAlmostEqual(
            wait_certificate.local_mean,
            copy_wait_certificate.local_mean)
        self.assertEqual(
            wait_certificate.validator_address,
            copy_wait_certificate.validator_address)
        self.assertEqual(
            wait_certificate.nonce,
            copy_wait_certificate.nonce)
        self.assertEqual(
            wait_certificate.block_digest,
            copy_wait_certificate.block_digest)
        self.assertEqual(
            wait_certificate.signature,
            copy_wait_certificate.signature)

        self.assertEqual(serialized, copy_wait_certificate.serialize())
Esempio n. 16
0
def _sign_message_with_transaction(transaction, message_type, key):
    """
    Signs a transaction message or transaction
    :param transaction (dict):
    :param key (str): A signing key
    returns message, txnid (tuple): The first 16 characters
    of a sha256 hexdigest.
    """
    transaction['Nonce'] = time.time()
    pub = signing.encode_pubkey(signing.generate_pubkey(key), "hex")
    transaction["PublicKey"] = pub
    sig = signing.sign(_dict2cbor(transaction), key)
    transaction['Signature'] = sig

    txnid = hashlib.sha256(transaction['Signature'].encode()).hexdigest()[:16]
    message = {
        'Transaction': transaction,
        '__TYPE__': message_type,
        '__NONCE__': time.time(),
    }
    cbor_serialized_message = _dict2cbor(message)
    signature = signing.sign(cbor_serialized_message, key)
    message['__SIGNATURE__'] = signature
    return message, txnid
Esempio n. 17
0
    def sign_object(self, signingkey):
        """Generates a string signature for the object using the signing
        key.

        Args:
            signingkey (str): hex encoded private key
        """

        self._originator_id = None
        serialized = self.serialize(signable=True)
        self.Signature = signing.sign(bytes(serialized), signingkey)

        self._recover_verifying_address()
        self._identifier = hashlib.sha256(
            self.Signature.encode()).hexdigest()
Esempio n. 18
0
def _sign_message_with_transaction(transaction, message_type, key):
    """
    Signs a transaction message or transaction
    :param transaction (dict):
    :param key (str): A signing key
    returns message, txnid (tuple): The first 16 characters
    of a sha256 hexdigest.
    """
    transaction['Nonce'] = time.time()
    pub = signing.encode_pubkey(signing.generate_pubkey(key), "hex")
    transaction["PublicKey"] = pub
    sig = signing.sign(_dict2cbor(transaction), key)
    transaction['Signature'] = sig

    txnid = hashlib.sha256(transaction['Signature'].encode()).hexdigest()[:16]
    message = {
        'Transaction': transaction,
        '__TYPE__': message_type,
        '__NONCE__': time.time(),
    }
    cbor_serialized_message = _dict2cbor(message)
    signature = signing.sign(cbor_serialized_message, key)
    message['__SIGNATURE__'] = signature
    return message, txnid
Esempio n. 19
0
    def _sign_block(self, block):
        """ The block should be complete and the final
        signature from the publishing validator (this validator) needs to
        be added.
        """
        public_key = signing.encode_pubkey(
            signing.generate_pubkey(self._identity_priv_key), "hex")

        block.block_header.signer_pubkey = public_key
        block_header = block.block_header
        header_bytes = block_header.SerializeToString()
        signature = signing.sign(
            header_bytes,
            self._identity_priv_key)
        block.set_signature(signature)
        return block
Esempio n. 20
0
    def test_invalid_verfication_report(self):
        """
        Test that a transaction whose verication report is invalid returns an
        invalid transaction.
        """
        signup_info = self.factory.create_signup_info(self.factory.pubkey_hash,
                                                      "000")

        # Verifcation Report is None
        proof_data = signup_info.proof_data
        signup_info.proof_data = json.dumps({})
        self._test_bad_signup_info(signup_info)

        # ------------------------------------------------------
        # No verification signature
        proof_data_dict = json.loads(proof_data)
        del proof_data_dict["signature"]

        signup_info.proof_data = json.dumps(proof_data_dict)

        self._test_bad_signup_info(signup_info)

        # ------------------------------------------------------
        # Bad verification signature
        proof_data_dict["signature"] = "bads"

        signup_info.proof_data = json.dumps(proof_data_dict)

        self._test_bad_signup_info(signup_info)

        # ------------------------------------------------------
        # No Nonce
        verification_report = \
            json.loads(proof_data_dict["verification_report"])

        verification_report["nonce"] = None
        proof_data_dict = {
            'verification_report':
            json.dumps(verification_report),
            'signature':
            signing.sign(json.dumps(verification_report),
                         self._report_private_key)
        }

        signup_info.proof_data = json.dumps(proof_data_dict)

        self._test_bad_signup_info(signup_info)
Esempio n. 21
0
    def _create_transactions(self, count, valid=True, valid_batcher=True):
        txn_list = []

        for i in range(count):
            payload = {'Verb': 'set',
                       'Name': 'name' + str(random.randint(0, 100)),
                       'Value': random.randint(0, 100)}
            intkey_prefix = \
                hashlib.sha512('intkey'.encode('utf-8')).hexdigest()[0:6]

            addr = intkey_prefix + \
                hashlib.sha512(payload["Name"].encode('utf-8')).hexdigest()

            payload_encode = hashlib.sha512(cbor.dumps(payload)).hexdigest()

            header = TransactionHeader(
                signer_pubkey=self.public_key,
                family_name='intkey',
                family_version='1.0',
                inputs=[addr],
                outputs=[addr],
                dependencies=[],
                payload_encoding="application/cbor",
                payload_sha512=payload_encode)

            if valid_batcher:
                header.batcher_pubkey = self.public_key
            else:
                header.batcher_pubkey = "bad_batcher"

            header_bytes = header.SerializeToString()

            if valid:
                signature = signing.sign(
                    header_bytes,
                    self.private_key)
            else:
                signature = "bad_signature"

            transaction = Transaction(
                header=header_bytes,
                payload=cbor.dumps(payload),
                header_signature=signature)

            txn_list.append(transaction)

        return txn_list
Esempio n. 22
0
    def _sign_block(block):
        """ The block should be complete and the final
        signature from the publishing validator (this validator) needs to
        be added.
        """
        temp_key = signing.generate_privkey()
        public_key = signing.encode_pubkey(
            signing.generate_pubkey(temp_key), "hex")

        block.block_header.signer_pubkey = public_key
        block_header = block.block_header
        header_bytes = block_header.SerializeToString()
        signature = signing.sign(
            header_bytes,
            temp_key)
        block.set_signature(signature)
        return block
Esempio n. 23
0
    def _create_transactions(self, count, valid=True, valid_batcher=True):
        txn_list = []

        for i in range(count):
            payload = {
                'Verb': 'set',
                'Name': 'name' + str(random.randint(0, 100)),
                'Value': random.randint(0, 100)
            }
            intkey_prefix = \
                hashlib.sha512('intkey'.encode('utf-8')).hexdigest()[0:6]

            addr = intkey_prefix + \
                hashlib.sha512(payload["Name"].encode('utf-8')).hexdigest()

            payload_encode = hashlib.sha512(cbor.dumps(payload)).hexdigest()

            header = TransactionHeader(signer_pubkey=self.public_key,
                                       family_name='intkey',
                                       family_version='1.0',
                                       inputs=[addr],
                                       outputs=[addr],
                                       dependencies=[],
                                       payload_encoding="application/cbor",
                                       payload_sha512=payload_encode)

            if valid_batcher:
                header.batcher_pubkey = self.public_key
            else:
                header.batcher_pubkey = "bad_batcher"

            header_bytes = header.SerializeToString()

            if valid:
                signature = signing.sign(header_bytes, self.private_key)
            else:
                signature = "bad_signature"

            transaction = Transaction(header=header_bytes,
                                      payload=cbor.dumps(payload),
                                      header_signature=signature)

            txn_list.append(transaction)

        return txn_list
    def test_is_valid_pub_key(self):
        pubkey = signing.generate_pubkey("5KQ4iQQGgbQX9MmfiPUwwHBL1R"
                                         "GPa86NwFbqrWoodjuzruqFVDd")
        pub = signing.encode_pubkey(pubkey, "hex")
        minfo = {'Nonce': 100, 'PublicKey': pub,
                 'TransactionType': '/Transaction', 'Dependencies': []}
        sig = signing.sign(
            signed_object.dict2cbor(minfo),
            "5KQ4iQQGgbQX9MmfiPUwwHBL1RGPa86NwFbqrWoodjuzruqFVDd"
        )
        # Create valid transaction
        minfo["Signature"] = sig
        temp = Transaction(minfo)
        self.assertTrue(temp.is_valid("unused"))

        # Change transaction after it was signed
        minfo["Nonce"] = time.time()
        temp = Transaction(minfo)
        self.assertFalse(temp.is_valid("unused"))
    def test_deserialized_wait_certificate(self):
        wait_timer = \
            EnclaveWaitTimer(
                validator_address='1600 Pennsylvania Avenue NW',
                duration=3.14159,
                previous_certificate_id='Smart, Maxwell Smart',
                local_mean=2.71828)

        wait_certificate = \
            EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                wait_timer=wait_timer,
                nonce='Eeny, meeny, miny, moe.',
                block_digest='Indigestion. Pepto Bismol.')

        serialized = wait_certificate.serialize()
        signing_key = self._create_random_key()
        wait_certificate.signature = \
            signing.sign(serialized, signing_key)

        copy_wait_certificate = \
            EnclaveWaitCertificate.wait_certificate_from_serialized(
                serialized,
                wait_certificate.signature)

        self.assertAlmostEqual(wait_certificate.request_time,
                               copy_wait_certificate.request_time)
        self.assertAlmostEqual(wait_certificate.duration,
                               copy_wait_certificate.duration)
        self.assertEqual(wait_certificate.previous_certificate_id,
                         copy_wait_certificate.previous_certificate_id)
        self.assertAlmostEqual(wait_certificate.local_mean,
                               copy_wait_certificate.local_mean)
        self.assertEqual(wait_certificate.validator_address,
                         copy_wait_certificate.validator_address)
        self.assertEqual(wait_certificate.nonce, copy_wait_certificate.nonce)
        self.assertEqual(wait_certificate.block_digest,
                         copy_wait_certificate.block_digest)
        self.assertEqual(wait_certificate.signature,
                         copy_wait_certificate.signature)

        self.assertEqual(serialized, copy_wait_certificate.serialize())
Esempio n. 26
0
    def test_is_valid_pub_key(self):
        pubkey = signing.generate_pubkey("5KQ4iQQGgbQX9MmfiPUwwHBL1R"
                                         "GPa86NwFbqrWoodjuzruqFVDd")
        pub = signing.encode_pubkey(pubkey, "hex")
        minfo = {
            'Nonce': 100,
            'PublicKey': pub,
            'TransactionType': '/Transaction',
            'Dependencies': []
        }
        sig = signing.sign(
            signed_object.dict2cbor(minfo),
            "5KQ4iQQGgbQX9MmfiPUwwHBL1RGPa86NwFbqrWoodjuzruqFVDd")
        # Create valid transaction
        minfo["Signature"] = sig
        temp = Transaction(minfo)
        self.assertTrue(temp.is_valid("unused"))

        # Change transaction after it was signed
        minfo["Nonce"] = time.time()
        temp = Transaction(minfo)
        self.assertFalse(temp.is_valid("unused"))
    def test_deserialized_wait_timer(self):
        wait_timer = \
            EnclaveWaitTimer(
                validator_address='1600 Pennsylvania Avenue NW',
                duration=3.14159,
                previous_certificate_id='Bond.  James Bond.',
                local_mean=2.71828)

        serialized = wait_timer.serialize()
        signing_key = self._create_random_key()
        wait_timer.signature = \
            signing.sign(serialized, signing_key)

        copy_wait_timer = \
            EnclaveWaitTimer.wait_timer_from_serialized(
                serialized,
                wait_timer.signature)

        self.assertEqual(
            wait_timer.validator_address,
            copy_wait_timer.validator_address)
        self.assertAlmostEqual(
            wait_timer.request_time,
            copy_wait_timer.request_time)
        self.assertAlmostEqual(
            wait_timer.duration,
            copy_wait_timer.duration)
        self.assertEqual(
            wait_timer.previous_certificate_id,
            copy_wait_timer.previous_certificate_id)
        self.assertAlmostEqual(
            wait_timer.local_mean,
            copy_wait_timer.local_mean)
        self.assertEqual(
            wait_timer.signature,
            copy_wait_timer.signature)

        self.assertEqual(serialized, copy_wait_timer.serialize())
Esempio n. 28
0
    def create_signup_info(self, originator_public_key_hash,
                           most_recent_wait_certificate_id):
        # First we need to create a public/private key pair for the PoET
        # enclave to use.
        _poet_private_key = \
            "1f70fa2518077ad18483f48e77882d11983b537fa5f7cf158684d2c670fe4f1f"
        _poet_public_key = \
            signing.generate_pubkey(_poet_private_key)
        # currently not used
        # _active_wait_timer = None

        _report_private_key = \
            signing.encode_privkey(
                signing.decode_privkey(
                    '5Jz5Kaiy3kCiHE537uXcQnJuiNJshf2bZZn43CrALMGoCd3zRuo',
                    'wif'), 'hex')

        # We are going to fake out the sealing the signup data.
        signup_data = {
            'poet_public_key': signing.encode_pubkey(_poet_public_key, 'hex'),
            'poet_private_key': signing.encode_privkey(_poet_private_key,
                                                       'hex')
        }

        # Create a fake report
        report_data = '{0}{1}'.format(
            originator_public_key_hash.upper(),
            signing.encode_pubkey(_poet_public_key, 'hex').upper())
        quote = {
            'report_body':
            hashlib.sha256(json.dumps(report_data).encode()).hexdigest()
        }

        # Fake our "proof" data.
        verification_report = {
            'id':
            base64.b64encode(
                bytes(
                    hashlib.sha256(b'2017-02-16T15:21:24.437048').hexdigest().
                    encode())).decode(),
            'isvEnclaveQuoteStatus':
            'OK',
            'isvEnclaveQuoteBody':
            base64.b64encode(json.dumps(quote).encode()).decode(),
            'pseManifestStatus':
            'OK',
            'pseManifestHash':
            base64.b64encode(
                hashlib.sha256(
                    bytes(
                        b'Do you believe in '
                        b'manifest destiny?')).hexdigest().encode()).decode(),
            'nonce':
            most_recent_wait_certificate_id
        }

        proof_data_dict = {
            'verification_report':
            json.dumps(verification_report),
            'signature':
            signing.sign(json.dumps(verification_report), _report_private_key)
        }
        proof_data = json.dumps(proof_data_dict)

        return \
            SignUpInfo(
                poet_public_key=signup_data['poet_public_key'],
                proof_data=proof_data,
                anti_sybil_id=originator_public_key_hash)
Esempio n. 29
0
    def test_invalid_pse_manifest(self):
        """
        Test that a transaction whose pse_manifast is invalid returns an
        invalid transaction.
        """
        signup_info = self.factory.create_signup_info(self.factory.pubkey_hash,
                                                      "000")

        proof_data = signup_info.proof_data
        proof_data_dict = json.loads(proof_data)

        # ------------------------------------------------------
        # no pseManifestStatus
        verification_report = \
            json.loads(proof_data_dict["verification_report"])
        pse_status = verification_report['pseManifestStatus']
        verification_report['pseManifestStatus'] = None
        proof_data_dict = {
            'verification_report':
            json.dumps(verification_report),
            'signature':
            signing.sign(json.dumps(verification_report),
                         self._report_private_key)
        }

        signup_info.proof_data = json.dumps(proof_data_dict)

        self._test_bad_signup_info(signup_info)

        # ------------------------------------------------------
        # Bad  pseManifestStatus
        verification_report = \
            json.loads(proof_data_dict["verification_report"])
        verification_report['pseManifestStatus'] = "bad"
        proof_data_dict = {
            'verification_report':
            json.dumps(verification_report),
            'signature':
            signing.sign(json.dumps(verification_report),
                         self._report_private_key)
        }

        signup_info.proof_data = json.dumps(proof_data_dict)

        self._test_bad_signup_info(signup_info)

        # ------------------------------------------------------
        # No pseManifestHash
        verification_report = \
            json.loads(proof_data_dict["verification_report"])
        verification_report['pseManifestStatus'] = pse_status
        verification_report['pseManifestHash'] = None
        proof_data_dict = {
            'verification_report':
            json.dumps(verification_report),
            'signature':
            signing.sign(json.dumps(verification_report),
                         self._report_private_key)
        }

        signup_info.proof_data = json.dumps(proof_data_dict)

        self._test_bad_signup_info(signup_info)

        # ------------------------------------------------------
        # Bad pseManifestHash
        verification_report = \
            json.loads(proof_data_dict["verification_report"])
        verification_report['pseManifestHash'] = "Bad"
        proof_data_dict = {
            'verification_report':
            json.dumps(verification_report),
            'signature':
            signing.sign(json.dumps(verification_report),
                         self._report_private_key)
        }

        signup_info.proof_data = json.dumps(proof_data_dict)

        self._test_bad_signup_info(signup_info)
    def create_signup_info(cls, originator_public_key_hash,
                           most_recent_wait_certificate_id):
        with cls._lock:
            # First we need to create a public/private key pair for the PoET
            # enclave to use.
            cls._poet_private_key = signing.generate_privkey()
            cls._poet_public_key = \
                signing.generate_pubkey(cls._poet_private_key)
            cls._active_wait_timer = None

            # We are going to fake out the sealing the signup data.
            signup_data = {
                'poet_public_key':
                signing.encode_pubkey(cls._poet_public_key, 'hex'),
                'poet_private_key':
                signing.encode_privkey(cls._poet_private_key, 'hex')
            }
            sealed_signup_data = \
                base64.b64encode(bytes(dict2json(signup_data).encode()))

            # Create a fake report
            report_data = '{0}{1}'.format(
                originator_public_key_hash.upper(),
                signing.encode_pubkey(cls._poet_public_key, 'hex').upper())
            quote = {
                'report_body':
                hashlib.sha256(dict2json(report_data).encode()).hexdigest()
            }

            # Fake our "proof" data.
            verification_report = {
                'id':
                base64.b64encode(
                    bytes(
                        hashlib.sha256(datetime.datetime.now().isoformat(
                        ).encode()).hexdigest().encode())).decode(),
                'isvEnclaveQuoteStatus':
                'OK',
                'isvEnclaveQuoteBody':
                base64.b64encode(dict2json(quote).encode()).decode(),
                'pseManifestStatus':
                'OK',
                'pseManifestHash':
                base64.b64encode(
                    hashlib.sha256(
                        bytes(b'Do you believe in '
                              b'manifest destiny?')).hexdigest().encode()).
                decode(),
                'nonce':
                most_recent_wait_certificate_id
            }

            proof_data_dict = {
                'verification_report':
                dict2json(verification_report),
                'signature':
                signing.sign(dict2json(verification_report),
                             cls._report_private_key)
            }
            proof_data = dict2json(proof_data_dict)

            return \
                EnclaveSignupInfo(
                    poet_public_key=signup_data['poet_public_key'],
                    proof_data=proof_data,
                    anti_sybil_id=originator_public_key_hash,
                    sealed_signup_data=sealed_signup_data)
    def create_wait_certificate(cls,
                                wait_timer,
                                block_digest):
        with cls._lock:
            # If we don't have a PoET private key, then the enclave has not
            # been properly initialized (either by calling create_signup_info
            # or unseal_signup_data)
            if cls._poet_private_key is None:
                raise \
                    ValueError(
                        'Enclave must be initialized before attempting to '
                        'create a wait certificate')

            # Several criteria need to be met before we can create a wait
            # certificate:
            # 1. We have an active timer
            # 2. The caller's wait timer is the active wait timer.  We are not
            #    going to rely the objects, being the same, but will compute
            #    a signature over the object and verify that the signatures
            #    are the same.
            # 3. The active timer has expired
            # 4. The active timer has not timed out
            #
            # Note - we make a concession for the genesis block (i.e., a wait
            # timer for which the previous certificate ID is the Null
            # identifier) in that we don't require the timer to have expired
            # and we don't worry about the timer having timed out.
            if cls._active_wait_timer is None:
                raise \
                    ValueError(
                        'There is not a current enclave active wait timer')

            if wait_timer is None or \
                    cls._active_wait_timer.signature != \
                    signing.sign(
                        wait_timer.serialize(),
                        cls._poet_private_key):
                raise \
                    ValueError(
                        'Validator is not using the current wait timer')

            is_not_genesis_block = \
                (cls._active_wait_timer.previous_certificate_id !=
                 NullIdentifier)

            now = time.time()
            expire_time = \
                cls._active_wait_timer.request_time + \
                cls._active_wait_timer.duration

            if is_not_genesis_block and now < expire_time:
                raise \
                    ValueError(
                        'Cannot create wait certificate because timer has '
                        'not expired')

            time_out_time = \
                cls._active_wait_timer.request_time + \
                cls._active_wait_timer.duration + \
                TIMER_TIMEOUT_PERIOD

            if is_not_genesis_block and time_out_time < now:
                raise \
                    ValueError(
                        'Cannot create wait certificate because timer '
                        'has timed out')

            # Create a random nonce for the certificate.  For our "random"
            # nonce we will take the timer signature, concat that with the
            # current time, JSON-ize it and create a SHA-256 hash over it.
            # Probably not considered random by security professional
            # standards, but it is good enough for the simulator.
            random_string = \
                dict2json({
                    'wait_timer_signature': cls._active_wait_timer.signature,
                    'now': datetime.datetime.utcnow().isoformat()
                })
            nonce = hashlib.sha256(random_string.encode()).hexdigest()

            # First create a new enclave wait certificate using the data
            # provided and then sign the certificate with the PoET private key
            wait_certificate = \
                EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                    wait_timer=cls._active_wait_timer,
                    nonce=nonce,
                    block_digest=block_digest)
            wait_certificate.signature = \
                signing.sign(
                    wait_certificate.serialize(),
                    cls._poet_private_key)

            # Now that we have created the certificate, we no longer have an
            # active timer
            cls._active_wait_timer = None

            return wait_certificate
    def create_wait_certificate(cls, wait_timer, block_digest):
        with cls._lock:
            # If we don't have a PoET private key, then the enclave has not
            # been properly initialized (either by calling create_signup_info
            # or unseal_signup_data)
            if cls._poet_private_key is None:
                raise \
                    ValueError(
                        'Enclave must be initialized before attempting to '
                        'create a wait certificate')

            # Several criteria need to be met before we can create a wait
            # certificate:
            # 1. We have an active timer
            # 2. The caller's wait timer is the active wait timer.  We are not
            #    going to rely the objects, being the same, but will compute
            #    a signature over the object and verify that the signatures
            #    are the same.
            # 3. The active timer has expired
            # 4. The active timer has not timed out
            #
            # Note - we make a concession for the genesis block (i.e., a wait
            # timer for which the previous certificate ID is the Null
            # identifier) in that we don't require the timer to have expired
            # and we don't worry about the timer having timed out.
            if cls._active_wait_timer is None:
                raise \
                    ValueError(
                        'There is not a current enclave active wait timer')

            if wait_timer is None or \
                    cls._active_wait_timer.signature != \
                    signing.sign(
                        wait_timer.serialize(),
                        cls._poet_private_key):
                raise \
                    ValueError(
                        'Validator is not using the current wait timer')

            is_not_genesis_block = \
                (cls._active_wait_timer.previous_certificate_id !=
                 NULL_BLOCK_IDENTIFIER)

            now = time.time()
            expire_time = \
                cls._active_wait_timer.request_time + \
                cls._active_wait_timer.duration

            if is_not_genesis_block and now < expire_time:
                raise \
                    ValueError(
                        'Cannot create wait certificate because timer has '
                        'not expired')

            time_out_time = \
                cls._active_wait_timer.request_time + \
                cls._active_wait_timer.duration + \
                TIMER_TIMEOUT_PERIOD

            if is_not_genesis_block and time_out_time < now:
                raise \
                    ValueError(
                        'Cannot create wait certificate because timer '
                        'has timed out')

            # Create a random nonce for the certificate.  For our "random"
            # nonce we will take the timer signature, concat that with the
            # current time, JSON-ize it and create a SHA-256 hash over it.
            # Probably not considered random by security professional
            # standards, but it is good enough for the simulator.
            random_string = \
                dict2json({
                    'wait_timer_signature': cls._active_wait_timer.signature,
                    'now': datetime.datetime.utcnow().isoformat()
                })
            nonce = hashlib.sha256(random_string.encode()).hexdigest()

            # First create a new enclave wait certificate using the data
            # provided and then sign the certificate with the PoET private key
            wait_certificate = \
                EnclaveWaitCertificate.wait_certificate_with_wait_timer(
                    wait_timer=cls._active_wait_timer,
                    nonce=nonce,
                    block_digest=block_digest)
            wait_certificate.signature = \
                signing.sign(
                    wait_certificate.serialize(),
                    cls._poet_private_key)

            # Now that we have created the certificate, we no longer have an
            # active timer
            cls._active_wait_timer = None

            return wait_certificate
Esempio n. 33
0
    def test_invalid_envalve_body(self):
        """
        Test that a transaction whose enclave_body is invalid returns an
        invalid transaction.
        """
        signup_info = self.factory.create_signup_info(self.factory.pubkey_hash,
                                                      "000")

        proof_data = signup_info.proof_data
        proof_data_dict = json.loads(proof_data)

        # ------------------------------------------------------
        # No isvEnclaveQuoteStatus
        verification_report = \
            json.loads(proof_data_dict["verification_report"])
        enclave_status = verification_report["isvEnclaveQuoteStatus"]
        verification_report["isvEnclaveQuoteStatus"] = None
        proof_data_dict = {
            'verification_report':
            json.dumps(verification_report),
            'signature':
            signing.sign(json.dumps(verification_report),
                         self._report_private_key)
        }

        signup_info.proof_data = json.dumps(proof_data_dict)

        self._test_bad_signup_info(signup_info)

        # ------------------------------------------------------
        # No isvEnclaveQuoteStatus
        verification_report = \
            json.loads(proof_data_dict["verification_report"])
        verification_report["isvEnclaveQuoteStatus"] = "Bad"
        proof_data_dict = {
            'verification_report':
            json.dumps(verification_report),
            'signature':
            signing.sign(json.dumps(verification_report),
                         self._report_private_key)
        }

        signup_info.proof_data = json.dumps(proof_data_dict)

        self._test_bad_signup_info(signup_info)

        # ------------------------------------------------------
        # No isvEnclaveQuoteBody
        verification_report = \
            json.loads(proof_data_dict["verification_report"])
        verification_report["isvEnclaveQuoteStatus"] = enclave_status
        verification_report['isvEnclaveQuoteBody'] = None
        proof_data_dict = {
            'verification_report':
            json.dumps(verification_report),
            'signature':
            signing.sign(json.dumps(verification_report),
                         self._report_private_key)
        }

        signup_info.proof_data = json.dumps(proof_data_dict)

        self._test_bad_signup_info(signup_info)

        # ------------------------------------------------------
        # No report body in isvEnclaveQuoteBody
        verification_report = \
            json.loads(proof_data_dict["verification_report"])
        quote = {"test": "none"}

        verification_report['isvEnclaveQuoteBody'] = \
            base64.b64encode(
                json.dumps(quote).encode()).decode()

        proof_data_dict = {
            'verification_report':
            json.dumps(verification_report),
            'signature':
            signing.sign(json.dumps(verification_report),
                         self._report_private_key)
        }

        signup_info.proof_data = json.dumps(proof_data_dict)

        self._test_bad_signup_info(signup_info)

        # ------------------------------------------------------
        # Bad isvEnclaveQuoteBody
        verification_report = \
            json.loads(proof_data_dict["verification_report"])
        quote = {"report_body": "none"}

        verification_report['isvEnclaveQuoteBody'] = \
            base64.b64encode(
                json.dumps(quote).encode()).decode()

        proof_data_dict = {
            'verification_report':
            json.dumps(verification_report),
            'signature':
            signing.sign(json.dumps(verification_report),
                         self._report_private_key)
        }

        signup_info.proof_data = json.dumps(proof_data_dict)

        self._test_bad_signup_info(signup_info)
    def create_signup_info(cls,
                           originator_public_key_hash,
                           most_recent_wait_certificate_id):
        with cls._lock:
            # First we need to create a public/private key pair for the PoET
            # enclave to use.
            cls._poet_private_key = signing.generate_privkey()
            cls._poet_public_key = \
                signing.generate_pubkey(cls._poet_private_key)
            cls._active_wait_timer = None

            # We are going to fake out the sealing the signup data.
            signup_data = {
                'poet_public_key':
                    signing.encode_pubkey(cls._poet_public_key, 'hex'),
                'poet_private_key':
                    signing.encode_privkey(
                        cls._poet_private_key,
                        'hex')
            }
            sealed_signup_data = \
                base64.b64encode(bytes(dict2json(signup_data).encode()))

            # Create a fake report
            report_data = '{0}{1}'.format(
                originator_public_key_hash.upper(),
                signing.encode_pubkey(
                    cls._poet_public_key,
                    'hex').upper()
            )
            quote = {
                'report_body': hashlib.sha256(
                    dict2json(report_data).encode()).hexdigest()
            }

            # Fake our "proof" data.
            verification_report = {
                'id': base64.b64encode(
                    bytes(hashlib.sha256(
                        datetime.datetime.now().isoformat().encode())
                        .hexdigest().encode())).decode(),
                'isvEnclaveQuoteStatus': 'OK',
                'isvEnclaveQuoteBody':
                    base64.b64encode(
                        dict2json(quote).encode()).decode(),
                'pseManifestStatus': 'OK',
                'pseManifestHash':
                    base64.b64encode(
                        hashlib.sha256(
                            bytes(b'Do you believe in '
                                  b'manifest destiny?')).hexdigest()
                        .encode()).decode(),
                'nonce': most_recent_wait_certificate_id
            }

            proof_data_dict = {
                'verification_report': dict2json(verification_report),
                'signature':
                    signing.sign(
                        dict2json(verification_report),
                        cls._report_private_key)
            }
            proof_data = dict2json(proof_data_dict)

            return \
                EnclaveSignupInfo(
                    poet_public_key=signup_data['poet_public_key'],
                    proof_data=proof_data,
                    anti_sybil_id=originator_public_key_hash,
                    sealed_signup_data=sealed_signup_data)