/** * Force the password hash to be recalculated and store the new hash in * the database. Return true if the upgrade succeeded. */ private function performUpgrade() { /* Note, that the upgrade CAN be performed even when we don't know the * original password. However, the process in slightly different in * such case. */ if ($this->correctPassword === null) { /* We don't know the password. */ $previousRounds = $this->rounds; if ($previousRounds > $this->wantedHashingRounds) { /* We would have to reduce the number of rounds, which is * impossible in this case. No update can be performed. */ return false; } $this->rounds = $this->wantedHashingRounds; if ($previousRounds <= 1) { /* Since the first round doesn't use a salt, it is safe for us * to change it. */ $this->salt = self::generateRandomString($this->wantedSaltLength); } $this->hash = $this->computeHash($this->hash, $previousRounds); } else { /* The correct password is known. In that case, we will generate * the hash "from scratch", and with a new salt. */ $this->rounds = $this->wantedHashingRounds; $this->salt = self::generateRandomString($this->wantedSaltLength); $this->hash = $this->computeHash($this->correctPassword); } $db = MyDB::getPDO(); $c = $db->prepare("\n update `user`\n set\n password = :password,\n password_salt = :password_salt,\n password_hashing_rounds = :password_hashing_rounds\n where\n user_id = :user_id\n "); $c->bindParam(":user_id", $this->user_id); $c->bindParam(":password", $this->hash); $c->bindParam(":password_salt", $this->salt); $c->bindParam(":password_hashing_rounds", $this->rounds); $c->execute(); return true; }