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')
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
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)
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
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
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/')
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
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
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
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
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
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
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)
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