Пример #1
0
    def gen_user_pwrd_hash_and_salt(self,
                                    user_pass,
                                    hash_func=SHA256.new,
                                    rand_pool=Random.new()):
        def gen_user_salt(rand_pool, num_salt_bytes=USR_DB_SALT_SIZE):
            return (rand_pool.read(num_salt_bytes))

        def gen_user_hash(user_pwrd, user_salt, hash_func=SHA256_HASH_FUNC):
            assert (type(user_pwrd) == str)
            assert (type(user_salt) == str)

            user_hash = hash_func(user_pwrd + user_salt)

            for i in xrange(PWRD_HASH_ROUNDS):
                user_hash = hash_func(user_hash.digest() + user_salt)

            return (user_hash.digest())

        user_pass = DECODE_FUNC(user_pass.encode("utf-8"))
        user_salt = gen_user_salt(rand_pool)
        user_hash = gen_user_hash(user_pass, user_salt, hash_func)

        assert (type(user_salt) == str)
        assert (type(user_hash) == str)
        return (ENCODE_FUNC(user_hash), ENCODE_FUNC(user_salt))
Пример #2
0
	def out_LOGIN(self):
		#print("[LOGIN][time=%d::iter=%d] sec_sess=%d" % (time.time(), self.iters, self.use_secure_session()))
		if (self.use_secure_session()):
			password = ENCODE_FUNC(self.password)
		else:
			password = ENCODE_FUNC(LEGACY_HASH_FUNC(self.password).digest())
		self.Send("LOGIN %s %s 0 *\tstresstester client\t0\tsp cl p" % (self.username, password))

		self.requested_authentication = True
Пример #3
0
	def out_REGISTER(self):
		print("[REGISTER][time=%d::iter=%d] sec_sess=%d" % (time.time(), self.iters, self.use_secure_session()))

		if (self.use_secure_session()):
			self.Send("REGISTER %s %s" % (self.username, ENCODE_FUNC(self.password)))
		else:
			self.Send("REGISTER %s %s" % (self.username, ENCODE_FUNC(LEGACY_HASH_FUNC(self.password).digest())))

		self.requested_registration = True
Пример #4
0
	def in_SHAREDKEY(self, key_status, key_digest, extra_data = ""):
		assert(self.received_public_key)
		assert(self.sent_unacked_shared_key)
		assert(not self.server_valid_shared_key)
		assert(not self.client_acked_shared_key)

		print("[SHAREDKEY][time=%d::iter=%d] %s %s %s" % (time.time(), self.iters, key_status, key_digest, extra_data))

		can_send_ack_shared_key = False

		if (key_status == "INITSESS"):
			## special case during first session-key exchange
			assert(not self.use_secure_session())
			assert(len(self.session_keys[self.session_key_id]) != 0)

			self.set_session_key(self.session_keys[self.session_key_id])
			return

		elif (key_status == "ACCEPTED"):
			server_key_sig = SAFE_DECODE_FUNC(key_digest)
			client_key_sha = SECURE_HASH_FUNC(self.session_keys[self.session_key_id])
			client_key_sig = client_key_sha.digest()

			print("\tserver_key_sig=%s\n\tclient_key_sig=%s (id=%d)" % (ENCODE_FUNC(server_key_sig), ENCODE_FUNC(client_key_sig), self.session_key_id))

			## server considers key valid and has accepted it
			## now check for data manipulation or corruption
			## before sending back our final acknowledgement
			self.server_valid_shared_key = True

			can_send_ack_shared_key = (server_key_sig == client_key_sig)

		elif (key_status == "DISABLED"):
			self.reset_session_state()
			self.set_session_key("")

			## never sent, no longer supported by server
			assert(False)
			return

		if (not can_send_ack_shared_key):
			## if this was triggered during an actual key RE-negotiation
			## (much more unlikely) the client's only option would be to
			## disconnect and initialize a new session
			assert(key_status != "ACCEPTED")

			self.sent_unacked_shared_key = False
			self.server_valid_shared_key = False
			self.client_acked_shared_key = False

			## try again with a new session key
			##
			## this assumes we did NOT get an ACCEPTED, which
			## would indicate data corruption or manipulation
			self.out_SETSHAREDKEY()
		else:
			## let server know it can begin sending secure data
			self.out_ACKSHAREDKEY()
Пример #5
0
	def out_GETSIGNEDMSG(self):
		assert(self.received_public_key)
		assert(not self.sent_unacked_shared_key)
		assert(not self.server_valid_shared_key)
		assert(not self.client_acked_shared_key)

		print("[GETSIGNEDMSG][time=%d::iter=%d]" % (time.time(), self.iters))

		self.Send("GETSIGNEDMSG %s" % ENCODE_FUNC(MAGIC_WORDS))
