Made message signing in Cryptography use SHA512 as the message content for... #1

Closed
netkas wants to merge 421 commits from master into dev
5 changed files with 333 additions and 6 deletions
Showing only changes of commit 83a47ddd5e - Show all commits

View file

@ -43,13 +43,11 @@
return $rpcRequest->produceError(StandardError::NOT_FOUND, 'Contact does not exist'); return $rpcRequest->produceError(StandardError::NOT_FOUND, 'Contact does not exist');
} }
$contact = ContactManager::getContact($request->getPeer(), $address); $rpcRequest->produceResponse(ContactManager::getStandardContact($request->getPeer(), $address));
} }
catch(DatabaseOperationException $e) catch(DatabaseOperationException $e)
{ {
throw new StandardRpcException('Failed to get contact', StandardError::INTERNAL_SERVER_ERROR, $e); throw new StandardRpcException('Failed to get contact', StandardError::INTERNAL_SERVER_ERROR, $e);
} }
return $rpcRequest->produceResponse($contact->toStandard());
} }
} }

View file

@ -8,10 +8,13 @@
use Socialbox\Classes\Database; use Socialbox\Classes\Database;
use Socialbox\Enums\Types\ContactRelationshipType; use Socialbox\Enums\Types\ContactRelationshipType;
use Socialbox\Exceptions\DatabaseOperationException; use Socialbox\Exceptions\DatabaseOperationException;
use Socialbox\Exceptions\Standard\StandardRpcException;
use Socialbox\Objects\Database\ContactDatabaseRecord; use Socialbox\Objects\Database\ContactDatabaseRecord;
use Socialbox\Objects\Database\ContactKnownKeyRecord; use Socialbox\Objects\Database\ContactKnownKeyRecord;
use Socialbox\Objects\PeerAddress; use Socialbox\Objects\PeerAddress;
use Socialbox\Objects\Standard\ContactRecord;
use Socialbox\Objects\Standard\SigningKey; use Socialbox\Objects\Standard\SigningKey;
use Socialbox\Socialbox;
class ContactManager class ContactManager
{ {
@ -173,7 +176,7 @@
} }
/** /**
* Updates the relationship type of a contact associated with a specific peer. * Updates the relationship type of contact associated with a specific peer.
* *
* @param string $peerUuid The unique identifier for the peer whose contact relationship is to be updated. * @param string $peerUuid The unique identifier for the peer whose contact relationship is to be updated.
* @param string|PeerAddress $contactAddress The address of the contact to update. Can be provided as a string or an instance of PeerAddress. * @param string|PeerAddress $contactAddress The address of the contact to update. Can be provided as a string or an instance of PeerAddress.
@ -476,4 +479,38 @@
throw new DatabaseOperationException('Failed to get the number of signing keys for a contact from the database', $e); throw new DatabaseOperationException('Failed to get the number of signing keys for a contact from the database', $e);
} }
} }
/**
* Returns a standard contact record for a given peer UUID and contact address.
*
* @param string $peerUuid The unique identifier of the peer.
* @param string|PeerAddress $contactAddress The contact's address, either as a string or a PeerAddress instance.
* @return ContactRecord|null The standard contact record if found, or null if no matching contact exists.
* @throws DatabaseOperationException If the database query fails.
*/
public static function getStandardContact(string $peerUuid, string|PeerAddress $contactAddress): ?ContactRecord
{
$contact = self::getContact($peerUuid, $contactAddress);
if($contact === null)
{
return null;
}
try
{
$peer = Socialbox::resolvePeer($contactAddress);
}
catch (StandardRpcException $e)
{
$peer = null;
}
return new ContactRecord([
'address' => $contact->getContactPeerAddress(),
'peer' => $peer,
'relationship' => $contact->getRelationship(),
'known_keys' => self::contactGetSigningKeys($contact),
'added_timestamp' => $contact->getCreated()->getTimestamp()
]);
}
} }

View file

