def forgot_password(mode) :
	"""
	@app.route('/forgot_password/', methods = ['GET', 'POST'])
	This function is called from the login view.
	build JWE to store timestamp, username and email, we use Talao RSA key
	"""
	if request.method == 'GET' :
		return render_template('./login/forgot_password_init.html')
	if request.method == 'POST' :
		username = request.form.get('username')
		if not ns.username_exist(username, mode) :
			flash("Username not found", "warning")
			return render_template('./login/login_password.html')
		email= ns.get_data_from_username(username, mode)['email']
		private_rsa_key = privatekey.get_key(mode.owner_talao, 'rsa_key', mode)
		RSA_KEY = RSA.import_key(private_rsa_key)
		public_rsa_key = RSA_KEY.publickey().export_key('PEM').decode('utf-8')
		expired = datetime.timestamp(datetime.now()) + 180 # 3 minutes live
		# build JWE
		jwe = JsonWebEncryption()
		header = {'alg': 'RSA1_5', 'enc': 'A256GCM'}
		json_string = json.dumps({'username' : username, 'email' : email, 'expired' : expired})
		payload = bytes(json_string, 'utf-8')
		token = jwe.serialize_compact(header, payload, public_rsa_key)
		link = mode.server + 'forgot_password_token/?'+ urlencode({'token'  : token.decode('utf-8')}, doseq=True)
		subject = "Renew your password"
		if Talao_message.messageHTML(subject, email, 'forgot_password', {'link': link}, mode):
			flash("You are going to receive an email to renew your password.", "success")
		return render_template('./login/login_password.html')
def forgot_password_token(mode) :
	"""
	@app.route('/forgot_password_token/', methods = ['GET', 'POST'])
	This function is called from email to decode token and reset password.
	"""
	if request.method == 'GET' :
		token = request.args.get('token')
		key = privatekey.get_key(mode.owner_talao, 'rsa_key', mode)
		jwe = JsonWebEncryption()
		try :
			data = jwe.deserialize_compact(token, key)
		except :
			flash ('Incorrect data', 'danger')
			logging.warning('JWE did not decrypt')
			return render_template('./login/login_password.html')
		payload = json.loads(data['payload'].decode('utf-8'))
		if payload['expired'] < datetime.timestamp(datetime.now()) :
			flash ('Delay expired (3 minutes maximum)', 'danger')
			return render_template('./login/login_password.html')
		session['email_password'] = payload['email']
		session['username_password'] = payload['username']
		return render_template('./login/update_password_external.html')
	if request.method == 'POST' :
		if session['email_password'] != request.form['email'] :
			flash('Incorrect email', 'danger')
			return render_template('./login/update_password_external.html')
		ns.update_password(session['username_password'], request.form['password'], mode)
		flash('Password updated', "success")
		del session['email_password']
		del session['username_password']
		return render_template('./login/login_password.html')
Beispiel #3
0
def get_partner_status(address, identity_workspace_contract, mode):
	# on obtient la liste des partners avec le Relay qui a une cle 1
	acct = Account.from_key(mode.relay_private_key)
	mode.w3.eth.defaultAccount = acct.address
	contract = mode.w3.eth.contract(identity_workspace_contract, abi=constante.workspace_ABI)
	partner_list = contract.functions.getKnownPartnershipsContracts().call()
	liste = ["Unknown", "Authorized", "Pending", "Rejected", "Removed", ]
	for partner_workspace_contract in partner_list:
		try:
			authorization_index = contract.functions.getPartnership(partner_workspace_contract).call()[1]
		except Exception as ex:
			logging.error('E = %s',ex)
			return None, None
		partner_address = contractsToOwners(partner_workspace_contract, mode)
		if partner_address == address :
			local_status = liste[authorization_index]
			break
	identity_address = contractsToOwners(identity_workspace_contract, mode)
	identity_private_key = privatekey.get_key(identity_address, 'private_key', mode)
	if identity_private_key :
		acct = Account.from_key(identity_private_key)
		mode.w3.eth.defaultAccount = acct.address
		contract = mode.w3.eth.contract(partner_workspace_contract,abi=constante.workspace_ABI)
		partner_status = liste[contract.functions.getMyPartnershipStatus().call()]
	else :
		partner_status = None
	return local_status, partner_status
