From 7485733219f20663f28bc32d218fd8160c5c640a Mon Sep 17 00:00:00 2001 From: netkas Date: Mon, 3 Feb 2025 14:11:07 -0500 Subject: [PATCH] Added method verifyPeerSignature(PeerAddress|string $signingPeer, string $signatureUuid, string $signatureKey, string $signature, string $messageHash, int $signatureTime): SignatureVerificationStatus --- .../Status/SignatureVerificationStatus.php | 17 ++++++++- src/Socialbox/Socialbox.php | 37 ++++++++++++++++--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/Socialbox/Enums/Status/SignatureVerificationStatus.php b/src/Socialbox/Enums/Status/SignatureVerificationStatus.php index 17f4055..3fb4cb0 100644 --- a/src/Socialbox/Enums/Status/SignatureVerificationStatus.php +++ b/src/Socialbox/Enums/Status/SignatureVerificationStatus.php @@ -10,7 +10,17 @@ case INVALID = 'INVALID'; /** - * The provided signature was valid but the key associated with the signature has expired. + * The provided signature was valid but the public key used to verify the signature was not the expected public key. + */ + case PUBLIC_KEY_MISMATCH = 'PUBLIC_KEY_MISMATCH'; + + /** + * The provided signature was valid but the UUID used to verify the signature was not the expected UUID. + */ + case UUID_MISMATCH = 'UUID_MISMATCH'; + + /** + * The provided signature was valid but the signing key has expired. */ case EXPIRED = 'EXPIRED'; @@ -18,4 +28,9 @@ * The provided signature was valid but unable to be verified against the peer's known public key. */ case UNVERIFIED = 'UNVERIFIED'; + + /** + * The provided signature was valid and verified locally and against the peer's known public key successfully. + */ + case VERIFIED = 'VERIFIED'; } diff --git a/src/Socialbox/Socialbox.php b/src/Socialbox/Socialbox.php index e0e598c..79c2b30 100644 --- a/src/Socialbox/Socialbox.php +++ b/src/Socialbox/Socialbox.php @@ -15,6 +15,7 @@ use Socialbox\Enums\PrivacyState; use Socialbox\Enums\ReservedUsernames; use Socialbox\Enums\SessionState; + use Socialbox\Enums\SigningKeyState; use Socialbox\Enums\StandardError; use Socialbox\Enums\StandardHeaders; use Socialbox\Enums\StandardMethods; @@ -751,6 +752,11 @@ } /** + * Verifies the signature of a message using the public key of the signing peer both locally and externally. + * If the peer is registered locally, the signature is verified using the local public key. + * If the peer is external, the signature is verified by resolving the peer's public key from the external server. + * The signature is verified against the resolved public key, and the status of the verification is returned. + * * @param PeerAddress|string $signingPeer The peer address or string identifier of the signing peer * @param string $signatureUuid The UUID of the signature key to be resolved * @param string $signatureKey The public key of the signature that was used to sign the message @@ -761,12 +767,9 @@ */ public static function verifyPeerSignature(PeerAddress|string $signingPeer, string $signatureUuid, string $signatureKey, string $signature, string $messageHash, int $signatureTime): SignatureVerificationStatus { - $messageHash = sprintf('%s:%d', $messageHash, $signatureTime); - - // First verify the signature with the provided parameters try { - if (!Cryptography::verifyMessage($messageHash, $signature, $signatureKey, false)) + if (!Cryptography::verifyTimedMessage($messageHash, $signature, $signatureKey, $signatureTime, false)) { return SignatureVerificationStatus::INVALID; } @@ -779,17 +782,37 @@ // Resolve the peer signature key try { - $signingKey = self::resolvePeerSignature($peerAddress, $signatureUuid); + $signingKey = self::resolvePeerSignature($signingPeer, $signatureUuid); } catch(StandardRpcException) { return SignatureVerificationStatus::UNVERIFIED; } + if($signingKey === null) + { + return SignatureVerificationStatus::UNVERIFIED; + } + + if($signingKey->getPublicKey() !== $signatureKey) + { + return SignatureVerificationStatus::PUBLIC_KEY_MISMATCH; + } + + if($signingKey->getUuid() !== $signatureUuid) + { + return SignatureVerificationStatus::UUID_MISMATCH; + } + + if(time() > $signingKey->getExpires()) + { + return SignatureVerificationStatus::EXPIRED; + } + // Verify the signature with the resolved key try { - if (!Cryptography::verifyMessage($messageHash, $signature, $signingKey->getPublicKey(), false)) + if (!Cryptography::verifyTimedMessage($messageHash, $signature, $signingKey->getPublicKey(), $signatureTime, false)) { return SignatureVerificationStatus::INVALID; } @@ -798,6 +821,8 @@ { return SignatureVerificationStatus::INVALID; } + + return SignatureVerificationStatus::VERIFIED; } /**