Exemplo n.º 1
0
def create_claim(address_from,workspace_contract_from, address_to, workspace_contract_to,private_key_from, topicname, data, privacy, mode) :
	""" main reate claim function
	@data = str
	@topicname is credential id
	@privacy is public/private/secret
	scheme 2
	"""
	# calculate claim_id derived from credential "id" (topicname)
	topicvalue = topicname2topicvalue(topicname)
	claim_id = mode.w3.solidityKeccak(['address', 'uint256'], [address_from, topicvalue]).hex()
	# encrypt data
	data_encrypted = encrypt_data(workspace_contract_to, {topicname : data}, privacy, mode, address_caller=address_from)
	if not data_encrypted :
		logging.warning('data encryption failed')
		return None

	# store on IPFS
	ipfs_hash = Talao_ipfs.ipfs_add(data_encrypted, mode)
	if not ipfs_hash :
		logging.error('ipfs failed')
		return None

	# fire transaction
	nonce = mode.w3.eth.getTransactionCount(address_from)
	contract = mode.w3.eth.contract(workspace_contract_to,abi=constante.workspace_ABI)
	txn = contract.functions.addClaim(topicvalue, 2, address_from, b'signature', privacy.encode(), ipfs_hash ).buildTransaction({'chainId': mode.CHAIN_ID,'gas': 4000000,'gasPrice': mode.w3.toWei(mode.GASPRICE, 'gwei'),'nonce': nonce,})
	signed_txn = mode.w3.eth.account.signTransaction(txn,private_key_from)
	mode.w3.eth.sendRawTransaction(signed_txn.rawTransaction)
	transaction_hash = mode.w3.toHex(mode.w3.keccak(signed_txn.rawTransaction))
	if not mode.w3.eth.waitForTransactionReceipt(transaction_hash, timeout=2000, poll_latency=1)['status']
		logging.error('transaction failed')
		return None
	return claim_id
Exemplo n.º 2
0
def _get_claim(workspace_contract_from, identity_workspace_contract, claim_id, mode) :
	""" Internal function to access claim data """
	w3 = mode.w3
	contract = w3.eth.contract(identity_workspace_contract, abi=constante.workspace_ABI)
	claim = contract.functions.getClaim(claim_id).call()
	privacy = claim[4].decode()
	ipfs_hash = claim[5]
	issuer = claim[2]
	scheme = claim[1]
	topic_value = claim[0]
	data_encrypted = Talao_ipfs.ipfs_get(ipfs_hash)
	address_from = contracts_to_owners(workspace_contract_from, mode)
	msg = decrypt_data(identity_workspace_contract, data_encrypted, privacy, mode, address_caller=address_from)
	if msg :
		data = list(msg.values())[0]
	else :
		logging.error('decrypt claim failed')
		return None
	return issuer, identity_workspace_contract, data, ipfs_hash,  scheme, claim_id, privacy, topic_value
Exemplo n.º 3
0
def _get_claim(workspace_contract_from, private_key_from,
               identity_workspace_contract, claim_id, mode):
    """ Internal function to access claim data """
    w3 = mode.w3
    contract = w3.eth.contract(identity_workspace_contract,
                               abi=constante.workspace_ABI)
    claim = contract.functions.getClaim(claim_id).call()
    data = claim[4].decode('utf-8')  # privacy
    ipfs_hash = claim[5]
    issuer = claim[2]
    scheme = claim[1]
    topic_value = claim[0]
    #topicname = topicvalue2topicname(topic_value)
    if data != 'private' and data != 'secret' and data != 'public':
        # compatiblité avec version precedente. data public non cryptee
        to_be_decrypted = False
        privacy = 'public'
    else:
        # toutes les datas sont encryptees
        to_be_decrypted = True
        privacy = data
    if to_be_decrypted:
        # upload data encrypted from ipfs
        data_encrypted = Talao_ipfs.ipfs_get(ipfs_hash)
        address_from = contracts_to_owners(workspace_contract_from, mode)
        msg = privatekey.decrypt_data(identity_workspace_contract,
                                      data_encrypted,
                                      privacy,
                                      mode,
                                      address_caller=address_from)
        if msg:
            #data= msg[topicname]
            data = list(msg.values())[0]
        else:
            logging.error('decrypt claim failed')
            data = None

    gas_used = 1000
    created = ""
    gas_price = 1
    transaction_hash = "0"

    return issuer, identity_workspace_contract, data, ipfs_hash, gas_price * gas_used, transaction_hash, scheme, claim_id, privacy, topic_value, created
