mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-21 00:52:33 -04:00
refactor sodium b2b encryption
This commit is contained in:
@@ -246,38 +246,45 @@ function bb_replace_images($body, $images) {
|
||||
function bb_parse_crypt($match) {
|
||||
|
||||
$matches = [];
|
||||
$attributes = $match[1];
|
||||
$hint = '';
|
||||
$algorithm = '';
|
||||
$payload = $match[1];
|
||||
|
||||
preg_match("/alg='(.*?)'/ism", $attributes, $matches);
|
||||
$algorithm = $matches[1] ?? '';
|
||||
if (isset($match[2])) {
|
||||
// backwards compatibility
|
||||
|
||||
if (!$algorithm) {
|
||||
preg_match("/alg=\"\;(.*?)\"\;/ism", $attributes, $matches);
|
||||
$attributes = $match[1];
|
||||
$payload = $match[2];
|
||||
|
||||
preg_match("/alg='(.*?)'/ism", $attributes, $matches);
|
||||
$algorithm = $matches[1] ?? '';
|
||||
}
|
||||
|
||||
preg_match("/hint='(.*?)'/ism", $attributes, $matches);
|
||||
$hint = $matches[1] ?? '';
|
||||
if (!$algorithm) {
|
||||
preg_match("/alg=\"\;(.*?)\"\;/ism", $attributes, $matches);
|
||||
$algorithm = $matches[1] ?? '';
|
||||
}
|
||||
|
||||
if (!$hint) {
|
||||
preg_match("/hint=\"\;(.*?)\"\;/ism", $attributes, $matches);
|
||||
preg_match("/hint='(.*?)'/ism", $attributes, $matches);
|
||||
$hint = $matches[1] ?? '';
|
||||
|
||||
if (!$hint) {
|
||||
preg_match("/hint=\"\;(.*?)\"\;/ism", $attributes, $matches);
|
||||
$hint = $matches[1] ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
$x = random_string();
|
||||
$x = random_string(32);
|
||||
|
||||
$f = 'sodium_decrypt';
|
||||
$onclick = 'onclick="sodium_decrypt(\'' . $payload . '\',\'#' . $x . '\');"';
|
||||
|
||||
if (in_array($algorithm, ['AES-128-CCM', 'rot13', 'triple-rot13'])) {
|
||||
$f = 'hz_decrypt'; // deprecated
|
||||
// backwards compatibility
|
||||
$onclick = 'onclick="hz_decrypt(\'' . $algorithm . '\',\'' . $hint . '\',\'' . $payload . '\',\'#' . $x . '\');"';
|
||||
}
|
||||
|
||||
$onclick = 'onclick="' . $f . '(\'' . $algorithm . '\',\'' . $hint . '\',\'' . $match[2] . '\',\'#' . $x . '\');"';
|
||||
$label = t('Encrypted content');
|
||||
|
||||
$text = '<br /><div id="' . $x . '"><img class="cursor-pointer" src="' . z_root() . '/images/lock_icon.svg" ' . $onclick . ' alt="' . $label . '" title="' . $label . '" /></div><br />';
|
||||
$text = '<div id="' . $x . '" class="encrypted-content"><img class="cursor-pointer" src="' . z_root() . '/images/lock_icon.svg" ' . $onclick . ' alt="' . $label . '" title="' . $label . '" /></div>';
|
||||
|
||||
return $text;
|
||||
}
|
||||
@@ -1627,8 +1634,7 @@ function bbcode($text, $options = []) {
|
||||
|
||||
// crypt
|
||||
if (strpos($text,'[/crypt]') !== false) {
|
||||
$x = random_string();
|
||||
$text = preg_replace("/\[crypt\](.*?)\[\/crypt\]/ism",'<br /><div id="' . $x . '"><img class="cursor-pointer" src="' .z_root() . '/images/lock_icon.svg" onclick="red_decrypt(\'rot13\',\'\',\'$1\',\'#' . $x . '\');" alt="' . t('Encrypted content') . '" title="' . t('Encrypted content') . '" /><br /></div>', $text);
|
||||
$text = preg_replace_callback("/\[crypt\](.*?)\[\/crypt\]/ism", 'bb_parse_crypt', $text);
|
||||
$text = preg_replace_callback("/\[crypt (.*?)\](.*?)\[\/crypt\]/ism", 'bb_parse_crypt', $text);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,11 @@ async function sodium_encrypt(element) {
|
||||
}
|
||||
|
||||
let message = $(element).val();
|
||||
|
||||
if (!message) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let password = prompt(aStr['passphrase']);
|
||||
|
||||
if (!password) {
|
||||
@@ -35,6 +40,7 @@ async function sodium_encrypt(element) {
|
||||
|
||||
let salt = await sodium.randombytes_buf(16);
|
||||
let nonce = await sodium.randombytes_buf(24);
|
||||
|
||||
let key = await sodium.crypto_pwhash(
|
||||
32,
|
||||
password,
|
||||
@@ -47,31 +53,37 @@ async function sodium_encrypt(element) {
|
||||
let ciphertext = await sodium.crypto_secretbox(message, nonce, key);
|
||||
delete message, password, key;
|
||||
|
||||
let s = await sodium.sodium_bin2hex(salt);
|
||||
let n = await sodium.sodium_bin2hex(nonce);
|
||||
let c = await sodium.sodium_bin2hex(ciphertext);
|
||||
let encrypted = window.btoa(s + '.' + n + '.' + c);
|
||||
let val = "[crypt alg='XSalsa20' hint='" + hint + "']" + encrypted + '[/crypt]';
|
||||
let payload = {
|
||||
hint: hint,
|
||||
alg: 'XSalsa20',
|
||||
salt: await sodium.sodium_bin2hex(salt),
|
||||
nonce: await sodium.sodium_bin2hex(nonce),
|
||||
ciphertext: await sodium.sodium_bin2hex(ciphertext)
|
||||
};
|
||||
|
||||
let val = "[crypt]" + window.btoa(JSON.stringify(payload)) + '[/crypt]';
|
||||
|
||||
$(element).val(val);
|
||||
}
|
||||
|
||||
async function sodium_decrypt(alg, hint, encrypted, element) {
|
||||
if (alg !== 'XSalsa20') {
|
||||
async function sodium_decrypt(payload, element) {
|
||||
let arr = JSON.parse(window.atob(payload));
|
||||
|
||||
if (arr.alg !== 'XSalsa20') {
|
||||
alert('Unsupported algorithm');
|
||||
return false;
|
||||
}
|
||||
|
||||
let arr = window.atob(encrypted).split('.');
|
||||
let salt = await sodium.sodium_hex2bin(arr[0]);
|
||||
let nonce = await sodium.sodium_hex2bin(arr[1]);
|
||||
let ciphertext = await sodium.sodium_hex2bin(arr[2]);
|
||||
let password = prompt((hint.length) ? hex2bin(hint) : aStr['passphrase']);
|
||||
let password = prompt((arr.hint.length) ? hex2bin(arr.hint) : aStr['passphrase']);
|
||||
|
||||
if (!password) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let salt = await sodium.sodium_hex2bin(arr.salt);
|
||||
let nonce = await sodium.sodium_hex2bin(arr.nonce);
|
||||
let ciphertext = await sodium.sodium_hex2bin(arr.ciphertext);
|
||||
|
||||
let key = await sodium.crypto_pwhash(
|
||||
32,
|
||||
password,
|
||||
@@ -84,7 +96,7 @@ async function sodium_decrypt(alg, hint, encrypted, element) {
|
||||
delete password, key;
|
||||
|
||||
if ($(element).css('display') === 'none' && typeof tinyMCE !== typeof undefined) {
|
||||
tinyMCE.activeEditor.setContent(newdiv);
|
||||
tinyMCE.activeEditor.setContent(decrypted.toString('utf-8'));
|
||||
}
|
||||
else {
|
||||
$(element).html(decrypted.toString('utf-8'));
|
||||
|
||||
Reference in New Issue
Block a user