/** * Create a unique ID (e.g. for permalinks) * * @param int $length * @return string */ function uniqueId(int $length = 24) : string { if ($length < 1) { return ''; } $n = (int) ceil($length * 0.75); $str = \random_bytes($n); return Binary::safeSubstr(Base64UrlSafe::encode($str), 0, $length); }
/** * @route notary */ public function index() { \Airship\json_response(['status' => 'OK', 'channel' => $this->channel, 'message' => '', 'public_key' => Base64UrlSafe::encode($this->pk->getRawKeyMaterial())]); }
/** * Create a random workspace directory * * @return string * @throws \Error */ protected function createWorkspace() : string { do { $dirname = Base64UrlSafe::encode(\random_bytes(18)); } while (\is_dir(AIRSHIP_LOCAL_CONFIG . DIRECTORY_SEPARATOR . $dirname)); if (!\mkdir(AIRSHIP_LOCAL_CONFIG . DIRECTORY_SEPARATOR . $dirname, 0700)) { throw new \Error('Could not create workspace directory: ' . AIRSHIP_LOCAL_CONFIG . DIRECTORY_SEPARATOR . $dirname); } return AIRSHIP_LOCAL_CONFIG . DIRECTORY_SEPARATOR . $dirname; }
/** * This propagates the new update through the network. */ protected function notifyPeersOfNewUpdate() { $state = State::instance(); if (IDE_HACKS) { $state->hail = new Hail(new Client()); } $resp = []; $peers = \Airship\loadJSON(ROOT . '/config/channel_peers/' . $this->channel . '.json'); foreach ($peers as $peer) { foreach ($peer['urls'] as $url) { $resp[] = $state->hail->getAsync($url, ['challenge' => Base64UrlSafe::encode(\random_bytes(21))]); } } foreach ($resp as $r) { $r->then(function (ResponseInterface $response) { $body = (string) $response->getBody(); $context = \json_decode(Binary::safeSubstr($body, 89)); $this->log('Peer notified of channel update', LogLevel::INFO, $context); }); } }
/** * Display the notary <meta> tag. * * @param SignaturePublicKey $pk */ function display_notary_tag(SignaturePublicKey $pk = null) { $state = State::instance(); $notary = $state->universal['notary']; if (!empty($notary['enabled'])) { if (!$pk) { $sk = $state->keyring['notary.online_signing_key']; if (!$sk instanceof SignatureSecretKey) { return; } $pk = $sk->derivePublicKey()->getRawKeyMaterial(); } echo '<meta name="airship-notary" content="' . Base64UrlSafe::encode($pk) . '; channel=' . Util::noHTML($notary['channel']) . '; url=' . cabin_url('Bridge') . 'notary' . '" />'; } }
/** * RFC 4648 Base64 (URL Safe) encoding * * "foo" -> "Zm9v" * * @param string $str * @return string */ public function base64UrlSafeEncode(string $str) : string { return Base64UrlSafe::encode($str); }
public function testEncoding() { $random_bytes = \random_bytes(31); // Backwards compatibility: $encoder = Halite::chooseEncoder(false); $this->assertSame(Hex::encode($random_bytes), $encoder($random_bytes)); $encoder = Halite::chooseEncoder(true); $this->assertSame(null, $encoder); // New encoding in version 3: $encoder = Halite::chooseEncoder(Halite::ENCODE_HEX); $this->assertSame(Hex::encode($random_bytes), $encoder($random_bytes)); $encoder = Halite::chooseEncoder(Halite::ENCODE_BASE32); $this->assertSame(Base32::encode($random_bytes), $encoder($random_bytes)); $encoder = Halite::chooseEncoder(Halite::ENCODE_BASE32HEX); $this->assertSame(Base32Hex::encode($random_bytes), $encoder($random_bytes)); $encoder = Halite::chooseEncoder(Halite::ENCODE_BASE64); $this->assertSame(Base64::encode($random_bytes), $encoder($random_bytes)); $encoder = Halite::chooseEncoder(Halite::ENCODE_BASE64URLSAFE); $this->assertSame(Base64UrlSafe::encode($random_bytes), $encoder($random_bytes)); }