@ -5,6 +5,7 @@
use DateTime; use DateTime;
use InvalidArgumentException; use InvalidArgumentException;
use Socialbox\Interfaces\SerializableInterface; use Socialbox\Interfaces\SerializableInterface;
use Socialbox\Objects\Standard\KnownSigningKey;
class ContactKnownKeyRecord implements SerializableInterface class ContactKnownKeyRecord implements SerializableInterface
{ {
@ -16,6 +17,12 @@
private DateTime $created; private DateTime $created;
private DateTime $trustedOn; private DateTime $trustedOn;
/**
* Constructs a new instance with the provided parameters.
*
* @param array $data The array of data to use for the object.
* @throws \DateMalformedStringException If the date string is malformed.
*/
public function __construct(array $data) public function __construct(array $data)
{ {
$this->contactUuid = $data['contact_uuid']; $this->contactUuid = $data['contact_uuid'];
@ -96,36 +103,71 @@
} }
} }
/**
* Gets the contact UUID.
*
* @return string The contact UUID.
*/
public function getContactUuid(): string public function getContactUuid(): string
{ {
return $this->contactUuid; return $this->contactUuid;
} }
/**
* Gets the signature UUID.
*
* @return string The signature UUID.
*/
public function getSignatureUuid(): string public function getSignatureUuid(): string
{ {
return $this->signatureUuid; return $this->signatureUuid;
} }
/**
* Gets the signature name.
*
* @return string The signature name.
*/
public function getSignatureName(): string public function getSignatureName(): string
{ {
return $this->signatureName; return $this->signatureName;
} }
/**
* Gets the signature key.
*
* @return string The signature key.
*/
public function getSignatureKey(): string public function getSignatureKey(): string
{ {
return $this->signatureKey; return $this->signatureKey;
} }
/**
* Gets the expiration date.
*
* @return DateTime|null The expiration date.
*/
public function getExpires(): ?DateTime public function getExpires(): ?DateTime
{ {
return $this->expires; return $this->expires;
} }
/**
* Gets the creation date.
*
* @return DateTime The creation date.
*/
public function getCreated(): DateTime public function getCreated(): DateTime
{ {
return $this->created; return $this->created;
} }
/**
* Gets the trusted on date.
*
* @return DateTime The trusted on date.
*/
public function getTrustedOn(): DateTime public function getTrustedOn(): DateTime
{ {
return $this->trustedOn; return $this->trustedOn;
@ -139,6 +181,21 @@
return new self($data); return new self($data);
} }
/**
* @inheritDoc
*/
public function toStandard(): KnownSigningKey
{
return new KnownSigningKey([
'uuid' => $this->signatureUuid,
'name' => $this->signatureName,
'public_key' => $this->signatureKey,
'expires' => $this->expires?->getTimestamp(),
'created' => $this->created->getTimestamp(),
'trusted_on' => $this->trustedOn->getTimestamp()
]);
}
/** /**
* @inheritDoc * @inheritDoc
*/ */

View file

