Made message signing in Cryptography use SHA512 as the message content for... #1
10 changed files with 1066 additions and 0 deletions
3
.idea/sqldialects.xml
generated
3
.idea/sqldialects.xml
generated
|
@ -4,8 +4,10 @@
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/authentication_otp.sql" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/authentication_otp.sql" dialect="MariaDB" />
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/authentication_passwords.sql" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/authentication_passwords.sql" dialect="MariaDB" />
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/captcha_images.sql" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/captcha_images.sql" dialect="MariaDB" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/channel_com.sql" dialect="MariaDB" />
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/contact_known_keys.sql" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/contact_known_keys.sql" dialect="MariaDB" />
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/contacts.sql" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/contacts.sql" dialect="MariaDB" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/encrypted_channels.sql" dialect="MariaDB" />
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/external_sessions.sql" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/external_sessions.sql" dialect="MariaDB" />
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/peer_information.sql" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/peer_information.sql" dialect="MariaDB" />
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/peers.sql" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/peers.sql" dialect="MariaDB" />
|
||||||
|
@ -14,6 +16,7 @@
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/variables.sql" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Classes/Resources/database/variables.sql" dialect="MariaDB" />
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Managers/CaptchaManager.php" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Managers/CaptchaManager.php" dialect="MariaDB" />
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Managers/ContactManager.php" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Managers/ContactManager.php" dialect="MariaDB" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Managers/EncryptionChannelManager.php" dialect="MariaDB" />
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Managers/ExternalSessionManager.php" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Managers/ExternalSessionManager.php" dialect="MariaDB" />
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Managers/OneTimePasswordManager.php" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Managers/OneTimePasswordManager.php" dialect="MariaDB" />
|
||||||
<file url="file://$PROJECT_DIR$/src/Socialbox/Managers/PasswordManager.php" dialect="MariaDB" />
|
<file url="file://$PROJECT_DIR$/src/Socialbox/Managers/PasswordManager.php" dialect="MariaDB" />
|
||||||
|
|
32
src/Socialbox/Classes/Resources/database/channel_com.sql
Normal file
32
src/Socialbox/Classes/Resources/database/channel_com.sql
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
create table channel_com
|
||||||
|
(
|
||||||
|
uuid varchar(36) default uuid() not null comment 'The UUID of the message',
|
||||||
|
channel_uuid varchar(36) not null comment 'The UUID of the encryption channel used',
|
||||||
|
recipient enum ('SENDER', 'RECEIVER') not null comment 'The recipient of the message',
|
||||||
|
message text not null comment 'The encrypted message content',
|
||||||
|
signature varchar(64) not null comment 'The signature of the decrypted message',
|
||||||
|
received tinyint(1) default 0 not null comment 'True if the message was received by the recipient',
|
||||||
|
timestamp timestamp default current_timestamp() not null comment 'The timestamp of the mssage being sent',
|
||||||
|
primary key (uuid, channel_uuid) comment 'The Unique Pair Index for the channel UUID and message UUID',
|
||||||
|
constraint channel_com_uuid_channel_uuid_uindex
|
||||||
|
unique (uuid, channel_uuid) comment 'The Unique Pair Index for the channel UUID and message UUID',
|
||||||
|
constraint channel_com_uuid_channel_uuid_uindex_2
|
||||||
|
unique (uuid, channel_uuid) comment 'The Unique Index Pair for the channel UUID and message UUID',
|
||||||
|
constraint channel_com_encryption_channels_uuid_fk
|
||||||
|
foreign key (channel_uuid) references encryption_channels (uuid)
|
||||||
|
on update cascade on delete cascade
|
||||||
|
)
|
||||||
|
comment 'Table for housing communication messages over encryption channels';
|
||||||
|
|
||||||
|
create index channel_com_received_index
|
||||||
|
on channel_com (received)
|
||||||
|
comment 'The index for the received column';
|
||||||
|
|
||||||
|
create index channel_com_recipient_index
|
||||||
|
on channel_com (recipient)
|
||||||
|
comment 'The index for the recipient column';
|
||||||
|
|
||||||
|
create index channel_com_timestamp_index
|
||||||
|
on channel_com (timestamp)
|
||||||
|
comment 'The index for the Timestamp column';
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
create table encryption_channels
|
||||||
|
(
|
||||||
|
uuid varchar(36) not null comment 'The Unique Universal Identifier for the encryption channel'
|
||||||
|
primary key comment 'The Unique Index of the encryption channel UUID',
|
||||||
|
calling_peer varchar(320) not null comment 'The address of the calling peer',
|
||||||
|
calling_signature_uuid varchar(64) not null comment 'The UUID of the signing key that the calling peer is going to use to sign their messages',
|
||||||
|
calling_signature_public_key varchar(32) not null,
|
||||||
|
calling_encryption_public_key varchar(32) not null comment 'The public encryption key of the caller',
|
||||||
|
receiving_peer varchar(320) not null comment 'The address of the receiving peer',
|
||||||
|
receiving_signature_uuid varchar(256) null comment 'The UUID of the signature that the receiver peer will use to sign messages with',
|
||||||
|
receiving_signature_public_key varchar(32) null comment 'The public key of the receiver''s signing key',
|
||||||
|
receiving_encryption_public_key varchar(32) null comment 'The encryption key of the receiver',
|
||||||
|
transport_encryption_algorithm enum ('xchacha20', 'chacha20', 'aes256gcm') default 'xchacha20' not null comment 'The transport encryption algorithm used as selected by the caller',
|
||||||
|
transport_encryption_key varchar(256) null comment 'The transport encryption key encrypted using the caller''s public encryption key',
|
||||||
|
state enum ('AWAITING_RECEIVER', 'ERROR', 'DECLINED', 'AWAITING_DHE', 'OPENED', 'CLOSED') default 'AWAITING_RECEIVER' not null comment 'The current state of the encryption channel',
|
||||||
|
created timestamp default current_timestamp() not null comment 'The Timestamp for when this record was created',
|
||||||
|
constraint encryption_channels_uuid_uindex
|
||||||
|
unique (uuid) comment 'The Unique Index of the encryption channel UUID'
|
||||||
|
);
|
||||||
|
|
||||||
|
create index encryption_channels_calling_peer_index
|
||||||
|
on encryption_channels (calling_peer)
|
||||||
|
comment 'The index of the calling peer address';
|
||||||
|
|
||||||
|
create index encryption_channels_created_index
|
||||||
|
on encryption_channels (created)
|
||||||
|
comment 'The Index for when the record was created';
|
||||||
|
|
||||||
|
create index encryption_channels_receiving_peer_index
|
||||||
|
on encryption_channels (receiving_peer)
|
||||||
|
comment 'The index of the receiving peer address';
|
||||||
|
|
||||||
|
create index encryption_channels_state_index
|
||||||
|
on encryption_channels (state)
|
||||||
|
comment 'The index for the state column';
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
case SIGNING_KEYS = 'signing_keys.sql';
|
case SIGNING_KEYS = 'signing_keys.sql';
|
||||||
case EXTERNAL_SESSIONS = 'external_sessions.sql';
|
case EXTERNAL_SESSIONS = 'external_sessions.sql';
|
||||||
|
|
||||||
|
case ENCRYPTED_CHANNELS = 'encrypted_channels.sql';
|
||||||
|
case CHANNEL_COM = 'channel_com.sql';
|
||||||
|
|
||||||
case CONTACT_KNOWN_KEYS = 'contact_known_keys.sql';
|
case CONTACT_KNOWN_KEYS = 'contact_known_keys.sql';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,6 +46,8 @@
|
||||||
self::SIGNING_KEYS,
|
self::SIGNING_KEYS,
|
||||||
self::EXTERNAL_SESSIONS => 2,
|
self::EXTERNAL_SESSIONS => 2,
|
||||||
|
|
||||||
|
self::ENCRYPTED_CHANNELS,
|
||||||
|
self::CHANNEL_COM,
|
||||||
self::CONTACT_KNOWN_KEYS => 3,
|
self::CONTACT_KNOWN_KEYS => 3,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
case CONFLICT = -107;
|
case CONFLICT = -107;
|
||||||
case EXPIRED = -108;
|
case EXPIRED = -108;
|
||||||
case CRYPTOGRAPHIC_ERROR = -109;
|
case CRYPTOGRAPHIC_ERROR = -109;
|
||||||
|
case UUID_CONFLICT = -110;
|
||||||
|
|
||||||
// RPC Errors
|
// RPC Errors
|
||||||
case RPC_METHOD_NOT_FOUND = -1000;
|
case RPC_METHOD_NOT_FOUND = -1000;
|
||||||
|
|
12
src/Socialbox/Enums/Status/EncryptionChannelState.php
Normal file
12
src/Socialbox/Enums/Status/EncryptionChannelState.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Socialbox\Enums\Status;
|
||||||
|
|
||||||
|
enum EncryptionChannelState : string
|
||||||
|
{
|
||||||
|
case AWAITING_RECEIVER = 'AWAITING_RECEIVER';
|
||||||
|
case ERROR = 'ERROR';
|
||||||
|
case DECLINED = 'DECLINED';
|
||||||
|
case OPENED = 'OPENED';
|
||||||
|
case CLOSED = 'CLOSED';
|
||||||
|
}
|
9
src/Socialbox/Enums/Types/CommunicationRecipientType.php
Normal file
9
src/Socialbox/Enums/Types/CommunicationRecipientType.php
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Socialbox\Enums\Types;
|
||||||
|
|
||||||
|
enum CommunicationRecipientType : string
|
||||||
|
{
|
||||||
|
case SENDER = 'SENDER';
|
||||||
|
case RECEIVER = 'RECEIVER';
|
||||||
|
}
|
568
src/Socialbox/Managers/EncryptionChannelManager.php
Normal file
568
src/Socialbox/Managers/EncryptionChannelManager.php
Normal file
|
@ -0,0 +1,568 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Socialbox\Managers;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use ncc\ThirdParty\Symfony\Uid\UuidV4;
|
||||||
|
use PDO;
|
||||||
|
use PDOException;
|
||||||
|
use Socialbox\Classes\Cryptography;
|
||||||
|
use Socialbox\Classes\Database;
|
||||||
|
use Socialbox\Enums\Status\EncryptionChannelState;
|
||||||
|
use Socialbox\Enums\Types\CommunicationRecipientType;
|
||||||
|
use Socialbox\Exceptions\DatabaseOperationException;
|
||||||
|
use Socialbox\Objects\Database\ChannelMessageRecord;
|
||||||
|
use Socialbox\Objects\Database\EncryptionChannelRecord;
|
||||||
|
use Socialbox\Objects\PeerAddress;
|
||||||
|
|
||||||
|
class EncryptionChannelManager
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a new encryption channel between two peers.
|
||||||
|
*
|
||||||
|
* @param PeerAddress|string $callingPeer The peer that is creating the channel.
|
||||||
|
* @param PeerAddress|string $receivingPeer The peer that is receiving the channel.
|
||||||
|
* @param string $signatureUuid The UUID of the signature used to create the channel.
|
||||||
|
* @param string $signingPublicKey The public key used for signing.
|
||||||
|
* @param string $encryptionPublicKey The public key used for encryption.
|
||||||
|
* @param string $transportEncryptionAlgorithm The algorithm used for transport encryption.
|
||||||
|
* @return string The UUID of the created channel.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while creating the channel.
|
||||||
|
*/
|
||||||
|
public static function createChannel(PeerAddress|string $callingPeer, PeerAddress|string $receivingPeer,
|
||||||
|
string $signatureUuid, string $signingPublicKey, string $encryptionPublicKey, string $transportEncryptionAlgorithm,
|
||||||
|
?string $uuid=null
|
||||||
|
): string
|
||||||
|
{
|
||||||
|
if(is_string($callingPeer))
|
||||||
|
{
|
||||||
|
$callingPeer = PeerAddress::fromAddress($callingPeer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_string($receivingPeer))
|
||||||
|
{
|
||||||
|
$receivingPeer = PeerAddress::fromAddress($receivingPeer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!Cryptography::validatePublicSigningKey($signingPublicKey))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException('Invalid signing public key provided');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!Cryptography::validatePublicEncryptionKey($encryptionPublicKey))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException('Invalid encryption public key provided');
|
||||||
|
}
|
||||||
|
|
||||||
|
$transportEncryptionAlgorithm = strtolower($transportEncryptionAlgorithm);
|
||||||
|
if(!Cryptography::isSupportedAlgorithm($transportEncryptionAlgorithm))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException('Unsupported transport encryption algorithm');
|
||||||
|
}
|
||||||
|
|
||||||
|
if($uuid === null)
|
||||||
|
{
|
||||||
|
$uuid = UuidV4::v4()->toRfc4122();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('INSERT INTO encryption_channels (uuid, calling_peer, calling_signature_uuid, calling_signature_public_key, calling_encryption_public_key, receiving_peer, transport_encryption_algorithm) VALUES (:uuid, :calling_peer, :calling_signature_uuid, :calling_signature_public_key, :calling_encryption_public_key, :receiving_peer, :transport_encryption_algorithm)');
|
||||||
|
$stmt->bindParam(':uuid', $uuid);
|
||||||
|
$callingPeerAddress = $callingPeer->getAddress();
|
||||||
|
$stmt->bindParam(':calling_peer', $callingPeerAddress);
|
||||||
|
$stmt->bindParam(':calling_signature_uuid', $signatureUuid);
|
||||||
|
$stmt->bindParam(':calling_signature_public_key', $signingPublicKey);
|
||||||
|
$stmt->bindParam(':calling_encryption_public_key', $encryptionPublicKey);
|
||||||
|
$receivingPeerAddress = $receivingPeer->getAddress();
|
||||||
|
$stmt->bindParam(':receiving_peer', $receivingPeerAddress);
|
||||||
|
$stmt->bindParam(':transport_encryption_algorithm', $transportEncryptionAlgorithm);
|
||||||
|
$stmt->execute();
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to create the encryption channel', $e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the incoming encryption channels for the specified peer.
|
||||||
|
*
|
||||||
|
* @param string|PeerAddress $peerAddress The peer to retrieve the channels for.
|
||||||
|
* @param int $limit The maximum number of channels to retrieve.
|
||||||
|
* @param int $page The page of channels to retrieve.
|
||||||
|
* @return EncryptionChannelRecord[] The incoming channels for the peer.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while retrieving the channels.
|
||||||
|
* @throws \DateMalformedStringException If the created date is not a valid date string.
|
||||||
|
*/
|
||||||
|
public static function getChannels(string|PeerAddress $peerAddress, int $limit=100, int $page=0): array
|
||||||
|
{
|
||||||
|
if($peerAddress instanceof PeerAddress)
|
||||||
|
{
|
||||||
|
$peerAddress = $peerAddress->getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('SELECT * FROM encryption_channels WHERE calling_peer=:address OR receiving_peer=:address LIMIT :limit OFFSET :offset');
|
||||||
|
$stmt->bindParam(':address', $peerAddress);
|
||||||
|
$stmt->bindParam(':limit', $limit, PDO::PARAM_INT);
|
||||||
|
$offset = $page * $limit;
|
||||||
|
$stmt->bindParam(':offset', $offset, PDO::PARAM_INT);
|
||||||
|
$stmt->execute();
|
||||||
|
$results = $stmt->fetchAll();
|
||||||
|
|
||||||
|
$channels = [];
|
||||||
|
foreach($results as $result)
|
||||||
|
{
|
||||||
|
$channels[] = new EncryptionChannelRecord($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $channels;
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to retrieve the encryption channels', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the incoming encryption channels for the specified peer.
|
||||||
|
*
|
||||||
|
* @param string|PeerAddress $peerAddress The peer to retrieve the channels for.
|
||||||
|
* @param int $limit The maximum number of channels to retrieve.
|
||||||
|
* @param int $page The page of channels to retrieve.
|
||||||
|
* @return EncryptionChannelRecord[] The incoming channels for the peer.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while retrieving the channels.
|
||||||
|
* @throws \DateMalformedStringException If the created date is not a valid date string.
|
||||||
|
*/
|
||||||
|
public static function getRequests(string|PeerAddress $peerAddress, int $limit=100, int $page=0): array
|
||||||
|
{
|
||||||
|
if($peerAddress instanceof PeerAddress)
|
||||||
|
{
|
||||||
|
$peerAddress = $peerAddress->getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('SELECT * FROM encryption_channels WHERE receiving_peer=:address AND state=:state LIMIT :limit OFFSET :offset');
|
||||||
|
$stmt->bindParam(':address', $peerAddress);
|
||||||
|
$state = EncryptionChannelState::AWAITING_RECEIVER->value;
|
||||||
|
$stmt->bindParam(':state', $state);
|
||||||
|
$stmt->bindParam(':limit', $limit, PDO::PARAM_INT);
|
||||||
|
$offset = $page * $limit;
|
||||||
|
$stmt->bindParam(':offset', $offset, PDO::PARAM_INT);
|
||||||
|
$stmt->execute();
|
||||||
|
$results = $stmt->fetchAll();
|
||||||
|
|
||||||
|
$channels = [];
|
||||||
|
foreach($results as $result)
|
||||||
|
{
|
||||||
|
$channels[] = new EncryptionChannelRecord($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $channels;
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to retrieve the encryption channels', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the incoming encryption channels for the specified peer.
|
||||||
|
*
|
||||||
|
* @param string|PeerAddress $peerAddress The peer to retrieve the channels for.
|
||||||
|
* @param int $limit The maximum number of channels to retrieve.
|
||||||
|
* @param int $page The page of channels to retrieve.
|
||||||
|
* @return EncryptionChannelRecord[] The incoming channels for the peer.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while retrieving the channels.
|
||||||
|
* @throws \DateMalformedStringException If the created date is not a valid date string.
|
||||||
|
*/
|
||||||
|
public static function getIncomingChannels(string|PeerAddress $peerAddress, int $limit=100, int $page=0): array
|
||||||
|
{
|
||||||
|
if($peerAddress instanceof PeerAddress)
|
||||||
|
{
|
||||||
|
$peerUuid = $peerAddress->getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('SELECT * FROM encryption_channels WHERE receiving_peer=:address LIMIT :limit OFFSET :offset');
|
||||||
|
$stmt->bindParam(':address', $peerUuid);
|
||||||
|
$stmt->bindParam(':limit', $limit, PDO::PARAM_INT);
|
||||||
|
$offset = $page * $limit;
|
||||||
|
$stmt->bindParam(':offset', $offset, PDO::PARAM_INT);
|
||||||
|
$stmt->execute();
|
||||||
|
$results = $stmt->fetchAll();
|
||||||
|
|
||||||
|
$channels = [];
|
||||||
|
foreach($results as $result)
|
||||||
|
{
|
||||||
|
$channels[] = new EncryptionChannelRecord($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $channels;
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to retrieve the encryption channels', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the outgoing channels for the specified peer.
|
||||||
|
*
|
||||||
|
* @param string|PeerAddress $peerAddress The peer to retrieve the channels for.
|
||||||
|
* @param int $limit The maximum number of channels to retrieve.
|
||||||
|
* @param int $page The page of channels to retrieve.
|
||||||
|
* @return EncryptionChannelRecord[] The outgoing channels for the specified peer.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while retrieving the channels.
|
||||||
|
* @throws \DateMalformedStringException If the created date is not a valid date string.
|
||||||
|
*/
|
||||||
|
public static function getOutgoingChannels(string|PeerAddress $peerAddress, int $limit=100, int $page=0): array
|
||||||
|
{
|
||||||
|
if($peerAddress instanceof PeerAddress)
|
||||||
|
{
|
||||||
|
$peerAddress = $peerAddress->getAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('SELECT * FROM encryption_channels WHERE calling_peer=:address LIMIT :limit OFFSET :offset');
|
||||||
|
$stmt->bindParam(':address', $peerAddress);
|
||||||
|
$stmt->bindParam(':limit', $limit, PDO::PARAM_INT);
|
||||||
|
$offset = $page * $limit;
|
||||||
|
$stmt->bindParam(':offset', $offset, PDO::PARAM_INT);
|
||||||
|
$stmt->execute();
|
||||||
|
$results = $stmt->fetchAll();
|
||||||
|
|
||||||
|
$channels = [];
|
||||||
|
foreach($results as $result)
|
||||||
|
{
|
||||||
|
$channels[] = new EncryptionChannelRecord($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $channels;
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to retrieve the encryption channels', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declines the encryption channel with the specified UUID.
|
||||||
|
*
|
||||||
|
* @param string $channelUuid The UUID of the channel to decline.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while declining the channel.
|
||||||
|
*/
|
||||||
|
public static function declineChannel(string $channelUuid): void
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('UPDATE encryption_channels SET state=:state WHERE uuid=:uuid');
|
||||||
|
$state = EncryptionChannelState::DECLINED->value;
|
||||||
|
$stmt->bindParam(':state', $state);
|
||||||
|
$stmt->bindParam(':uuid', $channelUuid);
|
||||||
|
$stmt->execute();
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to decline the encryption channel', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accepts the encryption channel with the specified UUID.
|
||||||
|
*
|
||||||
|
* @param string $channelUuid The UUID of the channel to accept.
|
||||||
|
* @param string $signatureUuid The UUID of the signature used to create the channel.
|
||||||
|
* @param string $signaturePublicKey The public key used for signing.
|
||||||
|
* @param string $encryptionPublicKey The public key used for encryption.
|
||||||
|
* @param string $transportEncryptionAlgorithm The algorithm used for transport encryption.
|
||||||
|
* @param string $encryptedTransportEncryptionKey The encrypted transport encryption key.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while accepting the channel.
|
||||||
|
*/
|
||||||
|
public static function acceptChannel(string $channelUuid, string $signatureUuid, string $signaturePublicKey, string $encryptionPublicKey, string $transportEncryptionAlgorithm, string $encryptedTransportEncryptionKey): void
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('UPDATE encryption_channels SET state=:state, receiving_signature_uuid=:receiving_signature_uuid, receiving_signature_public_key=:receiving_signature_public_key, receiving_encryption_public_key=:receiving_encryption_public_key, transport_encryption_algorithm=:transport_encryption_algorithm, transport_encryption_key=:transport_encryption_key WHERE uuid=:uuid');
|
||||||
|
$state = EncryptionChannelState::OPENED->value;
|
||||||
|
$stmt->bindParam(':state', $state);
|
||||||
|
$stmt->bindParam(':receiving_signature_uuid', $signatureUuid);
|
||||||
|
$stmt->bindParam(':receiving_signature_public_key', $signaturePublicKey);
|
||||||
|
$stmt->bindParam(':receiving_encryption_public_key', $encryptionPublicKey);
|
||||||
|
$stmt->bindParam(':transport_encryption_algorithm', $transportEncryptionAlgorithm);
|
||||||
|
$stmt->bindParam(':transport_encryption_key', $encryptedTransportEncryptionKey);
|
||||||
|
$stmt->bindParam(':uuid', $channelUuid);
|
||||||
|
$stmt->execute();
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to accept the encryption channel', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the encryption channel with the specified UUID.
|
||||||
|
*
|
||||||
|
* @param string $channelUuid The UUID of the channel to retrieve.
|
||||||
|
* @return EncryptionChannelRecord|null The record of the encryption channel. Null if the channel does not exist.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while retrieving the channel.
|
||||||
|
* @throws \DateMalformedStringException If the created date is not a valid date string.
|
||||||
|
*/
|
||||||
|
public static function getChannel(string $channelUuid): ?EncryptionChannelRecord
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('SELECT * FROM encryption_channels WHERE uuid=:uuid');
|
||||||
|
$stmt->bindParam(':uuid', $channelUuid);
|
||||||
|
$stmt->execute();
|
||||||
|
$result = $stmt->fetch();
|
||||||
|
|
||||||
|
if($result === false)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EncryptionChannelRecord($result);
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to retrieve the encryption channel', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the encryption channel with the specified UUID.
|
||||||
|
*
|
||||||
|
* @param string $channelUuid The UUID of the channel to delete.
|
||||||
|
* @return void
|
||||||
|
*@throws DatabaseOperationException If an error occurs while deleting the channel.
|
||||||
|
*/
|
||||||
|
public static function deleteChannel(string $channelUuid): void
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('DELETE FROM encryption_channels WHERE uuid=:uuid');
|
||||||
|
$stmt->bindParam(':uuid', $channelUuid);
|
||||||
|
$stmt->execute();
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to delete the encryption channel', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the state of the encryption channel with the specified UUID.
|
||||||
|
*
|
||||||
|
* @param string $channelUuid The UUID of the channel to update.
|
||||||
|
* @return EncryptionChannelState The current state of the channel.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while updating the channel state.
|
||||||
|
*/
|
||||||
|
public static function getChannelState(string $channelUuid): EncryptionChannelState
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('SELECT state FROM encryption_channels WHERE uuid=:uuid');
|
||||||
|
$stmt->bindParam(':uuid', $channelUuid);
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
return EncryptionChannelState::from($stmt->fetchColumn());
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to retrieve the encryption channel state', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the state of the encryption channel with the specified UUID.
|
||||||
|
*
|
||||||
|
* @param string $channelUuid The UUID of the channel to update.
|
||||||
|
* @param EncryptionChannelState $state The new state of the channel.
|
||||||
|
* @return void The current state of the channel.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while updating the channel state.
|
||||||
|
*/
|
||||||
|
public static function updateChannelState(string $channelUuid, EncryptionChannelState $state): void
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('UPDATE encryption_channels SET state=:state WHERE uuid=:uuid');
|
||||||
|
$state = $state->value;
|
||||||
|
$stmt->bindParam(':state', $state);
|
||||||
|
$stmt->bindParam(':uuid', $channelUuid);
|
||||||
|
$stmt->execute();
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to update the encryption channel state', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a channel with the provided UUID exists.
|
||||||
|
*
|
||||||
|
* @param string $uuid The UUID of the channel to check.
|
||||||
|
* @return bool True if the channel exists, False otherwise.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while checking the channel.
|
||||||
|
*/
|
||||||
|
public static function channelExists(string $uuid): bool
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('SELECT COUNT(*) FROM encryption_channels WHERE uuid=:uuid');
|
||||||
|
$stmt->bindParam(':uuid', $uuid);
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
return $stmt->fetchColumn() > 0;
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('There was an error while trying to check if the channel UUID exists', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends data to the specified channel.
|
||||||
|
*
|
||||||
|
* @param string $channelUuid The UUID of the channel to send the data to.
|
||||||
|
* @param string $message The message to send.
|
||||||
|
* @param string $signature The signature of the message.
|
||||||
|
* @param CommunicationRecipientType $recipient The recipient type.
|
||||||
|
* @return string The UUID of the sent message.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while sending the message.
|
||||||
|
*/
|
||||||
|
public static function sendData(string $channelUuid, string $message, string $signature, CommunicationRecipientType $recipient): string
|
||||||
|
{
|
||||||
|
$uuid = UuidV4::v4()->toRfc4122();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('INSERT INTO channel_com (uuid, channel_uuid, recipient, message, signature) VALUES (:uuid, :channel_uuid, :recipient, :message, :signature)');
|
||||||
|
$stmt->bindParam(':uuid', $uuid);
|
||||||
|
$stmt->bindParam(':channel_uuid', $channelUuid);
|
||||||
|
$recipient = $recipient->value;
|
||||||
|
$stmt->bindParam(':recipient', $recipient);
|
||||||
|
$stmt->bindParam(':message', $message);
|
||||||
|
$stmt->bindParam(':signature', $signature);
|
||||||
|
|
||||||
|
$stmt->execute();
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to send the message', $e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the messages for the specified channel and recipient.
|
||||||
|
*
|
||||||
|
* @param string $channelUuid The UUID of the channel to retrieve the messages for.
|
||||||
|
* @param CommunicationRecipientType $recipient The recipient type to retrieve the messages for.
|
||||||
|
* @return ChannelMessageRecord[] The messages for the specified channel and recipient.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while retrieving the messages.
|
||||||
|
*/
|
||||||
|
public static function receiveData(string $channelUuid, CommunicationRecipientType $recipient): array
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('SELECT * FROM channel_com WHERE channel_uuid=:channel_uuid AND recipient=:recipient AND received=0 ORDER BY timestamp');
|
||||||
|
$stmt->bindParam(':channel_uuid', $channelUuid);
|
||||||
|
$recipient = $recipient->value;
|
||||||
|
$stmt->bindParam(':recipient', $recipient);
|
||||||
|
$stmt->execute();
|
||||||
|
$results = $stmt->fetchAll();
|
||||||
|
|
||||||
|
$messages = [];
|
||||||
|
foreach($results as $result)
|
||||||
|
{
|
||||||
|
$messages[] = new ChannelMessageRecord($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $messages;
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to retrieve the messages', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the message with the specified UUID.
|
||||||
|
*
|
||||||
|
* @param string $channelUuid The UUID of the channel to retrieve the message for.
|
||||||
|
* @param string $messageUuid The UUID of the message to retrieve.
|
||||||
|
* @return ChannelMessageRecord|null The message with the specified UUID. Null if the message does not exist.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while retrieving the message.
|
||||||
|
*/
|
||||||
|
public static function getData(string $channelUuid, string $messageUuid): ?ChannelMessageRecord
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('SELECT * FROM channel_com WHERE channel_uuid=:channel_uuid AND uuid=:uuid');
|
||||||
|
$stmt->bindParam(':channel_uuid', $channelUuid);
|
||||||
|
$stmt->bindParam(':uuid', $messageUuid);
|
||||||
|
$stmt->execute();
|
||||||
|
$result = $stmt->fetch();
|
||||||
|
|
||||||
|
if($result === false)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ChannelMessageRecord($result);
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to retrieve the message', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the message with the specified UUID as received.
|
||||||
|
*
|
||||||
|
* @param string $uuid The UUID of the message to mark as received.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while marking the message as received.
|
||||||
|
*/
|
||||||
|
public static function markDataAsReceived(string $uuid): void
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('UPDATE channel_com SET received=1 WHERE uuid=:uuid');
|
||||||
|
$stmt->bindParam(':uuid', $uuid);
|
||||||
|
$stmt->execute();
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to mark the message as received', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the message with the specified UUID.
|
||||||
|
*
|
||||||
|
* @param string $uuid The UUID of the message to delete.
|
||||||
|
* @throws DatabaseOperationException If an error occurs while deleting the message.
|
||||||
|
*/
|
||||||
|
public static function deleteData(string $uuid): void
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$stmt = Database::getConnection()->prepare('DELETE FROM channel_com WHERE uuid=:uuid');
|
||||||
|
$stmt->bindParam(':uuid', $uuid);
|
||||||
|
$stmt->execute();
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
throw new DatabaseOperationException('Failed to delete the message', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
141
src/Socialbox/Objects/Database/ChannelMessageRecord.php
Normal file
141
src/Socialbox/Objects/Database/ChannelMessageRecord.php
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Socialbox\Objects\Database;
|
||||||
|
|
||||||
|
use Socialbox\Enums\Types\CommunicationRecipientType;
|
||||||
|
use Socialbox\Interfaces\SerializableInterface;
|
||||||
|
|
||||||
|
class ChannelMessageRecord implements SerializableInterface
|
||||||
|
{
|
||||||
|
private string $uuid;
|
||||||
|
private string $channelUuid;
|
||||||
|
private CommunicationRecipientType $recipient;
|
||||||
|
private string $message;
|
||||||
|
private string $signature;
|
||||||
|
private bool $received;
|
||||||
|
private \DateTime $timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new instance of this class and initializes its properties with the provided data.
|
||||||
|
*
|
||||||
|
* @param array $data An associative array containing initialization data. Expected keys:
|
||||||
|
* - 'uuid' (string): The unique identifier.
|
||||||
|
* - 'channel_uuid' (string): The channel UUID.
|
||||||
|
* - 'recipient' (string): The recipient type, which will be cast to a CommunicationRecipientType instance.
|
||||||
|
* - 'message' (string): The message.
|
||||||
|
* - 'signature' (string): The signature.
|
||||||
|
* - 'received' (bool): Whether the message has been received.
|
||||||
|
* - 'timestamp' (int|string|\DateTime): The timestamp of the message.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(array $data)
|
||||||
|
{
|
||||||
|
$this->uuid = $data['uuid'];
|
||||||
|
$this->channelUuid = $data['channel_uuid'];
|
||||||
|
$this->recipient = CommunicationRecipientType::from($data['recipient']);
|
||||||
|
$this->message = $data['message'];
|
||||||
|
$this->signature = $data['signature'];
|
||||||
|
$this->received = (bool)$data['received'];
|
||||||
|
|
||||||
|
if($data['timestamp'] instanceof \DateTime)
|
||||||
|
{
|
||||||
|
$this->timestamp = $data['timestamp'];
|
||||||
|
}
|
||||||
|
elseif(is_int($data['timestamp']))
|
||||||
|
{
|
||||||
|
$this->timestamp = (new \DateTime())->setTimestamp($data['timestamp']);
|
||||||
|
}
|
||||||
|
elseif(is_string($data['timestamp']))
|
||||||
|
{
|
||||||
|
$this->timestamp = new \DateTime($data['timestamp']);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new \InvalidArgumentException('Invalid timestamp type, got ' . gettype($data['timestamp']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the unique identifier for the message.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUuid(): string
|
||||||
|
{
|
||||||
|
return $this->uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the UUID of the channel that the message belongs to.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getChannelUuid(): string
|
||||||
|
{
|
||||||
|
return $this->channelUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the recipient type of the message.
|
||||||
|
*
|
||||||
|
* @return CommunicationRecipientType
|
||||||
|
*/
|
||||||
|
public function getRecipient(): CommunicationRecipientType
|
||||||
|
{
|
||||||
|
return $this->recipient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the message content.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getMessage(): string
|
||||||
|
{
|
||||||
|
return $this->message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the signature of the message.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSignature(): string
|
||||||
|
{
|
||||||
|
return $this->signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isReceived(): bool
|
||||||
|
{
|
||||||
|
return $this->received;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTimestamp(): \DateTime
|
||||||
|
{
|
||||||
|
return $this->timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public static function fromArray(array $data): ChannelMessageRecord
|
||||||
|
{
|
||||||
|
return new self($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function toArray(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'uuid' => $this->uuid,
|
||||||
|
'channel_uuid' => $this->channelUuid,
|
||||||
|
'recipient' => $this->recipient->value,
|
||||||
|
'message' => $this->message,
|
||||||
|
'signature' => $this->signature,
|
||||||
|
'received' => $this->received,
|
||||||
|
'timestamp' => $this->timestamp->format('Y-m-d H:i:s')
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
259
src/Socialbox/Objects/Database/EncryptionChannelRecord.php
Normal file
259
src/Socialbox/Objects/Database/EncryptionChannelRecord.php
Normal file
|
@ -0,0 +1,259 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Socialbox\Objects\Database;
|
||||||
|
|
||||||
|
use DateTime;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use Socialbox\Enums\Status\EncryptionChannelState;
|
||||||
|
use Socialbox\Interfaces\SerializableInterface;
|
||||||
|
use Socialbox\Objects\PeerAddress;
|
||||||
|
|
||||||
|
class EncryptionChannelRecord implements SerializableInterface
|
||||||
|
{
|
||||||
|
private string $uuid;
|
||||||
|
private PeerAddress $callingPeer;
|
||||||
|
private string $callingSignatureUuid;
|
||||||
|
private string $callingEncryptionPublicKey;
|
||||||
|
private PeerAddress $receivingPeer;
|
||||||
|
private ?string $receivingSignatureUuid;
|
||||||
|
private ?string $receivingSignaturePublicKey;
|
||||||
|
private ?string $receivingEncryptionPublicKey;
|
||||||
|
private string $transportEncryptionAlgorithm;
|
||||||
|
private ?string $transportEncryptionKey;
|
||||||
|
private EncryptionChannelState $state;
|
||||||
|
private DateTime $created;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public Constructor for the encryption channel record
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @throws \DateMalformedStringException
|
||||||
|
*/
|
||||||
|
public function __construct(array $data)
|
||||||
|
{
|
||||||
|
$this->uuid = $data['uuid'];
|
||||||
|
|
||||||
|
if(!isset($data['calling_peer']))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException('Missing property calling_peer');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(is_string($data['calling_peer']))
|
||||||
|
{
|
||||||
|
$this->callingPeer = PeerAddress::fromAddress($data['calling_peer']);
|
||||||
|
}
|
||||||
|
elseif($data['calling_peer'] instanceof PeerAddress)
|
||||||
|
{
|
||||||
|
$this->callingPeer = $data['calling_peer'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException('Unexpected calling_peer type, got ' . gettype($data['calling_peer']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->callingSignatureUuid = $data['calling_signature_uuid'];
|
||||||
|
$this->callingEncryptionPublicKey = $data['calling_encryption_public_key'];
|
||||||
|
|
||||||
|
if(!isset($data['receiving_peer']))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException('Missing property receiving_peer');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(is_string($data['receiving_peer']))
|
||||||
|
{
|
||||||
|
$this->receivingPeer = PeerAddress::fromAddress($data['receiving_peer']);
|
||||||
|
}
|
||||||
|
elseif($data['receiving_peer'] instanceof PeerAddress)
|
||||||
|
{
|
||||||
|
$this->receivingPeer = $data['receiving_peer'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException('Unexpected receiving_peer type, got ' . gettype($data['receiving_peer']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->receivingSignatureUuid = $data['receiving_signature_uuid'] ?? null;
|
||||||
|
$this->receivingSignaturePublicKey = $data['receiving_signature_public_key'] ?? null;
|
||||||
|
$this->receivingEncryptionPublicKey = $data['receiving_encryption_public_key'] ?? null;
|
||||||
|
$this->transportEncryptionAlgorithm = $data['transport_encryption_algorithm'];
|
||||||
|
$this->transportEncryptionKey = $data['transport_encryption_key'] ?? null;
|
||||||
|
$this->state = EncryptionChannelState::tryFrom($data['state']) ?? EncryptionChannelState::ERROR;
|
||||||
|
|
||||||
|
if(!isset($data['created']))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException('Missing property created');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(is_string($data['created']))
|
||||||
|
{
|
||||||
|
$this->created = new DateTime($data['created']);
|
||||||
|
}
|
||||||
|
elseif(is_int($data['created']))
|
||||||
|
{
|
||||||
|
$this->created = (new DateTime())->setTimestamp($data['created']);
|
||||||
|
}
|
||||||
|
elseif($data['created'] instanceof DateTime)
|
||||||
|
{
|
||||||
|
$this->created = $data['created'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException('Unexpected created type, got ' . gettype($data['created']));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Unique Universal Identifier for the encryption record
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getUuid(): string
|
||||||
|
{
|
||||||
|
return $this->uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the address of the calling peer
|
||||||
|
*
|
||||||
|
* @return PeerAddress
|
||||||
|
*/
|
||||||
|
public function getCallingPeer(): PeerAddress
|
||||||
|
{
|
||||||
|
return $this->callingPeer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the UUID of the signing keypair that the caller is using
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCallingSignatureUuid(): string
|
||||||
|
{
|
||||||
|
return $this->callingSignatureUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the public key of the encryption keypair that the caller is using
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCallingEncryptionPublicKey(): string
|
||||||
|
{
|
||||||
|
return $this->callingEncryptionPublicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the address of the receiving peer
|
||||||
|
*
|
||||||
|
* @return PeerAddress
|
||||||
|
*/
|
||||||
|
public function getReceivingPeer(): PeerAddress
|
||||||
|
{
|
||||||
|
return $this->receivingPeer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the UUID of the signing keypair that the receiver is using
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getReceivingSignatureUuid(): ?string
|
||||||
|
{
|
||||||
|
return $this->receivingSignatureUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the public key of the signing keypair that the receiver is using
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getReceivingSignaturePublicKey(): ?string
|
||||||
|
{
|
||||||
|
return $this->receivingSignaturePublicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the public key of the encryption keypair that the receiver is using
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getReceivingEncryptionPublicKey(): ?string
|
||||||
|
{
|
||||||
|
return $this->receivingEncryptionPublicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the algorithm used for transport encryption
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getTransportEncryptionAlgorithm(): string
|
||||||
|
{
|
||||||
|
return $this->transportEncryptionAlgorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key used for transport encryption
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getTransportEncryptionKey(): ?string
|
||||||
|
{
|
||||||
|
return $this->transportEncryptionKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current state of the encryption channel
|
||||||
|
*
|
||||||
|
* @return EncryptionChannelState
|
||||||
|
*/
|
||||||
|
public function getState(): EncryptionChannelState
|
||||||
|
{
|
||||||
|
return $this->state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the creation date of the encryption channel
|
||||||
|
*
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function getCreated(): DateTime
|
||||||
|
{
|
||||||
|
return $this->created;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public static function fromArray(array $data): EncryptionChannelRecord
|
||||||
|
{
|
||||||
|
return new self($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function toArray(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'uuid' => $this->uuid,
|
||||||
|
'calling_peer' => $this->callingPeer->getAddress(),
|
||||||
|
'calling_signature_uuid' => $this->callingSignatureUuid,
|
||||||
|
'calling_encryption_public_key' => $this->callingEncryptionPublicKey,
|
||||||
|
'receiving_peer' => $this->receivingPeer->getAddress(),
|
||||||
|
'receiving_signature_uuid' => $this->receivingSignatureUuid,
|
||||||
|
'receiving_signature_public_key' => $this->receivingSignaturePublicKey,
|
||||||
|
'receiving_encryption_public_key' => $this->receivingEncryptionPublicKey,
|
||||||
|
'transport_encryption_algorithm' => $this->transportEncryptionAlgorithm,
|
||||||
|
'transport_encryption_key' => $this->transportEncryptionKey,
|
||||||
|
'state' => $this->state->value,
|
||||||
|
'created' => $this->created->format('Y-m-d H:i:s')
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue