diff --git a/js/privatebin.js b/js/privatebin.js
index 0398dbd..412e31f 100644
--- a/js/privatebin.js
+++ b/js/privatebin.js
@@ -780,15 +780,19 @@ jQuery.PrivateBin = (function($, RawDeflate) {
* @private
* @param {string} message
* @param {string} mode
+ * @param {object} zlib
+ * @throws {string}
* @return {ArrayBuffer} data
*/
- async function compress(message, mode)
+ async function compress(message, mode, zlib)
{
message = stringToArraybuffer(
utf16To8(message)
);
if (mode === 'zlib') {
- let zlib = (await z);
+ if (typeof zlib === 'undefined') {
+ throw 'Error compressing paste, due to missing WebAssembly support.'
+ }
return zlib.deflate(message).buffer;
}
return message;
@@ -803,16 +807,16 @@ jQuery.PrivateBin = (function($, RawDeflate) {
* @private
* @param {ArrayBuffer} data
* @param {string} mode
+ * @param {object} zlib
+ * @throws {string}
* @return {string} message
*/
- async function decompress(data, mode)
+ async function decompress(data, mode, zlib)
{
if (mode === 'zlib' || mode === 'none') {
if (mode === 'zlib') {
- let zlib = (await z);
if (typeof zlib === 'undefined') {
- Alert.showError('Your browser doesn\'t support WebAssembly, used for zlib compression. You can create uncompressed documents, but can\'t read compressed ones.')
- return '';
+ throw 'Error decompressing paste, due to missing WebAssembly support.'
}
data = zlib.inflate(
new Uint8Array(data)
@@ -962,12 +966,13 @@ jQuery.PrivateBin = (function($, RawDeflate) {
*/
me.cipher = async function(key, password, message, adata)
{
+ let zlib = (await z);
// AES in Galois Counter Mode, keysize 256 bit,
// authentication tag 128 bit, 10000 iterations in key derivation
const compression = (
- typeof (await z) === 'undefined' ?
+ typeof zlib === 'undefined' ?
'none' : // client lacks support for WASM
- $('body').data('compression') || 'zlib'
+ ($('body').data('compression') || 'zlib')
),
spec = [
getRandomBytes(16), // initialization vector
@@ -997,7 +1002,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
await window.crypto.subtle.encrypt(
cryptoSettings(JSON.stringify(adata), spec),
await deriveKey(key, password, spec),
- await compress(message, compression)
+ await compress(message, compression, zlib)
).catch(Alert.showError)
)
),
@@ -1018,7 +1023,8 @@ jQuery.PrivateBin = (function($, RawDeflate) {
*/
me.decipher = async function(key, password, data)
{
- let adataString, spec, cipherMessage;
+ let adataString, spec, cipherMessage, plaintext;
+ let zlib = (await z);
if (data instanceof Array) {
// version 2
adataString = JSON.stringify(data[1]);
@@ -1045,20 +1051,29 @@ jQuery.PrivateBin = (function($, RawDeflate) {
}
spec[0] = atob(spec[0]);
spec[1] = atob(spec[1]);
+ if (spec[7] === 'zlib') {
+ if (typeof zlib === 'undefined') {
+ throw 'Error decompressing paste, due to missing WebAssembly support.'
+ }
+ }
try {
- return await decompress(
- await window.crypto.subtle.decrypt(
- cryptoSettings(adataString, spec),
- await deriveKey(key, password, spec),
- stringToArraybuffer(
- atob(cipherMessage)
- )
- ).catch(Alert.showError),
- spec[7]
+ plaintext = await window.crypto.subtle.decrypt(
+ cryptoSettings(adataString, spec),
+ await deriveKey(key, password, spec),
+ stringToArraybuffer(
+ atob(cipherMessage)
+ )
);
} catch(err) {
+ console.error(err);
return '';
}
+ try {
+ return await decompress(plaintext, spec[7], zlib);
+ } catch(err) {
+ Alert.showError(err);
+ return err;
+ }
};
/**
@@ -4522,7 +4537,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
// if all tries failed, we can only return an error
if (plaindata.length === 0) {
- throw 'failed to decipher data';
+ return false;
}
return plaindata;
@@ -4551,8 +4566,11 @@ jQuery.PrivateBin = (function($, RawDeflate) {
if (password.length === 0) {
throw 'waiting on user to provide a password';
} else {
- displayDecryptionError('failed to decipher paste text: Incorrect password?');
- throw 'waiting on user to provide correct password';
+ Alert.hideLoading();
+ // reset password, so it can be re-entered
+ Prompt.reset();
+ TopNav.showRetryButton();
+ throw 'Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.';
}
}
@@ -4642,27 +4660,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
});
}
- /**
- * displays and logs decryption errors
- *
- * @name PasteDecrypter.displayDecryptionError
- * @private
- * @function
- * @param {string} message
- */
- function displayDecryptionError(message)
- {
- Alert.hideLoading();
-
- // log detailed error, but display generic translation
- console.error(message);
- Alert.showError('Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.');
-
- // reset password, so it can be re-entered
- Prompt.reset();
- TopNav.showRetryButton();
- }
-
/**
* show decrypted text in the display area, including discussion (if open)
*
@@ -4714,7 +4711,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
.catch((err) => {
// wait for the user to type in the password,
// then PasteDecrypter.run will be called again
- console.error(err);
+ Alert.showError(err);
});
};
@@ -4818,34 +4815,14 @@ jQuery.PrivateBin = (function($, RawDeflate) {
'subtle' in window.crypto &&
'encrypt' in window.crypto.subtle &&
'decrypt' in window.crypto.subtle &&
+ 'Uint8Array' in window &&
'Uint32Array' in window
)) {
return true;
}
- if (!(
- 'WebAssembly' in window &&
- 'instantiate' in window.WebAssembly
- )) {
- return true;
- }
- try {
- // [\0, 'a', 's', 'm', (uint_32) 1] - smallest valid wasm module
- const module = new WebAssembly.Module(Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00));
- if (
- !(
- module instanceof WebAssembly.Module &&
- new WebAssembly.Instance(module) instanceof WebAssembly.Instance
- )
- ) {
- return true;
- }
- } catch (e) {
- return true;
- }
-
- // not checking for async/await, ES6, Promise or Uint8Array support,
- // as most browsers introduced these earlier then webassembly and webcrypto:
+ // not checking for async/await, ES6 or Promise support, as most
+ // browsers introduced these earlier then webassembly and webcrypto:
// https://github.com/PrivateBin/PrivateBin/pull/431#issuecomment-493129359
return false;
@@ -4881,7 +4858,9 @@ jQuery.PrivateBin = (function($, RawDeflate) {
}
z = zlib.catch(function () {
- Alert.showWarning('Your browser doesn\'t support WebAssembly, used for zlib compression. You can create uncompressed documents, but can\'t read compressed ones.');
+ if ($('body').data('compression') !== 'none') {
+ Alert.showWarning('Your browser doesn\'t support WebAssembly, used for zlib compression. You can create uncompressed documents, but can\'t read compressed ones.');
+ }
});
return true;
}
diff --git a/js/test/CryptTool.js b/js/test/CryptTool.js
index 9589ef9..b3aaaa5 100644
--- a/js/test/CryptTool.js
+++ b/js/test/CryptTool.js
@@ -8,9 +8,6 @@ describe('CryptTool', function () {
await new Promise(resolve => setTimeout(resolve, 1900));
});
- // ensure zlib is getting loaded
- $.PrivateBin.InitialCheck.init();
-
this.timeout(30000);
it('can en- and decrypt any message', function () {
jsc.assert(jsc.forall(
@@ -21,13 +18,15 @@ describe('CryptTool', function () {
// pause to let async functions conclude
await new Promise(resolve => setTimeout(resolve, 300));
let clean = jsdom();
+ // ensure zlib is getting loaded
+ $.PrivateBin.InitialCheck.init();
window.crypto = new WebCrypto();
message = message.trim();
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
key, password, message, []
),
plaintext = await $.PrivateBin.CryptTool.decipher(
- key, password, cipherMessage
+ key, password, cipherMessage
);
clean();
return message === plaintext;
@@ -182,6 +181,8 @@ describe('CryptTool', function () {
let message = fs.readFileSync('test/compression-sample.txt', 'utf8'),
clean = jsdom();
window.crypto = new WebCrypto();
+ // ensure zlib is getting loaded
+ $.PrivateBin.InitialCheck.init();
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
'foo', 'bar', message, []
),
@@ -225,6 +226,8 @@ isWhile : interp (while expr sBody) (MemElem mem) =
conseq_or_bottom inv (interp (nth_iterate sBody n) (MemElem mem))
`;
let clean = jsdom();
+ // ensure zlib is getting loaded
+ $.PrivateBin.InitialCheck.init();
window.crypto = new WebCrypto();
let cipherMessage = await $.PrivateBin.CryptTool.cipher(
key, password, message, []
diff --git a/tpl/bootstrap.php b/tpl/bootstrap.php
index c7f7868..45de8a8 100644
--- a/tpl/bootstrap.php
+++ b/tpl/bootstrap.php
@@ -71,7 +71,7 @@ if ($MARKDOWN):
endif;
?>
-
+
diff --git a/tpl/page.php b/tpl/page.php
index c6560d2..c93423d 100644
--- a/tpl/page.php
+++ b/tpl/page.php
@@ -49,7 +49,7 @@ if ($MARKDOWN):
endif;
?>
-
+