def decrypt(data, _key): """ ACCEPT BYTES -> UTF8 -> JSON -> {"salt":s, "length":l, "data":d} """ # Key and iv have not been generated or provided, bail out if _key is None: Log.error("Expecting a key") _input = get_module("mo_json").json2value(data.decode("utf8"), leaves=False, flexible=False) # Initialize encryption using key and iv key_expander_256 = key_expander.KeyExpander(256) expanded_key = key_expander_256.expand(_key) aes_cipher_256 = aes_cipher.AESCipher(expanded_key) aes_cbc_256 = cbc_mode.CBCMode(aes_cipher_256, 16) aes_cbc_256.set_iv(base642bytes(_input.salt)) raw = base642bytes(_input.data) out_data = bytearray() for _, e in _groupby16(raw): out_data.extend(aes_cbc_256.decrypt_block(e)) if _input.encoding: return binary_type(out_data[:_input.length:]).decode(_input.encoding) else: return binary_type(out_data[:_input.length:])
def verify(signed, public_key): data = base642bytes(signed.data) signature = base642bytes(signed.signature) key = RSAPublicNumbers(public_key.e, base642int(public_key.n)).public_key(BACKEND) key.verify( signature=signature, data=data, padding=PADDING.get(signed.padding, PSS), algorithm=ALGORITHM.get(signed.algorithm, SHA256), ) return json2value(data.decode("utf8"))
def device_register(self, path=None): """ EXPECTING A SIGNED REGISTRATION REQUEST RETURN JSON WITH url FOR LOGIN """ now = Date.now() expires = now + parse(self.device.register.session['max-age']) request_body = request.get_data() signed = json2value(request_body.decode("utf8")) command = json2value(base642bytes(signed.data).decode("utf8")) session.public_key = command.public_key rsa_crypto.verify(signed, session.public_key) self.session_manager.create_session(session) session.expires = expires.unix session.state = bytes2base64URL(crypto.bytes(32)) with self.device.db.transaction() as t: t.execute( sql_insert( self.device.table, { "state": session.state, "session_id": session.session_id }, )) body = value2json( Data( session_id=session.session_id, interval="5second", expires=session.expires, url=URL( self.device.home, path=self.device.endpoints.login, query={"state": session.state}, ), )) response = Response(body, headers={"Content-Type": mimetype.JSON}, status=200) response.set_cookie(self.device.register.session.name, session.session_id, path=self.device.login.session.path, domain=self.device.login.session.domain, expires=expires.format(RFC1123), secure=self.device.login.session.secure, httponly=self.device.login.session.httponly) return response
def device_register(self, path=None): """ EXPECTING A SIGNED REGISTRATION REQUEST RETURN JSON WITH url FOR LOGIN """ now = Date.now().unix request_body = request.get_data().strip() signed = json2value(request_body.decode("utf8")) command = json2value(base642bytes(signed.data).decode("utf8")) session.public_key = command.public_key rsa_crypto.verify(signed, session.public_key) self.session_manager.setup_session(session) session.expires = now + parse("10minute").seconds session.state = bytes2base64URL(Random.bytes(32)) with self.device.db.transaction() as t: t.execute( sql_insert( self.device.table, { "state": session.state, "session_id": session.session_id }, )) response = value2json( Data( session_id=session.session_id, interval="5second", expiry=session.expires, url=URL( self.device.home, path=self.device.endpoints.login, query={"state": session.state}, ), )) return Response(response, headers={"Content-Type": "application/json"}, status=200)