예제 #1
0
 public function post()
 {
     \header('Content-Type: application/json');
     if (!empty($_POST['message']) && !empty($_POST['signature']) && !empty($_POST['prevhash']) && !empty($_POST['merkleroot']) && !empty($_POST['block'])) {
         // Plausibly a message from the mother ship? Let's check our
         $signature = \base64_decode($_POST['signature']);
         $message = \base64_decode($_POST['message']);
         $pubkey = \base64_decode(\ParagonIE\AsgardClient\MetaData::AUTHORIZED_PUBLICKEY);
         if (\Sodium::crypto_sign_verify_detached($signature, $message, $pubkey)) {
             // Should be the same as a new message
             $re_encode = \json_encode(['signature' => $_POST['signature'], 'message' => $_POST['message']], JSON_PRETTY_PRINT);
             return $this->insertBlock($re_encode, $_POST['merkleroot'], $_POST['block'], $_POST['prevhash']);
         }
     }
     // Usual case: You are not l33t enough to grab our priv8 key
     echo \json_encode(['error' => 'Access denied.'], JSON_PRETTY_PRINT);
     exit;
 }
예제 #2
0
 /**
  * Verify the signature of a block
  * 
  * @param type $block
  */
 private function verifySignature($block)
 {
     $signed = \Sodium::crypto_sign_verify_detached(\base64_decode($block['signature']), \base64_decode($block['message']), \base64_decode(Base\MetaData::AUTHORIZED_PUBLICKEY));
     if ($signed === false) {
         die("Signature verification failed!");
     }
     return \json_decode(\base64_decode($block['message']), true);
 }
예제 #3
0
 /**
  * Verify new blocks with our peers
  * 
  * @param array $newBlocks
  * @param boolean $echo
  */
 private function peerPressure($newBlocks, $echo = false)
 {
     if ($echo) {
         echo "\n\tVerifying new blocks...\n";
     }
     // SELECT hash FROM blocks ORDER BY id DESC
     $lasthash = $this->bc->selectOne('blocks', ['hash'], [], [['id', 'DESC']], [], 0, 1);
     // SELECT * FROM notaries
     $notaries = $this->db->select('notaries');
     $consensus = ['fail' => 0, 'timeout' => 0, 'pass' => 0];
     foreach ($notaries as $peer) {
         $hostname = $peer['https'] > 0 ? 'https://' . $peer['host'] . ':' . $peer['port'] : 'http://' . $peer['host'] . ':' . $peer['port'];
         $net = new Base\HTTPS($hostname);
         $body = $net->get('/blockchain/hash/' . $lasthash);
         if (!empty($body)) {
             $response = \json_decode($body, true);
         } else {
             ++$consensus['timeout'];
             continue;
         }
         if (!empty($response['message']) && !empty($response['signature'])) {
             // Let's grab everything we need to verify the  detached signature
             $msg = \base64_decode($response['message']);
             $sig = \base64_decode($response['signature']);
             $pubkey = \base64_decode($peer['publickey']);
             if (\Sodium::crypto_sign_verify_detached($sig, $msg, $pubkey)) {
                 // At this point, we know the signature was valid.
                 $analysis = $this->analyzePeerResponse(\json_decode($msg, true), $newBlocks, $peer, $echo);
                 if ($analysis) {
                     ++$consensus['pass'];
                     // Don't run the last line of the loop
                     continue;
                 }
             } elseif ($echo) {
                 echo $this->c['red'], 'Peer signature failed: ', $peer['nickname'], $this->c[''], "\n";
             }
         } elseif ($echo) {
             echo $this->c['red'], 'Peer connection failed or response invalid: ', $peer['nickname'], $this->c[''], "\n";
         }
         // When something fails, increment it here.
         ++$consensus['fail'];
     }
     // After the foreach loop runs, decide whether or not to proceed.
     if ($consensus['fail'] === 0 && $consensus['pass'] > 0) {
         // No failures, at least 1 success
         return true;
     }
     if ($echo) {
         echo $this->c['red'], 'An error has occurred!', $this->c[''], "\n", 'Attempting to synchronize the distributed ledger failed!', "\n";
     }
     return false;
 }