Example #1
0
def do_init(email, password_b64, db_server, do_network, scrypt_server):
    UK_b64 = b64encode(os.urandom(2*KEYLEN))
    print "UK created:", UK_b64

    keys = build_PWK(email, password_b64, scrypt_server, do_network)
    PWK_b64, MAC_b64, SRPpw_b64 = keys
    SRPv_b64 = do_SRP_setup(SRPpw_b64, email)
    MAGIC_SEND_SAFELY(db_server, [email, SRPv_b64], do_network)

    WUK_b64 = encrypt_and_mac(PWK_b64, MAC_b64, UK_b64)
    SRPsession = do_SRP(db_server, email, SRPpw_b64, do_network)
    resp = do_request(SRPsession, ["set", WUK_b64], do_network, db_server)
    if resp[0] != "ok":
        raise Oops("server reject")
    return UK_b64
Example #2
0
def do_change(email, old_password_b64, new_password_b64, db_server, do_network,
              scrypt_server):
    # read the old password, compute the new secrets, send a change request
    UK_b64, old_SRPpw_b64 = read(email, old_password_b64, db_server, do_network,
                                 scrypt_server)

    keys = build_PWK(email, new_password_b64, scrypt_server, do_network)
    (new_PWK_b64, new_MAC_b64, new_SRPpw_b64) = keys
    new_SRPv_b64 = do_SRP_setup(new_SRPpw_b64, email)
    new_WUK_b64 = encrypt_and_mac(new_PWK_b64, new_MAC_b64, UK_b64)

    SRPsession = do_SRP(db_server, email, old_SRPpw_b64, do_network)
    resp = do_request(SRPsession,
                      ["change", new_SRPv_b64, new_WUK_b64],
                      do_network, db_server)
    if resp[0] != "ok":
        raise Oops("server reject")
Example #3
0
 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")