Beispiel #4
0
def well_known_did (mode) :
    """ did:web
    https://w3c-ccg.github.io/did-method-web/
    https://identity.foundation/.well-known/resources/did-configuration/#LinkedDomains
    """
    address = mode.owner_talao

    # RSA
    pvk = privatekey.get_key(address, 'rsa_key', mode)
    key = jwk.JWK.from_pem(pvk.encode())
    rsa_public = key.export_public(as_dict=True)
    del rsa_public['kid']
    # secp256k
    pvk = privatekey.get_key(address, 'private_key', mode)
    key = helpers.ethereum_to_jwk256k(pvk)
    ec_public = json.loads(key)
    del ec_public['d']
    del ec_public['alg']
    DidDocument = did_doc(address, ec_public, rsa_public, mode)
    return jsonify(DidDocument)
Beispiel #5
0
def generate_CA(mode):
    # upload RSA private pem
    talao_rsa_private_key = privatekey.get_key(mode.owner_talao, 'rsa_key',
                                               mode)
    if type(talao_rsa_private_key) == bytes:
        talao_rsa_key = serialization.load_pem_private_key(
            talao_rsa_private_key,
            password=None,
        )
    else:
        talao_rsa_key = serialization.load_pem_private_key(
            bytes(talao_rsa_private_key, 'utf-8'),
            password=None,
        )

    # Talao as Conformity Authority
    talao_issuer = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, "FR"),
        x509.NameAttribute(NameOID.LOCALITY_NAME, "Paris"),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Talao"),
        x509.NameAttribute(NameOID.DOMAIN_COMPONENT, "talao.io"),
        #x509.NameAttribute(NameOID.POSTAL_ADDRESS, "16 rue de wattignies, 75012 Paris"),
        x509.NameAttribute(NameOID.COMMON_NAME, "talao"),
        x509.NameAttribute(NameOID.USER_ID, 'did:web:talao.io'),
    ])

    # issue CA certificate for Talao
    cert = x509.CertificateBuilder()
    cert = cert.subject_name(talao_issuer)
    cert = cert.issuer_name(talao_issuer)
    cert = cert.public_key(talao_rsa_key.public_key())
    cert = cert.serial_number(x509.random_serial_number())
    cert = cert.not_valid_before(datetime.datetime.utcnow() -
                                 datetime.timedelta(days=1))
    cert = cert.not_valid_after(datetime.datetime.utcnow() +
                                datetime.timedelta(days=3650))
    cert = cert.add_extension(x509.BasicConstraints(ca=True, path_length=None),
                              critical=True)
    cert = cert.add_extension(x509.KeyUsage(digital_signature=True,
                                            key_encipherment=True,
                                            data_encipherment=True,
                                            key_agreement=True,
                                            content_commitment=True,
                                            key_cert_sign=True,
                                            crl_sign=True,
                                            encipher_only=False,
                                            decipher_only=False),
                              critical=False)
    cert = cert.sign(talao_rsa_key, hashes.SHA256())

    # Write this CA certificate out to disk.
    with open('talao.pem', "wb") as f:
        f.write(cert.public_bytes(serialization.Encoding.PEM))
    return