Exemplo n.º 4
0
def add_file(address_from, workspace_contract_from, address_to,
             workspace_contract_to, private_key_from, doctype, file_name,
             mydays, privacy, mode, synchronous):
    w3 = mode.w3
    file_path = mode.uploads_path + file_name
    try:
        this_file = open(file_path, mode='rb')  # b is important -> binary
    except IOError:
        logging.error('Error : IOEroor open file in File.py')
        return None, None, None
    this_data = this_file.read()
    data = {
        'filename': file_name,
        'content': b64encode(this_data).decode('utf_8')
    }

    # cryptage des données par le user
    if privacy != 'public':
        """
		contract = w3.eth.contract(workspace_contract_to,abi = constante.workspace_ABI)
		mydata = contract.functions.identityInformation().call()
		"""
        if privacy == 'private':
            my_aes = privatekey.get_key(address_to, 'aes_key', mode)
        if privacy == 'secret':
            my_aes = privatekey(address_to, 'secret_key', mode)
        if my_aes is None:
            return None, None, None

        # coder les datas
        bytesdatajson = bytes(json.dumps(data),
                              'utf-8')  # dict -> json(str) -> bytes
        header = b'header'
        cipher = AES.new(
            my_aes, AES.MODE_EAX
        )  #https://pycryptodome.readthedocs.io/en/latest/src/cipher/modern.html
        cipher.update(header)
        ciphertext, tag = cipher.encrypt_and_digest(bytesdatajson)
        json_k = ['nonce', 'header', 'ciphertext', 'tag']
        json_v = [
            b64encode(x).decode('utf-8')
            for x in [cipher.nonce, header, ciphertext, tag]
        ]
        data = dict(zip(json_k, json_v))
        data['filename'] = file_name

    # calcul de la date
    if mydays == 0:
        expires = 0
    else:
        myexpires = datetime.utcnow() + datetime.timedelta(days=mydays,
                                                           seconds=0)
        expires = int(myexpires.timestamp())

    #envoyer la transaction sur le contrat
    contract = w3.eth.contract(workspace_contract_to,
                               abi=constante.workspace_ABI)
    nonce = w3.eth.getTransactionCount(address_from)

    # stocke sur ipfs les data attention on archive des bytes
    ipfs_hash = Talao_ipfs.ipfs_add(data, mode)

    # calcul du checksum en bytes des data, conversion du dictionnaire data en chaine str
    #_data = json.dumps(data)
    #checksum = hashlib.md5(bytes(_data, 'utf-8')).hexdigest()
    # la conversion inverse de bytes(data, 'utf-8') est XXX.decode('utf-8')
    checksum = b''

    encrypted = False if privacy == 'public' else True
    # Transaction
    txn = contract.functions.createDocument(doctype, 2, expires, checksum, 1,
                                            bytes(ipfs_hash, 'utf-8'),
                                            encrypted).buildTransaction({
                                                'chainId':
                                                mode.CHAIN_ID,
                                                'gas':
                                                500000,
                                                'gasPrice':
                                                w3.toWei(
                                                    mode.GASPRICE, 'gwei'),
                                                'nonce':
                                                nonce,
                                            })
    signed_txn = w3.eth.account.signTransaction(txn, private_key_from)
    w3.eth.sendRawTransaction(signed_txn.rawTransaction)
    transaction_hash = w3.toHex(w3.keccak(signed_txn.rawTransaction))
    if synchronous == True:
        receipt = w3.eth.waitForTransactionReceipt(transaction_hash,
                                                   timeout=2000,
                                                   poll_latency=1)
        if receipt['status'] == 0:
            return None, None, None

    # recuperer l iD du document sur le dernier event DocumentAdded
    contract = w3.eth.contract(workspace_contract_to,
                               abi=constante.workspace_ABI)
    myfilter = contract.events.DocumentAdded.createFilter(
        fromBlock=mode.fromBlock, toBlock='latest')
    eventlist = myfilter.get_all_entries()
    document_id = eventlist[-1]['args']['id']
    return document_id, ipfs_hash, transaction_hash
