ソースを参照

drop legacy paste format support

remove support for ZeroBin & v1 pastes and base64 & rawinflate libraries
El RIDO 1 年間 前
コミット
6d5323e351

+ 3 - 1
CHANGELOG.md

@@ -1,7 +1,9 @@
 # PrivateBin version history
 
 ## 2.0.0 (not yet released)
-* CHANGED: Remove page template (#265)
+* CHANGED: Removed page template (#265)
+* CHANGED: Removed support for ZeroBin & v1 pastes - since release 1.3 the v2 format is used (#551)
+* CHANGED: Removed use of base64 & rawinflate libraries (#551)
 * FIXED: Name mismatches in attached files (#1584)
 * FIXED: Unable to paste attachments from clipboard (#1589)
 

+ 1 - 3
README.md

@@ -12,9 +12,7 @@ Data is encrypted and decrypted in the browser using 256bit AES in
 This is a fork of ZeroBin, originally developed by
 [Sébastien Sauvage](https://github.com/sebsauvage/ZeroBin). PrivateBin was
 refactored to allow easier and cleaner extensions and has many additional
-features. It is, however, still fully compatible to the original ZeroBin 0.19
-data storage scheme. Therefore, such installations can be upgraded to PrivateBin
-without losing any data.
+features.
 
 ## What PrivateBin provides
 

+ 0 - 5
cfg/conf.sample.php

@@ -124,11 +124,6 @@ languageselection = false
 ; The recommended and default used CSP is:
 ; cspheader = "default-src 'none'; base-uri 'self'; form-action 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'wasm-unsafe-eval'; style-src 'self'; font-src 'self'; frame-ancestors 'none'; frame-src blob:; img-src 'self' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-modals allow-downloads"
 
-; stay compatible with PrivateBin Alpha 0.19, less secure
-; if enabled will use base64.js version 1.7 instead of 2.1.9 and sha1 instead of
-; sha256 in HMAC for the deletion token
-; zerobincompatibility = false
-
 ; Enable or disable the warning message when the site is served over an insecure
 ; connection (insecure HTTP instead of HTTPS), defaults to true.
 ; Secure transport methods like Tor and I2P domains are automatically whitelisted.

+ 0 - 237
js/base64-1.7.js

@@ -1,237 +0,0 @@
-/*
- * $Id: base64.js,v 1.7 2012/08/23 10:30:18 dankogai Exp dankogai $
- *
- *  Licensed under the MIT license.
- *  https://www.opensource.org/licenses/mit-license.php
- *
- *  References:
- *    https://en.wikipedia.org/wiki/Base64
- */
-
-(function(global){
-
-var b64chars
-    = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
-
-var b64charcodes = function(){
-    var a = [];
-    var codeA = 'A'.charCodeAt(0);
-    var codea = 'a'.charCodeAt(0);
-    var code0 = '0'.charCodeAt(0);
-    for (var i = 0; i < 26; i ++) a.push(codeA + i);
-    for (var i = 0; i < 26; i ++) a.push(codea + i);
-    for (var i = 0; i < 10; i ++) a.push(code0 + i);
-    a.push('+'.charCodeAt(0));
-    a.push('/'.charCodeAt(0));
-    return a;
-}();
-
-var b64tab = function(bin){
-    var t = {};
-    for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
-    return t;
-}(b64chars);
-
-var stringToArray = function(s){
-    var a = [];
-    for (var i = 0, l = s.length; i < l; i ++) a[i] = s.charCodeAt(i);
-    return a;
-};
-
-var convertUTF8ArrayToBase64 = function(bin){
-    var padlen = 0;
-    while (bin.length % 3){
-        bin.push(0);
-        padlen++;
-    };
-    var b64 = [];
-    for (var i = 0, l = bin.length; i < l; i += 3){
-        var c0 = bin[i], c1 = bin[i+1], c2 = bin[i+2];
-        if (c0 >= 256 || c1 >= 256 || c2 >= 256)
-            throw 'unsupported character found';
-        var n = (c0 << 16) | (c1 << 8) | c2;
-        b64.push(
-            b64charcodes[ n >>> 18],
-            b64charcodes[(n >>> 12) & 63],
-            b64charcodes[(n >>>  6) & 63],
-            b64charcodes[ n         & 63]
-        );
-    }
-    while (padlen--) b64[b64.length - padlen - 1] = '='.charCodeAt(0);
-    return chunkStringFromCharCodeApply(b64);
-};
-
-var convertBase64ToUTF8Array = function(b64){
-    b64 = b64.replace(/[^A-Za-z0-9+\/]+/g, '');
-    var bin = [];
-    var padlen = b64.length % 4;
-    for (var i = 0, l = b64.length; i < l; i += 4){
-        var n = ((b64tab[b64.charAt(i  )] || 0) << 18)
-            |   ((b64tab[b64.charAt(i+1)] || 0) << 12)
-            |   ((b64tab[b64.charAt(i+2)] || 0) <<  6)
-            |   ((b64tab[b64.charAt(i+3)] || 0));
-        bin.push(
-            (  n >> 16 ),
-            ( (n >>  8) & 0xff ),
-            (  n        & 0xff )
-        );
-    }
-    bin.length -= [0,0,2,1][padlen];
-    return bin;
-};
-
-var convertUTF16ArrayToUTF8Array = function(uni){
-    var bin = [];
-    for (var i = 0, l = uni.length; i < l; i++){
-        var n = uni[i];
-        if (n < 0x80)
-            bin.push(n);
-        else if (n < 0x800)
-            bin.push(
-                0xc0 | (n >>>  6),
-                0x80 | (n & 0x3f));
-        else
-            bin.push(
-                0xe0 | ((n >>> 12) & 0x0f),
-                0x80 | ((n >>>  6) & 0x3f),
-                0x80 |  (n         & 0x3f));
-    }
-    return bin;
-};
-
-var convertUTF8ArrayToUTF16Array = function(bin){
-    var uni = [];
-    for (var i = 0, l = bin.length; i < l; i++){
-        var c0 = bin[i];
-        if    (c0 < 0x80){
-            uni.push(c0);
-        }else{
-            var c1 = bin[++i];
-            if (c0 < 0xe0){
-                uni.push(((c0 & 0x1f) << 6) | (c1 & 0x3f));
-            }else{
-                var c2 = bin[++i];
-                uni.push(
-                       ((c0 & 0x0f) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f)
-                );
-            }
-        }
-    }
-    return uni;
-};
-
-var convertUTF8StringToBase64 = function(bin){
-    return convertUTF8ArrayToBase64(stringToArray(bin));
-};
-
-var convertBase64ToUTF8String = function(b64){
-    return chunkStringFromCharCodeApply(convertBase64ToUTF8Array(b64));
-};
-
-var convertUTF8StringToUTF16Array = function(bin){
-    return convertUTF8ArrayToUTF16Array(stringToArray(bin));
-};
-
-var convertUTF8ArrayToUTF16String = function(bin){
-    return chunkStringFromCharCodeApply(convertUTF8ArrayToUTF16Array(bin));
-};
-
-var convertUTF8StringToUTF16String = function(bin){
-    return chunkStringFromCharCodeApply(
-        convertUTF8ArrayToUTF16Array(stringToArray(bin))
-    );
-};
-
-var convertUTF16StringToUTF8Array = function(uni){
-    return convertUTF16ArrayToUTF8Array(stringToArray(uni));
-};
-
-var convertUTF16ArrayToUTF8String = function(uni){
-    return chunkStringFromCharCodeApply(convertUTF16ArrayToUTF8Array(uni));
-};
-
-var convertUTF16StringToUTF8String = function(uni){
-    return chunkStringFromCharCodeApply(
-        convertUTF16ArrayToUTF8Array(stringToArray(uni))
-    );
-};
-
-/*
- * String.fromCharCode.apply will only handle arrays as big as 65536, 
- * after that it'll return a truncated string with no warning.
- */
-var chunkStringFromCharCodeApply = function(arr){
-    var strs = [], i;
-    for (i = 0; i < arr.length; i += 65536){
-        strs.push(String.fromCharCode.apply(String, arr.slice(i, i+65536)));
-    }
-    return strs.join('');
-};
-
-if (global.btoa){
-    var btoa = global.btoa;
-    var convertUTF16StringToBase64 = function (uni){
-        return btoa(convertUTF16StringToUTF8String(uni));
-    };
-}
-else {
-    var btoa = convertUTF8StringToBase64;
-    var convertUTF16StringToBase64 = function (uni){
-        return convertUTF8ArrayToBase64(convertUTF16StringToUTF8Array(uni));
-    };
-}
-
-if (global.atob){
-    var atob = global.atob;
-    var convertBase64ToUTF16String = function (b64){
-        return convertUTF8StringToUTF16String(atob(b64));
-    };
-}
-else {
-    var atob = convertBase64ToUTF8String;
-    var convertBase64ToUTF16String = function (b64){
-        return convertUTF8ArrayToUTF16String(convertBase64ToUTF8Array(b64));
-    };
-}
-
-global.Base64 = {
-    convertUTF8ArrayToBase64:convertUTF8ArrayToBase64,
-    convertByteArrayToBase64:convertUTF8ArrayToBase64,
-    convertBase64ToUTF8Array:convertBase64ToUTF8Array,
-    convertBase64ToByteArray:convertBase64ToUTF8Array,
-    convertUTF16ArrayToUTF8Array:convertUTF16ArrayToUTF8Array,
-    convertUTF16ArrayToByteArray:convertUTF16ArrayToUTF8Array,
-    convertUTF8ArrayToUTF16Array:convertUTF8ArrayToUTF16Array,
-    convertByteArrayToUTF16Array:convertUTF8ArrayToUTF16Array,
-    convertUTF8StringToBase64:convertUTF8StringToBase64,
-    convertBase64ToUTF8String:convertBase64ToUTF8String,
-    convertUTF8StringToUTF16Array:convertUTF8StringToUTF16Array,
-    convertUTF8ArrayToUTF16String:convertUTF8ArrayToUTF16String,
-    convertByteArrayToUTF16String:convertUTF8ArrayToUTF16String,
-    convertUTF8StringToUTF16String:convertUTF8StringToUTF16String,
-    convertUTF16StringToUTF8Array:convertUTF16StringToUTF8Array,
-    convertUTF16StringToByteArray:convertUTF16StringToUTF8Array,
-    convertUTF16ArrayToUTF8String:convertUTF16ArrayToUTF8String,
-    convertUTF16StringToUTF8String:convertUTF16StringToUTF8String,
-    convertUTF16StringToBase64:convertUTF16StringToBase64,
-    convertBase64ToUTF16String:convertBase64ToUTF16String,
-    fromBase64:convertBase64ToUTF8String,
-    toBase64:convertUTF8StringToBase64,
-    atob:atob,
-    btoa:btoa,
-    utob:convertUTF16StringToUTF8String,
-    btou:convertUTF8StringToUTF16String,
-    encode:convertUTF16StringToBase64,
-    encodeURI:function(u){
-        return convertUTF16StringToBase64(u).replace(/[+\/]/g, function(m0){
-            return m0 == '+' ? '-' : '_';
-        }).replace(/=+$/, '');
-    },
-    decode:function(a){
-        return convertBase64ToUTF16String(a.replace(/[-_]/g, function(m0){
-            return m0 == '-' ? '+' : '/';
-        }));
-    }
-};
-
-})(this);

+ 0 - 1
js/common.js

@@ -10,7 +10,6 @@ global.WebCrypto = require('@peculiar/webcrypto').Crypto;
 
 // application libraries to test
 global.$ = global.jQuery = require('./jquery-3.7.1');
-global.RawDeflate = require('./rawinflate-0.3').RawDeflate;
 global.zlib = require('./zlib-1.3.1-1').zlib;
 require('./prettify');
 global.prettyPrint = window.PR.prettyPrint;

+ 12 - 62
js/privatebin.js

@@ -10,7 +10,7 @@
  * @namespace
  */
 
-// global Base64, DOMPurify, FileReader, RawDeflate, history, navigator, prettyPrint, prettyPrintOne, showdown, kjua
+// global Base64, DOMPurify, FileReader, history, navigator, prettyPrint, prettyPrintOne, showdown, kjua
 
 jQuery.fn.draghover = function() {
     'use strict';
@@ -41,7 +41,7 @@ jQuery(document).ready(function() {
     $.PrivateBin.Controller.init();
 });
 
-jQuery.PrivateBin = (function($, RawDeflate) {
+jQuery.PrivateBin = (function($) {
     'use strict';
 
     /**
@@ -1119,39 +1119,17 @@ jQuery.PrivateBin = (function($, RawDeflate) {
          */
         async function decompress(data, mode, zlib)
         {
-            if (mode === 'zlib' || mode === 'none') {
-                if (mode === 'zlib') {
-                    if (typeof zlib === 'undefined') {
-                        throw 'Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.'
-                    }
-                    data = zlib.inflate(
-                        new Uint8Array(data)
-                    ).buffer;
+            if (mode === 'zlib') {
+                if (typeof zlib === 'undefined') {
+                    throw 'Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.'
                 }
-                return utf8To16(
-                    arraybufferToString(data)
-                );
-            }
-            // detect presence of Base64.js, indicating legacy ZeroBin paste
-            if (typeof Base64 === 'undefined') {
-                return utf8To16(
-                    RawDeflate.inflate(
-                        utf8To16(
-                            atob(
-                                arraybufferToString(data)
-                            )
-                        )
-                    )
-                );
-            } else {
-                return Base64.btou(
-                    RawDeflate.inflate(
-                        Base64.fromBase64(
-                            arraybufferToString(data)
-                        )
-                    )
-                );
+                data = zlib.inflate(
+                    new Uint8Array(data)
+                ).buffer;
             }
+            return utf8To16(
+                arraybufferToString(data)
+            );
         }
 
         /**
@@ -1191,19 +1169,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
         {
             let keyArray = stringToArraybuffer(key);
             if (password.length > 0) {
-                // version 1 pastes did append the passwords SHA-256 hash in hex
-                if (spec[7] === 'rawdeflate') {
-                    let passwordBuffer = await window.crypto.subtle.digest(
-                        {name: 'SHA-256'},
-                        stringToArraybuffer(
-                            utf16To8(password)
-                        )
-                    ).catch(Alert.showError);
-                    password = Array.prototype.map.call(
-                        new Uint8Array(passwordBuffer),
-                        x => ('00' + x.toString(16)).slice(-2)
-                    ).join('');
-                }
                 let passwordArray = stringToArraybuffer(password),
                     newKeyArray = new Uint8Array(keyArray.length + passwordArray.length);
                 newKeyArray.set(keyArray, 0);
@@ -1337,21 +1302,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
                 // clone the array instead of passing the reference
                 spec = (data[1][0] instanceof Array ? data[1][0] : data[1]).slice();
                 cipherMessage = data[0];
-            } else if (typeof data === 'string') {
-                // version 1
-                let object = JSON.parse(data);
-                adataString = atob(object.adata);
-                spec = [
-                    object.iv,
-                    object.salt,
-                    object.iter,
-                    object.ks,
-                    object.ts,
-                    object.cipher,
-                    object.mode,
-                    'rawdeflate'
-                ];
-                cipherMessage = object.ct;
             } else {
                 throw 'unsupported message format';
             }
@@ -6043,4 +5993,4 @@ jQuery.PrivateBin = (function($, RawDeflate) {
         CopyToClipboard: CopyToClipboard,
         Controller: Controller
     };
-})(jQuery, RawDeflate);
+})(jQuery);

+ 0 - 755
js/rawinflate-0.3.js

@@ -1,755 +0,0 @@
-/*
- * $Id: rawinflate.js,v 0.3 2013/04/09 14:25:38 dankogai Exp dankogai $
- *
- * GNU General Public License, version 2 (GPL-2.0)
- *   https://opensource.org/licenses/GPL-2.0
- * original:
- *   http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt
- */
-
-(function(ctx){
-
-/* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
- * Version: 1.0.0.1
- * LastModified: Dec 25 1999
- */
-
-/* Interface:
- * data = zip_inflate(src);
- */
-
-/* constant parameters */
-var zip_WSIZE = 32768;		// Sliding Window size
-var zip_STORED_BLOCK = 0;
-var zip_STATIC_TREES = 1;
-var zip_DYN_TREES    = 2;
-
-/* for inflate */
-var zip_lbits = 9; 		// bits in base literal/length lookup table
-var zip_dbits = 6; 		// bits in base distance lookup table
-var zip_INBUFSIZ = 32768;	// Input buffer size
-var zip_INBUF_EXTRA = 64;	// Extra buffer
-
-/* variables (inflate) */
-var zip_slide;
-var zip_wp;			// current position in slide
-var zip_fixed_tl = null;	// inflate static
-var zip_fixed_td;		// inflate static
-var zip_fixed_bl, fixed_bd;	// inflate static
-var zip_bit_buf;		// bit buffer
-var zip_bit_len;		// bits in bit buffer
-var zip_method;
-var zip_eof;
-var zip_copy_leng;
-var zip_copy_dist;
-var zip_tl, zip_td;	// literal/length and distance decoder tables
-var zip_bl, zip_bd;	// number of bits decoded by tl and td
-
-var zip_inflate_data;
-var zip_inflate_pos;
-
-
-/* constant tables (inflate) */
-var zip_MASK_BITS = new Array(
-    0x0000,
-    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
-    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff);
-// Tables for deflate from PKZIP's appnote.txt.
-var zip_cplens = new Array( // Copy lengths for literal codes 257..285
-    3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
-    35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0);
-/* note: see note #13 above about the 258 in this list. */
-var zip_cplext = new Array( // Extra bits for literal codes 257..285
-    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-    3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99); // 99==invalid
-var zip_cpdist = new Array( // Copy offsets for distance codes 0..29
-    1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
-    257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
-    8193, 12289, 16385, 24577);
-var zip_cpdext = new Array( // Extra bits for distance codes
-    0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
-    7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
-    12, 12, 13, 13);
-var zip_border = new Array(  // Order of the bit length code lengths
-    16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15);
-/* objects (inflate) */
-
-var zip_HuftList = function() {
-    this.next = null;
-    this.list = null;
-}
-
-var zip_HuftNode = function() {
-    this.e = 0; // number of extra bits or operation
-    this.b = 0; // number of bits in this code or subcode
-
-    // union
-    this.n = 0; // literal, length base, or distance base
-    this.t = null; // (zip_HuftNode) pointer to next level of table
-}
-
-var zip_HuftBuild = function(b,	// code lengths in bits (all assumed <= BMAX)
-		       n,	// number of codes (assumed <= N_MAX)
-		       s,	// number of simple-valued codes (0..s-1)
-		       d,	// list of base values for non-simple codes
-		       e,	// list of extra bits for non-simple codes
-		       mm	// maximum lookup bits
-		   ) {
-    this.BMAX = 16;   // maximum bit length of any code
-    this.N_MAX = 288; // maximum number of codes in any set
-    this.status = 0;	// 0: success, 1: incomplete table, 2: bad input
-    this.root = null;	// (zip_HuftList) starting table
-    this.m = 0;		// maximum lookup bits, returns actual
-
-/* Given a list of code lengths and a maximum table size, make a set of
-   tables to decode that set of codes.	Return zero on success, one if
-   the given code set is incomplete (the tables are still built in this
-   case), two if the input is invalid (all zero length codes or an
-   oversubscribed set of lengths), and three if not enough memory.
-   The code with value 256 is special, and the tables are constructed
-   so that no bits beyond that code are fetched when that code is
-   decoded. */
-    {
-	var a;			// counter for codes of length k
-	var c = new Array(this.BMAX+1);	// bit length count table
-	var el;			// length of EOB code (value 256)
-	var f;			// i repeats in table every f entries
-	var g;			// maximum code length
-	var h;			// table level
-	var i;			// counter, current code
-	var j;			// counter
-	var k;			// number of bits in current code
-	var lx = new Array(this.BMAX+1);	// stack of bits per table
-	var p;			// pointer into c[], b[], or v[]
-	var pidx;		// index of p
-	var q;			// (zip_HuftNode) points to current table
-	var r = new zip_HuftNode(); // table entry for structure assignment
-	var u = new Array(this.BMAX); // zip_HuftNode[BMAX][]  table stack
-	var v = new Array(this.N_MAX); // values in order of bit length
-	var w;
-	var x = new Array(this.BMAX+1);// bit offsets, then code stack
-	var xp;			// pointer into x or c
-	var y;			// number of dummy codes added
-	var z;			// number of entries in current table
-	var o;
-	var tail;		// (zip_HuftList)
-
-	tail = this.root = null;
-	for(i = 0; i < c.length; i++)
-	    c[i] = 0;
-	for(i = 0; i < lx.length; i++)
-	    lx[i] = 0;
-	for(i = 0; i < u.length; i++)
-	    u[i] = null;
-	for(i = 0; i < v.length; i++)
-	    v[i] = 0;
-	for(i = 0; i < x.length; i++)
-	    x[i] = 0;
-
-	// Generate counts for each bit length
-	el = n > 256 ? b[256] : this.BMAX; // set length of EOB code, if any
-	p = b; pidx = 0;
-	i = n;
-	do {
-	    c[p[pidx]]++;	// assume all entries <= BMAX
-	    pidx++;
-	} while(--i > 0);
-	if(c[0] == n) {	// null input--all zero length codes
-	    this.root = null;
-	    this.m = 0;
-	    this.status = 0;
-	    return;
-	}
-
-	// Find minimum and maximum length, bound *m by those
-	for(j = 1; j <= this.BMAX; j++)
-	    if(c[j] != 0)
-		break;
-	k = j;			// minimum code length
-	if(mm < j)
-	    mm = j;
-	for(i = this.BMAX; i != 0; i--)
-	    if(c[i] != 0)
-		break;
-	g = i;			// maximum code length
-	if(mm > i)
-	    mm = i;
-
-	// Adjust last length count to fill out codes, if needed
-	for(y = 1 << j; j < i; j++, y <<= 1)
-	    if((y -= c[j]) < 0) {
-		this.status = 2;	// bad input: more codes than bits
-		this.m = mm;
-		return;
-	    }
-	if((y -= c[i]) < 0) {
-	    this.status = 2;
-	    this.m = mm;
-	    return;
-	}
-	c[i] += y;
-
-	// Generate starting offsets into the value table for each length
-	x[1] = j = 0;
-	p = c;
-	pidx = 1;
-	xp = 2;
-	while(--i > 0)		// note that i == g from above
-	    x[xp++] = (j += p[pidx++]);
-
-	// Make a table of values in order of bit lengths
-	p = b; pidx = 0;
-	i = 0;
-	do {
-	    if((j = p[pidx++]) != 0)
-		v[x[j]++] = i;
-	} while(++i < n);
-	n = x[g];			// set n to length of v
-
-	// Generate the Huffman codes and for each, make the table entries
-	x[0] = i = 0;		// first Huffman code is zero
-	p = v; pidx = 0;		// grab values in bit order
-	h = -1;			// no tables yet--level -1
-	w = lx[0] = 0;		// no bits decoded yet
-	q = null;			// ditto
-	z = 0;			// ditto
-
-	// go through the bit lengths (k already is bits in shortest code)
-	for(; k <= g; k++) {
-	    a = c[k];
-	    while(a-- > 0) {
-		// here i is the Huffman code of length k bits for value p[pidx]
-		// make tables up to required level
-		while(k > w + lx[1 + h]) {
-		    w += lx[1 + h]; // add bits already decoded
-		    h++;
-
-		    // compute minimum size table less than or equal to *m bits
-		    z = (z = g - w) > mm ? mm : z; // upper limit
-		    if((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table
-			// too few codes for k-w bit table
-			f -= a + 1;	// deduct codes from patterns left
-			xp = k;
-			while(++j < z) { // try smaller tables up to z bits
-			    if((f <<= 1) <= c[++xp])
-				break;	// enough codes to use up j bits
-			    f -= c[xp];	// else deduct codes from patterns
-			}
-		    }
-		    if(w + j > el && w < el)
-			j = el - w;	// make EOB code end at table
-		    z = 1 << j;	// table entries for j-bit table
-		    lx[1 + h] = j; // set table size in stack
-
-		    // allocate and link in new table
-		    q = new Array(z);
-		    for(o = 0; o < z; o++) {
-			q[o] = new zip_HuftNode();
-		    }
-
-		    if(tail == null)
-			tail = this.root = new zip_HuftList();
-		    else
-			tail = tail.next = new zip_HuftList();
-		    tail.next = null;
-		    tail.list = q;
-		    u[h] = q;	// table starts after link
-
-		    /* connect to last table, if there is one */
-		    if(h > 0) {
-			x[h] = i;		// save pattern for backing up
-			r.b = lx[h];	// bits to dump before this table
-			r.e = 16 + j;	// bits in this table
-			r.t = q;		// pointer to this table
-			j = (i & ((1 << w) - 1)) >> (w - lx[h]);
-			u[h-1][j].e = r.e;
-			u[h-1][j].b = r.b;
-			u[h-1][j].n = r.n;
-			u[h-1][j].t = r.t;
-		    }
-		}
-
-		// set up table entry in r
-		r.b = k - w;
-		if(pidx >= n)
-		    r.e = 99;		// out of values--invalid code
-		else if(p[pidx] < s) {
-		    r.e = (p[pidx] < 256 ? 16 : 15); // 256 is end-of-block code
-		    r.n = p[pidx++];	// simple code is just the value
-		} else {
-		    r.e = e[p[pidx] - s];	// non-simple--look up in lists
-		    r.n = d[p[pidx++] - s];
-		}
-
-		// fill code-like entries with r //
-		f = 1 << (k - w);
-		for(j = i >> w; j < z; j += f) {
-		    q[j].e = r.e;
-		    q[j].b = r.b;
-		    q[j].n = r.n;
-		    q[j].t = r.t;
-		}
-
-		// backwards increment the k-bit code i
-		for(j = 1 << (k - 1); (i & j) != 0; j >>= 1)
-		    i ^= j;
-		i ^= j;
-
-		// backup over finished tables
-		while((i & ((1 << w) - 1)) != x[h]) {
-		    w -= lx[h];		// don't need to update q
-		    h--;
-		}
-	    }
-	}
-
-	/* return actual size of base table */
-	this.m = lx[1];
-
-	/* Return true (1) if we were given an incomplete table */
-	this.status = ((y != 0 && g != 1) ? 1 : 0);
-    } /* end of constructor */
-}
-
-
-/* routines (inflate) */
-
-var zip_GET_BYTE = function() {
-    if(zip_inflate_data.length == zip_inflate_pos)
-	return -1;
-    return zip_inflate_data.charCodeAt(zip_inflate_pos++) & 0xff;
-}
-
-var zip_NEEDBITS = function(n) {
-    while(zip_bit_len < n) {
-	zip_bit_buf |= zip_GET_BYTE() << zip_bit_len;
-	zip_bit_len += 8;
-    }
-}
-
-var zip_GETBITS = function(n) {
-    return zip_bit_buf & zip_MASK_BITS[n];
-}
-
-var zip_DUMPBITS = function(n) {
-    zip_bit_buf >>= n;
-    zip_bit_len -= n;
-}
-
-var zip_inflate_codes = function(buff, off, size) {
-    /* inflate (decompress) the codes in a deflated (compressed) block.
-       Return an error code or zero if it all goes ok. */
-    var e;		// table entry flag/number of extra bits
-    var t;		// (zip_HuftNode) pointer to table entry
-    var n;
-
-    if(size == 0)
-      return 0;
-
-    // inflate the coded data
-    n = 0;
-    for(;;) {			// do until end of block
-	zip_NEEDBITS(zip_bl);
-	t = zip_tl.list[zip_GETBITS(zip_bl)];
-	e = t.e;
-	while(e > 16) {
-	    if(e == 99)
-		return -1;
-	    zip_DUMPBITS(t.b);
-	    e -= 16;
-	    zip_NEEDBITS(e);
-	    t = t.t[zip_GETBITS(e)];
-	    e = t.e;
-	}
-	zip_DUMPBITS(t.b);
-
-	if(e == 16) {		// then it's a literal
-	    zip_wp &= zip_WSIZE - 1;
-	    buff[off + n++] = zip_slide[zip_wp++] = t.n;
-	    if(n == size)
-		return size;
-	    continue;
-	}
-
-	// exit if end of block
-	if(e == 15)
-	    break;
-
-	// it's an EOB or a length
-
-	// get length of block to copy
-	zip_NEEDBITS(e);
-	zip_copy_leng = t.n + zip_GETBITS(e);
-	zip_DUMPBITS(e);
-
-	// decode distance of block to copy
-	zip_NEEDBITS(zip_bd);
-	t = zip_td.list[zip_GETBITS(zip_bd)];
-	e = t.e;
-
-	while(e > 16) {
-	    if(e == 99)
-		return -1;
-	    zip_DUMPBITS(t.b);
-	    e -= 16;
-	    zip_NEEDBITS(e);
-	    t = t.t[zip_GETBITS(e)];
-	    e = t.e;
-	}
-	zip_DUMPBITS(t.b);
-	zip_NEEDBITS(e);
-	zip_copy_dist = zip_wp - t.n - zip_GETBITS(e);
-	zip_DUMPBITS(e);
-
-	// do the copy
-	while(zip_copy_leng > 0 && n < size) {
-	    zip_copy_leng--;
-	    zip_copy_dist &= zip_WSIZE - 1;
-	    zip_wp &= zip_WSIZE - 1;
-	    buff[off + n++] = zip_slide[zip_wp++]
-		= zip_slide[zip_copy_dist++];
-	}
-
-	if(n == size)
-	    return size;
-    }
-
-    zip_method = -1; // done
-    return n;
-}
-
-var zip_inflate_stored = function(buff, off, size) {
-    /* "decompress" an inflated type 0 (stored) block. */
-    var n;
-
-    // go to byte boundary
-    n = zip_bit_len & 7;
-    zip_DUMPBITS(n);
-
-    // get the length and its complement
-    zip_NEEDBITS(16);
-    n = zip_GETBITS(16);
-    zip_DUMPBITS(16);
-    zip_NEEDBITS(16);
-    if(n != ((~zip_bit_buf) & 0xffff))
-	return -1;			// error in compressed data
-    zip_DUMPBITS(16);
-
-    // read and output the compressed data
-    zip_copy_leng = n;
-
-    n = 0;
-    while(zip_copy_leng > 0 && n < size) {
-	zip_copy_leng--;
-	zip_wp &= zip_WSIZE - 1;
-	zip_NEEDBITS(8);
-	buff[off + n++] = zip_slide[zip_wp++] =
-	    zip_GETBITS(8);
-	zip_DUMPBITS(8);
-    }
-
-    if(zip_copy_leng == 0)
-      zip_method = -1; // done
-    return n;
-}
-
-var zip_inflate_fixed = function(buff, off, size) {
-    /* decompress an inflated type 1 (fixed Huffman codes) block.  We should
-       either replace this with a custom decoder, or at least precompute the
-       Huffman tables. */
-
-    // if first time, set up tables for fixed blocks
-    if(zip_fixed_tl == null) {
-	var i;			// temporary variable
-	var l = new Array(288);	// length list for huft_build
-	var h;	// zip_HuftBuild
-
-	// literal table
-	for(i = 0; i < 144; i++)
-	    l[i] = 8;
-	for(; i < 256; i++)
-	    l[i] = 9;
-	for(; i < 280; i++)
-	    l[i] = 7;
-	for(; i < 288; i++)	// make a complete, but wrong code set
-	    l[i] = 8;
-	zip_fixed_bl = 7;
-
-	h = new zip_HuftBuild(l, 288, 257, zip_cplens, zip_cplext,
-			      zip_fixed_bl);
-	if(h.status != 0) {
-	    alert("HufBuild error: "+h.status);
-	    return -1;
-	}
-	zip_fixed_tl = h.root;
-	zip_fixed_bl = h.m;
-
-	// distance table
-	for(i = 0; i < 30; i++)	// make an incomplete code set
-	    l[i] = 5;
-	zip_fixed_bd = 5;
-
-	h = new zip_HuftBuild(l, 30, 0, zip_cpdist, zip_cpdext, zip_fixed_bd);
-	if(h.status > 1) {
-	    zip_fixed_tl = null;
-	    alert("HufBuild error: "+h.status);
-	    return -1;
-	}
-	zip_fixed_td = h.root;
-	zip_fixed_bd = h.m;
-    }
-
-    zip_tl = zip_fixed_tl;
-    zip_td = zip_fixed_td;
-    zip_bl = zip_fixed_bl;
-    zip_bd = zip_fixed_bd;
-    return zip_inflate_codes(buff, off, size);
-}
-
-var zip_inflate_dynamic = function(buff, off, size) {
-    // decompress an inflated type 2 (dynamic Huffman codes) block.
-    var i;		// temporary variables
-    var j;
-    var l;		// last length
-    var n;		// number of lengths to get
-    var t;		// (zip_HuftNode) literal/length code table
-    var nb;		// number of bit length codes
-    var nl;		// number of literal/length codes
-    var nd;		// number of distance codes
-    var ll = new Array(286+30); // literal/length and distance code lengths
-    var h;		// (zip_HuftBuild)
-
-    for(i = 0; i < ll.length; i++)
-	ll[i] = 0;
-
-    // read in table lengths
-    zip_NEEDBITS(5);
-    nl = 257 + zip_GETBITS(5);	// number of literal/length codes
-    zip_DUMPBITS(5);
-    zip_NEEDBITS(5);
-    nd = 1 + zip_GETBITS(5);	// number of distance codes
-    zip_DUMPBITS(5);
-    zip_NEEDBITS(4);
-    nb = 4 + zip_GETBITS(4);	// number of bit length codes
-    zip_DUMPBITS(4);
-    if(nl > 286 || nd > 30)
-      return -1;		// bad lengths
-
-    // read in bit-length-code lengths
-    for(j = 0; j < nb; j++)
-    {
-	zip_NEEDBITS(3);
-	ll[zip_border[j]] = zip_GETBITS(3);
-	zip_DUMPBITS(3);
-    }
-    for(; j < 19; j++)
-	ll[zip_border[j]] = 0;
-
-    // build decoding table for trees--single level, 7 bit lookup
-    zip_bl = 7;
-    h = new zip_HuftBuild(ll, 19, 19, null, null, zip_bl);
-    if(h.status != 0)
-	return -1;	// incomplete code set
-
-    zip_tl = h.root;
-    zip_bl = h.m;
-
-    // read in literal and distance code lengths
-    n = nl + nd;
-    i = l = 0;
-    while(i < n) {
-	zip_NEEDBITS(zip_bl);
-	t = zip_tl.list[zip_GETBITS(zip_bl)];
-	j = t.b;
-	zip_DUMPBITS(j);
-	j = t.n;
-	if(j < 16)		// length of code in bits (0..15)
-	    ll[i++] = l = j;	// save last length in l
-	else if(j == 16) {	// repeat last length 3 to 6 times
-	    zip_NEEDBITS(2);
-	    j = 3 + zip_GETBITS(2);
-	    zip_DUMPBITS(2);
-	    if(i + j > n)
-		return -1;
-	    while(j-- > 0)
-		ll[i++] = l;
-	} else if(j == 17) {	// 3 to 10 zero length codes
-	    zip_NEEDBITS(3);
-	    j = 3 + zip_GETBITS(3);
-	    zip_DUMPBITS(3);
-	    if(i + j > n)
-		return -1;
-	    while(j-- > 0)
-		ll[i++] = 0;
-	    l = 0;
-	} else {		// j == 18: 11 to 138 zero length codes
-	    zip_NEEDBITS(7);
-	    j = 11 + zip_GETBITS(7);
-	    zip_DUMPBITS(7);
-	    if(i + j > n)
-		return -1;
-	    while(j-- > 0)
-		ll[i++] = 0;
-	    l = 0;
-	}
-    }
-
-    // build the decoding tables for literal/length and distance codes
-    zip_bl = zip_lbits;
-    h = new zip_HuftBuild(ll, nl, 257, zip_cplens, zip_cplext, zip_bl);
-    if(zip_bl == 0)	// no literals or lengths
-	h.status = 1;
-    if(h.status != 0) {
-	if(h.status == 1)
-	    ;// **incomplete literal tree**
-	return -1;		// incomplete code set
-    }
-    zip_tl = h.root;
-    zip_bl = h.m;
-
-    for(i = 0; i < nd; i++)
-	ll[i] = ll[i + nl];
-    zip_bd = zip_dbits;
-    h = new zip_HuftBuild(ll, nd, 0, zip_cpdist, zip_cpdext, zip_bd);
-    zip_td = h.root;
-    zip_bd = h.m;
-
-    if(zip_bd == 0 && nl > 257) {   // lengths but no distances
-	// **incomplete distance tree**
-	return -1;
-    }
-
-    if(h.status == 1) {
-	;// **incomplete distance tree**
-    }
-    if(h.status != 0)
-	return -1;
-
-    // decompress until an end-of-block code
-    return zip_inflate_codes(buff, off, size);
-}
-
-var zip_inflate_start = function() {
-    var i;
-
-    if(zip_slide == null)
-	zip_slide = new Array(2 * zip_WSIZE);
-    zip_wp = 0;
-    zip_bit_buf = 0;
-    zip_bit_len = 0;
-    zip_method = -1;
-    zip_eof = false;
-    zip_copy_leng = zip_copy_dist = 0;
-    zip_tl = null;
-}
-
-var zip_inflate_internal = function(buff, off, size) {
-    // decompress an inflated entry
-    var n, i;
-
-    n = 0;
-    while(n < size) {
-	if(zip_eof && zip_method == -1)
-	    return n;
-
-	if(zip_copy_leng > 0) {
-	    if(zip_method != zip_STORED_BLOCK) {
-		// STATIC_TREES or DYN_TREES
-		while(zip_copy_leng > 0 && n < size) {
-		    zip_copy_leng--;
-		    zip_copy_dist &= zip_WSIZE - 1;
-		    zip_wp &= zip_WSIZE - 1;
-		    buff[off + n++] = zip_slide[zip_wp++] =
-			zip_slide[zip_copy_dist++];
-		}
-	    } else {
-		while(zip_copy_leng > 0 && n < size) {
-		    zip_copy_leng--;
-		    zip_wp &= zip_WSIZE - 1;
-		    zip_NEEDBITS(8);
-		    buff[off + n++] = zip_slide[zip_wp++] = zip_GETBITS(8);
-		    zip_DUMPBITS(8);
-		}
-		if(zip_copy_leng == 0)
-		    zip_method = -1; // done
-	    }
-	    if(n == size)
-		return n;
-	}
-
-	if(zip_method == -1) {
-	    if(zip_eof)
-		break;
-
-	    // read in last block bit
-	    zip_NEEDBITS(1);
-	    if(zip_GETBITS(1) != 0)
-		zip_eof = true;
-	    zip_DUMPBITS(1);
-
-	    // read in block type
-	    zip_NEEDBITS(2);
-	    zip_method = zip_GETBITS(2);
-	    zip_DUMPBITS(2);
-	    zip_tl = null;
-	    zip_copy_leng = 0;
-	}
-
-	switch(zip_method) {
-	  case 0: // zip_STORED_BLOCK
-	    i = zip_inflate_stored(buff, off + n, size - n);
-	    break;
-
-	  case 1: // zip_STATIC_TREES
-	    if(zip_tl != null)
-		i = zip_inflate_codes(buff, off + n, size - n);
-	    else
-		i = zip_inflate_fixed(buff, off + n, size - n);
-	    break;
-
-	  case 2: // zip_DYN_TREES
-	    if(zip_tl != null)
-		i = zip_inflate_codes(buff, off + n, size - n);
-	    else
-		i = zip_inflate_dynamic(buff, off + n, size - n);
-	    break;
-
-	  default: // error
-	    i = -1;
-	    break;
-	}
-
-	if(i == -1) {
-	    if(zip_eof)
-		return 0;
-	    return -1;
-	}
-	n += i;
-    }
-    return n;
-}
-
-var zip_inflate = function(str) {
-    var i, j;
-
-    zip_inflate_start();
-    zip_inflate_data = str;
-    zip_inflate_pos = 0;
-
-    var buff = new Array(1024);
-    var aout = [];
-    while((i = zip_inflate_internal(buff, 0, buff.length)) > 0) {
-	var cbuf = new Array(i);
-	for(j = 0; j < i; j++){
-	    cbuf[j] = String.fromCharCode(buff[j]);
-	}
-	aout[aout.length] = cbuf.join("");
-    }
-    zip_inflate_data = null; // G.C.
-    return aout.join("");
-}
-
-if (! ctx.RawDeflate) ctx.RawDeflate = {};
-ctx.RawDeflate.inflate = zip_inflate;
-
-})(this);

+ 0 - 185
js/test/CryptTool.js

@@ -40,191 +40,6 @@ describe('CryptTool', function () {
             {tests: 3});
         });
 
-        // The below static unit tests are included to ensure deciphering of "classic"
-        // SJCL based pastes still works
-        it(
-            'supports PrivateBin v1 ciphertext with password (SJCL & browser atob)',
-            async function () {
-                delete global.Base64;
-                const clean = jsdom();
-                Object.defineProperty(window, 'crypto', {
-                    value: new WebCrypto(),
-                    writeable: false,
-                });
-                global.atob = common.atob;
-
-                // Of course you can easily decipher the following texts, if you like.
-                // Bonus points for finding their sources and hidden meanings.
-                const paste = await $.PrivateBin.CryptTool.decipher(
-                    '6t2qsmLyfXIokNCL+3/yl15rfTUBQvm5SOnFPvNE7Q8=',
-                    // -- "That's amazing. I've got the same combination on my luggage."
-                    Array.apply(0, Array(6)).map((_,b) => b + 1).join(''),
-                    '{"iv":"4HNFIl7eYbCh6HuShctTIA==","v":1,"iter":10000,"ks"' +
-                    ':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
-                    'lt":"u0lQvePq6L0=","ct":"fGPUVrDyaVr1ZDGb+kqQ3CPEW8x4YKG' +
-                    'fzHDmA0Vjkh250aWNe7Cnigkps9aaFVMX9AaerrTp3yZbojJtNqVGMfL' +
-                    'dUTu+53xmZHqRKxCCqSfDNSNoW4Oxk5OVgAtRyuG4bXHDsWTXDNz2xce' +
-                    'qzVFqhkwTwlUchrV7uuFK/XUKTNjPFM744moivIcBbfM2FOeKlIFs8RY' +
-                    'PYuvqQhp2rMLlNGwwKh//4kykQsHMQDeSDuJl8stMQzgWR/btUBZuwNZ' +
-                    'EydkMH6IPpTdf5WTSrZ+wC2OK0GutCm4UaEe6txzaTMfu+WRVu4PN6q+' +
-                    'N+2zljWJ1XdpVcN/i0Sv4QVMym0Xa6y0eccEhj/69o47PmExmMMeEwEx' +
-                    'ImPalMNT9JUSiZdOZJ/GdzwrwoIuq1mdQR6vSH+XJ/8jXJQ7bjjJVJYX' +
-                    'TcT0Di5jixArI2Kpp1GGlGVFbLgPugwU1wczg+byqeDOAECXRRnQcoge' +
-                    'aJtVcRwXwfy4j3ORFcblYMilxyHqKBewcYPRVBGtBs50cVjSIkAfR84r' +
-                    'nc1nfvnxK/Gmm+4VBNHI6ODWNpRolVMCzXjbKYnV3Are5AgSpsTqaGl4' +
-                    '1VJGpcco6cAwi4K0Bys1seKR+bLSdUgqRrkEqSRSdu3/VTu9HhEk8an0' +
-                    'rjTE4CBB5/LMn16p0TGLoOb32odKFIEtpanVvLjeyiVMvSxcgYLNnTi/' +
-                    '5FiaAC4pJxRD+AZHedU1FICUeEXxIcac/4E5qjkHjX9SpQtLl80QLIVn' +
-                    'jNliZm7QLB/nKu7W8Jb0+/CiTdV3Q9LhxlH4ciprnX+W0B00BKYFHnL9' +
-                    'jRVzKdXhf1EHydbXMAfpCjHAXIVCkFakJinQBDIIw/SC6Yig0u0ddEID' +
-                    '2B7LYAP1iE4RZwzTrxCB+ke2jQr8c20Jj6u6ShFOPC9DCw9XupZ4HAal' +
-                    'VG00kSgjus+b8zrVji3/LKEhb4EBzp1ctBJCFTeXwej8ZETLoXTylev5' +
-                    'dlwZSYAbuBPPcbFR/xAIPx3uDabd1E1gTqUc68ICIGhd197Mb2eRWiSv' +
-                    'Hr5SPsASerMxId6XA6+iQlRiI+NDR+TGVNmCnfxSlyPFMOHGTmslXOGI' +
-                    'qGfBR8l4ft8YVZ70lCwmwTuViGc75ULSf9mM57/LmRzQFMYQtvI8IFK9' +
-                    'JaQEMY5xz0HLtR4iyQUUdwR9e0ytBNdWF2a2WPDEnJuY/QJo4GzTlgv4' +
-                    'QUxMXI5htsn2rf0HxCFu7Po8DNYLxTS+67hYjDIYWYaEIc8LXWMLyDm9' +
-                    'C5fARPJ4F2BIWgzgzkNj+dVjusft2XnziamWdbS5u3kuRlVuz5LQj+R5' +
-                    'imnqQAincdZTkTT1nYx+DatlOLllCYIHffpI="}'
-                );
-                clean();
-                const result = typeof paste === 'string' && paste.includes('securely packed in iron');
-                if (!result) console.log(paste);
-                assert.ok(result);
-            }
-        );
-
-        it(
-            'supports PrivateBin v1 ciphertext no password (SJCL & browser atob)',
-            async function () {
-                delete global.Base64;
-                const clean = jsdom();
-                // ensure zlib is getting loaded
-                $.PrivateBin.Controller.initZ();
-                Object.defineProperty(window, 'crypto', {
-                    value: new WebCrypto(),
-                    writeable: false,
-                });
-                global.atob = common.atob;
-
-                // Of course you can easily decipher the following texts, if you like.
-                // Bonus points for finding their sources and hidden meanings.
-                const paste = await $.PrivateBin.CryptTool.decipher(
-                    's9pmKZKOBN7EVvHpTA8jjLFH3Xlz/0l8lB4+ONPACrM=',
-                    '', // no password
-                    '{"iv":"WA42mdxIVXUwBqZu7JYNiw==","v":1,"iter":10000,"ks"' +
-                    ':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
-                    'lt":"jN6CjbQMJCM=","ct":"kYYMo5DFG1+w0UHiYXT5pdV0IUuXxzO' +
-                    'lslkW/c3DRCbGFROCVkAskHce7HoRczee1N9c5MhHjVMJUIZE02qIS8U' +
-                    'yHdJ/GqcPVidTUcj9rnDNWsTXkjVv8jCwHS/cwmAjDTWpwp5ThECN+ov' +
-                    '/wNp/NdtTj8Qj7f/T3rfZIOCWfwLH9s4Des35UNcUidfPTNQ1l0Gm0X+' +
-                    'r98CCUSYZjQxkZc6hRZBLPQ8EaNVooUwd5eP4GiYlmSDNA0wOSA+5isP' +
-                    'YxomVCt+kFf58VBlNhpfNi7BLYAUTPpXT4SfH5drR9+C7NTeZ+tTCYjb' +
-                    'U94PzYItOpu8vgnB1/a6BAM5h3m9w+giUb0df4hgTWeZnZxLjo5BN8WV' +
-                    '+kdTXMj3/Vv0gw0DQrDcCuX/cBAjpy3lQGwlAN1vXoOIyZJUjMpQRrOL' +
-                    'dKvLB+zcmVNtGDbgnfP2IYBzk9NtodpUa27ne0T0ZpwOPlVwevsIVZO2' +
-                    '24WLa+iQmmHOWDFFpVDlS0t0fLfOk7Hcb2xFsTxiCIiyKMho/IME1Du3' +
-                    'X4e6BVa3hobSSZv0rRtNgY1KcyYPrUPW2fxZ+oik3y9SgGvb7XpjVIta' +
-                    '8DWlDWRfZ9kzoweWEYqz9IA8Xd373RefpyuWI25zlHoX3nwljzsZU6dC' +
-                    '//h/Dt2DNr+IAvKO3+u23cWoB9kgcZJ2FJuqjLvVfCF+OWcig7zs2pTY' +
-                    'JW6Rg6lqbBCxiUUlae6xJrjfv0pzD2VYCLY7v1bVTagppwKzNI3WaluC' +
-                    'OrdDYUCxUSe56yd1oAoLPRVbYvomRboUO6cjQhEknERyvt45og2kORJO' +
-                    'EJayHW+jZgR0Y0jM3Nk17ubpij2gHxNx9kiLDOiCGSV5mn9mV7qd3HHc' +
-                    'OMSykiBgbyzjobi96LT2dIGLeDXTIdPOog8wyobO4jWq0GGs0vBB8oSY' +
-                    'XhHvixZLcSjX2KQuHmEoWzmJcr3DavdoXZmAurGWLKjzEdJc5dSD/eNr' +
-                    '99gjHX7wphJ6umKMM+fn6PcbYJkhDh2GlJL5COXjXfm/5aj/vuyaRRWZ' +
-                    'MZtmnYpGAtAPg7AUG"}'
-                );
-                clean();
-                const result = typeof paste === 'string' && paste.includes('Sol is right');
-                if (!result) console.log(paste);
-                assert.ok(result);
-            }
-        );
-
-        it(
-            'supports ZeroBin ciphertext with password (SJCL & Base64 1.7)',
-            async function () {
-                global.Base64 = require('../base64-1.7').Base64;
-                const clean = jsdom();
-                Object.defineProperty(window, 'crypto', {
-                    value: new WebCrypto(),
-                    writeable: false,
-                });
-                global.atob = common.atob;
-
-                // Of course you can easily decipher the following texts, if you like.
-                // Bonus points for finding their sources and hidden meanings.
-                const paste = await $.PrivateBin.CryptTool.decipher(
-                    '6t2qsmLyfXIokNCL+3/yl15rfTUBQvm5SOnFPvNE7Q8=',
-                    // -- "That's amazing. I've got the same combination on my luggage."
-                    Array.apply(0, Array(6)).map((_,b) => b + 1).join(''),
-                    '{"iv":"aTnR2qBL1CAmLX8FdWe3VA==","v":1,"iter":10000,"ks"' +
-                    ':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
-                    'lt":"u0lQvePq6L0=","ct":"A3nBTvICZtYy6xqbIJE0c8Veored5lM' +
-                    'JUGgGUm4581wjrPFlU0Q0tUZSf+RUUoZj2jqDa4kiyyZ5YNMe30hNMV0' +
-                    'oVSalNhRgD9svVMnPuF162IbyhVCwr7ULjT981CHxVlGNqGqmIU6L/Xi' +
-                    'xgdArxAA8x1GCrfAkBWWGeq8Qw5vJPG/RCHpwR4Wy3azrluqeyERBzma' +
-                    'OQjO/kM35TiI6IrLYFyYyL7upYlxAaxS0XBMZvN8QU8Lnerwvh5JVC6O' +
-                    'kkKrhogajTJIKozCF79yI78c50LUh7tTuI3Yoh7+fXxhoODvQdYFmoiU' +
-                    'lrutN7Y5ZMRdITvVu8fTYtX9c7Fiufmcq5icEimiHp2g1bvfpOaGOsFT' +
-                    '+XNFgC9215jcp5mpBdN852xs7bUtw+nDrf+LsDEX6iRpRZ+PYgLDN5xQ' +
-                    'T1ByEtYbeP+tO38pnx72oZdIB3cj8UkOxnxdNiZM5YB5egn4jUj1fHot' +
-                    '1I69WoTiUJipZ5PIATv7ScymRB+AYzjxjurQ9lVfX9QtAbEH2dhdmoUo' +
-                    '3IDRSXpWNCe9RC1aUIyWfZO7oI7FEohNscHNTLEcT+wFnFUPByLlXmjN' +
-                    'Z7FKeNpvUm3jTY4t4sbZH8o2dUl624PAw1INcJ6FKqWGWwoFT2j1MYC+' +
-                    'YV/LkLTdjuWfayvwLMh27G/FfKCRbW36vqinegqpPDylsx9+3oFkEw3y' +
-                    '5Z8+44oN91rE/4Md7JhPJeRVlFC9TNCj4dA+EVhbbQqscvSnIH2uHkMw' +
-                    '7mNNo7xba/YT9KoPDaniqnYqb+q2pX1WNWE7dLS2wfroMAS3kh8P22DA' +
-                    'V37AeiNoD2PcI6ZcHbRdPa+XRrRcJhSPPW7UQ0z4OvBfjdu/w390QxAx' +
-                    'SxvZewoh49fKKB6hTsRnZb4tpHkjlww=="}'
-                );
-                clean();
-                delete global.Base64;
-                const result = typeof paste === 'string' && paste.includes('securely packed in iron');
-                if (!result) console.log(paste);
-                assert.ok(result);
-            }
-        );
-
-        it(
-            'supports ZeroBin ciphertext no password (SJCL & Base64 1.7)',
-            async function () {
-                global.Base64 = require('../base64-1.7').Base64;
-                const clean = jsdom();
-                Object.defineProperty(window, 'crypto', {
-                    value: new WebCrypto(),
-                    writeable: false,
-                });
-                global.atob = common.atob;
-
-                const paste = await $.PrivateBin.CryptTool.decipher(
-                    's9pmKZKOBN7EVvHpTA8jjLFH3Xlz/0l8lB4+ONPACrM=',
-                    '', // no password
-                    '{"iv":"Z7lAZQbkrqGMvruxoSm6Pw==","v":1,"iter":10000,"ks"' +
-                    ':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
-                    'lt":"jN6CjbQMJCM=","ct":"PuOPWB3i2FPcreSrLYeQf84LdE8RHjs' +
-                    'c+MGtiOr4b7doNyWKYtkNorbRadxaPnEee2/Utrp1MIIfY5juJSy8RGw' +
-                    'EPX5ciWcYe6EzsXWznsnvhmpKNj9B7eIIrfSbxfy8E2e/g7xav1nive+' +
-                    'ljToka3WT1DZ8ILQd/NbnJeHWaoSEOfvz8+d8QJPb1tNZvs7zEY95Dum' +
-                    'QwbyOsIMKAvcZHJ9OJNpujXzdMyt6DpcFcqlldWBZ/8q5rAUTw0HNx/r' +
-                    'CgbhAxRYfNoTLIcMM4L0cXbPSgCjwf5FuO3EdE13mgEDhcClW79m0Qvc' +
-                    'nIh8xgzYoxLbp0+AwvC/MbZM8savN/0ieWr2EKkZ04ggiOIEyvfCUuNp' +
-                    'rQBYO+y8kKduNEN6by0Yf4LRCPfmwN+GezDLuzTnZIMhPbGqUAdgV6Ex' +
-                    'qK2ULEEIrQEMoOuQIxfoMhqLlzG79vXGt2O+BY+4IiYfvmuRLks4UXfy' +
-                    'HqxPXTJg48IYbGs0j4TtJPUgp3523EyYLwEGyVTAuWhYAmVIwd/hoV7d' +
-                    '7tmfcF73w9dufDFI3LNca2KxzBnWNPYvIZKBwWbq8ncxkb191dP6mjEi' +
-                    '7NnhqVk5A6vIBbu4AC5PZf76l6yep4xsoy/QtdDxCMocCXeAML9MQ9uP' +
-                    'QbuspOKrBvMfN5igA1kBqasnxI472KBNXsdZnaDddSVUuvhTcETM="}'
-                );
-                clean();
-                delete global.Base64;
-                const result = typeof paste === 'string' && paste.includes('Sol is right');
-                if (!result) console.log(paste);
-                assert.ok(result);
-            }
-        );
-
         it('does not truncate messages', async function () {
             const message = fs.readFileSync('test/compression-sample.txt', 'ascii').trim(),
                 clean = jsdom();

+ 1 - 4
lib/Configuration.php

@@ -65,7 +65,6 @@ class Configuration
             'email'                    => true,
             'icon'                     => 'identicon',
             'cspheader'                => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'wasm-unsafe-eval\'; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; frame-src blob:; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-modals allow-downloads',
-            'zerobincompatibility'     => false,
             'httpwarning'              => true,
             'compression'              => 'zlib',
         ),
@@ -110,7 +109,6 @@ class Configuration
         // update this array when adding/changing/removing js files
         'sri' => array(
             'js/base-x-4.0.0.js'     => 'sha512-nNPg5IGCwwrveZ8cA/yMGr5HiRS5Ps2H+s0J/mKTPjCPWUgFGGw7M5nqdnPD3VsRwCVysUh3Y8OWjeSKGkEQJQ==',
-            'js/base64-1.7.js'       => 'sha512-JdwsSP3GyHR+jaCkns9CL9NTt4JUJqm/BsODGmYhBcj5EAPKcHYh+OiMfyHbcDLECe17TL0hjXADFkusAqiYgA==',
             'js/bootstrap-3.4.1.js'  => 'sha512-oBTprMeNEKCnqfuqKd6sbvFzmFQtlXS3e0C/RGFV0hD6QzhHV+ODfaQbAlmY6/q0ubbwlAM/nCJjkrgA3waLzg==',
             'js/bootstrap-5.3.3.js'  => 'sha512-in2rcOpLTdJ7/pw5qjF4LWHFRtgoBDxXCy49H4YGOcVdGiPaQucGIbOqxt1JvmpvOpq3J/C7VTa0FlioakB2gQ==',
             'js/dark-mode-switch.js' => 'sha512-BhY7dNU14aDN5L+muoUmA66x0CkYUWkQT0nxhKBLP/o2d7jE025+dvWJa4OiYffBGEFgmhrD/Sp+QMkxGMTz2g==',
@@ -118,9 +116,8 @@ class Configuration
             'js/kjua-0.9.0.js'       => 'sha512-CVn7af+vTMBd9RjoS4QM5fpLFEOtBCoB0zPtaqIDC7sF4F8qgUSRFQQpIyEDGsr6yrjbuOLzdf20tkHHmpaqwQ==',
             'js/legacy.js'           => 'sha512-UxW/TOZKon83n6dk/09GsYKIyeO5LeBHokxyIq+r7KFS5KMBeIB/EM7NrkVYIezwZBaovnyNtY2d9tKFicRlXg==',
             'js/prettify.js'         => 'sha512-puO0Ogy++IoA2Pb9IjSxV1n4+kQkKXYAEUtVzfZpQepyDPyXk8hokiYDS7ybMogYlyyEIwMLpZqVhCkARQWLMg==',
-            'js/privatebin.js'       => 'sha512-9X1Ns+w/WPlWde118Mbl1UFDPsFmBcXK2zr6ny7oDOuZMVP1hFCPzXjKbC+59xDQW0Q+NmyT4NC6/5B6UzkkDw==',
+            'js/privatebin.js'       => 'sha512-wQci0zYb+eGsbQaLWunZ7sMoT7+3w5SUfvBJ3JactOOO2WytQGt/q6wRdWZsCkZjCE6hxkEBOxlfSqLHluh3KQ==',
             'js/purify-3.2.6.js'     => 'sha512-zqwL4OoBLFx89QPewkz4Lz5CSA2ktU+f31fuECkF0iK3Id5qd3Zpq5dMby8KwHjIEpsUgOqwF58cnmcaNem0EA==',
-            'js/rawinflate-0.3.js'   => 'sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==',
             'js/showdown-2.1.0.js'   => 'sha512-WYXZgkTR0u/Y9SVIA4nTTOih0kXMEd8RRV6MLFdL6YU8ymhR528NLlYQt1nlJQbYz4EW+ZsS0fx1awhiQJme1Q==',
             'js/zlib-1.3.1-1.js'     => 'sha512-5bU9IIP4PgBrOKLZvGWJD4kgfQrkTz8Z3Iqeu058mbQzW3mCumOU6M3UVbVZU9rrVoVwaW4cZK8U8h5xjF88eQ==',
         ),

+ 0 - 1
lib/Controller.php

@@ -473,7 +473,6 @@ class Controller
         $page->assign('BURNAFTERREADINGSELECTED', $this->_conf->getKey('burnafterreadingselected'));
         $page->assign('PASSWORD', $this->_conf->getKey('password'));
         $page->assign('FILEUPLOAD', $this->_conf->getKey('fileupload'));
-        $page->assign('ZEROBINCOMPATIBILITY', $this->_conf->getKey('zerobincompatibility'));
         $page->assign('LANGUAGESELECTION', $languageselection);
         $page->assign('LANGUAGES', I18n::getLanguageLabels(I18n::getAvailableLanguages()));
         $page->assign('TEMPLATESELECTION', $templateselection);

+ 1 - 5
lib/Model/Paste.php

@@ -190,11 +190,7 @@ class Paste extends AbstractModel
         if (!array_key_exists('salt', $this->_data['meta'])) {
             $this->get();
         }
-        return hash_hmac(
-            $this->_conf->getKey('zerobincompatibility') ? 'sha1' : 'sha256',
-            $this->getId(),
-            $this->_data['meta']['salt']
-        );
+        return hash_hmac('sha256', $this->getId(), $this->_data['meta']['salt']);
     }
 
     /**

+ 0 - 6
tpl/bootstrap.php

@@ -49,15 +49,9 @@ if ($QRCODE) :
 		<?php $this->_scriptTag('js/kjua-0.9.0.js', 'async'); ?>
 <?php
 endif;
-if ($ZEROBINCOMPATIBILITY) :
-?>
-		<?php $this->_scriptTag('js/base64-1.7.js', 'async'); ?>
-<?php
-endif;
 ?>
 		<?php $this->_scriptTag('js/zlib-1.3.1-1.js', 'async'); ?>
 		<?php $this->_scriptTag('js/base-x-4.0.0.js', 'defer'); ?>
-		<?php $this->_scriptTag('js/rawinflate-0.3.js', 'defer'); ?>
 		<?php $this->_scriptTag('js/bootstrap-3.4.1.js', 'defer'); ?>
 <?php
 if ($SYNTAXHIGHLIGHTING) :

+ 0 - 6
tpl/bootstrap5.php

@@ -32,15 +32,9 @@ if ($QRCODE) :
 		<?php $this->_scriptTag('js/kjua-0.9.0.js', 'async'); ?>
 <?php
 endif;
-if ($ZEROBINCOMPATIBILITY) :
-?>
-		<?php $this->_scriptTag('js/base64-1.7.js', 'defer'); ?>
-<?php
-endif;
 ?>
 		<?php $this->_scriptTag('js/zlib-1.3.1-1.js', 'defer'); ?>
 		<?php $this->_scriptTag('js/base-x-4.0.0.js', 'defer'); ?>
-		<?php $this->_scriptTag('js/rawinflate-0.3.js', 'defer'); ?>
 		<?php $this->_scriptTag('js/bootstrap-5.3.3.js', 'async'); ?>
 		<?php $this->_scriptTag('js/dark-mode-switch.js', 'defer'); ?>
 <?php

+ 0 - 1
tst/ViewTest.php

@@ -52,7 +52,6 @@ class ViewTest extends TestCase
         $page->assign('BURNAFTERREADINGSELECTED', false);
         $page->assign('PASSWORD', true);
         $page->assign('FILEUPLOAD', false);
-        $page->assign('ZEROBINCOMPATIBILITY', false);
         $page->assign('INFO', 'example');
         $page->assign('NOTICE', 'example');
         $page->assign('LANGUAGESELECTION', '');