mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-21 00:52:33 -04:00
implement sodium-plus library to replace unmaintained sjcl
This commit is contained in:
@@ -247,41 +247,39 @@ function bb_parse_crypt($match) {
|
||||
|
||||
$matches = [];
|
||||
$attributes = $match[1];
|
||||
|
||||
$algorithm = "";
|
||||
$hint = '';
|
||||
$algorithm = '';
|
||||
|
||||
preg_match("/alg='(.*?)'/ism", $attributes, $matches);
|
||||
if ($matches[1] != "")
|
||||
$algorithm = $matches[1];
|
||||
$algorithm = $matches[1] ?? '';
|
||||
|
||||
preg_match("/alg=\"\;(.*?)\"\;/ism", $attributes, $matches);
|
||||
if ($matches[1] != "")
|
||||
$algorithm = $matches[1];
|
||||
|
||||
$hint = "";
|
||||
if (!$algorithm) {
|
||||
preg_match("/alg=\"\;(.*?)\"\;/ism", $attributes, $matches);
|
||||
$algorithm = $matches[1] ?? '';
|
||||
}
|
||||
|
||||
preg_match("/hint='(.*?)'/ism", $attributes, $matches);
|
||||
if ($matches[1] != "")
|
||||
$hint = $matches[1];
|
||||
preg_match("/hint=\"\;(.*?)\"\;/ism", $attributes, $matches);
|
||||
if ($matches[1] != "")
|
||||
$hint = $matches[1];
|
||||
$hint = $matches[1] ?? '';
|
||||
|
||||
if (!$hint) {
|
||||
preg_match("/hint=\"\;(.*?)\"\;/ism", $attributes, $matches);
|
||||
$hint = $matches[1] ?? '';
|
||||
}
|
||||
|
||||
$x = random_string();
|
||||
|
||||
$f = 'hz_decrypt';
|
||||
$f = 'sodium_decrypt';
|
||||
|
||||
//legacy cryptojs support
|
||||
if(plugin_is_installed('cryptojs')) {
|
||||
$f = ((in_array($algorithm, ['AES-128-CCM', 'rot13', 'triple-rot13'])) ? 'hz_decrypt' : 'red_decrypt');
|
||||
if (in_array($algorithm, ['AES-128-CCM', 'rot13', 'triple-rot13'])) {
|
||||
$f = 'hz_decrypt'; // deprecated
|
||||
}
|
||||
|
||||
$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 = '<br /><div id="' . $x . '"><img class="cursor-pointer" src="' . z_root() . '/images/lock_icon.svg" ' . $onclick . ' alt="' . $label . '" title="' . $label . '" /></div><br />';
|
||||
|
||||
return $Text;
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,82 @@ function str_rot13 (str) {
|
||||
});
|
||||
}
|
||||
|
||||
async function sodium_encrypt(element) {
|
||||
if (!window.sodium) {
|
||||
window.sodium = await SodiumPlus.auto();
|
||||
}
|
||||
|
||||
if (typeof tinyMCE !== typeof undefined) {
|
||||
tinyMCE.triggerSave(false,true);
|
||||
}
|
||||
|
||||
let message = $(element).val();
|
||||
let password = prompt(aStr['passphrase']);
|
||||
|
||||
if (!password) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let hint = bin2hex(prompt(aStr['passhint']));
|
||||
|
||||
let salt = await sodium.randombytes_buf(16);
|
||||
let nonce = await sodium.randombytes_buf(24);
|
||||
let key = await sodium.crypto_pwhash(
|
||||
32,
|
||||
password,
|
||||
salt,
|
||||
sodium.CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
|
||||
sodium.CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
|
||||
);
|
||||
|
||||
// Message can be a string, buffer, array, etc.
|
||||
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]';
|
||||
|
||||
$(element).val(val);
|
||||
}
|
||||
|
||||
async function sodium_decrypt(alg, hint, encrypted, element) {
|
||||
if (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']);
|
||||
|
||||
if (!password) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let key = await sodium.crypto_pwhash(
|
||||
32,
|
||||
password,
|
||||
salt,
|
||||
sodium.CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
|
||||
sodium.CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
|
||||
);
|
||||
|
||||
let decrypted = await sodium.crypto_secretbox_open(ciphertext, nonce, key);
|
||||
delete password, key;
|
||||
|
||||
if ($(element).css('display') === 'none' && typeof tinyMCE !== typeof undefined) {
|
||||
tinyMCE.activeEditor.setContent(newdiv);
|
||||
}
|
||||
else {
|
||||
$(element).html(decrypted.toString('utf-8'));
|
||||
}
|
||||
}
|
||||
|
||||
function hz_encrypt(alg, elem) {
|
||||
var enc_text = '';
|
||||
var newdiv = '';
|
||||
@@ -33,7 +109,7 @@ function hz_encrypt(alg, elem) {
|
||||
var enc_key = bin2hex(passphrase);
|
||||
|
||||
// If you don't provide a key you get rot13, which doesn't need a key
|
||||
// but consequently isn't secure.
|
||||
// but consequently isn't secure.
|
||||
|
||||
if(! enc_key)
|
||||
alg = 'rot13';
|
||||
@@ -44,7 +120,7 @@ function hz_encrypt(alg, elem) {
|
||||
if(alg == 'AES-128-CCM') {
|
||||
|
||||
// This is the prompt we're going to use when the receiver tries to open it.
|
||||
// Maybe "Grandma's maiden name" or "our secret place" or something.
|
||||
// Maybe "Grandma's maiden name" or "our secret place" or something.
|
||||
|
||||
var enc_hint = bin2hex(prompt(aStr['passhint']));
|
||||
|
||||
@@ -62,7 +138,7 @@ function hz_encrypt(alg, elem) {
|
||||
// property of our source element - because a tinymce instance
|
||||
// will have display "none". If a normal textarea such as in a comment
|
||||
// box has display "none" you wouldn't be able to type in it.
|
||||
|
||||
|
||||
if($(elem).css('display') == 'none' && typeof tinyMCE !== "undefined") {
|
||||
tinyMCE.activeEditor.setContent(newdiv);
|
||||
}
|
||||
@@ -98,8 +174,8 @@ function hz_decrypt(alg, hint, text, elem) {
|
||||
enc_key = '';
|
||||
|
||||
// Not sure whether to drop this back in the conversation display.
|
||||
// It probably needs a lightbox or popup window because any conversation
|
||||
// updates could
|
||||
// It probably needs a lightbox or popup window because any conversation
|
||||
// updates could
|
||||
// wipe out the text and make you re-enter the key if it was in the
|
||||
// conversation. For now we do that so you can read it.
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ head_add_js('/library/readmore.js/readmore.js');
|
||||
head_add_js('/library/jgrowl/jquery.jgrowl.min.js');
|
||||
|
||||
head_add_js('/library/sjcl/sjcl.js');
|
||||
head_add_js('/library/sodium-plus/dist/sodium-plus.min.js');
|
||||
|
||||
head_add_js('acl.js');
|
||||
head_add_js('webtoolkit.base64.js');
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
</div>
|
||||
{{if $feature_encrypt}}
|
||||
<div class="btn-group me-2 d-none d-md-flex">
|
||||
<button id="chat-encrypt-wrapper" class="btn btn-outline-secondary btn-sm" onclick="hz_encrypt('{{$cipher}}', '#chatText'); return false;">
|
||||
<button id="chat-encrypt-wrapper" class="btn btn-outline-secondary btn-sm" onclick="sodium_encrypt('#chatText'); return false;">
|
||||
<i id="chat-encrypt" class="fa fa-key jot-icons" title="{{$encrypt}}" ></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -83,7 +83,7 @@
|
||||
<a class="dropdown-item" href="#" onclick="chatJotGetLink(); return false;" ><i class="fa fa-link"></i> {{$insert}}</a>
|
||||
{{if $feature_encrypt}}
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" onclick="hz_encrypt('{{$cipher}}', '#chatText'); return false;"><i class="fa fa-key"></i> {{$encrypt}}</a>
|
||||
<a class="dropdown-item" href="#" onclick="sodium_encrypt('#chatText'); return false;"><i class="fa fa-key"></i> {{$encrypt}}</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
</div>
|
||||
{{if $feature_encrypt}}
|
||||
<div class="btn-group me-2">
|
||||
<button class="btn btn-outline-secondary btn-sm border-0" title="{{$encrypt}}" onclick="hz_encrypt('{{$cipher}}','#comment-edit-text-' + '{{$id}}'); return false;">
|
||||
<button class="btn btn-outline-secondary btn-sm border-0" title="{{$encrypt}}" onclick="sodium_encrypt('#comment-edit-text-' + '{{$id}}'); return false;">
|
||||
<i class="fa fa-key comment-icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
</button>
|
||||
{{/if}}
|
||||
{{if $feature_encrypt}}
|
||||
<button type="button" id="profile-encrypt-wrapper" class="btn btn-outline-secondary btn-sm border-0" title="{{$encrypt}}" onclick="hz_encrypt('{{$cipher}}','#profile-jot-text');return false;">
|
||||
<button type="button" id="profile-encrypt-wrapper" class="btn btn-outline-secondary btn-sm border-0" title="{{$encrypt}}" onclick="sodium_encrypt('#profile-jot-text'); return false;">
|
||||
<i id="profile-encrypt" class="fa fa-key jot-icons"></i>
|
||||
</button>
|
||||
{{/if}}
|
||||
|
||||
Reference in New Issue
Block a user