Beispiel #6
0
	def load(self, mode, did) :
		if did.split(':')[1] not in ['web', 'tz', 'ethr', 'key'] :
			raise RepositoryException('DID method not supported')
		self.did = did
		self.private_key = '0x' + PBKDF2(did.encode(), SALT, 32, count=1000000, hmac_hash_module=SHA512).hex()
		self.address = helpers.ethereum_pvk_to_address(self.private_key)
		self.workspace_contract = ownersToContracts(self.address, mode)
		if not self.workspace_contract or self.workspace_contract == '0x0000000000000000000000000000000000000000' :
			logging.warning('no repository for this DID')
			return False
		self.RSA_private = privatekey.get_key(self.address, 'rsa_key', mode)
		if not self.RSA_private :
			logging.warning('RSA file not found')
			return False
		self.public_key = helpers.ethereum_pvk_to_pub(self.private_key)
		self.jwk = helpers.ethereum_to_jwk(self.private_key, 'ethr')
		self.private = privatekey.get_key(self.address, 'private', mode).hex()
		self.secret = privatekey.get_key(self.address, 'secret', mode).hex()
		self.category = get_category(self.workspace_contract, mode)
		self.email = None # need email TODO
		return True
Beispiel #7
0
def did_auth(mode):
    """ login with DID

	DEPRECATED

	@app.route('ssi/login/', methods = ['GET', 'POST'])
	https://github.com/WebOfTrustInfo/rwot6-santabarbara/blob/master/final-documents/did-auth.md
	only based on secp256k1 
	we use webauth more than did auth : we pass the public key to the server to verify the signature of te challenge.
	we do not have the lib to verfy te signatuer from the DID document (except for ion:did and did:web)

	"""
    if request.method == 'GET':
        session.clear()
        session['challenge'] = str(uuid.uuid1())
        payload = {
            "did": "did:web:talao.co",
            "challenge": session['challenge']
        }
        private_key = privatekey.get_key(mode.owner_talao, 'private_key', mode)
        key = helpers.ethereum_to_jwk256k(private_key)
        key = jwt.algorithms.ECAlgorithm.from_jwk(key)
        JWT = jwt.encode(payload, key=key, algorithm="ES256K")
        return render_template('./login/did_auth.html', request=JWT)

    if request.method == 'POST':
        response_dict = json.loads(request.form['response'])
        publicJwk = response_dict['publicJwk']
        did = publicJwk['kid']
        signed_challenge = response_dict['signed_challenge']
        publicKey = jwt.algorithms.ECAlgorithm.from_jwk(publicJwk)
        try:
            decoded = jwt.decode(signed_challenge,
                                 key=publicKey,
                                 algorithms=["ES256K"])
            if decoded['challenge'] == session['challenge']:
                logging.info('Success, Identity logged !')
                wc = ns.get_workspace_contract_from_did(did, mode)
                if not wc:
                    logging.info('User unknown')
                    flash('User unknown', 'warning')
                else:
                    session['workspace_contract'] = wc
                return redirect(mode.server + 'user/')
            else:
                logging.info(
                    'Key is correct but challenge failed, Identity rejected')
                return redirect(mode.server + 'did_auth/')
        except:
            logging.info('Wrong key, Identity rejected')
        return redirect(mode.server + 'did_auth/')