Пример #6
0
    def secure_test_user_pwrd(self,
                              user_inst,
                              user_pwrd,
                              hash_func=SHA256.new):
        user_pwrd = DECODE_FUNC(user_pwrd.encode("utf-8"))
        user_salt = DECODE_FUNC(user_inst.randsalt.encode("utf-8"))
        user_hash = hash_func(user_pwrd + user_salt)

        for i in xrange(PWRD_HASH_ROUNDS):
            user_hash = hash_func(user_hash.digest() + user_salt)

        return (user_inst.password.encode("utf-8") == ENCODE_FUNC(
            user_hash.digest()))
Пример #7
0
    def out_SETSHAREDKEY(self):
        assert (self.received_public_key)
        assert (not self.sent_unacked_shared_key)
        assert (not self.server_valid_shared_key)
        assert (not self.client_acked_shared_key)

        def generate_session_key(num_bytes=CryptoHandler.MIN_AES_KEY_SIZE * 2):
            ## encrypt converts its argument to a long, so the
            ## MSB should *always* be non-zero or D(E(K)) != K
            key_head = "\x00"
            key_tail = GLOBAL_RAND_POOL.read(num_bytes - 1)

            while (ord(key_head) == 0):
                key_head = GLOBAL_RAND_POOL.read(1)

            return (key_head + key_tail)

        ## note: server will use HASH(RAW) as key and echo back HASH(HASH(RAW))
        ## hence we send ENCODE(ENCRYPT(RAW)) and use HASH(RAW) on our side too
        aes_key_raw = generate_session_key()
        aes_key_sig = SECURE_HASH_FUNC(aes_key_raw)
        aes_key_enc = self.rsa_cipher_obj.encrypt_encode_bytes(aes_key_raw)

        ## make a copy of the previous key (if any) since
        ## we still need it to decrypt SHAREDKEY response
        ## etc
        self.session_keys[(self.session_key_id + 0) %
                          NUM_SESSION_KEYS] = self.aes_cipher_obj.get_key()
        self.session_keys[(self.session_key_id + 1) %
                          NUM_SESSION_KEYS] = aes_key_sig.digest()

        ## wrap around when we reach the largest allowed id
        self.session_key_id += 1
        self.session_key_id %= NUM_SESSION_KEYS

        print("[SETSHAREDKEY][time=%d::iter=%d] client_key_sig=%s" %
              (time.time(), self.iters,
               ENCODE_FUNC(SECURE_HASH_FUNC(aes_key_sig.digest()).digest())))

        ## when re-negotiating a key during an established session,
        ## reset_session_state() makes this false but we need it to
        ## be true temporarily to get the message out
        self.client_acked_shared_key = self.use_secure_session()

        ## ENCODE(ENCRYPT_RSA(AES_KEY, RSA_PUB_KEY))
        self.Send("SETSHAREDKEY %s" % aes_key_enc)

        self.client_acked_shared_key = False
        self.sent_unacked_shared_key = True
Пример #8
0
    def convert_legacy_user_pwrd(self, session, db_user, password):
        assert (db_user != None)
        assert (len(db_user.randsalt) == 0)

        ## in a secure session, so password was only base64-encoded
        ## by client and we must apply B64ENCODE(MD5(B64DECODE(..)))
        ## to it first
        legacy_pwrd = password.encode("utf-8")
        legacy_pwrd = DECODE_FUNC(legacy_pwrd)
        legacy_pwrd = MD5.new(legacy_pwrd)
        legacy_pwrd = ENCODE_FUNC(legacy_pwrd.digest())
        legacy_pwrd = legacy_pwrd.decode("utf-8")

        ## check if a legacy LOGIN would succeed with given password
        if (not self.legacy_test_user_pwrd(db_user, legacy_pwrd)):
            return False

        ## commit new-style password(-hash) and salt to DB
        db_user.set_pwrd_salt(self.gen_user_pwrd_hash_and_salt(password))
        session.commit()

        assert (not db_user.has_legacy_password())
        assert (self.secure_test_user_pwrd(db_user, password))
        return True
Пример #9
0
	def EncodePassword(self, password):
		return ENCODE_FUNC(md5(self.password.encode()).digest()).decode()
Пример #10
0
def encode_password(password):
    return ENCODE_FUNC(md5(password.encode()).digest()).decode()
Пример #11
0
	def out_REGISTER(self):
		print("[REGISTER][time=%d::iter=%d]" % (time.time(), self.iters))

		self.Send("REGISTER %s %s" % (self.username, ENCODE_FUNC(LEGACY_HASH_FUNC(self.password).digest())))

		self.requested_registration = True
Пример #12
0
	def out_LOGIN(self):
		print("[LOGIN][time=%d::iter=%d]" % (time.time(), self.iters))

		self.Send("LOGIN %s %s" % (self.username, ENCODE_FUNC(LEGACY_HASH_FUNC(self.password.encode("utf-8")).digest())))

		self.requested_authentication = True