def validate(self, admissions, doctors, vaccines):
        """Validate the existing signatures.

        Check if the transaction fulfills the requirements
        WONTFIX: won't implement checking if patient is registered in presentation demo
        """
        if self.vaccine not in vaccines:
            logger.debug("vaccine is not registered.")
            self.validation_text = "vaccine is not registered."
            return False
        if self.doctor_pub_key not in doctors:
            logger.debug("doctor is not registered.")
            self.validation_text = "doctor is not registered."
            return False

        if not self.doctor_signature or not self.patient_signature:
            return False

        bin_doctor_key = key_utils.bytes_to_rsa(self.doctor_pub_key)
        doctor_signature = self._verify_doctor_signature(bin_doctor_key)
        if not doctor_signature:
            logger.debug("doctor signature is not valid")
            self.validation_text = "doctor signature is not valid"
            return False

        bin_patient_key = key_utils.bytes_to_rsa(self.patient_pub_key)
        patient_signature = self._verify_patient_signature(bin_patient_key)
        if not patient_signature:
            logger.debug("patient signature is not valid")
            self.validation_text = "patient signature is not valid"
            return False

        self.validation_text = "valid"
        return True
    def _verify_signature(self):
        """Verify existing signature.

        Overwrite the method if you need more than one signature.
        """
        if not self.signature:  # fail if object has no signature attribute
            self.validation_text = "No signature found."
            return False
        message = crypto.get_bytes(self._get_information_for_hashing())
        result = crypto.verify(message, self.signature,
                               key_utils.bytes_to_rsa(self.sender_pubkey))
        if not result:
            self.validation_text = "Signature not valid"
            return False
        self.validation_text = "valid"
        return True
Exemplo n.º 3
0
def test_bytes_to_rsa(public_key, private_key):
    rsa_object = key_utils.bytes_to_rsa(public_key.exportKey("DER"))
    assert rsa_object == public_key
    rsa_object = key_utils.bytes_to_rsa(private_key.exportKey("DER"))
    assert rsa_object == private_key
def validate_block(block, previous_block):
    """Validate correctness of block by defined rules.

    This module doesn't check if there are transactions since the demo will
    generate blocks without transactions.
    """
    if not previous_block:
        return False

    # Index is incremented by 1
    if block.index != previous_block.index + 1:
        logger.info(
            "Wrong index, block index {}, index of last block {}".format(
                block.index, previous_block.index))
        return False

    # New block references old one
    if block.previous_block != previous_block.hash:
        logger.info(
            ("New block does not reference previous one, block hash"
             " {}, hash of last block {}").format(block.hash,
                                                  previous_block.hash))
        return False

    # Matching versions
    if block.version < CONFIG.version:
        logger.info("Older version, block version {}, chain version {}".format(
            block.version, CONFIG.version))
        return False

    # Timestamp not in the future
    if block.timestamp > int(time()):
        logger.info("Timestamp of the new block is in the future")
        return False

    # Valid signature
    content_to_sign = str.encode(block._get_content_for_signing())
    signature = key_utils.hex_to_bytes(block.signature)
    public_key = key_utils.bytes_to_rsa(block.public_key)
    valid = verify(content_to_sign, signature, public_key)
    if not valid:
        logger.info("Signature is not valid, block must be altered")
        return False

    # Check if all transactions are valid
    admissions, doctors, vaccines = Chain().\
        get_registration_caches_by_blockhash(block.previous_block)
    for transaction in block.transactions:
        if not transaction.validate(admissions, doctors, vaccines):
            logger.info("Block contains invalid transactions")
            return False

    # WONTFIX: Actually, a block should never be empty. However, we leave this
    # check disabled for demo purposes.
    # Block has no transactions
    # if len(block.transactions) == 0:
    #     logger.info("Block does not contain any transaction")
    #     return False

    # Number of transactions exceeds the maximum
    if len(block.transactions) > CONFIG.block_size:
        logger.info(
            "Too many transactions, block has {}, maximum is {}".format(
                len(block.transactions), CONFIG.block_size))
        return False

    # Duplicate transactions
    distinct_transactions = len(set([repr(tx) for tx in block.transactions]))
    if len(block.transactions) > distinct_transactions:
        logger.info("Block contains duplicate transactions")
        return False

    # Block hash valid
    content_to_hash = block.get_content_for_hashing()
    sha = sha256()
    sha.update(content_to_hash.encode("utf-8"))
    if block.hash != sha.hexdigest():
        logger.info("Hash is not valid, block must be altered")
        return False

    return True
Exemplo n.º 5
0
 def _verify_approval_signature(self, approval):
     # WONTFIX: susceptible to replay attacks because there is no clear indication
     # which transaction the approval belongs to, approvals could be copy-pasted to confirm malicious actors.
     approving_pubkey, signature = approval
     return crypto.verify(approving_pubkey, signature, key_utils.bytes_to_rsa(approving_pubkey))