Exemplo n.º 5
0
def get_file(workspace_contract_from, private_key_from,
             workspace_contract_user, documentId, new_filename, mode):
    w3 = mode.w3
    contract = w3.eth.contract(workspace_contract_user,
                               abi=constante.workspace_ABI)
    (doctype, doctypeversion, expires, issuer, checksum, engine, ipfshash,
     encrypted, related) = contract.functions.getDocument(documentId).call()
    if doctype == 30000:
        privacy = 'public'
    elif doctype == 30001:
        privacy = 'private'
    elif doctype == 30002:
        privacy = 'secret'
    else:
        logging.error('Error : wrong doctype in get file')
        return None

    # get transaction info
    contract = w3.eth.contract(workspace_contract_user,
                               abi=constante.workspace_ABI)
    claim_filter = contract.events.DocumentAdded.createFilter(
        fromBlock=mode.fromBlock, toBlock='latest')
    event_list = claim_filter.get_all_entries()
    found = False
    for doc in event_list:
        if doc['args']['id'] == documentId:
            found = True
            transactionhash = doc['transactionHash']
            transaction_hash = transactionhash.hex()
            transaction = w3.eth.getTransaction(transaction_hash)
            gas_price = transaction['gasPrice']
            identity_workspace_contract = transaction['to']
            block_number = transaction['blockNumber']
            block = mode.w3.eth.getBlock(block_number)
            date = datetime.fromtimestamp(block['timestamp'])
            #gas_used = w3.eth.getTransactionReceipt(transaction_hash).gasUsed
            gas_used = 1000
            created = str(date)
            break
    if not found:
        logging.error('Error : event list in get_file')
        return None

    # recuperation du msg
    data = Talao_ipfs.ipfs_get(ipfshash.decode('utf-8'))
    filename = data['filename']

    # calcul de la date
    expires = 'Unlimited' if expires == 0 else str(
        datetime.fromtimestamp(expires))

    if privacy == 'public':
        to_be_decrypted = False
        to_be_stored = True

    elif workspace_contract_from != workspace_contract_user and privacy == 'private' and private_key_from is not None:
        #recuperer les cle AES cryptée du user sur son partnership de l identité
        contract = w3.eth.contract(workspace_contract_from,
                                   abi=constante.workspace_ABI)
        acct = Account.from_key(private_key_from)
        mode.w3.eth.defaultAccount = acct.address
        partnership_data = contract.functions.getPartnership(
            workspace_contract_user).call()
        # one tests if the user in in partnershipg with identity (pending or authorized)
        if partnership_data[1] in [1, 2] and partnership_data[4] != b'':
            his_aes_encrypted = partnership_data[4]
            to_be_decrypted = True
            to_be_stored = True
        else:
            to_be_decrypted = False
            to_be_stored = False
            data = {'filename': filename, 'content': "Encrypted"}

    elif workspace_contract_from == workspace_contract_user:
        #recuperer les cle AES cryptée dans l identité
        contract = w3.eth.contract(workspace_contract_user,
                                   abi=constante.workspace_ABI)
        mydata = contract.functions.identityInformation().call()
        if privacy == 'private':
            his_aes_encrypted = mydata[5]
        if privacy == 'secret':
            his_aes_encrypted = mydata[6]

        to_be_decrypted = True
        to_be_stored = True

    else:  # workspace_contract_from != wokspace_contract_user and privacy == secret or private_key_from is None:
        to_be_decrypted = False
        to_be_stored = False
        logging.error(
            'Warning : workspace_contract_from != wokspace_contract_user and privacy == secret or private_key_from is None (file.py)'
        )
        data = {'filename': filename, 'content': "Encrypted"}

    if to_be_decrypted:
        # read la cle RSA privee sur le fichier de l identité
        contract = mode.w3.eth.contract(mode.foundation_contract,
                                        abi=constante.foundation_ABI)
        address_from = contract.functions.contractsToOwners(
            workspace_contract_from).call()
        rsa_key = privatekey.get_key(address_from, 'rsa_key', mode)
        if rsa_key is None:
            logging.error('Warning : RSA key not found in file.py')
            return None

        # decoder la cle AES cryptée avec la cle RSA privée
        key = RSA.importKey(rsa_key)
        cipher = PKCS1_OAEP.new(key)
        his_aes = cipher.decrypt(his_aes_encrypted)

        # decoder les datas
        try:
            del data['filename']
            b64 = data  #json.loads(json_input)
            json_k = ['nonce', 'header', 'ciphertext', 'tag']
            jv = {k: b64decode(b64[k]) for k in json_k}
            cipher = AES.new(his_aes, AES.MODE_EAX, nonce=jv['nonce'])
            cipher.update(jv['header'])
            plaintext = cipher.decrypt_and_verify(jv['ciphertext'], jv['tag'])
            msg = json.loads(plaintext.decode('utf-8'))
            data = msg
        except ValueError:
            logging.error("Error : data Decryption error")
            return None

    new_filename = filename if new_filename == "" else new_filename
    if to_be_stored:
        new_file = open(mode.uploads_path + new_filename, "wb")
        new_file.write(b64decode(data['content']))
        new_file.close()
    return issuer, identity_workspace_contract, data, ipfshash.decode(
        'utf-8'
    ), gas_price * gas_used, transaction_hash, doctype, doctypeversion, created, expires, issuer, privacy, related
