示例#1
0
    def test_register_validator_key_mismatch(self):
        key = signed_object.generate_signing_key()
        public_key_hash = \
            hashlib.sha256(
                signing.encode_pubkey(
                    signing.generate_pubkey(key),
                    'hex')).hexdigest()
        key2 = signed_object.generate_signing_key()
        validator_id = signed_object.generate_identifier(key)
        name = 'DasValidator'
        signup_info = \
            SignupInfo.create_signup_info(
                originator_public_key_hash=public_key_hash,
                most_recent_wait_certificate_id='0' * 16)

        store = ObjectStore()
        transaction = \
            ValidatorRegistryTransaction.register_validator(
                name,
                validator_id,
                signup_info)
        transaction.sign_object(key2)
        with self.assertRaises(InvalidTransactionError):
            transaction.check_valid(store)
            self.fail("Failure: Verified an invalid transaction")
示例#2
0
    def test_register_validator_re_register(self):
        key = signed_object.generate_signing_key()
        public_key_hash = \
            hashlib.sha256(
                signing.encode_pubkey(
                    signing.generate_pubkey(key),
                    'hex')).hexdigest()
        validator_id = signed_object.generate_identifier(key)
        name = 'DasValidator'
        signup_info = \
            SignupInfo.create_signup_info(
                originator_public_key_hash=public_key_hash,
                most_recent_wait_certificate_id='0' * 16)

        store = ObjectStore()
        transaction = \
            ValidatorRegistryTransaction.register_validator(
                name,
                validator_id,
                signup_info)
        transaction.sign_object(key)
        try:
            transaction.check_valid(store)
            transaction.apply(store)
        except InvalidTransactionError as e:
            self.fail('Failed valid transaction: {}'.format(e))
        try:  # check if valid to register again
            transaction.check_valid(store)
        except InvalidTransactionError as e:
            self.fail('Failure: Double registered validator: {}'.format(e))
 def setUp(self):
     self.private_key = signing.generate_privkey()
     self.public_key = signing.encode_pubkey(
         signing.generate_pubkey(self.private_key), "hex")
     self._out = queue.Queue()
     self._in = queue.Queue()
     self._in_condition = Condition()
     self._out_condition = Condition()
     self.verifier = SignatureVerifier(self._in, self._out,
                                       self._in_condition,
                                       self._out_condition)
示例#4
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.
        """
        # Temp signature creation to use as identifier
        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
示例#5
0
    def register_signup_information(self, journal):
        wait_certificate_id = journal.most_recent_committed_block_id
        public_key_hash = \
            hashlib.sha256(
                signing.encode_pubkey(journal.local_node.public_key(),
                                      'hex')).hexdigest()

        signup_info = \
            SignupInfo.create_signup_info(
                validator_address=journal.local_node.signing_address(),
                originator_public_key_hash=public_key_hash,
                most_recent_wait_certificate_id=wait_certificate_id)

        # Save off the sealed signup data and cache the PoET public key
        journal.local_store.set(
            'sealed_signup_data',
            signup_info.sealed_signup_data)
        journal.local_store.sync()

        self.poet_public_key = signup_info.poet_public_key

        LOGGER.debug(
            'Register %s (%s)',
            journal.local_node.Name,
            journal.local_node.Identifier)

        # Create a validator register transaction and sign it.  Wrap
        # the transaction in a message.  Broadcast it to out.
        transaction = \
            val_reg.ValidatorRegistryTransaction.register_validator(
                journal.local_node.Name,
                journal.local_node.Identifier,
                signup_info)
        transaction.sign_from_node(journal.local_node)

        message = \
            val_reg.ValidatorRegistryTransactionMessage()
        message.Transaction = transaction

        LOGGER.info(
            'Advertise PoET 1 validator %s (ID = %s) has PoET public key '
            '%s',
            journal.local_node.Name,
            journal.local_node.Identifier,
            signup_info.poet_public_key)

        journal.gossip.broadcast_message(message)
示例#6
0
    def check_valid(self, store, txn):
        """Determines if the update is valid.
            Check policy on each element of validator_name, validator_id,
            and signup_info

        Args:
            store (Store): Transaction store.
            txn (Transaction): Transaction encompassing this update.
        """
        LOGGER.debug('check update %s from %s', str(self), self.validator_id)

        # Check name
        if not self.is_valid_name():
            raise InvalidTransactionError(
                'Illegal validator name {}'.format(self.validator_name[:64]))

        # Check registering validator matches transaction signer.
        if self.validator_id != txn.OriginatorID:
            raise InvalidTransactionError(
                'Signature mismatch on validator registration with validator'
                ' {} signed by {}'.format(self.validator_id,
                                          txn.OriginatorID))

        # Nothing to check for anti_sybil_id
        # Apply will invalidate any previous entries for this anti_sybil_id
        # and create a new entry.

        try:
            public_key_hash = \
                hashlib.sha256(
                    signing.encode_pubkey(
                        txn.originator_public_key,
                        'hex')).hexdigest()

            self.signup_info.check_valid(
                originator_public_key_hash=public_key_hash,
                most_recent_wait_certificate_id='0' * 16)
        except SignupInfoError as error:
            raise InvalidTransactionError(
                'Invalid Signup Info: {0}, Reason: {1}'.format(
                    self.signup_info,
                    error))

        return True
示例#7
0
    def sign_object(self, signingkey):
        """Generates a string signature for the object using the signing
        key.

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

        if self.public_key is None:
            self.public_key = signing.encode_pubkey(
                signing.generate_pubkey(signingkey), "hex")

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

        self._recover_verifying_address()
        self._identifier = hashlib.sha256(self.Signature).hexdigest()
    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"))
