Airship\Engine\Keyggdrasil::checkWithPeer PHP Method

checkWithPeer() protected method

Does this peer notary see the same Merkle root?
protected checkWithPeer ( Peer $peer, string $expectedRoot ) : boolean
$peer Peer
$expectedRoot string
return boolean
    protected function checkWithPeer(Peer $peer, string $expectedRoot) : bool
    {
        foreach ($peer->getAllURLs('/verify') as $url) {
            // Challenge nonce:
            $challenge = Base64UrlSafe::encode(\random_bytes(33));
            // Peer's response:
            $response = $this->hail->postJSON($url, ['challenge' => $challenge]);
            if ($response['status'] !== 'OK') {
                $this->log('Upstream error.', LogLevel::EMERGENCY, ['response' => $response]);
                return false;
            }
            // Decode then verify signature
            $message = Base64UrlSafe::decode($response['response']);
            $signature = Base64UrlSafe::decode($response['signature']);
            $isValid = AsymmetricCrypto::verify($message, $peer->getPublicKey(), $signature, true);
            if (!$isValid) {
                $this->log('Invalid digital signature (i.e. it was signed with an incorrect key).', LogLevel::EMERGENCY);
                throw new PeerSignatureFailed('Invalid digital signature (i.e. it was signed with an incorrect key).');
            }
            // Make sure our challenge was signed.
            $decoded = \json_decode($message, true);
            if (!\hash_equals($challenge, $decoded['challenge'])) {
                $this->log('Challenge-response authentication failed.', LogLevel::EMERGENCY);
                throw new CouldNotUpdate(\__('Challenge-response authentication failed.'));
            }
            // Make sure this was a recent signature (it *should* be).
            // The earliest timestamp we will accept from a peer:
            $min = (new \DateTime('now'))->sub(new \DateInterval('P01D'));
            // The timestamp the server provided:
            $time = new \DateTime($decoded['timestamp']);
            if ($time < $min) {
                throw new CouldNotUpdate(\__('Timestamp %s is far too old.', 'default', $decoded['timestamp']));
            }
            // Return TRUE if it matches the expected root.
            // Return FALSE if it matches.
            return \hash_equals($expectedRoot, $decoded['root']);
        }
        // When all else fails, throw a TransferException
        throw new TransferException();
    }