Exemplo n.º 6
0
def _create(address_from, workspace_contract_from, address_to,
            workspace_contract_to, private_key_from, doctype, data, mydays,
            privacy, mode, synchronous, version, id, sequence):

    # align doctype with privacy
    if privacy == 'private' and doctype == 20000:
        doctype = 20001
    if privacy == 'secret' and doctype == 20000:
        doctype = 20002

    # @data = dict
    if isinstance(data, str):
        data = json.loads(data)
        logging.error('data must be a dict')

    #encrypt data with AES key (public, private or secret) Deprecated
    if version == 3:
        data = privatekey.encrypt_data(workspace_contract_to, data, privacy,
                                       mode)
        if not data:
            logging.error('encryption problem')
            return None, None, None

    #encrypt server side data as JWE with identity RSA key
    elif version == 4:
        jwe = JsonWebEncryption()
        protected = {'alg': 'RSA-OAEP', 'enc': 'A256GCM'}
        payload = json.dumps(data).encode()
        private_rsa_key = privatekey.get_key(address_to, 'rsa_key', mode)
        RSA_KEY = RSA.import_key(private_rsa_key)
        public_rsa_key = RSA_KEY.publickey().export_key('PEM').decode('utf-8')
        if not id:
            id = str(uuid.uuid1())
        if not sequence:
            sequence = 0
        data = {
            "id":
            id,
            "sequence":
            sequence,
            "jwe":
            jwe.serialize_compact(protected, payload, public_rsa_key).decode()
        }

    # encrypt data with AES key of identity"
    elif version == 5:
        jwe = JsonWebEncryption()
        protected = {'alg': 'A128KW', 'enc': 'A128CBC-HS256'}
        payload = json.dumps(data).encode()
        if privacy == 'public':
            secret = mode.aes_public_key.encode()
        else:
            secret = privatekey.get_key(address_to, privacy, mode)
        if not id:
            id = str(uuid.uuid1())
        if not sequence:
            sequence = 0
        data = {
            "id": id,
            "sequence": sequence,
            "jwe": jwe.serialize_compact(protected, payload, secret).decode()
        }

    # No data encryption. data have been probably encrypted as JWE client side
    elif version == 6:
        data = {
            "id": str(uuid.uuid1()),
            "sequence": 0,
            'jwe': json.dumps(data)
        }

    else:
        logging.error('pb version')
        return None, None, None

    # Build transaction
    contract = mode.w3.eth.contract(workspace_contract_to,
                                    abi=constante.workspace_ABI)
    nonce = mode.w3.eth.getTransactionCount(address_from)

    # upkoad on ipfs
    ipfs_hash = Talao_ipfs.ipfs_add(data, mode)
    if not ipfs_hash:
        logging.error('IPFS connexion problem')
        return None, None, None

    # checksum (bytes)
    checksum = hashlib.md5(bytes(json.dumps(data), 'utf-8')).hexdigest()

    # Transaction
    expires = 0
    txn = contract.functions.createDocument(doctype, version, expires,
                                            checksum, 1,
                                            bytes(ipfs_hash, 'utf-8'),
                                            True).buildTransaction({
                                                'chainId':
                                                mode.CHAIN_ID,
                                                'gas':
                                                1000000,
                                                'gasPrice':
                                                mode.w3.toWei(
                                                    mode.GASPRICE, 'gwei'),
                                                'nonce':
                                                nonce,
                                            })
    signed_txn = mode.w3.eth.account.signTransaction(txn, private_key_from)
    mode.w3.eth.sendRawTransaction(signed_txn.rawTransaction)
    transaction_hash = mode.w3.toHex(mode.w3.keccak(signed_txn.rawTransaction))
    if synchronous:
        if not mode.w3.eth.waitForTransactionReceipt(
                transaction_hash, timeout=2000, poll_latency=1)['status']:
            logging.error('transaction to create document failed')
            return None, None, None

        # Get document id on last event
        contract = mode.w3.eth.contract(workspace_contract_to,
                                        abi=constante.workspace_ABI)
        from_block = mode.w3.eth.blockNumber - 10
        myfilter = contract.events.DocumentAdded.createFilter(
            fromBlock=from_block, toBlock='latest')
        eventlist = myfilter.get_all_entries()
        document_id = eventlist[-1]['args']['id']
        return document_id, ipfs_hash, transaction_hash
    else:
        return None, None, None