Beispiel #8
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
Beispiel #9
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
Beispiel #10
0
def _create_user_step_2(wallet_address, address, workspace_contract,
                        private_key, username, email, mode,
                        user_aes_encrypted_with_talao_key, decentralized):

    # For ID issuance Talao requests partnership to Identity, (key 3 will be issued too)
    talao_rsa_key = privatekey.get_key(mode.owner_talao, 'rsa_key', mode)
    talao_private_key = privatekey.get_key(mode.owner_talao, 'private_key',
                                           mode)
    if partnershiprequest(mode.owner_talao, mode.workspace_contract_talao,
                          mode.owner_talao, mode.workspace_contract_talao,
                          talao_private_key, workspace_contract, talao_rsa_key,
                          mode, user_aes_encrypted_with_talao_key):
        print('Success : Talao partnership request has been sent')
        if decentralized:
            # get bytes from str received from JS
            user_private_encrypted_with_talao_key = bytes.fromhex(
                user_aes_encrypted_with_talao_key[2:])
            # Identity(user) must accept partnership request
            nonce = mode.w3.eth.getTransactionCount(address)
            contract = mode.w3.eth.contract(workspace_contract,
                                            abi=constante.workspace_ABI)
            txn = contract.functions.authorizePartnership(
                mode.workspace_contract_talao,
                user_private_encrypted_with_talao_key).buildTransaction({
                    'chainId':
                    mode.CHAIN_ID,
                    'gas':
                    6500000,
                    'gasPrice':
                    mode.w3.toWei(mode.GASPRICE, 'gwei'),
                    'nonce':
                    nonce,
                })
            signed_txn = mode.w3.eth.account.signTransaction(txn, private_key)
            mode.w3.eth.sendRawTransaction(signed_txn.rawTransaction)
            h = mode.w3.toHex(mode.w3.keccak(signed_txn.rawTransaction))
            receipt = mode.w3.eth.waitForTransactionReceipt(h,
                                                            timeout=2000,
                                                            poll_latency=1)
            if receipt['status']:
                print(
                    'Success : Talao partnership request has been accepted by Identity (decentralized)'
                )
            else:
                print(
                    'Error : authorize partnership with Talao failed (decentralized)'
                )
        else:
            RSA_private = privatekey.get_key(address, 'rsa_key', mode)
            if authorize_partnership(address, workspace_contract, address,
                                     workspace_contract, private_key,
                                     mode.workspace_contract_talao,
                                     RSA_private, mode):
                print(
                    'Success : Talao partnership request has been accepted by Identity (centralized)'
                )
            else:
                print(
                    'Error : authorize partnership with Talao failed (centralized)'
                )

    else:
        print('Error : partnership request from Talao failed')

    # key 3 issued to Web Relay to issue self claims
    if add_key(address, workspace_contract, address, workspace_contract,
               private_key, mode.relay_address, 3, mode):
        print('Success : key 3 issued to Relay')
    else:
        print('Error : key 3 to Relay failed')

    # key 20002 issued to Web Relay to issue documents for self resume
    if add_key(address, workspace_contract, address, workspace_contract,
               private_key, mode.relay_address, 20002, mode):
        print('Success : key 20002 issued to Relay')
    else:
        print('Error : key 20002 to Relay failed')

    # key 5 to Talao be in  White List
    #if add_key(address, workspace_contract, address, workspace_contract, private_key, mode.owner_talao, 5, mode) :
    #	print('Warning : key 5 issued to Talao')
    #else :
    #	print('Warning : key 5 to Talao failed')

    # key 20002 issued Talao to issue documents
    #if not transfer :
    #	if add_key(address, workspace_contract, address, workspace_contract, private_key, mode.owner_talao, 20002 , mode) :
    #		print('Warning : key 20002 issued to Talao')
    #	else :
    #		print('Warning : key 20002 to Talao failed')

    # rewrite previous email to get an encrypted email with public key
    #if Claim().add(address,workspace_contract, address, workspace_contract,private_key, 'email', email, 'public', mode)[0] :
    #	print('Success : email encryted updated')
    #else :
    #	print('Error : email encrypted not updated')

    print("Success : create identity process step 2 is over")
    return
