diff options
Diffstat (limited to 'view')
-rw-r--r-- | view/js/crypto.js | 86 | ||||
-rw-r--r-- | view/php/theme_init.php | 1 | ||||
-rw-r--r-- | view/tpl/chat.tpl | 4 | ||||
-rw-r--r-- | view/tpl/comment_item.tpl | 2 | ||||
-rw-r--r-- | view/tpl/jot.tpl | 2 |
5 files changed, 86 insertions, 9 deletions
diff --git a/view/js/crypto.js b/view/js/crypto.js index 14bc1e0a2..55b9aea11 100644 --- a/view/js/crypto.js +++ b/view/js/crypto.js @@ -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. diff --git a/view/php/theme_init.php b/view/php/theme_init.php index b08651689..50da8b5f9 100644 --- a/view/php/theme_init.php +++ b/view/php/theme_init.php @@ -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'); diff --git a/view/tpl/chat.tpl b/view/tpl/chat.tpl index da8da30f2..a0e528894 100644 --- a/view/tpl/chat.tpl +++ b/view/tpl/chat.tpl @@ -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> diff --git a/view/tpl/comment_item.tpl b/view/tpl/comment_item.tpl index d29193901..891d901c9 100644 --- a/view/tpl/comment_item.tpl +++ b/view/tpl/comment_item.tpl @@ -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> diff --git a/view/tpl/jot.tpl b/view/tpl/jot.tpl index 0ffdc0517..eedd92170 100644 --- a/view/tpl/jot.tpl +++ b/view/tpl/jot.tpl @@ -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}} |