Exemplo n.º 7
0
def _get(workspace_contract_from, private_key_from, workspace_contract_user,
         documentId, mode):

    # @documentID is int
    if not isinstance(documentId, int):
        documentId = int(documentId)
        logging.error('doc_id must be int')

    w3 = mode.w3
    contract = w3.eth.contract(workspace_contract_user,
                               abi=constante.workspace_ABI)
    #try :
    (doctype, doctypeversion, unused, issuer, unused, unused, ipfshash, unused,
     unused) = contract.functions.getDocument(documentId).call()
    #except :
    #	logging.error('connexion blockchain talaonet impossble, document.py')
    #	return None, None, None, None, None, None, None

    if doctype in [50000, 40000, 10000, 15000, 20000, 11000]:
        privacy = 'public'
    if doctype in [50001, 40001, 15001, 20001]:
        privacy = 'private'
    if doctype in [50002, 40002, 20002]:
        privacy = 'secret'
    workspace_contract_identity = workspace_contract_user

    # download from IPFS
    ipfs_data = Talao_ipfs.ipfs_get(ipfshash.decode('utf-8'))

    # previous version (deprecated)
    if privacy == 'public' and doctypeversion == 2:
        return issuer, workspace_contract_identity, ipfs_data, ipfshash.decode(
        ), privacy, "", 0

    # data encrypted server side with AES algo and server keys (public, private, secret)
    elif doctypeversion == 3:
        msg = privatekey.decrypt_data(workspace_contract_user, ipfs_data,
                                      privacy, mode)
        if msg:
            # decrypt avec algo AES-EAX ou AES-CBC
            return issuer, workspace_contract_user, msg, ipfshash.decode(
                'utf-8'), privacy, "", 0
        else:
            # la clé RSA n'est pas disponible sur le serveur
            logging.warning('Cannot decrypt data')
            return issuer, workspace_contract_user, {
                "data": 'Encrypted'
            }, ipfshash.decode('utf-8'), privacy, "", 0

    # data encrypted server side as JWE with RSA identity key
    elif doctypeversion == 4:
        jwe = JsonWebEncryption()
        address_user = contracts_to_owners(workspace_contract_user, mode)
        key = privatekey.get_key(address_user, 'rsa_key', mode)
        data = jwe.deserialize_compact(ipfs_data['jwe'], key)
        payload = data['payload']
        return issuer, workspace_contract_user, payload.decode(
        ), ipfshash.decode(), privacy, "", 0

    # data encrypted server side as JWE with AES key
    elif doctypeversion == 5:
        jwe = JsonWebEncryption()
        address_user = contracts_to_owners(workspace_contract_user, mode)
        if privacy == 'public':
            secret = mode.aes_public_key.encode()
        else:
            secret = privatekey.get_key(address_user, privacy, mode)
        data = jwe.deserialize_compact(ipfs_data['jwe'], secret)
        payload = data['payload']
        return issuer, workspace_contract_user, payload.decode(
        ), ipfshash.decode(), privacy, ipfs_data['id'], ipfs_data['sequence']

    # data encrypted client side as JWE. There is no server decryption.
    elif doctypeversion == 6:
        return issuer, workspace_contract_user, ipfs_data[
            'jwe'], ipfshash.decode(), privacy, "", 0

    else:
        logging.error('pb doctypeversion')
        return None, None, None, None, None, None, None
