universe

Universe
git clone https://git.dasho.dev/universe.git
Log | Files | Refs | Submodules | README

commit d81aff72c75e7cc7fddaa50a0d513bbbed89c440
parent 77a23918340223e133b32e48b73bc1b593772029
Author: Dasho <git@dasho.dev>
Date:   Wed, 14 May 2025 17:37:49 +0100

[crypto] ➕ Add payload maker and verifier for verify.dasho.dev

Added the  crypto/verify/payload-[maker, verifier].php  files that are used for  verify.dasho.dev  .

Diffstat:
MREADME.md | 2+-
Acrypto/verify/payload-maker.php | 1218+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acrypto/verify/payload-verifier.php | 1204+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 2423 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md @@ -9,7 +9,7 @@ This is the central repository for all my development projects, including chat a - **chat/** – Real-time chat application - **droplets/** – Microservices for various tasks - **docs/** – Documentation and guides -- **verify/** – Verification services +- **crypto/** – Crypto & Verification services - **sshchat/** – Secure chat platform - **dotfiles/** – Development environment configurations diff --git a/crypto/verify/payload-maker.php b/crypto/verify/payload-maker.php @@ -0,0 +1,1218 @@ +<?php +// Made by Dasho +// You can generate a good random salt value from the PHP CLI like this: php -r "echo bin2hex(random_bytes(16));" +// The resulting string will look like this: 7674ffcd9882e411415ea1ab7726642d + +/* +This is a copy of the script that is used to generate the payload for the verification process on verify.dasho.dev. Use this script alongside with the payload-verifier-v1.php script to make payloads that others can verify. +*/ + +define('SALT', sodium_hex2bin('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')); + +$b91_enctab = array( + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '!', '#', '$', + '%', '&', '(', ')', '*', '+', ',', '.', '/', ':', ';', '<', '=', + '>', '?', '@', '[', ']', '^', '_', '`', '{', '|', '}', '~', '"' +); + +$b91_dectab = array_flip($b91_enctab); + +function base91_decode($d) { + global $b91_dectab; + $n = $b = $o = null; + $l = strlen($d); + $v = -1; + for ($i = 0; $i < $l; ++$i) { + $c = $b91_dectab[$d[$i]]; + if(!isset($c)) + continue; + if($v < 0) + $v = $c; + else { + $v += $c * 91; + $b |= $v << $n; + $n += ($v & 8191) > 88 ? 13 : 14; + do { + $o .= chr($b & 255); + $b >>= 8; + $n -= 8; + } while ($n > 7); + $v = -1; + } + } + if($v + 1) + $o .= chr(($b | $v << $n) & 255); + return $o; +} + +function base91_encode($d) { + global $b91_enctab; + $n = $b = $o = null; + $l = strlen($d); + for ($i = 0; $i < $l; ++$i) { + $b |= ord($d[$i]) << $n; + $n += 8; + if($n > 13) { + $v = $b & 8191; + if($v > 88) { + $b >>= 13; + $n -= 13; + } else { + $v = $b & 16383; + $b >>= 14; + $n -= 14; + } + $o .= $b91_enctab[$v % 91] . $b91_enctab[$v / 91]; + } + } + if($n) { + $o .= $b91_enctab[$b % 91]; + if($n > 7 || $b > 90) + $o .= $b91_enctab[$b / 91]; + } + return $o; +} + +function saltify_encrypt($message, $key) { + $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); + $cipher = base91_encode($nonce.sodium_crypto_secretbox($message, $nonce, $key)); + sodium_memzero($message); + sodium_memzero($key); + return $cipher; +} + +function saltify_decrypt($encrypted, $key) { + $decoded = base91_decode($encrypted); + if($decoded === false) return false; + if(mb_strlen($decoded, '8bit') < (SODIUM_CRYPTO_SECRETBOX_NONCEBYTES + SODIUM_CRYPTO_SECRETBOX_MACBYTES)) return false; + $nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit'); + $ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit'); + $plain = sodium_crypto_secretbox_open($ciphertext, $nonce, $key); + if($plain === false) return false; + sodium_memzero($ciphertext); + sodium_memzero($key); + return $plain; +} + +function saltify_key($key) { + $key = sodium_crypto_pwhash(32, $key, SALT, SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE); + return $key; +} + +if(isset($_REQUEST['payload'])) { + $payload = $_REQUEST['payload']; + $key = $_REQUEST['key']; + $saltify_key = saltify_key($key); + + $pl = $payload; + + $pl = str_replace('-- BEGIN VERIFICATION PAYLOAD --', '', $pl); + $pl = str_replace('-- END VERIFICATION PAYLOAD --', '', $pl); + $pl = str_replace("\n", '', $pl); + $pl = str_replace("\r", '', $pl); + $pl = str_replace(' ', '', $pl); + + // is the resulting payload something that comes back as valid? + $dec = saltify_decrypt($pl, $saltify_key); + + $result = "\n".'<section id="results"><h2>Results</h2>'; + + if($dec === false) { + $result .= "\n".'<p><span class="detected">🎯 Payload Created</span></p>'; + $enc = saltify_encrypt($payload, $saltify_key); //generates random encrypted string (Base64 related) + $encrypted = str_split($enc, 2); + $encrypted = '-- BEGIN VERIFICATION PAYLOAD --'."\n".implode(' ', $encrypted)."\n".'-- END VERIFICATION PAYLOAD --'; + $dec = saltify_decrypt($enc, $saltify_key); //generates random encrypted string (Base64 related) + $result .= "\n".'<h3>🔐 Verification payload</h3>'; + $result .= "\n".'<pre>'.htmlentities($encrypted).'</pre>'; + $enc2 = saltify_encrypt($payload, $saltify_key); //generates random encrypted string (Base64 related) + $result .= "\n".'<h3>🔑 Compressed version</h3>'; + $result .= "\n".'<pre>'.htmlentities($enc2).'</pre><p><small><span class="chars">'.strlen($enc2).' chars</span></small></p>'; + } + else { + if(preg_match('/Expires (\d\d\ (January|February|March|April|May|June|July|August|September|October|November|December) \d\d\d\d)/i', $dec, $date)) { + $expiry_date = strtotime($date[1]); + if(strtotime("now") > $expiry_date){ + $result .= "\n".'<p><span class="detected">⛔ Payload cannot verify - Payload expired ⛔</span></p>'; + }else{ + $result .= "\n".'<p><span class="detected">✅ Payload verifies correctly ✅</span></p>'; + $result .= "\n".'<pre>'.htmlentities($dec).'</pre>'; + } + }else{ + $result .= "\n".'<p><span class="detected">✅ Payload verifies correctly ✅</span></p>'; + $result .= "\n".'<pre>'.htmlentities($dec).'</pre>'; + } + } + + $result .= "\n</section>"; + + } + else { + $payload = 'Enter verification payload here...'; + $key = 'Enter your script secret key here...'; + + $result = null; + } + +?> + +<!DOCTYPE html> +<html lang="en"> +<head> +<title>Auth Dasho</title> +<link rel="shortcut icon" href="https://cdn.onionz.dev/global/images/favicon.svg" /> +<meta property="og:title" content="Auth Dasho"> +<meta property="og:description" content="Auth Dasho"> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<style> + +/* + * + * 𝗖 𝗢 𝗟 𝗢 𝗥 + * v 1.7.0 + * + * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */ + + :root { + + /* General + * ─────────────────────────────────── */ + + --oc-white: #ffffff; + --oc-white-rgb: 255, 255, 255; + --oc-black: #000000; + --oc-black-rgb: 0, 0, 0; + + + /* Gray + * ─────────────────────────────────── */ + + --oc-gray-0: #f8f9fa; + --oc-gray-0-rgb: 248, 249, 250; + --oc-gray-1: #f1f3f5; + --oc-gray-1-rgb: 241, 243, 245; + --oc-gray-2: #e9ecef; + --oc-gray-2-rgb: 233, 236, 239; + --oc-gray-3: #dee2e6; + --oc-gray-3-rgb: 222, 226, 230; + --oc-gray-4: #ced4da; + --oc-gray-4-rgb: 206, 212, 218; + --oc-gray-5: #adb5bd; + --oc-gray-5-rgb: 173, 181, 189; + --oc-gray-6: #868e96; + --oc-gray-6-rgb: 134, 142, 150; + --oc-gray-7: #495057; + --oc-gray-7-rgb: 73, 80, 87; + --oc-gray-8: #343a40; + --oc-gray-8-rgb: 52, 58, 64; + --oc-gray-9: #212529; + --oc-gray-9-rgb: 33, 37, 41; + + + /* Red + * ─────────────────────────────────── */ + + --oc-red-0: #fff5f5; + --oc-red-0-rgb: 255, 245, 245; + --oc-red-1: #ffe3e3; + --oc-red-1-rgb: 255, 227, 227; + --oc-red-2: #ffc9c9; + --oc-red-2-rgb: 255, 201, 201; + --oc-red-3: #ffa8a8; + --oc-red-3-rgb: 255, 168, 168; + --oc-red-4: #ff8787; + --oc-red-4-rgb: 255, 135, 135; + --oc-red-5: #ff6b6b; + --oc-red-5-rgb: 255, 107, 107; + --oc-red-6: #fa5252; + --oc-red-6-rgb: 250, 82, 82; + --oc-red-7: #f03e3e; + --oc-red-7-rgb: 240, 62, 62; + --oc-red-8: #e03131; + --oc-red-8-rgb: 224, 49, 49; + --oc-red-9: #c92a2a; + --oc-red-9-rgb: 201, 42, 42; + + + /* Pink + * ─────────────────────────────────── */ + + --oc-pink-0: #fff0f6; + --oc-pink-0-rgb: 255, 240, 246; + --oc-pink-1: #ffdeeb; + --oc-pink-1-rgb: 255, 222, 235; + --oc-pink-2: #fcc2d7; + --oc-pink-2-rgb: 252, 194, 215; + --oc-pink-3: #faa2c1; + --oc-pink-3-rgb: 250, 162, 193; + --oc-pink-4: #f783ac; + --oc-pink-4-rgb: 247, 131, 172; + --oc-pink-5: #f06595; + --oc-pink-5-rgb: 240, 101, 149; + --oc-pink-6: #e64980; + --oc-pink-6-rgb: 230, 73, 128; + --oc-pink-7: #d6336c; + --oc-pink-7-rgb: 214, 51, 108; + --oc-pink-8: #c2255c; + --oc-pink-8-rgb: 194, 37, 92; + --oc-pink-9: #a61e4d; + --oc-pink-9-rgb: 166, 30, 77; + + + /* Grape + * ─────────────────────────────────── */ + + --oc-grape-0: #f8f0fc; + --oc-grape-0-rgb: 248, 240, 252; + --oc-grape-1: #f3d9fa; + --oc-grape-1-rgb: 243, 217, 250; + --oc-grape-2: #eebefa; + --oc-grape-2-rgb: 238, 190, 250; + --oc-grape-3: #e599f7; + --oc-grape-3-rgb: 229, 153, 247; + --oc-grape-4: #da77f2; + --oc-grape-4-rgb: 218, 119, 242; + --oc-grape-5: #cc5de8; + --oc-grape-5-rgb: 204, 93, 232; + --oc-grape-6: #be4bdb; + --oc-grape-6-rgb: 190, 75, 219; + --oc-grape-7: #ae3ec9; + --oc-grape-7-rgb: 174, 62, 201; + --oc-grape-8: #9c36b5; + --oc-grape-8-rgb: 156, 54, 181; + --oc-grape-9: #862e9c; + --oc-grape-9-rgb: 134, 46, 156; + + + /* Violet + * ─────────────────────────────────── */ + + --oc-violet-0: #f3f0ff; + --oc-violet-0-rgb: 243, 240, 255; + --oc-violet-1: #e5dbff; + --oc-violet-1-rgb: 229, 219, 255; + --oc-violet-2: #d0bfff; + --oc-violet-2-rgb: 208, 191, 255; + --oc-violet-3: #b197fc; + --oc-violet-3-rgb: 177, 151, 252; + --oc-violet-4: #9775fa; + --oc-violet-4-rgb: 151, 117, 250; + --oc-violet-5: #845ef7; + --oc-violet-5-rgb: 132, 94, 247; + --oc-violet-6: #7950f2; + --oc-violet-6-rgb: 121, 80, 242; + --oc-violet-7: #7048e8; + --oc-violet-7-rgb: 112, 72, 232; + --oc-violet-8: #6741d9; + --oc-violet-8-rgb: 103, 65, 217; + --oc-violet-9: #5f3dc4; + --oc-violet-9-rgb: 95, 61, 196; + + + /* Indigo + * ─────────────────────────────────── */ + + --oc-indigo-0: #edf2ff; + --oc-indigo-0-rgb: 237, 242, 255; + --oc-indigo-1: #dbe4ff; + --oc-indigo-1-rgb: 219, 228, 255; + --oc-indigo-2: #bac8ff; + --oc-indigo-2-rgb: 186, 200, 255; + --oc-indigo-3: #91a7ff; + --oc-indigo-3-rgb: 145, 167, 255; + --oc-indigo-4: #748ffc; + --oc-indigo-4-rgb: 116, 143, 252; + --oc-indigo-5: #5c7cfa; + --oc-indigo-5-rgb: 92, 124, 250; + --oc-indigo-6: #4c6ef5; + --oc-indigo-6-rgb: 76, 110, 245; + --oc-indigo-7: #4263eb; + --oc-indigo-7-rgb: 66, 99, 235; + --oc-indigo-8: #3b5bdb; + --oc-indigo-8-rgb: 59, 91, 219; + --oc-indigo-9: #364fc7; + --oc-indigo-9-rgb: 54, 79, 199; + + + /* Blue + * ─────────────────────────────────── */ + + --oc-blue-0: #e7f5ff; + --oc-blue-0-rgb: 231, 245, 255; + --oc-blue-1: #d0ebff; + --oc-blue-1-rgb: 208, 235, 255; + --oc-blue-2: #a5d8ff; + --oc-blue-2-rgb: 165, 216, 255; + --oc-blue-3: #74c0fc; + --oc-blue-3-rgb: 116, 192, 252; + --oc-blue-4: #4dabf7; + --oc-blue-4-rgb: 77, 171, 247; + --oc-blue-5: #339af0; + --oc-blue-5-rgb: 51, 154, 240; + --oc-blue-6: #228be6; + --oc-blue-6-rgb: 34, 139, 230; + --oc-blue-7: #1c7ed6; + --oc-blue-7-rgb: 28, 126, 214; + --oc-blue-8: #1971c2; + --oc-blue-8-rgb: 25, 113, 194; + --oc-blue-9: #1864ab; + --oc-blue-9-rgb: 24, 100, 171; + + + /* Cyan + * ─────────────────────────────────── */ + + --oc-cyan-0: #e3fafc; + --oc-cyan-0-rgb: 227, 250, 252; + --oc-cyan-1: #c5f6fa; + --oc-cyan-1-rgb: 197, 246, 250; + --oc-cyan-2: #99e9f2; + --oc-cyan-2-rgb: 153, 233, 242; + --oc-cyan-3: #66d9e8; + --oc-cyan-3-rgb: 102, 217, 232; + --oc-cyan-4: #3bc9db; + --oc-cyan-4-rgb: 59, 201, 219; + --oc-cyan-5: #22b8cf; + --oc-cyan-5-rgb: 34, 184, 207; + --oc-cyan-6: #15aabf; + --oc-cyan-6-rgb: 21, 170, 191; + --oc-cyan-7: #1098ad; + --oc-cyan-7-rgb: 16, 152, 173; + --oc-cyan-8: #0c8599; + --oc-cyan-8-rgb: 12, 133, 153; + --oc-cyan-9: #0b7285; + --oc-cyan-9-rgb: 11, 114, 133; + + + /* Teal + * ─────────────────────────────────── */ + + --oc-teal-0: #e6fcf5; + --oc-teal-0-rgb: 230, 252, 245; + --oc-teal-1: #c3fae8; + --oc-teal-1-rgb: 195, 250, 232; + --oc-teal-2: #96f2d7; + --oc-teal-2-rgb: 150, 242, 215; + --oc-teal-3: #63e6be; + --oc-teal-3-rgb: 99, 230, 190; + --oc-teal-4: #38d9a9; + --oc-teal-4-rgb: 56, 217, 169; + --oc-teal-5: #20c997; + --oc-teal-5-rgb: 32, 201, 151; + --oc-teal-6: #12b886; + --oc-teal-6-rgb: 18, 184, 134; + --oc-teal-7: #0ca678; + --oc-teal-7-rgb: 12, 166, 120; + --oc-teal-8: #099268; + --oc-teal-8-rgb: 9, 146, 104; + --oc-teal-9: #087f5b; + --oc-teal-9-rgb: 8, 127, 91; + + + /* Green + * ─────────────────────────────────── */ + + --oc-green-0: #ebfbee; + --oc-green-0-rgb: 235, 251, 238; + --oc-green-1: #d3f9d8; + --oc-green-1-rgb: 211, 249, 216; + --oc-green-2: #b2f2bb; + --oc-green-2-rgb: 178, 242, 187; + --oc-green-3: #8ce99a; + --oc-green-3-rgb: 140, 233, 154; + --oc-green-4: #69db7c; + --oc-green-4-rgb: 105, 219, 124; + --oc-green-5: #51cf66; + --oc-green-5-rgb: 81, 207, 102; + --oc-green-6: #40c057; + --oc-green-6-rgb: 64, 192, 87; + --oc-green-7: #37b24d; + --oc-green-7-rgb: 55, 178, 77; + --oc-green-8: #2f9e44; + --oc-green-8-rgb: 47, 158, 68; + --oc-green-9: #2b8a3e; + --oc-green-9-rgb: 43, 138, 62; + + + /* Lime + * ─────────────────────────────────── */ + + --oc-lime-0: #f4fce3; + --oc-lime-0-rgb: 244, 252, 227; + --oc-lime-1: #e9fac8; + --oc-lime-1-rgb: 233, 250, 200; + --oc-lime-2: #d8f5a2; + --oc-lime-2-rgb: 216, 245, 162; + --oc-lime-3: #c0eb75; + --oc-lime-3-rgb: 192, 235, 117; + --oc-lime-4: #a9e34b; + --oc-lime-4-rgb: 169, 227, 75; + --oc-lime-5: #94d82d; + --oc-lime-5-rgb: 148, 216, 45; + --oc-lime-6: #82c91e; + --oc-lime-6-rgb: 130, 201, 30; + --oc-lime-7: #74b816; + --oc-lime-7-rgb: 116, 184, 22; + --oc-lime-8: #66a80f; + --oc-lime-8-rgb: 102, 168, 15; + --oc-lime-9: #5c940d; + --oc-lime-9-rgb: 92, 148, 13; + + + /* Yellow + * ─────────────────────────────────── */ + + --oc-yellow-0: #fff9db; + --oc-yellow-0-rgb: 255, 249, 219; + --oc-yellow-1: #fff3bf; + --oc-yellow-1-rgb: 255, 243, 191; + --oc-yellow-2: #ffec99; + --oc-yellow-2-rgb: 255, 236, 153; + --oc-yellow-3: #ffe066; + --oc-yellow-3-rgb: 255, 224, 102; + --oc-yellow-4: #ffd43b; + --oc-yellow-4-rgb: 255, 212, 59; + --oc-yellow-5: #fcc419; + --oc-yellow-5-rgb: 252, 196, 25; + --oc-yellow-6: #fab005; + --oc-yellow-6-rgb: 250, 176, 5; + --oc-yellow-7: #f59f00; + --oc-yellow-7-rgb: 245, 159, 0; + --oc-yellow-8: #f08c00; + --oc-yellow-8-rgb: 240, 140, 0; + --oc-yellow-9: #e67700; + --oc-yellow-9-rgb: 230, 119, 0; + + + /* Orange + * ─────────────────────────────────── */ + + --oc-orange-0: #fff4e6; + --oc-orange-0-rgb: 255, 244, 230; + --oc-orange-1: #ffe8cc; + --oc-orange-1-rgb: 255, 232, 204; + --oc-orange-2: #ffd8a8; + --oc-orange-2-rgb: 255, 216, 168; + --oc-orange-3: #ffc078; + --oc-orange-3-rgb: 255, 192, 120; + --oc-orange-4: #ffa94d; + --oc-orange-4-rgb: 255, 169, 77; + --oc-orange-5: #ff922b; + --oc-orange-5-rgb: 255, 146, 43; + --oc-orange-6: #fd7e14; + --oc-orange-6-rgb: 253, 126, 20; + --oc-orange-7: #f76707; + --oc-orange-7-rgb: 247, 103, 7; + --oc-orange-8: #e8590c; + --oc-orange-8-rgb: 232, 89, 12; + --oc-orange-9: #d9480f; + --oc-orange-9-rgb: 217, 72, 15; + + } + +/* Colors */ + +:root { + --background: var(--oc-gray-9); + --background-secondary: var(--oc-gray-8); + --background-tertiary: var(--oc-gray-7); + --foreground: var(--oc-white); + --foreground-heavy: var(--oc-white); +} + +*, *::before, *::after { + box-sizing: border-box; +} + +a:link, a:visited, a:hover, a:active { + color: inherit !important; +} + +html { + font-family: 'Inter', sans-serif; + font-feature-settings: "calt" 1; + font-size: 1.2em; + background: var(--background); + color: var(--foreground); + height: 100%; +} + +* { + transition: background .1s; +} + +body { + margin: 0; + padding: 0; +} + +@supports (font-variation-settings: normal) { + html { + font-family: 'Inter var', sans-serif; + } +} + +/* Type */ + +.centered { + text-align: center; +} + +/* Flexbox */ + +.flex { + display: flex; + flex-wrap: wrap; +} + +.box { + flex-grow: 1; + flex-basis: 15em; + margin: 0 .5em .5em 0; +} + +.fit { + flex-basis: 1em; +} + +.half { flex-basis: calc(50% - (.5em * 2)); } +.third { flex-basis: calc(33% - (.5em * 3)); } +.fourth { flex-basis: calc(25% - (.5em * 4)); } +.fifth { flex-basis: calc(20% - (.5em * 5)); } + +.clickable:hover { + cursor: pointer; +} + +main, header, footer { + display: block; + margin: auto; + padding: 0 2em; + max-width: 50em; +} + +header nav { + margin: 1em 0 5em 0; + padding: 0; + background: var(--background); + font-size: 80%; +} + +header nav .fa-long-arrow-alt-right { + padding: 0 .7em 0 .1em; + color: var(--foreground); +} + +header, footer { + padding-top: 2em; +} + +footer { + text-align: center; + padding-bottom: 3em; +} + +footer small { + font-size: .8em; +} + +footer small a { + text-decoration: none; +} + +footer li a:link, footer li a:visited { + color: #333; +} + +footer li a:hover, footer li a:active { + color: #555; +} + +footer .fab { + font-size: 1.6em; +} + +footer .site { + font-size: 80%; + margin: 1.5em 0 !important; +} + +footer .site li { + padding-right: .5em; +} + +footer .site li a { + text-decoration: none; +} + +footer img { + width: 4em; + margin: 2em 0 1em 0; +} + +/* Headings */ + +h1, h2, h3, h4, h5, h6 { + margin: 2rem 0; + font-weight: 500; + color: var(--foreground-heavy); +} + +h1 { + font-weight: 700; +} + +section h2 { + margin: 1rem 0 2rem 0; +} + +p, ul, li, div { + line-height: 160%; +} + +ul.horizontal { + list-style-type: none; + margin: 0; + padding: 0; +} + +ul.horizontal li { + display: inline; +} + +.bulletless { + list-style-type: none; + margin: 0; + padding: 0; +} + +hr { + border: 0; + height: 1px; + background: var(--foreground); + margin: 2em 0; +} + +/* Sections */ + +section { + border-left: .5em solid var(--background); + padding-left: 1em; + padding-top: .5em; + padding-bottom: .5em; + margin-left: -1.5em; +} + +/* Blockquotes & Code */ + +.code, pre, code, .monospace { + font-family: 'Fira Code'; +} + +pre { + white-space: pre-wrap; + word-break: break-word; +} + +/* Messages */ + +.message { + display: flex; + color: var(--foreground); + margin: 1.5em 0; + width: 100%; + align-items: stretch; + align-content: stretch; +} + +.message-icon { + background: var(--background-tertiary); + align-self: stretch; + padding: .5em; + border-top-left-radius: .2em; + border-bottom-left-radius: .2em; +} + +.message-icon i { + font-size: 1.5em; + margin: .5em; +} + +.message-text { + flex-basis: 100%; + margin: 0; + padding: 1.25em; + overflow: hidden; + background: var(--background-secondary); + align-self: stretch; + border-top-right-radius: .2em; + border-bottom-right-radius: .2em; +} + +.confirmation .message-icon { background: var(--oc-green-5); color: var(--oc-black); } +.confirmation .message-text { background: var(--oc-green-3); color: var(--oc-black); } + +.notice .message-icon { background: var(--oc-yellow-5); color: var(--oc-black); } +.notice .message-text { background: var(--oc-yellow-3); color: var(--oc-black); } + +.warning .message-icon { background: var(--oc-orange-5); color: var(--oc-black); } +.warning .message-text { background: var(--oc-orange-3); color: var(--oc-black); } + +.alert .message-icon { background: var(--oc-red-5); color: var(--oc-black); } +.alert .message-text { background: var(--oc-red-3); color: var(--oc-black); } + +/* Nav */ + +nav { + width: 100%; + padding: .5em 1em; + border-radius: 0.2em; + margin: 2em 0; + background: var(--background-secondary); +} + +nav a:link, nav a:visited { + text-decoration: none; +} + +nav a:hover, nav a:active { + text-decoration: none; +} + +nav li { + margin-right: .5em; +} + +.smaller { + font-size: 90%; +} + +.even-smaller { + font-size: 80%; +} + +.larger { + font-size: 120%; +} + +.even-larger { + font-size: 130%; +} + +.border-solid { + border: 1px solid #888; + border-radius: .2em; +} + +.border-dashed { + border: 1px dashed #888; + border-radius: .2em; +} + +.border-dotted { + border: 1px dotted #888; + border-radius: .2em; +} + +/* Forms */ + +.required:before { + content: "REQUIRED"; + font-size: 60%; + /*background: #e75757;*/ + color: #fff; + padding: .25em .5em; + border-radius: .25em; + margin: 0 0 0 .5em; +} + +.form_note { + padding: .5em 1em; + margin-top: 2em; + border-radius: .2em; +} + +fieldset { + margin: 1.5em 0; + padding: 1em; + border: 0; + background: var(--background-secondary); + color: var(--foreground); + border-radius: .2em; +} + +legend { + padding: .7em 1em 2.5em .85em; + margin: 0 0 -2.5em -.85em; + font-weight: 700; + font-size: 120%; + background: var(--background-secondary); + color: var(--foereground); + border-radius: .2em; +} + +input, button, select, option, textarea { + font-family: inherit; + font-size: inherit; + background: var(--background); + color: var(--foreground); + padding: .5em; + border-radius: .2em; +} + +button, select, option { + cursor: pointer; +} + +input, select, option, textarea { + border: 1px solid #999; +} + +textarea { + width: 100%; +} + +select { + -webkit-appearance: none; +} + +label { + cursor: pointer; + display: block; + margin: 1em 0 .5em 0; + font-weight: normal; +} + +.label { + cursor: pointer; + margin: .4em 0 .4em 0;; +} + +.radio label, +.checkbox label { + display: inline; + margin: 0; +} + +.group { + margin-bottom: 1em; +} + +button, .button, input[type="submit"] { + border: 0; + padding: .5em 1em; + cursor: pointer; + border-radius: .2em; + background: var(--oc-blue-7); + color: var(--oc-white); +} + +input[type="text"], input[type="password"], select { + width: 95%; + margin-bottom: .5em; +} + +button:hover, +button:focus { + opacity: .85; +} + +button:active { + transform: scale(0.97); + transition: transform 0.1s ease-in-out; +} + +form { + width: 100%; +} + +.form-reset { + margin: 0; +} + +form aside { + margin: .2em 0 2em 0; + font-size: 80%; +} + +aside { + float: right; +} + +aside nav { + margin: 0 0 1em 1em; + padding: .3em .2em; +} + +.heading-aligned { + margin-top: -4em; +} + +/* Toggle Switch */ + +.switch { + --line: #ccc; + --dot: var(--oc-violet-4); + --circle: var(--oc-yellow-3); + --background: #aaa; + --duration: .3s; + --text: #000; + --shadow: 0 1px 3px rgba(0, 9, 61, 0.08); + cursor: pointer; + position: relative; +} +.switch:before { + content: ''; + width: 60px; + height: 32px; + border-radius: 16px; + background: var(--background); + position: absolute; + left: 0; + top: 0; + box-shadow: var(--shadow); +} +.switch input { + display: none; +} +.switch input + div { + position: relative; +} +.switch input + div:before, .switch input + div:after { + --s: 1; + content: ''; + position: absolute; + height: 4px; + top: 14px; + width: 24px; + background: var(--line); + -webkit-transform: scaleX(var(--s)); + transform: scaleX(var(--s)); + -webkit-transition: -webkit-transform var(--duration) ease; + transition: -webkit-transform var(--duration) ease; + transition: transform var(--duration) ease; + transition: transform var(--duration) ease, -webkit-transform var(--duration) ease; +} +.switch input + div:before { + --s: 0; + left: 4px; + -webkit-transform-origin: 0 50%; + transform-origin: 0 50%; + border-radius: 2px 0 0 2px; +} +.switch input + div:after { + left: 32px; + -webkit-transform-origin: 100% 50%; + transform-origin: 100% 50%; + border-radius: 0 2px 2px 0; +} +.switch input + div span { + padding-left: 60px; + line-height: 28px; + color: var(--text); +} +.switch input + div span:before { + --x: 0; + --b: var(--circle); + --s: 15px; + content: ''; + position: absolute; + left: 4px; + top: 4px; + width: 24px; + height: 24px; + border-radius: 50%; + box-shadow: inset 0 0 0 var(--s) var(--b); + -webkit-transform: translateX(var(--x)); + transform: translateX(var(--x)); + -webkit-transition: box-shadow var(--duration) ease, -webkit-transform var(--duration) ease; + transition: box-shadow var(--duration) ease, -webkit-transform var(--duration) ease; + transition: box-shadow var(--duration) ease, transform var(--duration) ease; + transition: box-shadow var(--duration) ease, transform var(--duration) ease, -webkit-transform var(--duration) ease; +} +.switch input + div span:not(:empty) { + padding-left: 68px; +} +.switch input:checked + div:before { + --s: 1; +} +.switch input:checked + div:after { + --s: 0; +} +.switch input:checked + div span:before { + --x: 28px; + --s: 12px; + --b: var(--dot); +} + +body .switch + .switch { + margin-top: 32px; +} + +/* Checkboxes */ + +input[type=checkbox] { display: none; } +input[type=checkbox] + label:before { + font-family: 'Font Awesome 6 Pro'; + display: inline-block; + width: 1.3em; +} +input[type=checkbox] + label:before { content: "\f0c8"; } +input[type=checkbox]:checked + label:before { content: "\f14a"; } + +/* Radio Buttons */ + +input[type=radio] { display: none; } +input[type=radio] + label:before { + font-family: 'Font Awesome 6 Pro'; + display: inline-block; + width: 1.3em; +} +input[type=radio] + label:before { content: "\f111"; } +input[type=radio]:checked + label:before { content: "\f192"; } + +/* Tables */ + +.table-container { + overflow-x: auto; +} + +table { + border-collapse: collapse; + width: 100%; +} + +th, td { + background: var(--background); + padding: .5em; +} + +th { + border-bottom: 1px solid var(--foreground); + background: var(--background-secondary); +} + +tr:nth-child(even) td { + background: var(--background-secondary); +} + +th:first-child { border-top-left-radius: 0.2em; } +th:last-child { border-top-right-radius: 0.2em; } +tr:last-child td:first-child { border-bottom-left-radius: 0.2em; } +tr:last-child td:last-child { border-bottom-right-radius: 0.2em; } + +::selection { + color: var(--background); + background: var(--foreground); +} + +@media (max-width: 900px) { + html { + font-size: 1.05em; + } + main, header, footer { + padding: 0 1.5em; + } + header { + padding-top: 2em; + } + header nav { + margin: .5 0 3em 0; + } + footer { + padding-top: 2em; + padding-bottom: 3em; + } +} + +@media (max-width: 500px) { + html { + font-size: 1em; + } + main, header, footer { + padding: 0 1em; + } + header { + padding-top: 2em; + } + header nav { + margin: 0 0 2em 0; + } + footer { + padding-top: 2em; + padding-bottom: 3em; + } +} + +body { + font-family: sans-serif; +} +main { + margin: auto; + max-width: 50em; + line-height: 1.5em; +} +input, textarea { + display: block; + width: 100%; +} +pre { + font-family: Courier, monospace; + font-size: 14px; + white-space: pre-wrap; + white-space: -moz-pre-wrap; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; +} +</style> +</head> +<body> + +<header> + +<h1>Auth Dasho</h1> +</header> + +<main> + +<form action="#results" method="post"> + <fieldset> + <legend>Authenticate</legend> + <p>Create an authenticated payload below.</p> + <p> + <label for="payload">Payload</label> + <textarea name="payload" id="payload"><?php echo $payload; ?></textarea> + </p> + <p> + <label for="key">Key</label> + <textarea name="key" id="key"><?php echo $key; ?></textarea> + </p> + <input type="submit" value="Go"> + </fieldset> +</form> + + +<?php + +echo $result; + +?> + +</main> + +<footer> + +<ul class="horizontal site"> + <li>&copy; Dasho</li> +</ul> + +</footer> + +</body> +</html> diff --git a/crypto/verify/payload-verifier.php b/crypto/verify/payload-verifier.php @@ -0,0 +1,1204 @@ +<?php +// Made by Dasho +// You can generate a good random salt value from the PHP CLI like this: php -r "echo bin2hex(random_bytes(16));" +// The resulting string will look like this: 7674ffcd9882e411415ea1ab7726642d + +/* +This is a copy of the script that is used on verify.dasho.dev. It is provided here for reference purposes only. You can use it too, by creating and setting your own salt value in the SALT constant below, and by setting the $key variable to the key you want to use on line 108. +*/ + +define('SALT', sodium_hex2bin('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX')); + +$b91_enctab = array( + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '!', '#', '$', + '%', '&', '(', ')', '*', '+', ',', '.', '/', ':', ';', '<', '=', + '>', '?', '@', '[', ']', '^', '_', '`', '{', '|', '}', '~', '"' +); + +$b91_dectab = array_flip($b91_enctab); + +function base91_decode($d) { + global $b91_dectab; + $n = $b = $o = null; + $l = strlen($d); + $v = -1; + for ($i = 0; $i < $l; ++$i) { + $c = $b91_dectab[$d[$i]]; + if(!isset($c)) + continue; + if($v < 0) + $v = $c; + else { + $v += $c * 91; + $b |= $v << $n; + $n += ($v & 8191) > 88 ? 13 : 14; + do { + $o .= chr($b & 255); + $b >>= 8; + $n -= 8; + } while ($n > 7); + $v = -1; + } + } + if($v + 1) + $o .= chr(($b | $v << $n) & 255); + return $o; +} + +function base91_encode($d) { + global $b91_enctab; + $n = $b = $o = null; + $l = strlen($d); + for ($i = 0; $i < $l; ++$i) { + $b |= ord($d[$i]) << $n; + $n += 8; + if($n > 13) { + $v = $b & 8191; + if($v > 88) { + $b >>= 13; + $n -= 13; + } else { + $v = $b & 16383; + $b >>= 14; + $n -= 14; + } + $o .= $b91_enctab[$v % 91] . $b91_enctab[$v / 91]; + } + } + if($n) { + $o .= $b91_enctab[$b % 91]; + if($n > 7 || $b > 90) + $o .= $b91_enctab[$b / 91]; + } + return $o; +} + +function saltify_encrypt($message, $key) { + $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); + $cipher = base91_encode($nonce.sodium_crypto_secretbox($message, $nonce, $key)); + sodium_memzero($message); + sodium_memzero($key); + return $cipher; +} + +function saltify_decrypt($encrypted, $key) { + $decoded = base91_decode($encrypted); + if($decoded === false) return false; + if(mb_strlen($decoded, '8bit') < (SODIUM_CRYPTO_SECRETBOX_NONCEBYTES + SODIUM_CRYPTO_SECRETBOX_MACBYTES)) return false; + $nonce = mb_substr($decoded, 0, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, '8bit'); + $ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, null, '8bit'); + $plain = sodium_crypto_secretbox_open($ciphertext, $nonce, $key); + if($plain === false) return false; + sodium_memzero($ciphertext); + sodium_memzero($key); + return $plain; +} + +function saltify_key($key) { + $key = sodium_crypto_pwhash(32, $key, SALT, SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE); + return $key; +} + +if(isset($_REQUEST['payload'])) { + $payload = $_REQUEST['payload']; + $key = '/* YOUR KEY HERE */'; + $saltify_key = saltify_key($key); + + $pl = $payload; + + $pl = str_replace('-- BEGIN VERIFICATION PAYLOAD --', '', $pl); + $pl = str_replace('-- END VERIFICATION PAYLOAD --', '', $pl); + $pl = str_replace("\n", '', $pl); + $pl = str_replace("\r", '', $pl); + $pl = str_replace(' ', '', $pl); + + // is the resulting payload something that comes back as valid? + $dec = saltify_decrypt($pl, $saltify_key); + + $result = "\n".'<section id="results"><h2>Results</h2>'; + + if($dec === false) { + $result .= "\n".'<p><span class="detected">⛔ Unverified ⛔</span></p>'; + } + else { + if(preg_match('/Expires (\d\d\ (January|February|March|April|May|June|July|August|September|October|November|December) \d\d\d\d)/i', $dec, $date)) { + $expiry_date = strtotime($date[1]); + if(strtotime("now") > $expiry_date){ + $result .= "\n".'<p><span class="detected">⛔ Expired ⛔</span></p>'; + }else{ + $result .= "\n".'<p><span class="detected">✅ Verified ✅</span></p>'; + $result .= "\n".'<pre>'.htmlentities($dec).'</pre>'; + } + }else{ + $result .= "\n".'<p><span class="detected">✅ Verified ✅</span></p>'; + $result .= "\n".'<pre>'.htmlentities($dec).'</pre>'; + } + } + + $result .= "\n</section>"; + +} +else { + $payload = ''; + $result = null; +} +?> + +<!DOCTYPE html> +<html lang="en"> +<head> +<title>Verify Dasho</title> +<link rel="shortcut icon" href="https://cdn.onionz.dev/global/images/favicon.svg" /> +<meta property="og:title" content="Verify Dasho"> +<meta property="og:description" content="Verify Dasho"> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<style> + +/* + * + * 𝗖 𝗢 𝗟 𝗢 𝗥 + * v 1.7.0 + * + * ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */ + + :root { + + /* General + * ─────────────────────────────────── */ + + --oc-white: #ffffff; + --oc-white-rgb: 255, 255, 255; + --oc-black: #000000; + --oc-black-rgb: 0, 0, 0; + + + /* Gray + * ─────────────────────────────────── */ + + --oc-gray-0: #f8f9fa; + --oc-gray-0-rgb: 248, 249, 250; + --oc-gray-1: #f1f3f5; + --oc-gray-1-rgb: 241, 243, 245; + --oc-gray-2: #e9ecef; + --oc-gray-2-rgb: 233, 236, 239; + --oc-gray-3: #dee2e6; + --oc-gray-3-rgb: 222, 226, 230; + --oc-gray-4: #ced4da; + --oc-gray-4-rgb: 206, 212, 218; + --oc-gray-5: #adb5bd; + --oc-gray-5-rgb: 173, 181, 189; + --oc-gray-6: #868e96; + --oc-gray-6-rgb: 134, 142, 150; + --oc-gray-7: #495057; + --oc-gray-7-rgb: 73, 80, 87; + --oc-gray-8: #343a40; + --oc-gray-8-rgb: 52, 58, 64; + --oc-gray-9: #212529; + --oc-gray-9-rgb: 33, 37, 41; + + + /* Red + * ─────────────────────────────────── */ + + --oc-red-0: #fff5f5; + --oc-red-0-rgb: 255, 245, 245; + --oc-red-1: #ffe3e3; + --oc-red-1-rgb: 255, 227, 227; + --oc-red-2: #ffc9c9; + --oc-red-2-rgb: 255, 201, 201; + --oc-red-3: #ffa8a8; + --oc-red-3-rgb: 255, 168, 168; + --oc-red-4: #ff8787; + --oc-red-4-rgb: 255, 135, 135; + --oc-red-5: #ff6b6b; + --oc-red-5-rgb: 255, 107, 107; + --oc-red-6: #fa5252; + --oc-red-6-rgb: 250, 82, 82; + --oc-red-7: #f03e3e; + --oc-red-7-rgb: 240, 62, 62; + --oc-red-8: #e03131; + --oc-red-8-rgb: 224, 49, 49; + --oc-red-9: #c92a2a; + --oc-red-9-rgb: 201, 42, 42; + + + /* Pink + * ─────────────────────────────────── */ + + --oc-pink-0: #fff0f6; + --oc-pink-0-rgb: 255, 240, 246; + --oc-pink-1: #ffdeeb; + --oc-pink-1-rgb: 255, 222, 235; + --oc-pink-2: #fcc2d7; + --oc-pink-2-rgb: 252, 194, 215; + --oc-pink-3: #faa2c1; + --oc-pink-3-rgb: 250, 162, 193; + --oc-pink-4: #f783ac; + --oc-pink-4-rgb: 247, 131, 172; + --oc-pink-5: #f06595; + --oc-pink-5-rgb: 240, 101, 149; + --oc-pink-6: #e64980; + --oc-pink-6-rgb: 230, 73, 128; + --oc-pink-7: #d6336c; + --oc-pink-7-rgb: 214, 51, 108; + --oc-pink-8: #c2255c; + --oc-pink-8-rgb: 194, 37, 92; + --oc-pink-9: #a61e4d; + --oc-pink-9-rgb: 166, 30, 77; + + + /* Grape + * ─────────────────────────────────── */ + + --oc-grape-0: #f8f0fc; + --oc-grape-0-rgb: 248, 240, 252; + --oc-grape-1: #f3d9fa; + --oc-grape-1-rgb: 243, 217, 250; + --oc-grape-2: #eebefa; + --oc-grape-2-rgb: 238, 190, 250; + --oc-grape-3: #e599f7; + --oc-grape-3-rgb: 229, 153, 247; + --oc-grape-4: #da77f2; + --oc-grape-4-rgb: 218, 119, 242; + --oc-grape-5: #cc5de8; + --oc-grape-5-rgb: 204, 93, 232; + --oc-grape-6: #be4bdb; + --oc-grape-6-rgb: 190, 75, 219; + --oc-grape-7: #ae3ec9; + --oc-grape-7-rgb: 174, 62, 201; + --oc-grape-8: #9c36b5; + --oc-grape-8-rgb: 156, 54, 181; + --oc-grape-9: #862e9c; + --oc-grape-9-rgb: 134, 46, 156; + + + /* Violet + * ─────────────────────────────────── */ + + --oc-violet-0: #f3f0ff; + --oc-violet-0-rgb: 243, 240, 255; + --oc-violet-1: #e5dbff; + --oc-violet-1-rgb: 229, 219, 255; + --oc-violet-2: #d0bfff; + --oc-violet-2-rgb: 208, 191, 255; + --oc-violet-3: #b197fc; + --oc-violet-3-rgb: 177, 151, 252; + --oc-violet-4: #9775fa; + --oc-violet-4-rgb: 151, 117, 250; + --oc-violet-5: #845ef7; + --oc-violet-5-rgb: 132, 94, 247; + --oc-violet-6: #7950f2; + --oc-violet-6-rgb: 121, 80, 242; + --oc-violet-7: #7048e8; + --oc-violet-7-rgb: 112, 72, 232; + --oc-violet-8: #6741d9; + --oc-violet-8-rgb: 103, 65, 217; + --oc-violet-9: #5f3dc4; + --oc-violet-9-rgb: 95, 61, 196; + + + /* Indigo + * ─────────────────────────────────── */ + + --oc-indigo-0: #edf2ff; + --oc-indigo-0-rgb: 237, 242, 255; + --oc-indigo-1: #dbe4ff; + --oc-indigo-1-rgb: 219, 228, 255; + --oc-indigo-2: #bac8ff; + --oc-indigo-2-rgb: 186, 200, 255; + --oc-indigo-3: #91a7ff; + --oc-indigo-3-rgb: 145, 167, 255; + --oc-indigo-4: #748ffc; + --oc-indigo-4-rgb: 116, 143, 252; + --oc-indigo-5: #5c7cfa; + --oc-indigo-5-rgb: 92, 124, 250; + --oc-indigo-6: #4c6ef5; + --oc-indigo-6-rgb: 76, 110, 245; + --oc-indigo-7: #4263eb; + --oc-indigo-7-rgb: 66, 99, 235; + --oc-indigo-8: #3b5bdb; + --oc-indigo-8-rgb: 59, 91, 219; + --oc-indigo-9: #364fc7; + --oc-indigo-9-rgb: 54, 79, 199; + + + /* Blue + * ─────────────────────────────────── */ + + --oc-blue-0: #e7f5ff; + --oc-blue-0-rgb: 231, 245, 255; + --oc-blue-1: #d0ebff; + --oc-blue-1-rgb: 208, 235, 255; + --oc-blue-2: #a5d8ff; + --oc-blue-2-rgb: 165, 216, 255; + --oc-blue-3: #74c0fc; + --oc-blue-3-rgb: 116, 192, 252; + --oc-blue-4: #4dabf7; + --oc-blue-4-rgb: 77, 171, 247; + --oc-blue-5: #339af0; + --oc-blue-5-rgb: 51, 154, 240; + --oc-blue-6: #228be6; + --oc-blue-6-rgb: 34, 139, 230; + --oc-blue-7: #1c7ed6; + --oc-blue-7-rgb: 28, 126, 214; + --oc-blue-8: #1971c2; + --oc-blue-8-rgb: 25, 113, 194; + --oc-blue-9: #1864ab; + --oc-blue-9-rgb: 24, 100, 171; + + + /* Cyan + * ─────────────────────────────────── */ + + --oc-cyan-0: #e3fafc; + --oc-cyan-0-rgb: 227, 250, 252; + --oc-cyan-1: #c5f6fa; + --oc-cyan-1-rgb: 197, 246, 250; + --oc-cyan-2: #99e9f2; + --oc-cyan-2-rgb: 153, 233, 242; + --oc-cyan-3: #66d9e8; + --oc-cyan-3-rgb: 102, 217, 232; + --oc-cyan-4: #3bc9db; + --oc-cyan-4-rgb: 59, 201, 219; + --oc-cyan-5: #22b8cf; + --oc-cyan-5-rgb: 34, 184, 207; + --oc-cyan-6: #15aabf; + --oc-cyan-6-rgb: 21, 170, 191; + --oc-cyan-7: #1098ad; + --oc-cyan-7-rgb: 16, 152, 173; + --oc-cyan-8: #0c8599; + --oc-cyan-8-rgb: 12, 133, 153; + --oc-cyan-9: #0b7285; + --oc-cyan-9-rgb: 11, 114, 133; + + + /* Teal + * ─────────────────────────────────── */ + + --oc-teal-0: #e6fcf5; + --oc-teal-0-rgb: 230, 252, 245; + --oc-teal-1: #c3fae8; + --oc-teal-1-rgb: 195, 250, 232; + --oc-teal-2: #96f2d7; + --oc-teal-2-rgb: 150, 242, 215; + --oc-teal-3: #63e6be; + --oc-teal-3-rgb: 99, 230, 190; + --oc-teal-4: #38d9a9; + --oc-teal-4-rgb: 56, 217, 169; + --oc-teal-5: #20c997; + --oc-teal-5-rgb: 32, 201, 151; + --oc-teal-6: #12b886; + --oc-teal-6-rgb: 18, 184, 134; + --oc-teal-7: #0ca678; + --oc-teal-7-rgb: 12, 166, 120; + --oc-teal-8: #099268; + --oc-teal-8-rgb: 9, 146, 104; + --oc-teal-9: #087f5b; + --oc-teal-9-rgb: 8, 127, 91; + + + /* Green + * ─────────────────────────────────── */ + + --oc-green-0: #ebfbee; + --oc-green-0-rgb: 235, 251, 238; + --oc-green-1: #d3f9d8; + --oc-green-1-rgb: 211, 249, 216; + --oc-green-2: #b2f2bb; + --oc-green-2-rgb: 178, 242, 187; + --oc-green-3: #8ce99a; + --oc-green-3-rgb: 140, 233, 154; + --oc-green-4: #69db7c; + --oc-green-4-rgb: 105, 219, 124; + --oc-green-5: #51cf66; + --oc-green-5-rgb: 81, 207, 102; + --oc-green-6: #40c057; + --oc-green-6-rgb: 64, 192, 87; + --oc-green-7: #37b24d; + --oc-green-7-rgb: 55, 178, 77; + --oc-green-8: #2f9e44; + --oc-green-8-rgb: 47, 158, 68; + --oc-green-9: #2b8a3e; + --oc-green-9-rgb: 43, 138, 62; + + + /* Lime + * ─────────────────────────────────── */ + + --oc-lime-0: #f4fce3; + --oc-lime-0-rgb: 244, 252, 227; + --oc-lime-1: #e9fac8; + --oc-lime-1-rgb: 233, 250, 200; + --oc-lime-2: #d8f5a2; + --oc-lime-2-rgb: 216, 245, 162; + --oc-lime-3: #c0eb75; + --oc-lime-3-rgb: 192, 235, 117; + --oc-lime-4: #a9e34b; + --oc-lime-4-rgb: 169, 227, 75; + --oc-lime-5: #94d82d; + --oc-lime-5-rgb: 148, 216, 45; + --oc-lime-6: #82c91e; + --oc-lime-6-rgb: 130, 201, 30; + --oc-lime-7: #74b816; + --oc-lime-7-rgb: 116, 184, 22; + --oc-lime-8: #66a80f; + --oc-lime-8-rgb: 102, 168, 15; + --oc-lime-9: #5c940d; + --oc-lime-9-rgb: 92, 148, 13; + + + /* Yellow + * ─────────────────────────────────── */ + + --oc-yellow-0: #fff9db; + --oc-yellow-0-rgb: 255, 249, 219; + --oc-yellow-1: #fff3bf; + --oc-yellow-1-rgb: 255, 243, 191; + --oc-yellow-2: #ffec99; + --oc-yellow-2-rgb: 255, 236, 153; + --oc-yellow-3: #ffe066; + --oc-yellow-3-rgb: 255, 224, 102; + --oc-yellow-4: #ffd43b; + --oc-yellow-4-rgb: 255, 212, 59; + --oc-yellow-5: #fcc419; + --oc-yellow-5-rgb: 252, 196, 25; + --oc-yellow-6: #fab005; + --oc-yellow-6-rgb: 250, 176, 5; + --oc-yellow-7: #f59f00; + --oc-yellow-7-rgb: 245, 159, 0; + --oc-yellow-8: #f08c00; + --oc-yellow-8-rgb: 240, 140, 0; + --oc-yellow-9: #e67700; + --oc-yellow-9-rgb: 230, 119, 0; + + + /* Orange + * ─────────────────────────────────── */ + + --oc-orange-0: #fff4e6; + --oc-orange-0-rgb: 255, 244, 230; + --oc-orange-1: #ffe8cc; + --oc-orange-1-rgb: 255, 232, 204; + --oc-orange-2: #ffd8a8; + --oc-orange-2-rgb: 255, 216, 168; + --oc-orange-3: #ffc078; + --oc-orange-3-rgb: 255, 192, 120; + --oc-orange-4: #ffa94d; + --oc-orange-4-rgb: 255, 169, 77; + --oc-orange-5: #ff922b; + --oc-orange-5-rgb: 255, 146, 43; + --oc-orange-6: #fd7e14; + --oc-orange-6-rgb: 253, 126, 20; + --oc-orange-7: #f76707; + --oc-orange-7-rgb: 247, 103, 7; + --oc-orange-8: #e8590c; + --oc-orange-8-rgb: 232, 89, 12; + --oc-orange-9: #d9480f; + --oc-orange-9-rgb: 217, 72, 15; + + } + +/* Colors */ + +:root { + --background: var(--oc-gray-9); + --background-secondary: var(--oc-gray-8); + --background-tertiary: var(--oc-gray-7); + --foreground: var(--oc-white); + --foreground-heavy: var(--oc-white); +} + +*, *::before, *::after { + box-sizing: border-box; +} + +a:link, a:visited, a:hover, a:active { + color: inherit !important; +} + +html { + font-family: 'Inter', sans-serif; + font-feature-settings: "calt" 1; + font-size: 1.2em; + background: var(--background); + color: var(--foreground); + height: 100%; +} + +* { + transition: background .1s; +} + +body { + margin: 0; + padding: 0; +} + +@supports (font-variation-settings: normal) { + html { + font-family: 'Inter var', sans-serif; + } +} + +/* Type */ + +.centered { + text-align: center; +} + +/* Flexbox */ + +.flex { + display: flex; + flex-wrap: wrap; +} + +.box { + flex-grow: 1; + flex-basis: 15em; + margin: 0 .5em .5em 0; +} + +.fit { + flex-basis: 1em; +} + +.half { flex-basis: calc(50% - (.5em * 2)); } +.third { flex-basis: calc(33% - (.5em * 3)); } +.fourth { flex-basis: calc(25% - (.5em * 4)); } +.fifth { flex-basis: calc(20% - (.5em * 5)); } + +.clickable:hover { + cursor: pointer; +} + +main, header, footer { + display: block; + margin: auto; + padding: 0 2em; + max-width: 50em; +} + +header nav { + margin: 1em 0 5em 0; + padding: 0; + background: var(--background); + font-size: 80%; +} + +header nav .fa-long-arrow-alt-right { + padding: 0 .7em 0 .1em; + color: var(--foreground); +} + +header, footer { + padding-top: 2em; +} + +footer { + text-align: center; + padding-bottom: 3em; +} + +footer small { + font-size: .8em; +} + +footer small a { + text-decoration: none; +} + +footer li a:link, footer li a:visited { + color: #333; +} + +footer li a:hover, footer li a:active { + color: #555; +} + +footer .fab { + font-size: 1.6em; +} + +footer .site { + font-size: 80%; + margin: 1.5em 0 !important; +} + +footer .site li { + padding-right: .5em; +} + +footer .site li a { + text-decoration: none; +} + +footer img { + width: 4em; + margin: 2em 0 1em 0; +} + +/* Headings */ + +h1, h2, h3, h4, h5, h6 { + margin: 2rem 0; + font-weight: 500; + color: var(--foreground-heavy); +} + +h1 { + font-weight: 700; +} + +section h2 { + margin: 1rem 0 2rem 0; +} + +p, ul, li, div { + line-height: 160%; +} + +ul.horizontal { + list-style-type: none; + margin: 0; + padding: 0; +} + +ul.horizontal li { + display: inline; +} + +.bulletless { + list-style-type: none; + margin: 0; + padding: 0; +} + +hr { + border: 0; + height: 1px; + background: var(--foreground); + margin: 2em 0; +} + +/* Sections */ + +section { + border-left: .5em solid var(--background); + padding-left: 1em; + padding-top: .5em; + padding-bottom: .5em; + margin-left: -1.5em; +} + +/* Blockquotes & Code */ + +.code, pre, code, .monospace { + font-family: 'Fira Code'; +} + +pre { + white-space: pre-wrap; + word-break: break-word; +} + +/* Messages */ + +.message { + display: flex; + color: var(--foreground); + margin: 1.5em 0; + width: 100%; + align-items: stretch; + align-content: stretch; +} + +.message-icon { + background: var(--background-tertiary); + align-self: stretch; + padding: .5em; + border-top-left-radius: .2em; + border-bottom-left-radius: .2em; +} + +.message-icon i { + font-size: 1.5em; + margin: .5em; +} + +.message-text { + flex-basis: 100%; + margin: 0; + padding: 1.25em; + overflow: hidden; + background: var(--background-secondary); + align-self: stretch; + border-top-right-radius: .2em; + border-bottom-right-radius: .2em; +} + +.confirmation .message-icon { background: var(--oc-green-5); color: var(--oc-black); } +.confirmation .message-text { background: var(--oc-green-3); color: var(--oc-black); } + +.notice .message-icon { background: var(--oc-yellow-5); color: var(--oc-black); } +.notice .message-text { background: var(--oc-yellow-3); color: var(--oc-black); } + +.warning .message-icon { background: var(--oc-orange-5); color: var(--oc-black); } +.warning .message-text { background: var(--oc-orange-3); color: var(--oc-black); } + +.alert .message-icon { background: var(--oc-red-5); color: var(--oc-black); } +.alert .message-text { background: var(--oc-red-3); color: var(--oc-black); } + +/* Nav */ + +nav { + width: 100%; + padding: .5em 1em; + border-radius: 0.2em; + margin: 2em 0; + background: var(--background-secondary); +} + +nav a:link, nav a:visited { + text-decoration: none; +} + +nav a:hover, nav a:active { + text-decoration: none; +} + +nav li { + margin-right: .5em; +} + +.smaller { + font-size: 90%; +} + +.even-smaller { + font-size: 80%; +} + +.larger { + font-size: 120%; +} + +.even-larger { + font-size: 130%; +} + +.border-solid { + border: 1px solid #888; + border-radius: .2em; +} + +.border-dashed { + border: 1px dashed #888; + border-radius: .2em; +} + +.border-dotted { + border: 1px dotted #888; + border-radius: .2em; +} + +/* Forms */ + +.required:before { + content: "REQUIRED"; + font-size: 60%; + /*background: #e75757;*/ + color: #fff; + padding: .25em .5em; + border-radius: .25em; + margin: 0 0 0 .5em; +} + +.form_note { + padding: .5em 1em; + margin-top: 2em; + border-radius: .2em; +} + +fieldset { + margin: 1.5em 0; + padding: 1em; + border: 0; + background: var(--background-secondary); + color: var(--foreground); + border-radius: .2em; +} + +legend { + padding: .7em 1em 2.5em .85em; + margin: 0 0 -2.5em -.85em; + font-weight: 700; + font-size: 120%; + background: var(--background-secondary); + color: var(--foereground); + border-radius: .2em; +} + +input, button, select, option, textarea { + font-family: inherit; + font-size: inherit; + background: var(--background); + color: var(--foreground); + padding: .5em; + border-radius: .2em; +} + +button, select, option { + cursor: pointer; +} + +input, select, option, textarea { + border: 1px solid #999; +} + +textarea { + width: 100%; +} + +select { + -webkit-appearance: none; +} + +label { + cursor: pointer; + display: block; + margin: 1em 0 .5em 0; + font-weight: normal; +} + +.label { + cursor: pointer; + margin: .4em 0 .4em 0;; +} + +.radio label, +.checkbox label { + display: inline; + margin: 0; +} + +.group { + margin-bottom: 1em; +} + +button, .button, input[type="submit"] { + border: 0; + padding: .5em 1em; + cursor: pointer; + border-radius: .2em; + background: var(--oc-blue-7); + color: var(--oc-white); +} + +input[type="text"], input[type="password"], select { + width: 95%; + margin-bottom: .5em; +} + +button:hover, +button:focus { + opacity: .85; +} + +button:active { + transform: scale(0.97); + transition: transform 0.1s ease-in-out; +} + +form { + width: 100%; +} + +.form-reset { + margin: 0; +} + +form aside { + margin: .2em 0 2em 0; + font-size: 80%; +} + +aside { + float: right; +} + +aside nav { + margin: 0 0 1em 1em; + padding: .3em .2em; +} + +.heading-aligned { + margin-top: -4em; +} + +/* Toggle Switch */ + +.switch { + --line: #ccc; + --dot: var(--oc-violet-4); + --circle: var(--oc-yellow-3); + --background: #aaa; + --duration: .3s; + --text: #000; + --shadow: 0 1px 3px rgba(0, 9, 61, 0.08); + cursor: pointer; + position: relative; +} +.switch:before { + content: ''; + width: 60px; + height: 32px; + border-radius: 16px; + background: var(--background); + position: absolute; + left: 0; + top: 0; + box-shadow: var(--shadow); +} +.switch input { + display: none; +} +.switch input + div { + position: relative; +} +.switch input + div:before, .switch input + div:after { + --s: 1; + content: ''; + position: absolute; + height: 4px; + top: 14px; + width: 24px; + background: var(--line); + -webkit-transform: scaleX(var(--s)); + transform: scaleX(var(--s)); + -webkit-transition: -webkit-transform var(--duration) ease; + transition: -webkit-transform var(--duration) ease; + transition: transform var(--duration) ease; + transition: transform var(--duration) ease, -webkit-transform var(--duration) ease; +} +.switch input + div:before { + --s: 0; + left: 4px; + -webkit-transform-origin: 0 50%; + transform-origin: 0 50%; + border-radius: 2px 0 0 2px; +} +.switch input + div:after { + left: 32px; + -webkit-transform-origin: 100% 50%; + transform-origin: 100% 50%; + border-radius: 0 2px 2px 0; +} +.switch input + div span { + padding-left: 60px; + line-height: 28px; + color: var(--text); +} +.switch input + div span:before { + --x: 0; + --b: var(--circle); + --s: 15px; + content: ''; + position: absolute; + left: 4px; + top: 4px; + width: 24px; + height: 24px; + border-radius: 50%; + box-shadow: inset 0 0 0 var(--s) var(--b); + -webkit-transform: translateX(var(--x)); + transform: translateX(var(--x)); + -webkit-transition: box-shadow var(--duration) ease, -webkit-transform var(--duration) ease; + transition: box-shadow var(--duration) ease, -webkit-transform var(--duration) ease; + transition: box-shadow var(--duration) ease, transform var(--duration) ease; + transition: box-shadow var(--duration) ease, transform var(--duration) ease, -webkit-transform var(--duration) ease; +} +.switch input + div span:not(:empty) { + padding-left: 68px; +} +.switch input:checked + div:before { + --s: 1; +} +.switch input:checked + div:after { + --s: 0; +} +.switch input:checked + div span:before { + --x: 28px; + --s: 12px; + --b: var(--dot); +} + +body .switch + .switch { + margin-top: 32px; +} + +/* Checkboxes */ + +input[type=checkbox] { display: none; } +input[type=checkbox] + label:before { + font-family: 'Font Awesome 6 Pro'; + display: inline-block; + width: 1.3em; +} +input[type=checkbox] + label:before { content: "\f0c8"; } +input[type=checkbox]:checked + label:before { content: "\f14a"; } + +/* Radio Buttons */ + +input[type=radio] { display: none; } +input[type=radio] + label:before { + font-family: 'Font Awesome 6 Pro'; + display: inline-block; + width: 1.3em; +} +input[type=radio] + label:before { content: "\f111"; } +input[type=radio]:checked + label:before { content: "\f192"; } + +/* Tables */ + +.table-container { + overflow-x: auto; +} + +table { + border-collapse: collapse; + width: 100%; +} + +th, td { + background: var(--background); + padding: .5em; +} + +th { + border-bottom: 1px solid var(--foreground); + background: var(--background-secondary); +} + +tr:nth-child(even) td { + background: var(--background-secondary); +} + +th:first-child { border-top-left-radius: 0.2em; } +th:last-child { border-top-right-radius: 0.2em; } +tr:last-child td:first-child { border-bottom-left-radius: 0.2em; } +tr:last-child td:last-child { border-bottom-right-radius: 0.2em; } + +::selection { + color: var(--background); + background: var(--foreground); +} + +@media (max-width: 900px) { + html { + font-size: 1.05em; + } + main, header, footer { + padding: 0 1.5em; + } + header { + padding-top: 2em; + } + header nav { + margin: .5 0 3em 0; + } + footer { + padding-top: 2em; + padding-bottom: 3em; + } +} + +@media (max-width: 500px) { + html { + font-size: 1em; + } + main, header, footer { + padding: 0 1em; + } + header { + padding-top: 2em; + } + header nav { + margin: 0 0 2em 0; + } + footer { + padding-top: 2em; + padding-bottom: 3em; + } +} + +body { + font-family: sans-serif; +} +main { + margin: auto; + max-width: 50em; + line-height: 1.5em; +} +input, textarea { + display: block; + width: 100%; +} +pre { + font-family: Courier, monospace; + font-size: 14px; + white-space: pre-wrap; + white-space: -moz-pre-wrap; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word; +} +</style> +</head> +<body> + +<header> + +<h1>Verify Dasho</h1> +</header> + +<main> + +<p>This is the easiest way to verify Dasho's identity. It uses <a href="https://nacl.cr.yp.to">NaCl</a> for encryption and <a href="http://base91.sourceforge.net">basE91</a> for portability. Payloads can only be created by Dasho, the owner of this service, the dasho.dev domain, and the d_a_s_h_o account on Keybase. By being able to provide a payload which can be verified here, you know that it comes from Dasho. Some payloads have expiry dates, and will need to be renewed. Always check to see if a payload has an expiry date, and when that expiry date is upon verification.</p> + +<form action="#results" method="post"> + <fieldset> + <legend>Verify</legend> + <p>Provide a payload below to verify Dasho's identity.</p> + <p> + <label for="payload">Payload</label> + <textarea name="payload" id="payload"><?php echo $payload; ?></textarea> + </p> + <input type="submit" value="Go"> + </fieldset> +</form> + + +<?php + +echo $result; + +?> + +</main> + +<footer> + +<ul class="horizontal site"> + <li>&copy; Dasho</li> +</ul> + +</footer> + +</body> +</html>