@ -2,6 +2,7 @@
namespace Socialbox\Objects\Standard; namespace Socialbox\Objects\Standard;
use InvalidArgumentException;
use Socialbox\Enums\Types\ContactRelationshipType; use Socialbox\Enums\Types\ContactRelationshipType;
use Socialbox\Interfaces\SerializableInterface; use Socialbox\Interfaces\SerializableInterface;
use Socialbox\Objects\PeerAddress; use Socialbox\Objects\PeerAddress;
@ -9,7 +10,12 @@
class ContactRecord implements SerializableInterface class ContactRecord implements SerializableInterface
{ {
private PeerAddress $address; private PeerAddress $address;
private ?Peer $peer;
private ContactRelationshipType $relationship; private ContactRelationshipType $relationship;
/**
* @var KnownSigningKey[]
*/
private array $knownKeys;
private int $addedTimestamp; private int $addedTimestamp;
/** /**
@ -20,7 +26,53 @@
public function __construct(array $data) public function __construct(array $data)
{ {
$this->address = PeerAddress::fromAddress($data['address']); $this->address = PeerAddress::fromAddress($data['address']);
$this->relationship = ContactRelationshipType::tryFrom($data['relationship']) ?? ContactRelationshipType::MUTUAL; if(is_array($data['peer']))
{
$this->peer = Peer::fromArray($data['peer']);
}
elseif($data['peer'] instanceof Peer)
{
$this->peer = $data['peer'];
}
elseif(is_null($data['peer']))
{
$this->peer = null;
}
else
{
throw new InvalidArgumentException('Invalid peer data');
}
if($data['relationship'] instanceof ContactRelationshipType)
{
$this->relationship = $data['relationship'];
}
elseif(is_string($data['relationship']))
{
$this->relationship = ContactRelationshipType::tryFrom($data['relationship']) ?? ContactRelationshipType::MUTUAL;
}
else
{
throw new InvalidArgumentException('Invalid relationship data');
}
$this->knownKeys = [];
foreach($data['known_keys'] as $key)
{
if(is_array($key))
{
$this->knownKeys[] = KnownSigningKey::fromArray($key);
}
elseif($key instanceof KnownSigningKey)
{
$this->knownKeys[] = $key;
}
else
{
throw new InvalidArgumentException('Invalid known key data');
}
}
$this->addedTimestamp = $data['added_timestamp']; $this->addedTimestamp = $data['added_timestamp'];
} }
@ -34,6 +86,16 @@
return $this->address; return $this->address;
} }
/**
* Retrieves the peer of the contact.
*
* @return Peer|null Returns the peer of the contact. If the peer is not known, null is returned.
*/
public function getPeer(): ?Peer
{
return $this->peer;
}
/** /**
* Retrieves the relationship of the contact. * Retrieves the relationship of the contact.
* *
@ -44,6 +106,16 @@
return $this->relationship; return $this->relationship;
} }
/**
* Retrieves the known keys of the contact.
*
* @return KnownSigningKey[] Returns the known keys of the contact.
*/
public function getKnownKeys(): array
{
return $this->knownKeys;
}
/** /**
* Retrieves the timestamp when the contact was added. * Retrieves the timestamp when the contact was added.
* *
@ -57,7 +129,7 @@
/** /**
* @inheritDoc * @inheritDoc
*/ */
public static function fromArray(array $data): object public static function fromArray(array $data): ContactRecord
{ {
return new self($data); return new self($data);
} }
@ -69,7 +141,9 @@
{ {
return [ return [
'address' => $this->address->getAddress(), 'address' => $this->address->getAddress(),
'peer' => $this->peer?->toArray(),
'relationship' => $this->relationship->value, 'relationship' => $this->relationship->value,
'known_keys' => array_map(function($key) {return $key->toArray();}, $this->knownKeys),
'added_timestamp' => $this->addedTimestamp 'added_timestamp' => $this->addedTimestamp
]; ];
} }

View file

@ -0,0 +1,161 @@
<?php
namespace Socialbox\Objects\Standard;
use DateTime;
use InvalidArgumentException;
use Socialbox\Interfaces\SerializableInterface;
class KnownSigningKey implements SerializableInterface
{
private string $uuid;
private string $name;
private string $publicKey;
private int $expires;
private int $created;
private int $trustedOn;
/**
* Constructs a new instance of the class, initializing its properties using the provided data.
*
* @param array $data An associative array containing initialization data.
* Expected keys are:
* - 'uuid' (string): The unique identifier for the instance.
* - 'name' (string|null): The optional name for the instance.
* - 'public_key' (string): The public key associated with the instance.
* - 'expires' (int|DateTime): The expiration timestamp or DateTime object.
* - 'created' (int|DateTime): The creation timestamp or DateTime object.
* - 'trusted_on' (int|DateTime): The trusted on timestamp or DateTime object.
*
* @return void
* @throws InvalidArgumentException If 'expires' or 'created' are not valid integer timestamps or DateTime instances.
*/
public function __construct(array $data)
{
$this->uuid = $data['uuid'];
$this->name = $data['name'];
$this->publicKey = $data['public_key'];
if(is_int($data['expires']))
{
$this->expires = $data['expires'];
}
elseif($data['expires'] instanceof DateTime)
{
$this->expires = $data['expires']->getTimestamp();
}
else
{
throw new InvalidArgumentException('Invalid expires value');
}
if(is_int($data['created']))
{
$this->created = $data['created'];
}
elseif($data['created'] instanceof DateTime)
{
$this->created = $data['created']->getTimestamp();
}
else
{
throw new InvalidArgumentException('Invalid created value');
}
if(is_int($data['trusted_on']))
{
$this->trustedOn = $data['trusted_on'];
}
elseif($data['trusted_on'] instanceof DateTime)
{
$this->trustedOn = $data['trusted_on']->getTimestamp();
}
else
{
throw new InvalidArgumentException('Invalid trusted_on value');
}
}
/**
* Retrieves the UUID associated with this instance.
*
* @return string The UUID as a string.
*/
public function getUuid(): string
{
return $this->uuid;
}
/**
* Retrieves the name associated with this instance.
*
* @return string|null The name as a string, or null if not set.
*/
public function getName(): ?string
{
return $this->name;
}
/**
*
* Retrieves the public key.
*
* @return string The public key.
*/
public function getPublicKey(): string
{
return $this->publicKey;
}
/**
* Retrieves the expiration time.
*
* @return int The expiration time as an integer.
*/
public function getExpires(): int
{
return $this->expires;
}
/**
*
* @return int The timestamp representing the creation time.
*/
public function getCreated(): int
{
return $this->created;
}
/**
* Retrieves the timestamp representing the time the key was trusted.
*
* @return int The timestamp representing the time the key was trusted.
*/
public function getTrustedOn(): int
{
return $this->trustedOn;
}
/**
* @inheritDoc
*/
public static function fromArray(array $data): KnownSigningKey
{
return new self($data);
}
/**
* @inheritDoc
*/
public function toArray(): array
{
return [
'uuid' => $this->uuid,
'name' => $this->name,
'public_key' => $this->publicKey,
'expires' => $this->expires,
'created' => $this->created,
'trusted_on' => $this->trustedOn
];
}
}