Beispiel #11
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
Beispiel #12
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
Beispiel #13
0
def generate_X509(workspace_contract, password, mode):

    did = helpers.ethereum_pvk_to_DID(session['private_key_value'],
                                      session['method'])

    talao_issuer = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, "FR"),
        x509.NameAttribute(NameOID.LOCALITY_NAME, "Paris"),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Talao"),
        x509.NameAttribute(NameOID.DOMAIN_COMPONENT, "talao.io"),
        #x509.NameAttribute(NameOID.POSTAL_ADDRESS, "16 rue de wattignies, 75012 Paris"),
        x509.NameAttribute(NameOID.COMMON_NAME, "talao"),
        x509.NameAttribute(NameOID.USER_ID, did),
    ])

    # upload the Talao private rsa key
    talao_rsa_private_key = privatekey.get_key(mode.owner_talao, 'rsa_key',
                                               mode)
    if type(talao_rsa_private_key) == bytes:
        talao_rsa_key = serialization.load_pem_private_key(
            talao_rsa_private_key,
            password=None,
        )
    else:
        talao_rsa_key = serialization.load_pem_private_key(
            bytes(talao_rsa_private_key, 'utf-8'),
            password=None,
        )

    # get identity data
    address = contractsToOwners(workspace_contract, mode)

    rsa_privatekey = privatekey.get_key(address, 'rsa_key', mode)
    if type(rsa_privatekey) == bytes:
        subject_key = serialization.load_pem_private_key(
            rsa_privatekey,
            password=None,
        )
    else:
        subject_key = serialization.load_pem_private_key(
            bytes(rsa_privatekey, 'utf-8'),
            password=None,
        )

    #profil = read_profil(workspace_contract, mode, 'full')[0]
    #name = profil['firstname'] + ' ' + profil['lastname']
    username = ns.get_username_from_resolver(workspace_contract, mode)
    email = ns.get_data_from_username(username, mode)['email']

    subject = x509.Name([
        #x509.NameAttribute(NameOID.COUNTRY_NAME, "FR"),
        #x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, ""),
        #x509.NameAttribute(NameOID.LOCALITY_NAME, "Paris"),
        #x509.NameAttribute(NameOID.ORGANIZATION_NAME, ""),
        x509.NameAttribute(NameOID.COMMON_NAME, session['name']),
        x509.NameAttribute(NameOID.EMAIL_ADDRESS, email),
        x509.NameAttribute(NameOID.USER_ID, did),
    ])

    cert = x509.CertificateBuilder()
    cert = cert.subject_name(subject)
    # talao as CA
    cert = cert.issuer_name(talao_issuer)
    cert = cert.public_key(subject_key.public_key())
    cert = cert.serial_number(x509.random_serial_number())
    cert = cert.not_valid_before(datetime.datetime.utcnow() -
                                 datetime.timedelta(days=1))
    cert = cert.not_valid_after(datetime.datetime.utcnow() +
                                datetime.timedelta(days=3650))
    cert = cert.add_extension(x509.BasicConstraints(ca=False,
                                                    path_length=None),
                              critical=True)
    cert = cert.add_extension(x509.ExtendedKeyUsage([
        x509.oid.ExtendedKeyUsageOID.EMAIL_PROTECTION,
        x509.oid.ExtendedKeyUsageOID.CODE_SIGNING,
        x509.oid.ExtendedKeyUsageOID.TIME_STAMPING
    ]),
                              critical=True)
    #cert=cert.add_extension(x509.SubjectAlternativeName([x509.RFC822Name(email), x509.OtherName(NameOID.COMMON_NAME, bytes(did, 'utf-8'))]),critical=True,)
    #cert=cert.add_extension(x509.SubjectAlternativeName([x509.OtherName(NameOID.COMMON_NAME, bytes(did, 'utf-8'))]),critical=True,)
    cert = cert.add_extension(x509.KeyUsage(digital_signature=True,
                                            key_encipherment=True,
                                            data_encipherment=True,
                                            key_agreement=True,
                                            content_commitment=False,
                                            key_cert_sign=False,
                                            crl_sign=False,
                                            encipher_only=False,
                                            decipher_only=False),
                              critical=True)
    cert = cert.sign(talao_rsa_key, hashes.SHA256())

    # Write our certificate out to disk.
    filename = mode.uploads_path + workspace_contract + ".pem"
    with open(filename, "wb") as f:
        f.write(cert.public_bytes(serialization.Encoding.PEM))

    certificate = pkcs12.serialize_key_and_certificates(
        bytes(did, 'utf-8'), subject_key, cert, None,
        serialization.BestAvailableEncryption(bytes(password, 'utf-8')))
    filename = mode.uploads_path + workspace_contract + ".p12"
    with open(filename, "wb") as f:
        f.write(certificate)
    return True
Beispiel #14
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)
Beispiel #15
0
 def has_relay_rsa_key(self, mode):
     self.rsa_key_value = privatekey.get_key(self.address, 'rsa_key', mode)
     self.rsa_key = False if not self.rsa_key_value else True