Major changes, revamp required
This commit is contained in:
parent
1f9890bba0
commit
29a3d42538
20 changed files with 523 additions and 662 deletions
|
@ -166,6 +166,10 @@
|
|||
// value that exceeds this limit, the server will use this limit instead.
|
||||
// recommendation: 100
|
||||
$config->setDefault('policies.get_contacts_limit', 100);
|
||||
$config->setDefault('policies.get_encryption_channel_requests_limit', 100);
|
||||
$config->setDefault('policies.get_encryption_channels_limit', 100);
|
||||
$config->setDefault('policies.get_encryption_channel_incoming_limit', 100);
|
||||
$config->setDefault('policies.get_encryption_channel_outgoing_limit', 100);
|
||||
|
||||
// Default privacy states for information fields associated with the peer
|
||||
$config->setDefault('policies.default_display_picture_privacy', 'PUBLIC');
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
private int $imageCaptchaExpires;
|
||||
private int $peerSyncInterval;
|
||||
private int $getContactsLimit;
|
||||
private int $getEncryptionChannelRequestsLimit;
|
||||
private int $getEncryptionChannelsLimit;
|
||||
private int $getEncryptionChannelIncomingLimit;
|
||||
private int $getEncryptionChannelOutgoingLimit;
|
||||
private PrivacyState $defaultDisplayPicturePrivacy;
|
||||
private PrivacyState $defaultFirstNamePrivacy;
|
||||
private PrivacyState $defaultMiddleNamePrivacy;
|
||||
|
@ -43,6 +47,10 @@
|
|||
$this->imageCaptchaExpires = $data['image_captcha_expires'];
|
||||
$this->peerSyncInterval = $data['peer_sync_interval'];
|
||||
$this->getContactsLimit = $data['get_contacts_limit'];
|
||||
$this->getEncryptionChannelRequestsLimit = $data['get_encryption_channel_requests_limit'];
|
||||
$this->getEncryptionChannelsLimit = $data['get_encryption_channels_limit'];
|
||||
$this->getEncryptionChannelIncomingLimit = $data['get_encryption_channel_incoming_limit'];
|
||||
$this->getEncryptionChannelOutgoingLimit = $data['get_encryption_channel_outgoing_limit'];
|
||||
$this->defaultDisplayPicturePrivacy = PrivacyState::tryFrom($data['default_display_picture_privacy']) ?? PrivacyState::PRIVATE;
|
||||
$this->defaultFirstNamePrivacy = PrivacyState::tryFrom($data['default_first_name_privacy']) ?? PrivacyState::PRIVATE;
|
||||
$this->defaultMiddleNamePrivacy = PrivacyState::tryFrom($data['default_middle_name_privacy']) ?? PrivacyState::PRIVATE;
|
||||
|
@ -110,6 +118,46 @@
|
|||
return $this->getContactsLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum number of encryption channel requests that can be retrieved in a single request
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getEncryptionChannelRequestsLimit(): int
|
||||
{
|
||||
return $this->getEncryptionChannelRequestsLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum number of encryption channels that can be retrieved in a single request
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getEncryptionChannelsLimit(): int
|
||||
{
|
||||
return $this->getEncryptionChannelsLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum number of incoming encryption channels that can be retrieved in a single request
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getEncryptionChannelIncomingLimit(): int
|
||||
{
|
||||
return $this->getEncryptionChannelIncomingLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum number of outgoing encryption channels that can be retrieved in a single request
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getEncryptionChannelOutgoingLimit(): int
|
||||
{
|
||||
return $this->getEncryptionChannelOutgoingLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default privacy state for the display picture
|
||||
*
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
use Socialbox\Exceptions\DatabaseOperationException;
|
||||
use Socialbox\Exceptions\ResolutionException;
|
||||
use Socialbox\Exceptions\RpcException;
|
||||
use Socialbox\Objects\Client\EncryptionChannelSecret;
|
||||
use Socialbox\Objects\Client\ExportedSession;
|
||||
use Socialbox\Objects\Client\SignatureKeyPair;
|
||||
use Socialbox\Objects\KeyPair;
|
||||
|
@ -39,6 +40,7 @@
|
|||
private string $sessionUuid;
|
||||
private ?string $defaultSigningKey;
|
||||
private array $signingKeys;
|
||||
private array $encryptionChannelSecrets;
|
||||
|
||||
/**
|
||||
* Constructs a new instance with the specified peer address.
|
||||
|
@ -78,6 +80,7 @@
|
|||
$this->serverTransportEncryptionKey = $exportedSession->getServerTransportEncryptionKey();
|
||||
$this->signingKeys = $exportedSession->getSigningKeys();
|
||||
$this->defaultSigningKey = $exportedSession->getDefaultSigningKey();
|
||||
$this->encryptionChannelSecrets = $exportedSession->getEncryptionChannelSecrets();
|
||||
|
||||
// Still solve the server information
|
||||
$this->serverInformation = self::getServerInformation();
|
||||
|
@ -107,6 +110,7 @@
|
|||
|
||||
// Set the initial properties
|
||||
$this->signingKeys = [];
|
||||
$this->encryptionChannelSecrets = [];
|
||||
$this->defaultSigningKey = null;
|
||||
$this->identifiedAs = $identifiedAs;
|
||||
$this->remoteServer = $server ?? $identifiedAs->getDomain();
|
||||
|
@ -771,6 +775,17 @@
|
|||
return $this->signingKeys[$uuid] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a signing key from the current instance.
|
||||
*
|
||||
* @param string $uuid The UUID of the signing key to be deleted.
|
||||
* @return void
|
||||
*/
|
||||
public function deleteSigningKey(string $uuid): void
|
||||
{
|
||||
unset($this->signingKeys[$uuid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the default signing key associated with the current instance.
|
||||
*
|
||||
|
@ -797,6 +812,71 @@
|
|||
$this->defaultSigningKey = $uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the encryption channel keys associated with the current instance.
|
||||
*
|
||||
* @return EncryptionChannelSecret[] The encryption channel keys.
|
||||
*/
|
||||
public function getEncryptionChannelSecrets(): array
|
||||
{
|
||||
return $this->encryptionChannelSecrets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new encryption channel key to the current instance.
|
||||
*
|
||||
* @param EncryptionChannelSecret $key The encryption channel key to be added.
|
||||
* @return void
|
||||
*/
|
||||
public function addEncryptionChannelSecret(EncryptionChannelSecret $key): void
|
||||
{
|
||||
$this->encryptionChannelSecrets[$key->getChannelUuid()] = $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an encryption channel key from the current instance.
|
||||
*
|
||||
* @param string $uuid The UUID of the encryption channel key to be removed.
|
||||
* @return void
|
||||
*/
|
||||
public function removeEncryptionChannelKey(string $uuid): void
|
||||
{
|
||||
unset($this->encryptionChannelSecrets[$uuid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the encryption channel key associated with the specified UUID.
|
||||
*
|
||||
* @param string $uuid The UUID of the encryption channel key to be retrieved.
|
||||
* @return EncryptionChannelSecret|null The encryption channel key associated with the UUID, or null if not found.
|
||||
*/
|
||||
public function getEncryptionChannelKey(string $uuid): ?EncryptionChannelSecret
|
||||
{
|
||||
return $this->encryptionChannelSecrets[$uuid] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an encryption channel key exists with the specified UUID.
|
||||
*
|
||||
* @param string $uuid The UUID of the encryption channel key to check.
|
||||
* @return bool True if the encryption channel key exists, false otherwise.
|
||||
*/
|
||||
public function encryptionChannelKeyExists(string $uuid): bool
|
||||
{
|
||||
return isset($this->encryptionChannelSecrets[$uuid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an encryption channel key from the current instance.
|
||||
*
|
||||
* @param string $uuid The UUID of the encryption channel key to be deleted.
|
||||
* @return void
|
||||
*/
|
||||
public function deleteEncryptionChannelKey(string $uuid): void
|
||||
{
|
||||
unset($this->encryptionChannelSecrets[$uuid]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports the current session details into an ExportedSession object.
|
||||
*
|
||||
|
@ -821,7 +901,8 @@
|
|||
'client_transport_encryption_key' => $this->clientTransportEncryptionKey,
|
||||
'server_transport_encryption_key' => $this->serverTransportEncryptionKey,
|
||||
'default_signing_key' => $this->defaultSigningKey,
|
||||
'signing_keys' => array_map(fn(SignatureKeyPair $key) => $key->toArray(), $this->signingKeys)
|
||||
'signing_keys' => array_map(fn(SignatureKeyPair $key) => $key->toArray(), $this->signingKeys),
|
||||
'encryption_channel_secrets' => array_map(fn(EncryptionChannelSecret $key) => $key->toArray(), $this->encryptionChannelSecrets)
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use Socialbox\Abstracts\Method;
|
||||
use Socialbox\Classes\Validator;
|
||||
use Socialbox\Enums\StandardError;
|
||||
use Socialbox\Exceptions\Standard\InvalidRpcArgumentException;
|
||||
use Socialbox\Exceptions\Standard\MissingRpcArgumentException;
|
||||
|
@ -16,7 +17,7 @@
|
|||
use Socialbox\Socialbox;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
class ResolvePeerSignature extends Method
|
||||
class ResolveSignature extends Method
|
||||
{
|
||||
|
||||
/**
|
||||
|
@ -30,30 +31,17 @@
|
|||
throw new MissingRpcArgumentException('peer');
|
||||
}
|
||||
|
||||
if(!$rpcRequest->containsParameter('uuid'))
|
||||
if(!$rpcRequest->containsParameter('signature_uuid'))
|
||||
{
|
||||
throw new MissingRpcArgumentException('uuid');
|
||||
throw new MissingRpcArgumentException('signature_uuid');
|
||||
}
|
||||
elseif(!Validator::validateUuid($rpcRequest->getParameter('signature_uuid')))
|
||||
{
|
||||
throw new InvalidRpcArgumentException('signature_uuid', 'Invalid UUID V4');
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$uuid = Uuid::fromString($rpcRequest->getParameter('uuid'));
|
||||
}
|
||||
catch(InvalidArgumentException $e)
|
||||
{
|
||||
throw new InvalidRpcArgumentException('uuid', $e);
|
||||
}
|
||||
|
||||
// Parse the peer address
|
||||
try
|
||||
{
|
||||
$peerAddress = PeerAddress::fromAddress($rpcRequest->getParameter('peer'));
|
||||
}
|
||||
catch(InvalidArgumentException $e)
|
||||
{
|
||||
throw new InvalidRpcArgumentException('peer', $e);
|
||||
}
|
||||
|
||||
return $rpcRequest->produceResponse(Socialbox::resolvePeerSignature($peerAddress, $uuid->toRfc4122()));
|
||||
return $rpcRequest->produceResponse(Socialbox::resolvePeerSignature(
|
||||
$rpcRequest->getParameter('peer'), $rpcRequest->getParameter('signature_uuid')
|
||||
));
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
use Socialbox\Objects\RpcRequest;
|
||||
use Socialbox\Socialbox;
|
||||
|
||||
class VerifyPeerSignature extends Method
|
||||
class VerifySignature extends Method
|
||||
{
|
||||
|
||||
/**
|
||||
|
@ -37,11 +37,6 @@
|
|||
throw new InvalidRpcArgumentException('signature_uuid', 'Invalid UUID V4');
|
||||
}
|
||||
|
||||
if(!$rpcRequest->containsParameter('signature_public_key'))
|
||||
{
|
||||
throw new MissingRpcArgumentException('signature_public_key');
|
||||
}
|
||||
|
||||
if(!$rpcRequest->containsParameter('signature'))
|
||||
{
|
||||
throw new MissingRpcArgumentException('signature');
|
||||
|
@ -66,27 +61,25 @@
|
|||
throw new InvalidRpcArgumentException('peer', $e);
|
||||
}
|
||||
|
||||
if($rpcRequest->containsParameter('signature_time'))
|
||||
if($rpcRequest->containsParameter('time'))
|
||||
{
|
||||
if(!is_numeric($rpcRequest->getParameter('signature_time')))
|
||||
if(!is_numeric($rpcRequest->getParameter('time')))
|
||||
{
|
||||
throw new InvalidRpcArgumentException('signature_time', 'Invalid timestamp, must be a Unix Timestamp');
|
||||
throw new InvalidRpcArgumentException('time', 'Invalid timestamp, must be a Unix Timestamp');
|
||||
}
|
||||
|
||||
return $rpcRequest->produceResponse(Socialbox::verifyTimedSignature(
|
||||
signingPeer: $peerAddress,
|
||||
signatureUuid: $rpcRequest->getParameter('signature_uuid'),
|
||||
signatureKey: $rpcRequest->getParameter('signature_public_key'),
|
||||
signature: $rpcRequest->getParameter('signature'),
|
||||
messageHash: $rpcRequest->getParameter('sha512'),
|
||||
signatureTime: (int)$rpcRequest->getParameter('signature_time')
|
||||
signatureTime: (int)$rpcRequest->getParameter('time')
|
||||
)->value);
|
||||
}
|
||||
|
||||
return $rpcRequest->produceResponse(Socialbox::verifySignature(
|
||||
signingPeer: $peerAddress,
|
||||
signatureUuid: $rpcRequest->getParameter('signature_uuid'),
|
||||
signatureKey: $rpcRequest->getParameter('signature_public_key'),
|
||||
signature: $rpcRequest->getParameter('signature'),
|
||||
messageHash: $rpcRequest->getParameter('sha512'),
|
||||
)->value);
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Socialbox\Classes\StandardMethods\Encryption;
|
||||
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use Socialbox\Abstracts\Method;
|
||||
use Socialbox\Classes\Cryptography;
|
||||
use Socialbox\Classes\Validator;
|
||||
use Socialbox\Enums\ReservedUsernames;
|
||||
use Socialbox\Enums\StandardError;
|
||||
use Socialbox\Exceptions\Standard\InvalidRpcArgumentException;
|
||||
use Socialbox\Exceptions\Standard\MissingRpcArgumentException;
|
||||
use Socialbox\Exceptions\Standard\StandardRpcException;
|
||||
use Socialbox\Interfaces\SerializableInterface;
|
||||
use Socialbox\Managers\EncryptionChannelManager;
|
||||
use Socialbox\Objects\ClientRequest;
|
||||
use Socialbox\Objects\PeerAddress;
|
||||
use Socialbox\Objects\RpcRequest;
|
||||
|
||||
class EncryptionAcceptChannel extends Method
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function execute(ClientRequest $request, RpcRequest $rpcRequest): ?SerializableInterface
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,317 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Socialbox\Classes\StandardMethods\Encryption;
|
||||
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use Socialbox\Abstracts\Method;
|
||||
use Socialbox\Classes\Configuration;
|
||||
use Socialbox\Classes\Cryptography;
|
||||
use Socialbox\Classes\Validator;
|
||||
use Socialbox\Enums\ReservedUsernames;
|
||||
use Socialbox\Enums\SigningKeyState;
|
||||
use Socialbox\Enums\StandardError;
|
||||
use Socialbox\Exceptions\DatabaseOperationException;
|
||||
use Socialbox\Exceptions\Standard\InvalidRpcArgumentException;
|
||||
use Socialbox\Exceptions\Standard\MissingRpcArgumentException;
|
||||
use Socialbox\Exceptions\Standard\StandardRpcException;
|
||||
use Socialbox\Interfaces\SerializableInterface;
|
||||
use Socialbox\Managers\EncryptionChannelManager;
|
||||
use Socialbox\Objects\ClientRequest;
|
||||
use Socialbox\Objects\PeerAddress;
|
||||
use Socialbox\Objects\RpcRequest;
|
||||
use Socialbox\Objects\Standard\Signature;
|
||||
use Socialbox\Socialbox;
|
||||
|
||||
class EncryptionCreateChannel extends Method
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function execute(ClientRequest $request, RpcRequest $rpcRequest): ?SerializableInterface
|
||||
{
|
||||
// Check the calling peer, if a server is making the request, it must be identified
|
||||
// Otherwise, we assume the authenticated user is the calling peer
|
||||
// But a server must provide a UUID. This is to prevent a user from creating a channel with a UUID
|
||||
$callingPeer = self::getCallingPeer($request, $rpcRequest);
|
||||
$callingPeerSignature = self::getCallingSignature($callingPeer, $rpcRequest);
|
||||
$receivingPeer = self::getReceivingPeer($rpcRequest);
|
||||
$receivingPeerSignature = self::getReceivingSignature($receivingPeer, $rpcRequest);
|
||||
$channelUuid = self::getChannelUuid($request, $rpcRequest);
|
||||
|
||||
// Verify the calling encryption public key
|
||||
if(!$rpcRequest->containsParameter('calling_encryption_public_key'))
|
||||
{
|
||||
throw new MissingRpcArgumentException('calling_encryption_public_key');
|
||||
}
|
||||
if(!Cryptography::validatePublicEncryptionKey($rpcRequest->getParameter('calling_encryption_public_key')))
|
||||
{
|
||||
throw new InvalidRpcArgumentException('calling_encryption_public_key', 'Invalid calling encryption public key');
|
||||
}
|
||||
|
||||
// Transport Algorithm Validation
|
||||
if(!$rpcRequest->containsParameter('transport_encryption_algorithm'))
|
||||
{
|
||||
throw new MissingRpcArgumentException('transport_encryption_algorithm');
|
||||
}
|
||||
if(!Cryptography::isSupportedAlgorithm($rpcRequest->getParameter('transport_encryption_algorithm')))
|
||||
{
|
||||
throw new InvalidRpcArgumentException('transport_encryption_algorithm', 'Unsupported Transport Encryption Algorithm');
|
||||
}
|
||||
|
||||
// Create/Import the encryption channel
|
||||
try
|
||||
{
|
||||
$channelUuid = EncryptionChannelManager::createChannel(
|
||||
callingPeer: $callingPeer,
|
||||
receivingPeer: $receivingPeer,
|
||||
signatureUuid: $callingPeerSignature->getUuid(),
|
||||
signingPublicKey: $callingPeerSignature->getPublicKey(),
|
||||
encryptionPublicKey: $rpcRequest->getParameter('calling_encryption_public_key'),
|
||||
transportEncryptionAlgorithm: $rpcRequest->getParameter('transport_encryption_algorithm'),
|
||||
uuid: $channelUuid
|
||||
);
|
||||
}
|
||||
catch (DatabaseOperationException $e)
|
||||
{
|
||||
throw new StandardRpcException('Failed to create the encryption channel', StandardError::INTERNAL_SERVER_ERROR, $e);
|
||||
}
|
||||
|
||||
// If the receiving peer resides on an external server, then we need to tell the external server
|
||||
// about the encryption channel so that the receiving peer can see it.
|
||||
if($receivingPeer->getDomain() !== Configuration::getInstanceConfiguration()->getDomain())
|
||||
{
|
||||
$rpcClient = Socialbox::getExternalSession($receivingPeer->getDomain());
|
||||
|
||||
}
|
||||
|
||||
return $rpcRequest->produceResponse($channelUuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PeerAddress of the calling peer, if a server is making a request then the server must provide
|
||||
* both the UUID of the encryption channel and the PeerAddress of the calling peer to prevent UUID conflicts
|
||||
*
|
||||
* Otherwise, the calling peer is assumed to be the authenticated user and no UUID is required
|
||||
*
|
||||
* @param ClientRequest $request The full client request
|
||||
* @param RpcRequest $rpcRequest The focused RPC request
|
||||
* @return PeerAddress The calling peer
|
||||
* @throws StandardRpcException If the calling peer cannot be resolved
|
||||
*/
|
||||
private static function getCallingPeer(ClientRequest $request, RpcRequest $rpcRequest): PeerAddress
|
||||
{
|
||||
if($request->getIdentifyAs() !== null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Prevent UUID conflicts if the server is trying to use an UUID that already exists on this server
|
||||
if (EncryptionChannelManager::channelExists($rpcRequest->getParameter('uuid')))
|
||||
{
|
||||
throw new StandardRpcException('UUID Conflict, a channel with this UUID already exists', StandardError::UUID_CONFLICT);
|
||||
}
|
||||
}
|
||||
catch (DatabaseOperationException $e)
|
||||
{
|
||||
throw new StandardRpcException('Failed to resolve channel UUID', StandardError::INTERNAL_SERVER_ERROR, $e);
|
||||
}
|
||||
|
||||
if($request->getIdentifyAs()->getUsername() == ReservedUsernames::HOST)
|
||||
{
|
||||
throw new StandardRpcException('The identifier cannot be a host', StandardError::BAD_REQUEST);
|
||||
}
|
||||
|
||||
if($request->getIdentifyAs()->getDomain() !== Configuration::getInstanceConfiguration()->getDomain())
|
||||
{
|
||||
Socialbox::resolvePeer($request->getIdentifyAs());
|
||||
}
|
||||
|
||||
return $request->getIdentifyAs();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return PeerAddress::fromAddress($request->getPeer()->getAddress());
|
||||
}
|
||||
catch(StandardRpcException $e)
|
||||
{
|
||||
throw $e;
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new StandardRpcException('The calling peer cannot be resolved', StandardError::INTERNAL_SERVER_ERROR, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves and returns the calling peer's signing key, if the calling peer is coming from an external server
|
||||
* then the signature returned is the resolved signature from the external server, otherwise the signature
|
||||
* is locally resolved and returned
|
||||
*
|
||||
* @param PeerAddress $callingPeer The calling peer
|
||||
* @param RpcRequest $rpcRequest The focused RPC request
|
||||
* @return Signature The resolved signing key
|
||||
* @throws InvalidRpcArgumentException If one or more RPC parameters are invalid
|
||||
* @throws MissingRpcArgumentException If one or more RPC parameters are missing
|
||||
* @throws StandardRpcException If the calling signature cannot be resolved
|
||||
*/
|
||||
private static function getCallingSignature(PeerAddress $callingPeer, RpcRequest $rpcRequest): Signature
|
||||
{
|
||||
// Caller signature verification
|
||||
if(!$rpcRequest->containsParameter('calling_signature_uuid'))
|
||||
{
|
||||
throw new MissingRpcArgumentException('calling_signature_uuid');
|
||||
}
|
||||
if(!Validator::validateUuid($rpcRequest->getParameter('calling_signature_uuid')))
|
||||
{
|
||||
throw new InvalidRpcArgumentException('calling_signature_uuid', 'Invalid UUID V4');
|
||||
}
|
||||
if(!$rpcRequest->containsParameter('calling_signature_public_key'))
|
||||
{
|
||||
throw new MissingRpcArgumentException('calling_signature_public_key');
|
||||
}
|
||||
if(!Cryptography::validatePublicSigningKey($rpcRequest->getParameter('calling_signature_public_key')))
|
||||
{
|
||||
throw new InvalidRpcArgumentException('calling_signature_public_key', 'Invalid Public Key');
|
||||
}
|
||||
|
||||
// Resolve the signature
|
||||
$resolvedCallingSignature = Socialbox::resolvePeerSignature($callingPeer, $rpcRequest->getParameter('calling_signature_uuid'));
|
||||
if($resolvedCallingSignature->getPublicKey() !== $rpcRequest->getParameter('calling_signature_public_key'))
|
||||
{
|
||||
throw new InvalidRpcArgumentException('calling_signature_public_key', 'Public signing key of the calling peer does not match the resolved signature');
|
||||
}
|
||||
if($resolvedCallingSignature->getState() === SigningKeyState::EXPIRED)
|
||||
{
|
||||
throw new StandardRpcException('The public signing key of the calling peer has expired', StandardError::EXPIRED);
|
||||
}
|
||||
|
||||
$resolvedSignature = Socialbox::resolvePeerSignature($callingPeer, $rpcRequest->getParameter('calling_signature_uuid'));
|
||||
if($resolvedSignature === null)
|
||||
{
|
||||
throw new StandardRpcException('The calling peer signature could not be resolved', StandardError::NOT_FOUND);
|
||||
}
|
||||
|
||||
return $resolvedSignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PeerAddress of the receiving peer, if the receiving peer is from an external server then the
|
||||
* receiving peer is resolved and returned, otherwise the receiving peer is locally resolved and returned
|
||||
*
|
||||
* @param RpcRequest $rpcRequest The focused RPC request
|
||||
* @return PeerAddress The receiving peer
|
||||
* @throws InvalidRpcArgumentException If one or more RPC parameters are invalid
|
||||
* @throws MissingRpcArgumentException If one or more RPC parameters are missing
|
||||
* @throws StandardRpcException If the receiving peer cannot be resolved
|
||||
*/
|
||||
private static function getReceivingPeer(RpcRequest $rpcRequest): PeerAddress
|
||||
{
|
||||
if(!$rpcRequest->containsParameter('receiving_peer'))
|
||||
{
|
||||
throw new MissingRpcArgumentException('receiving_peer');
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$receivingPeer = PeerAddress::fromAddress($rpcRequest->getParameter('receiving_peer'));
|
||||
}
|
||||
catch(InvalidArgumentException $e)
|
||||
{
|
||||
throw new InvalidRpcArgumentException('receiving_peer', $e);
|
||||
}
|
||||
|
||||
if($receivingPeer->getUsername() == ReservedUsernames::HOST)
|
||||
{
|
||||
throw new InvalidRpcArgumentException('receiving_peer', 'Hosts cannot receive channels');
|
||||
}
|
||||
|
||||
// Resolve the receiving peer if it's from an external server
|
||||
if($receivingPeer->getDomain() !== Configuration::getInstanceConfiguration()->getDomain())
|
||||
{
|
||||
Socialbox::resolvePeer($receivingPeer);
|
||||
}
|
||||
|
||||
return $receivingPeer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PeerAddress $receivingPeer
|
||||
* @param RpcRequest $rpcRequest
|
||||
* @return Signature
|
||||
* @throws InvalidRpcArgumentException
|
||||
* @throws MissingRpcArgumentException
|
||||
* @throws StandardRpcException
|
||||
*/
|
||||
private static function getReceivingSignature(PeerAddress $receivingPeer, RpcRequest $rpcRequest): Signature
|
||||
{
|
||||
// Receiving signature verification
|
||||
if(!$rpcRequest->containsParameter('receiving_signature_uuid'))
|
||||
{
|
||||
throw new MissingRpcArgumentException('receiving_signature_uuid');
|
||||
}
|
||||
if(!Validator::validateUuid($rpcRequest->getParameter('receiving_signature_uuid')))
|
||||
{
|
||||
throw new InvalidRpcArgumentException('receiving_signature_uuid', 'Invalid UUID V4');
|
||||
}
|
||||
if(!$rpcRequest->containsParameter('receiving_signature_public_key'))
|
||||
{
|
||||
throw new MissingRpcArgumentException('receiving_signature_public_key');
|
||||
}
|
||||
if(!Cryptography::validatePublicSigningKey($rpcRequest->getParameter('receiving_signature_public_key')))
|
||||
{
|
||||
throw new InvalidRpcArgumentException('receiving_signature_public_key', 'Invalid Public Key');
|
||||
}
|
||||
|
||||
// Resolve the signature
|
||||
$resolvedReceivingSignature = Socialbox::resolvePeerSignature($receivingPeer, $rpcRequest->getParameter('receiving_signature_uuid'));
|
||||
if($resolvedReceivingSignature->getPublicKey() !== $rpcRequest->getParameter('receiving_signature_public_key'))
|
||||
{
|
||||
throw new InvalidRpcArgumentException('receiving_signature_public_key', 'Public signing key of the receiving peer does not match the resolved signature');
|
||||
}
|
||||
if($resolvedReceivingSignature->getState() === SigningKeyState::EXPIRED)
|
||||
{
|
||||
throw new StandardRpcException('The public signing key of the receiving peer has expired', StandardError::EXPIRED);
|
||||
}
|
||||
|
||||
$resolvedSignature = Socialbox::resolvePeerSignature($receivingPeer, $rpcRequest->getParameter('receiving_signature_uuid'));
|
||||
if($resolvedSignature === null)
|
||||
{
|
||||
throw new StandardRpcException('The receiving peer signature could not be resolved', StandardError::NOT_FOUND);
|
||||
}
|
||||
|
||||
return $resolvedSignature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClientRequest $request
|
||||
* @param RpcRequest $rpcRequest
|
||||
* @return string|null
|
||||
* @throws InvalidRpcArgumentException
|
||||
* @throws MissingRpcArgumentException
|
||||
*/
|
||||
private static function getChannelUuid(ClientRequest $request, RpcRequest $rpcRequest): ?string
|
||||
{
|
||||
if($request->getIdentifyAs() !== null)
|
||||
{
|
||||
if(!$rpcRequest->containsParameter('uuid'))
|
||||
{
|
||||
throw new MissingRpcArgumentException('uuid');
|
||||
}
|
||||
|
||||
if(!Validator::validateUuid($rpcRequest->getParameter('uuid')))
|
||||
{
|
||||
throw new InvalidRpcArgumentException('uuid', 'Invalid UUID V4');
|
||||
}
|
||||
|
||||
if(EncryptionChannelManager::channelExists($rpcRequest->getParameter('uuid')))
|
||||
{
|
||||
throw new StandardRpcException('UUID Conflict, a channel with this UUID already exists', StandardError::UUID_CONFLICT);
|
||||
}
|
||||
|
||||
return $rpcRequest->getParameter('uuid');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue