def validate_certificate(cert, hash_prefix, testnet):
    filename = os.path.basename(cert)
    tmp_filename = '__' + filename
    shutil.copy(cert, tmp_filename)

    proof = get_and_remove_chainpoint_proof(tmp_filename)
    if proof == None:
        os.remove(tmp_filename)
        return False

    # get the hash after removing the metadata
    filehash = ''
    with open(tmp_filename, 'rb') as pdf_file:
        filehash = hashlib.sha256(pdf_file.read()).hexdigest()

    # cleanup now that we got original filehash
    os.remove(tmp_filename)

    # validate receipt
    cp = ChainPointV2()
    if cp.validate_receipt(proof, filehash, hash_prefix, testnet):
        return True
    else:
        return False
def prepare_chainpoint_tree(hashes):
    cp = ChainPointV2()
    cp.add_leaf(hashes)
    cp.make_tree()
    return cp
def validate_certificate(cert, issuer_identifier, testnet):
    valid_certificate = False

    filename = os.path.basename(cert)
    tmp_filename = '__' + filename
    shutil.copy(cert, tmp_filename)

    proof = get_and_remove_chainpoint_proof(tmp_filename)
    if proof == None:
        os.remove(tmp_filename)
        return False

    # get the hash after removing the metadata
    filehash = ''
    with open(tmp_filename, 'rb') as pdf_file:
        filehash = hashlib.sha256(pdf_file.read()).hexdigest()

    # cleanup now that we got original filehash
    os.remove(tmp_filename)

    # validate receipt
    cp = ChainPointV2()
    if cp.validate_receipt(proof, filehash, issuer_identifier, testnet):
        valid_certificate = True
    else:
        return False

    # blockchain receipt is valid but we need to also check if the certificate
    # was revoked after issuing
    txid = proof['anchors'][0]['sourceId']
    data_before_issuance, data_after_issuance = network_utils.get_all_op_return_hexes(
        txid, testnet)

    # check if cert or batch was revoked from oldest to newest; if a valid
    # revoke address is found further commands are ignored
    # (TODO: REVOKE ADDRESS CMD
    for op_return in reversed(data_after_issuance):
        cred_dict = cred_protocol.parse_op_return_hex(op_return)
        if cred_dict:
            if cred_dict['cmd'] == cred_protocol.hex_op('op_revoke_batch'):
                if txid == cred_dict['data']['txid']:
                    return False  # log: cert invalid - batch was revoked
            elif cred_dict['cmd'] == cred_protocol.hex_op('op_revoke_creds'):
                if txid == cred_dict['data']['txid']:
                    # compare the certificate hash bytes
                    filehash_bytes = utils.hex_to_bytes(filehash)
                    ripemd_filehash = utils.ripemd160(filehash_bytes)
                    ripemd_hex = utils.bytes_to_hex(ripemd_filehash)
                    if ripemd_hex == cred_dict['data']['hashes'][0]:
                        return False  # log: cert invalid - cert was revoked

                    if len(cred_dict['data']['hashes']) > 1:
                        if ripemd_hex == cred_dict['data']['hashes'][1]:
                            return False  # log: cert invalid - cert was revoked
            elif cred_dict['cmd'] == cred_protocol.hex_op('op_revoke_address'):
                # if correct address and valid revoke then stop checking other
                # revokes and break loop (TODO: REVOKE ADDRESS CMD)
                print("TODO: revoke address not implemented yet!")

    # check if cert's issuance is after a revoke address cmd on that address
    # TODO: REVOKE ADDRESS CMD
    # check the data_before_issuance...  and return False!!

    return True