diff --git a/src/Socialbox/Classes/StandardMethods/SettingsUpdatePassword.php b/src/Socialbox/Classes/StandardMethods/SettingsUpdatePassword.php index eb6b62a..d62339d 100644 --- a/src/Socialbox/Classes/StandardMethods/SettingsUpdatePassword.php +++ b/src/Socialbox/Classes/StandardMethods/SettingsUpdatePassword.php @@ -30,6 +30,16 @@ return $rpcRequest->produceError(StandardError::RPC_INVALID_ARGUMENTS, "Invalid 'password' parameter, must be a valid argon2id hash"); } + if(!$rpcRequest->containsParameter('existing_password')) + { + return $rpcRequest->produceError(StandardError::RPC_INVALID_ARGUMENTS, "Missing 'existing_password' parameter"); + } + + if(!Cryptography::validateSha512($rpcRequest->getParameter('existing_password'))) + { + return $rpcRequest->produceError(StandardError::RPC_INVALID_ARGUMENTS, "Invalid 'existing_password' parameter, must be a valid SHA-512 hash"); + } + try { if (!PasswordManager::usesPassword($request->getPeer()->getUuid())) @@ -42,6 +52,18 @@ throw new StandardException('Failed to check password due to an internal exception', StandardError::INTERNAL_SERVER_ERROR, $e); } + try + { + if (!PasswordManager::verifyPassword($request->getPeer()->getUuid(), $rpcRequest->getParameter('existing_password'))) + { + return $rpcRequest->produceError(StandardError::METHOD_NOT_ALLOWED, "Failed to update password due to incorrect existing password"); + } + } + catch (Exception $e) + { + throw new StandardException('Failed to verify existing password due to an internal exception', StandardError::INTERNAL_SERVER_ERROR, $e); + } + try { // Set the password diff --git a/src/Socialbox/Classes/StandardMethods/VerificationPasswordAuthentication.php b/src/Socialbox/Classes/StandardMethods/VerificationPasswordAuthentication.php new file mode 100644 index 0000000..9954186 --- /dev/null +++ b/src/Socialbox/Classes/StandardMethods/VerificationPasswordAuthentication.php @@ -0,0 +1,49 @@ +containsParameter('password')) + { + return $rpcRequest->produceError(StandardError::RPC_INVALID_ARGUMENTS, "Missing 'password' parameter"); + } + + if(!Cryptography::validateSha512($rpcRequest->getParameter('password'))) + { + return $rpcRequest->produceError(StandardError::RPC_INVALID_ARGUMENTS, "Invalid 'password' parameter, must be a valid SHA-512 hash"); + } + + try + { + return $rpcRequest->produceResponse(PasswordManager::verifyPassword($request->getPeer()->getUuid(), $rpcRequest->getParameter('password'))); + } + catch (CryptographyException $e) + { + return $rpcRequest->produceResponse(false); + } + catch (Exception $e) + { + Logger::getLogger()->error('Failed to verify password due to an internal exception', $e); + throw new StandardException('Failed to verify password due to an internal exception', StandardError::INTERNAL_SERVER_ERROR, $e); + } + } + } \ No newline at end of file diff --git a/src/Socialbox/Managers/PasswordManager.php b/src/Socialbox/Managers/PasswordManager.php index 0a6947c..e9c3b26 100644 --- a/src/Socialbox/Managers/PasswordManager.php +++ b/src/Socialbox/Managers/PasswordManager.php @@ -59,7 +59,10 @@ } // Throws an exception if the hash is invalid - Cryptography::validatePasswordHash($hash); + if(!Cryptography::validatePasswordHash($hash)) + { + throw new CryptographyException('Invalid password hash'); + } $encryptionKey = Configuration::getCryptographyConfiguration()->getRandomInternalEncryptionKey(); $securedPassword = Cryptography::encryptMessage($hash, $encryptionKey, Configuration::getCryptographyConfiguration()->getEncryptionKeysAlgorithm()); @@ -94,7 +97,10 @@ $peerUuid = $peerUuid->getUuid(); } - Cryptography::validatePasswordHash($hash); + if(!Cryptography::validatePasswordHash($hash)) + { + throw new CryptographyException('Invalid password hash'); + } $encryptionKey = Configuration::getCryptographyConfiguration()->getRandomInternalEncryptionKey(); $securedPassword = Cryptography::encryptMessage($hash, $encryptionKey, Configuration::getCryptographyConfiguration()->getEncryptionKeysAlgorithm()); @@ -145,20 +151,18 @@ * Verifies a given password against a stored password hash for a specific peer. * * @param string|RegisteredPeerRecord $peerUuid The unique identifier of the peer, or an instance of RegisteredPeerRecord. - * @param string $hash The password hash to verify. + * @param string $sha512 The SHA-512 hash of the password to be verified. * @return bool Returns true if the password matches the stored hash; false otherwise. * @throws CryptographyException If the password hash is invalid or an error occurs during the cryptographic operation. * @throws DatabaseOperationException If an error occurs during the database operation. */ - public static function verifyPassword(string|RegisteredPeerRecord $peerUuid, string $hash): bool + public static function verifyPassword(string|RegisteredPeerRecord $peerUuid, string $sha512): bool { if($peerUuid instanceof RegisteredPeerRecord) { $peerUuid = $peerUuid->getUuid(); } - Cryptography::validatePasswordHash($hash); - try { $stmt = Database::getConnection()->prepare('SELECT hash FROM authentication_passwords WHERE peer_uuid=:uuid'); @@ -190,7 +194,7 @@ throw new CryptographyException('Cannot decrypt hashed password'); } - return Cryptography::verifyPassword($hash, $decryptedHash); + return Cryptography::verifyPassword($sha512, $decryptedHash); } catch(PDOException $e) {