示例#9
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["public_key"] = pub
    sig = signing.sign(_dict2cbor(transaction), key)
    transaction['Signature'] = sig

    txnid = hashlib.sha256(transaction['Signature']).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
示例#10
0
    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(dict2json(signup_data))

            # 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)).hexdigest()
            }

            # Fake our "proof" data.
            verification_report = {
                'id':
                base64.b64encode(
                    hashlib.sha256(
                        datetime.datetime.now().isoformat()).hexdigest()),
                'isvEnclaveQuoteStatus':
                'OK',
                'isvEnclaveQuoteBody':
                base64.b64encode(dict2json(quote)),
                'pseManifestStatus':
                'OK',
                'pseManifestHash':
                base64.b64encode(
                    hashlib.sha256(b'Do you believe in '
                                   'manifest destiny?').hexdigest()),
                '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 initialization_complete(self, journal):
        """Processes all invocations that arrived while the ledger was
        being initialized.
        """
        # Before we allow the base journal to do anything that might result
        # in a wait timer or wait certificate being created, we have to ensure
        # the PoET enclave has been initialized.  This can be done in one of
        # two ways:
        # 1. If we have sealed signup data (meaning that we have previously
        #    created signup info), we can request that the enclave unseal it,
        #    in the process restoring the enclave to its previous state.
        # 2. Create new signup information.
        signup_info = None
        sealed_signup_data = journal.local_store.get('sealed_signup_data')

        if sealed_signup_data is not None:
            self.poet_public_key = \
                SignupInfo.unseal_signup_data(
                    validator_address=journal.local_node.signing_address(),
                    sealed_signup_data=sealed_signup_data)
        else:
            wait_certificate_id = journal.most_recent_committed_block_id
            public_key_hash = \
                hashlib.sha256(
                    signing.encode_pubkey(journal.local_node.public_key(),
                                          'hex')).hexdigest()

            signup_info = \
                SignupInfo.create_signup_info(
                    validator_address=journal.local_node.signing_address(),
                    originator_public_key_hash=public_key_hash,
                    most_recent_wait_certificate_id=wait_certificate_id)

            # Save off the sealed signup data
            journal.local_store.set('sealed_signup_data',
                                    signup_info.sealed_signup_data)
            journal.local_store.sync()

            self.poet_public_key = signup_info.poet_public_key

        # propagate the maximum blocks to keep
        journal.maximum_blocks_to_keep = max(
            journal.maximum_blocks_to_keep,
            WaitTimer.certificate_sample_length)

        # initialize stats specifically for the block chain journal
        journal.JournalStats.add_metric(stats.Value('LocalMeanTime', 0))
        journal.JournalStats.add_metric(stats.Value('AggregateLocalMean', 0))
        journal.JournalStats.add_metric(stats.Value('PopulationEstimate', 0))
        journal.JournalStats.add_metric(
            stats.Value('ExpectedExpirationTime', 0))
        journal.JournalStats.add_metric(stats.Value('Duration', 0))

        # initialize the block handlers
        poet_transaction_block.register_message_handlers(journal)

        # If we created signup information, then advertise self to network
        if signup_info is not None:
            # Create a validator register transaction and sign it.  Wrap
            # the transaction in a message.  Broadcast it to out.
            transaction = \
                val_reg.ValidatorRegistryTransaction.register_validator(
                    journal.local_node.Name,
                    journal.local_node.Identifier,
                    signup_info)
            transaction.sign_from_node(journal.local_node)

            message = \
                val_reg.ValidatorRegistryTransactionMessage()
            message.Transaction = transaction

            LOGGER.info('Advertise PoET 1 validator with name %s',
                        journal.local_node.Name)

            journal.gossip.broadcast_message(message)
示例#12
0
def create_random_public_key_hash():
    return \
        hashlib.sha256(
            signing.encode_pubkey(
                create_random_public_key(),
                'hex')).hexdigest()