multi-tenant relay und card-push to user
This commit is contained in:
1 parent
7219bae655
commit
5b18c46ac2
22 files changed
+7453
-519
No files matched your search
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
// Crypto helpers: at-rest encryption with master key, plus the
|
||||
// HYPRCRD-RELAY-V1 envelope format used by both the JS client and
|
||||
// the relay's internal re-encryption hops.
|
||||
|
||||
if (!defined('RELAY_BOOTSTRAPPED')) { http_response_code(404); exit; }
|
||||
|
||||
/**
|
||||
* Encrypt a value at-rest with the master key. Used for tenant secrets
|
||||
* and the inter-tenant key in the DB.
|
||||
*/
|
||||
function masterEncrypt(string $plain, string $masterKeyHex): string {
|
||||
$key = hex2bin($masterKeyHex);
|
||||
$iv = random_bytes(16);
|
||||
$cipher = openssl_encrypt($plain, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
|
||||
return base64_encode($iv . $cipher);
|
||||
}
|
||||
|
||||
function masterDecrypt(string $encoded, string $masterKeyHex): string {
|
||||
$key = hex2bin($masterKeyHex);
|
||||
$raw = base64_decode($encoded);
|
||||
if (!$raw || strlen($raw) < 17) return '';
|
||||
$iv = substr($raw, 0, 16);
|
||||
$cipher = substr($raw, 16);
|
||||
return openssl_decrypt($cipher, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv) ?: '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Match the JS client's encryption format exactly:
|
||||
* key = first 32 chars of hex(SHA-256(secret)) used as 32-byte ASCII key
|
||||
* envelope = "HYPRCRD-RELAY-V1\n" + base64(iv || ciphertext)
|
||||
*/
|
||||
function clientEncrypt(string $plain, string $secret): string {
|
||||
$key = substr(hash('sha256', $secret), 0, 32);
|
||||
$iv = random_bytes(16);
|
||||
$cipher = openssl_encrypt($plain, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
|
||||
return "HYPRCRD-RELAY-V1\n" . base64_encode($iv . $cipher);
|
||||
}
|
||||
|
||||
function clientDecrypt(string $envelope, string $secret): string {
|
||||
if (!str_starts_with($envelope, 'HYPRCRD-RELAY-V1')) return $envelope;
|
||||
$b64 = trim(substr($envelope, strlen('HYPRCRD-RELAY-V1') + 1));
|
||||
$raw = base64_decode($b64);
|
||||
if (!$raw || strlen($raw) < 17) return '';
|
||||
$key = substr(hash('sha256', $secret), 0, 32);
|
||||
$iv = substr($raw, 0, 16);
|
||||
$cipher = substr($raw, 16);
|
||||
$result = openssl_decrypt($cipher, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
|
||||
return $result !== false ? $result : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Inter-tenant key: relay-wide shared "super secret" key. Set by the admin
|
||||
* during initial setup (it's the third field in the setup form). Used to
|
||||
* re-encrypt messages at rest so they can be routed between tenants.
|
||||
*
|
||||
* Returns null if not set yet (e.g. legacy v2 installs that haven't been
|
||||
* upgraded through the new setup wizard).
|
||||
*/
|
||||
function getInterTenantKey(PDO $db, string $masterKey): ?string {
|
||||
$stored = $db->query("SELECT value FROM settings WHERE key = 'inter_tenant_key'")->fetchColumn();
|
||||
if (!$stored) return null;
|
||||
$decrypted = masterDecrypt($stored, $masterKey);
|
||||
return $decrypted !== '' ? $decrypted : null;
|
||||
}
|
||||
|
||||
/** Set/replace the inter-tenant key. Stored encrypted with the master key. */
|
||||
function setInterTenantKey(PDO $db, string $masterKey, string $newKey): void {
|
||||
$encrypted = masterEncrypt($newKey, $masterKey);
|
||||
$db->prepare("INSERT OR REPLACE INTO settings (key, value) VALUES ('inter_tenant_key', :v)")
|
||||
->execute(['v' => $encrypted]);
|
||||
}
|
||||
|
||||
/** True if the relay-wide super secret has been configured. */
|
||||
function hasInterTenantKey(PDO $db): bool {
|
||||
$stored = $db->query("SELECT value FROM settings WHERE key = 'inter_tenant_key'")->fetchColumn();
|
||||
return !empty($stored);
|
||||
}
|
||||
Reference in new issue
Block a user