Exemplo n.º 8
0
    def __init__(self,
                 workspace_contract,
                 mode,
                 authenticated=False,
                 workspace_contract_from=None,
                 private_key_from=None):

        self.workspace_contract = workspace_contract
        category = get_category(self.workspace_contract, mode)
        if category == 2001:  # company
            self.type = "company"
        if category == 1001:  # person
            self.type = "person"
        self.authenticated = authenticated
        self.did = 'did:talao:' + mode.BLOCKCHAIN + ':' + self.workspace_contract[
            2:]
        self.address = contractsToOwners(self.workspace_contract, mode)
        self.get_all_documents(mode)
        self.get_issuer_keys(mode)
        self.get_identity_skills(mode)
        self.get_identity_certificate(mode)
        self.get_identity_private_certificate(mode)
        self.get_identity_secret_certificate(mode)
        self.has_vault_access = has_vault_access(self.address, mode)

        if self.authenticated:
            self.has_relay_private_key(mode)
            if self.private_key:
                self.get_partners(mode)
            else:
                self.partners = []

            self.has_relay_rsa_key(mode)
            if self.rsa_key:
                self.get_secret(mode)  # get aes and secret keys
            else:
                self.secret = 'Encrypted'
                self.aes = 'Encrypted'
            self.eth = mode.w3.eth.getBalance(
                self.address) / 1000000000000000000
            self.token = token_balance(self.address, mode)
            self.is_relay_activated(mode)
            self.get_identity_personal(self.workspace_contract,
                                       self.private_key_value, mode)
            self.get_identity_file(self.workspace_contract,
                                   self.private_key_value, mode)
        else:
            self.partners = []
            self.private_key = False
            self.rsa_key = False
            self.relay_activated = False
            address_from = contractsToOwners(workspace_contract_from, mode)
            private_key_from = privatekey.get_key(address_from, 'private_key',
                                                  mode)
            self.get_identity_file(workspace_contract_from, private_key_from,
                                   mode)
            self.get_identity_personal(workspace_contract_from,
                                       private_key_from, mode)
        if self.type == "company":
            self.name = self.personal['name']['claim_value']
        else:  # self.type == "person" :
            self.profil_title = self.personal['profil_title']['claim_value']
            self.name = self.personal['firstname'][
                'claim_value'] + ' ' + self.personal['lastname']['claim_value']
            personal = json.loads(
                ns.get_personal(self.workspace_contract, mode))
            self.experience = personal.get('experience_claims', [])
            self.education = personal.get('education_claims', [])

        #get image/logo and signature ipfs and download files to upload folder
        #self.picture = get_image(self.workspace_contract, 'picture', mode)
        self.picture = self.personal['picture']
        if not self.picture:
            self.picture = 'QmRzXTCn5LyVpdUK9Mc5kTa3VH7qH4mqgFGaSZ3fncEFaq' if self.type == "person" else 'QmXKeAgNZhLibNjYJFHCiXFvGhqsqNV2sJCggzGxnxyhJ5'
        if not os.path.exists(mode.uploads_path + self.picture):
            Talao_ipfs.get_picture(self.picture,
                                   mode.uploads_path + self.picture)

        #self.signature = get_image(self.workspace_contract, 'signature', mode)
        self.signature = self.personal['signature']
        if not self.signature:
            self.signature = 'QmS9TTtjw1Fr5oHkbW8gcU7TnnmDvnFVUxYP9BF36kgV7u'
        if not os.path.exists(mode.uploads_path + self.signature):
            Talao_ipfs.get_picture(self.signature,
                                   mode.uploads_path + self.signature)