Refactor cryptography handling and improve test coverage

This commit is contained in:
netkas 2024-10-24 13:55:21 -04:00
parent 26593d37e4
commit 0f5c8b40e2
18 changed files with 66 additions and 30 deletions

View file

@ -8,8 +8,8 @@ use Socialbox\Exceptions\StandardException;
use Socialbox\Interfaces\SerializableInterface;
use Socialbox\Managers\SessionManager;
use Socialbox\Objects\ClientRequest;
use Socialbox\Objects\Database\SessionRecord;
use Socialbox\Objects\RpcRequest;
use Socialbox\Objects\SessionRecord;
abstract class Method
{

View file

@ -108,14 +108,28 @@ class Cryptography
*/
public static function verifyContent(string $content, string $signature, string $publicKey): bool
{
$publicKey = openssl_pkey_get_public(self::derToPem(Utilities::base64decode($publicKey), self::PEM_PUBLIC_HEADER));
try
{
$publicKey = openssl_pkey_get_public(self::derToPem(Utilities::base64decode($publicKey), self::PEM_PUBLIC_HEADER));
}
catch(InvalidArgumentException $e)
{
throw new CryptographyException('Failed to decode public key: ' . $e->getMessage());
}
if (!$publicKey)
{
throw new CryptographyException('Invalid public key: ' . openssl_error_string());
}
return openssl_verify($content, base64_decode($signature), $publicKey, self::HASH_ALGORITHM) === 1;
try
{
return openssl_verify($content, Utilities::base64decode($signature), $publicKey, self::HASH_ALGORITHM) === 1;
}
catch(InvalidArgumentException $e)
{
throw new CryptographyException('Failed to verify content: ' . $e->getMessage());
}
}
/**

View file

@ -2,10 +2,10 @@
namespace Socialbox\Classes;
use Exception;
use InvalidArgumentException;
use RuntimeException;
use Socialbox\Enums\StandardHeaders;
use Socialbox\Exceptions\CryptographyException;
use Socialbox\Exceptions\DatabaseOperationException;
use Socialbox\Exceptions\RpcException;
use Socialbox\Exceptions\StandardException;
@ -87,25 +87,31 @@ class RpcHandler
try
{
$session = SessionManager::getSession($clientRequest->getSessionUuid());
// Verify the signature of the request
if(!Cryptography::verifyContent($clientRequest->getHash(), $clientRequest->getSignature(), $session->getPublicKey()))
{
throw new RpcException('Request signature check failed', 400);
}
}
catch(StandardException $e)
{
throw new RpcException($e->getMessage(), 400);
}
catch(CryptographyException $e)
{
throw new RpcException('Request signature check failed (Cryptography Error)', 400, $e);
}
catch(DatabaseOperationException $e)
{
throw new RpcException('Failed to verify session', 500, $e);
}
try
{
if(!Cryptography::verifyContent($clientRequest->getHash(), $clientRequest->getSignature(), $session->getPublicKey()))
{
throw new RpcException('Request signature check failed', 400);
}
}
catch(RpcException $e)
{
throw $e;
}
catch(Exception $e)
{
throw new RpcException('Request signature check failed (Cryptography Error): ' . $e->getMessage(), 400, $e);
}
}
return $clientRequest;

View file

@ -40,8 +40,6 @@ class CreateSession extends Method
return $rpcRequest->produceError(StandardError::RPC_INVALID_ARGUMENTS, $e->getMessage());
}
return $rpcRequest->produceResponse([
'uuid' => $uuid
]);
return $rpcRequest->produceResponse($uuid);
}
}

View file

@ -43,7 +43,7 @@ class Utilities
}
catch(\JsonException $e)
{
throw new \RuntimeException("Failed to encode json input", $e);
throw new InvalidArgumentException("Failed to encode json input", $e);
}
}

View file

@ -9,12 +9,11 @@
use PDOException;
use Socialbox\Classes\Cryptography;
use Socialbox\Classes\Database;
use Socialbox\Classes\Utilities;
use Socialbox\Enums\SessionState;
use Socialbox\Enums\StandardError;
use Socialbox\Exceptions\DatabaseOperationException;
use Socialbox\Exceptions\StandardException;
use Socialbox\Objects\SessionRecord;
use Socialbox\Objects\Database\SessionRecord;
use Symfony\Component\Uid\Uuid;
class SessionManager
@ -41,7 +40,6 @@
throw new InvalidArgumentException('The given public key is invalid', 400);
}
$publicKey = Utilities::base64decode($publicKey);
$uuid = Uuid::v4()->toRfc4122();
try

View file

@ -1,6 +1,6 @@
<?php
namespace Socialbox\Objects;
namespace Socialbox\Objects\Database;
use DateTime;
use Socialbox\Enums\SessionState;

View file

@ -47,7 +47,6 @@
}
catch(Exception $e)
{
var_dump($e);
if(Configuration::getConfiguration()['security']['display_internal_exceptions'])
{
$response = $rpcRequest->produceError(StandardError::INTERNAL_SERVER_ERROR, Utilities::throwableToString($e));