def do_request(SRPsession, req, do_network, db_server): SRPKsession_b64, sid_b64 = SRPsession enc1_b64,mac1_b64,enc2_b64,mac2_b64 = make_session_keys(SRPKsession_b64) msg = client_create_request(req, enc1_b64, mac1_b64, sid_b64) rx = do_network(db_server, msg) return client_process_response(rx, enc2_b64, mac2_b64)
def receive_request(self, tx): # HTTP body is utf8(json(PIECES)) pieces = json.loads(tx.decode("utf-8")) if pieces[0] == "magic-init": # PIECES = ["magic-init", email, b64(SRPv)] # reponse: "ok" print "MAGIC" email, SRPverifier_b64 = pieces[1:3] self.SRPverifier_b64[email] = SRPverifier_b64 return "ok" if pieces[0] == "srp-1": # PIECES = ["srp-1", b64(sessionid), email, b64(A)] # response: utf8(json(["ok", b64(s), b64(B)])) sid_b64, email, A_b64 = pieces[1:4] if sid_b64 in self.verifiers or sid_b64 in self.sessions: raise Oops("sessionid already claimed") salt = "" vkey = b64decode(self.SRPverifier_b64[email]) v = srp.Verifier(email.encode("utf-8"), salt, vkey, b64decode(A_b64), hash_alg=srp.SHA256) self.verifiers[sid_b64] = (v, email) s,B = v.get_challenge() if s is None or B is None: raise Oops("SRP rejected (A)") resp = ["ok", b64encode(s), b64encode(B)] return json.dumps(resp).encode("utf-8") if pieces[0] == "srp-2": # PIECES = ["srp-2", b64(sessionid), b64(M)] # response: utf8(json(["ok", b64(HAMK)])) sid_b64, M_b64 = pieces[1:3] if sid_b64 not in self.verifiers: raise Oops("no such session") if sid_b64 in self.sessions: raise Oops("sessionid already claimed") (v,email) = self.verifiers.pop(sid_b64) HAMK = v.verify_session(b64decode(M_b64)) if HAMK is None: raise Oops("SRP rejected (M)") if not v.authenticated(): raise Oops("SRP rejected") k_b64 = b64encode(v.get_session_key()) self.sessions[sid_b64] = (k_b64, email) resp = ["ok", b64encode(HAMK)] return json.dumps(resp).encode("utf-8") if pieces[0] == "encrypted-request": # PIECES = ["encrypted-request", b64(sessionid), b64(encreqdata)] # reqdata = utf8(json([REQ])) # response = b64(enc(utf8(json(RESP))) sid_b64, enc_req_b64 = (pieces[1], pieces[2]) if sid_b64 not in self.sessions: raise Oops("no such session") # We use very short-lived sessions for now: just one request. # TODO: need to time out old sessions, say after 5 minutes. k_b64,email = self.sessions.pop(sid_b64) (enc1_b64,mac1_b64,enc2_b64,mac2_b64) = make_session_keys(k_b64) rd_b64 = decrypt(enc1_b64, mac1_b64, enc_req_b64) req = json.loads(b64decode(rd_b64).decode("utf-8")) response = self.process_request(email, req) response_data_b64 = b64encode(json.dumps(response).encode("utf-8")) rx_b64 = encrypt_and_mac(enc2_b64, mac2_b64, response_data_b64) return rx_b64 print "bad request", pieces raise Oops("bad request")