Explorar el Código

switching to client side libraries for key generation, remove legacy browser support

El RIDO hace 8 años
padre
commit
6f25d651b7
Se han modificado 17 ficheros con 68 adiciones y 147 borrados
  1. 1 3
      i18n/de.json
  2. 1 3
      i18n/es.json
  3. 1 3
      i18n/fr.json
  4. 1 3
      i18n/hu.json
  5. 1 3
      i18n/it.json
  6. 1 3
      i18n/nl.json
  7. 1 3
      i18n/no.json
  8. 1 3
      i18n/oc.json
  9. 1 3
      i18n/pl.json
  10. 1 3
      i18n/pt.json
  11. 1 3
      i18n/ru.json
  12. 0 2
      i18n/sl.json
  13. 0 2
      i18n/zh.json
  14. 48 90
      js/privatebin.js
  15. 7 18
      js/test/CryptTool.js
  16. 1 1
      tpl/bootstrap.php
  17. 1 1
      tpl/page.php

+ 1 - 3
i18n/de.json

@@ -112,8 +112,6 @@
         "Fehler auf dem Server oder keine Antwort vom Server",
     "Could not post comment: %s":
         "Konnte Kommentar nicht senden: %s",
-    "Please move your mouse for more entropy…":
-        "Bitte bewege Deine Maus um die Entropie zu erhöhen…",
     "Sending paste…":
         "Sende Paste…",
     "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
@@ -156,4 +154,4 @@
     "+++ no paste text +++": "+++ kein Paste-Text +++",
     "Could not get paste data: %s":
         "Konnte Paste nicht laden: %s"
-}
+}

+ 1 - 3
i18n/es.json

@@ -112,8 +112,6 @@
         "Error del servidor o el servidor no responde",
     "Could not post comment: %s":
         "No fue posible publicar comentario: %s",
-    "Please move your mouse for more entropy…":
-        "Por favor, mueva el ratón para mayor entropía…",
     "Sending paste…":
         "Enviando texto…",
     "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
@@ -156,4 +154,4 @@
     "+++ no paste text +++": "+++ sin texto +++",
     "Could not get paste data: %s":
         "Could not get paste data: %s"
-}
+}

+ 1 - 3
i18n/fr.json

@@ -112,8 +112,6 @@
         "Le serveur ne répond pas ou a rencontré une erreur",
     "Could not post comment: %s":
         "Impossible de poster le commentaire : %s",
-    "Please move your mouse for more entropy…":
-        "Merci de bouger votre souris pour plus d'entropie…",
     "Sending paste…":
         "Envoi du paste…",
     "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
@@ -165,4 +163,4 @@
     "+++ no paste text +++": "+++ pas de paste-text +++",
     "Could not get paste data: %s":
         "Could not get paste data: %s"
-}
+}

+ 1 - 3
i18n/hu.json

@@ -112,8 +112,6 @@
         "A szerveren hiba lépett fel vagy nem válaszol.",
     "Could not post comment: %s":
         "Nem tudtuk beküldeni a hozzászólást: %s",
-    "Please move your mouse for more entropy…":
-        "Nincs elég véletlenszerűség a rendszerben. Mozgasd az egered, hogy növeld az entrópiát.",
     "Sending paste…":
         "Bejegyzés elküldése...",
     "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
@@ -156,4 +154,4 @@
     "+++ no paste text +++": "+++ nincs beillesztett szöveg +++",
     "Could not get paste data: %s":
         "Could not get paste data: %s"
-}
+}

+ 1 - 3
i18n/it.json

@@ -112,8 +112,6 @@
         "errore o mancata risposta dal server",
     "Could not post comment: %s":
         "Impossibile inviare il commento: %s",
-    "Please move your mouse for more entropy…":
-        "Muovi il mouse in modo casuale, per generare maggior entropia…",
     "Sending paste…":
         "Messaggio in fase di invio…",
     "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
@@ -156,4 +154,4 @@
     "+++ no paste text +++": "+++ nessun testo nel messaggio +++",
     "Could not get paste data: %s":
         "Could not get paste data: %s"
-}
+}

+ 1 - 3
i18n/nl.json

@@ -112,8 +112,6 @@
         "Serverfout of server reageert niet",
     "Could not post comment: %s":
         "Kon het commentaar niet plaatsen: %s",
-    "Please move your mouse for more entropy…":
-        "Aub uw muis bewegen voor meer entropie…",
      "Sending paste…":
         "Geplakte tekst verzenden…",
     "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
@@ -156,4 +154,4 @@
     "+++ no paste text +++": "+++ geen geplakte tekst +++",
     "Could not get paste data: %s":
         "Could not get paste data: %s"
-}
+}

+ 1 - 3
i18n/no.json

@@ -112,8 +112,6 @@
         "tjener feilet eller svarer ikke",
     "Could not post comment: %s":
         "Kunne ikke sende kommentar: %s",
-    "Please move your mouse for more entropy…":
-        "Flytt musen for mer entropi…",
     "Sending paste…":
         "Sender innlegg…",
     "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
@@ -156,4 +154,4 @@
     "+++ no paste text +++": "+++ ingen innleggstekst +++",
     "Could not get paste data: %s":
         "Could not get paste data: %s"
-}
+}

+ 1 - 3
i18n/oc.json

@@ -112,8 +112,6 @@
         "Lo servidor respond pas o a rencontrat una error",
     "Could not post comment: %s":
         "Impossible de mandar lo comentari : %s",
-    "Please move your mouse for more entropy…":
-        "Mercés de bolegar vòstra mirga per mai entropia…",
     "Sending paste…":
         "Mandadís del tèxte…",
     "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
@@ -165,4 +163,4 @@
     "+++ no paste text +++": "+++ cap de tèxte pegat +++",
     "Could not get paste data: %s":
         "Could not get paste data: %s"
-}
+}

+ 1 - 3
i18n/pl.json

@@ -112,8 +112,6 @@
         "bląd serwera lub brak odpowiedzi",
     "Could not post comment: %s":
         "Nie udało się wysłać komentarza: %s",
-    "Please move your mouse for more entropy…":
-        "Proszę poruszać myszą aby uzyskać większą entropię…",
     "Sending paste…":
         "Wysyłanie wklejki…",
     "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
@@ -156,4 +154,4 @@
     "+++ no paste text +++": "+++ no paste text +++",
     "Could not get paste data: %s":
         "Could not get paste data: %s"
-}
+}

+ 1 - 3
i18n/pt.json

@@ -112,8 +112,6 @@
         "Servidor em erro ou não responsivo",
     "Could not post comment: %s":
         "Não foi possível publicar o comentário: %s",
-    "Please move your mouse for more entropy…":
-        "Por favor, mova o mouse para maior entropia…",
     "Sending paste…":
         "Enviando cópia…",
     "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
@@ -156,4 +154,4 @@
     "+++ no paste text +++": "+++ sem texto de cópia +++",
     "Could not get paste data: %s":
         "Could not get paste data: %s"
-}
+}

+ 1 - 3
i18n/ru.json

@@ -112,8 +112,6 @@
         "ошибка сервера или нет ответа",
     "Could not post comment: %s":
         "Не удалось опубликовать комментарий: %s",
-    "Please move your mouse for more entropy…":
-        "Пожалуйста двигайте мышкой для большей энтропии…",
     "Sending paste…":
         "Отправка записи…",
     "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":
@@ -166,4 +164,4 @@
     "+++ no paste text +++": "+++ в записи нет текста +++",
     "Could not get paste data: %s":
         "Could not get paste data: %s"
-}
+}

+ 0 - 2
i18n/sl.json

@@ -112,8 +112,6 @@
         "napaka na strežniku, ali pa se strežnik ne odziva",
     "Could not post comment: %s":
         "Komentarja ni bilo mogoče objaviti : %s",
-    "Please move your mouse for more entropy…":
-        "Prosim premakni svojo miško za več entropije…",
     "Sending paste…":
         "Pošiljam prilepek…",
     "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":

+ 0 - 2
i18n/zh.json

@@ -112,8 +112,6 @@
         "服务器错误或无回应",
     "Could not post comment: %s":
         "无法发送评论: %s",
-    "Please move your mouse for more entropy…":
-        "请移动鼠标增加随机性…",
     "Sending paste…":
         "粘贴提交中…",
     "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>":

+ 48 - 90
js/privatebin.js

@@ -23,11 +23,6 @@
 /** global: sjcl */
 /** global: kjua */
 
-// Immediately start random number generator collector.
-sjcl.random.startCollectors();
-// Setting this to 10 ensures 1024 bits of entropy get collected before generating the paste key
-sjcl.random.setDefaultParanoia(10);
-
 // main application start, called when DOM is fully loaded
 jQuery(document).ready(function() {
     'use strict';
@@ -257,7 +252,7 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
             // check whether a bot user agent part can be found in the current
             // user agent
             var arrayLength = BadBotUA.length;
-            for (var i = 0; i < arrayLength; i++) {
+            for (var i = 0; i < arrayLength; ++i) {
                 if (navigator.userAgent.indexOf(BadBotUA) >= 0) {
                     return true;
                 }
@@ -609,40 +604,40 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
             }
         };
 
-        /**
-         * checks whether the crypt tool has collected enough entropy
-         *
-         * @name   CryptTool.isEntropyReady
-         * @function
-         * @return {bool}
-         */
-        me.isEntropyReady = function()
-        {
-            return sjcl.random.isReady();
-        };
-
-        /**
-         * add a listener function, triggered when enough entropy is available
-         *
-         * @name   CryptTool.addEntropySeedListener
-         * @function
-         * @param {function} func
-         */
-        me.addEntropySeedListener = function(func)
-        {
-            sjcl.random.addEventListener('seeded', func);
-        };
-
         /**
          * returns a random symmetric key
          *
+         * generates 256 bit long keys (8 Bits * 32) for AES with 256 bit long blocks
+         *
          * @name   CryptTool.getSymmetricKey
          * @function
-         * @return {string} func
+         * @throws {string}
+         * @return {string} base64 encoded key
          */
         me.getSymmetricKey = function()
         {
-            return sjcl.codec.base64.fromBits(sjcl.random.randomWords(8, 10), 0);
+            var crypto, key;
+            if (typeof module !== 'undefined' && module.exports) {
+                // node environment
+                key = require('crypto').randomBytes(32).toString('base64');
+            } else if (
+                typeof window !== 'undefined' &&
+                typeof Uint8Array !== 'undefined' &&
+                String.fromCodePoint &&
+                (crypto = window.crypto || window.msCrypto)
+            ) {
+                // modern browser environment
+                var bytes = '', byteArray = new Uint8Array(32);
+                crypto.getRandomValues(byteArray);
+                for (var i = 0; i < 32; ++i) {
+                    bytes += String.fromCharCode(byteArray[i]);
+                }
+                key = btoa(bytes);
+            } else {
+                // legacy browser or unsupported environment
+                throw 'No supported crypto API detected, you may read pastes and post comments, but can\'t create pastes.';
+            }
+            return key;
         };
 
         return me;
@@ -2028,13 +2023,13 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
                     // extract mediaType
                     var mediaType = attachmentData.substring(5, mediaTypeEnd);
                     // extract data and convert to binary
-                    var decodedData = Base64.atob(attachmentData.substring(base64Start));
+                    var decodedData = atob(attachmentData.substring(base64Start));
 
                     // Transform into a Blob
                     var decodedDataLength = decodedData.length;
                     var buf = new Uint8Array(decodedDataLength);
 
-                    for (var i = 0; i < decodedDataLength; i++) {
+                    for (var i = 0; i < decodedDataLength; ++i) {
                         buf[i] = decodedData.charCodeAt(i);
                     }
 
@@ -2373,16 +2368,13 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
         function addClipboardEventHandler() {
             $(document).on('paste', function (event) {
                 var items = (event.clipboardData || event.originalEvent.clipboardData).items;
-                for (var i in items) {
-                    if (items.hasOwnProperty(i)) {
-                        var item = items[i];
-                        if (item.kind === 'file') {
-                            //Clear the file input:
-                            $fileInput.wrap('<form>').closest('form').get(0).reset();
-                            $fileInput.unwrap();
-
-                            readFileData(item.getAsFile());
-                        }
+                for (var i = 0; i < items.length; ++i) {
+                    if (items[i].kind === 'file') {
+                        //Clear the file input:
+                        $fileInput.wrap('<form>').closest('form').get(0).reset();
+                        $fileInput.unwrap();
+
+                        readFileData(items[i].getAsFile());
                     }
                 }
             });
@@ -2890,7 +2882,7 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
             var $head = $('head').children().not('noscript, script, link[type="text/css"]');
             var newDoc = document.open('text/html', 'replace');
             newDoc.write('<!DOCTYPE html><html><head>');
-            for (var i = 0; i < $head.length; i++) {
+            for (var i = 0; i < $head.length; ++i) {
                 newDoc.write($head[i].outerHTML);
             }
             newDoc.write('</head><body><pre>' + DOMPurify.sanitize(paste) + '</pre></body></html>');
@@ -3405,7 +3397,7 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
                     symmetricKey = CryptTool.getSymmetricKey();
                     break;
                 default:
-                    console.error('current invalid symmetricKey:', symmetricKey);
+                    console.error('current invalid symmetricKey: ', symmetricKey);
                     throw 'symmetricKey is invalid, probably the module was not prepared';
             }
             // password is optional
@@ -3658,34 +3650,6 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
 
         var requirementsChecked = false;
 
-        /**
-         * checks whether there is a suitable amount of entrophy
-         *
-         * @name PasteEncrypter.checkRequirements
-         * @private
-         * @function
-         * @param {function} retryCallback - the callback to execute to retry the upload
-         * @return {bool}
-         */
-        function checkRequirements(retryCallback) {
-            // skip double requirement checks
-            if (requirementsChecked === true) {
-                return true;
-            }
-
-            if (!CryptTool.isEntropyReady()) {
-                // display a message and wait
-                Alert.showStatus('Please move your mouse for more entropy…');
-
-                CryptTool.addEntropySeedListener(retryCallback);
-                return false;
-            }
-
-            requirementsChecked = true;
-
-            return true;
-        }
-
         /**
          * called after successful paste upload
          *
@@ -3801,13 +3765,6 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
                 return;
             }
 
-            // check entropy
-            if (!checkRequirements(function () {
-                me.sendComment();
-            })) {
-                return; // to prevent multiple executions
-            }
-
             // prepare Uploader
             Uploader.prepare();
             Uploader.setCryptParameters(Prompt.getPassword(), Model.getPasteKey());
@@ -3839,7 +3796,11 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
             }
 
             // encrypt data
-            Uploader.setData('data', plainText);
+            try {
+                Uploader.setData('data', plainText);
+            } catch (e) {
+                Alert.showError(e);
+            }
 
             if (nickname.length > 0) {
                 Uploader.setData('nickname', nickname);
@@ -3878,13 +3839,6 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
                 return;
             }
 
-            // check entropy
-            if (!checkRequirements(function () {
-                me.sendPaste();
-            })) {
-                return; // to prevent multiple executions
-            }
-
             // prepare Uploader
             Uploader.prepare();
             Uploader.setCryptParameters(TopNav.getPassword());
@@ -3915,7 +3869,11 @@ jQuery.PrivateBin = (function($, sjcl, Base64, RawDeflate) {
             PasteViewer.setFormat(format);
 
             // encrypt cipher data
-            Uploader.setData('data', plainText);
+            try {
+                Uploader.setData('data', plainText);
+            } catch (e) {
+                Alert.showError(e);
+            }
 
             // encrypt attachments
             encryptAttachments(

+ 7 - 18
js/test/CryptTool.js

@@ -161,28 +161,14 @@ describe('CryptTool', function () {
         );
     });
 
-    describe('isEntropyReady & addEntropySeedListener', function () {
-        it(
-            'lets us know that enough entropy is collected or make us wait for it',
-            function(done) {
-                if ($.PrivateBin.CryptTool.isEntropyReady()) {
-                    done();
-                } else {
-                    $.PrivateBin.CryptTool.addEntropySeedListener(function() {
-                        done();
-                    });
-                }
-            }
-        );
-    });
-
     describe('getSymmetricKey', function () {
         var keys = [];
 
         // the parameter is used to ensure the test is run more then one time
         jsc.property(
             'returns random, non-empty keys',
-            function() {
+            'integer',
+            function(counter) {
                 var key = $.PrivateBin.CryptTool.getSymmetricKey(),
                     result = (key !== '' && keys.indexOf(key) === -1);
                 keys.push(key);
@@ -198,8 +184,11 @@ describe('CryptTool', function () {
             function(string) {
                 var base64 = Base64.toBase64(string),
                     sjcl = global.sjcl.codec.base64.fromBits(global.sjcl.codec.utf8String.toBits(string)),
-                    abab = window.btoa(Base64.utob(string));
-                return base64 === sjcl && sjcl === abab;
+                    abab = window.btoa(Base64.utob(string)),
+                    esab46 = Base64.fromBase64(sjcl),
+                    lcjs = global.sjcl.codec.utf8String.fromBits(global.sjcl.codec.base64.toBits(abab)),
+                    baba = Base64.btou(window.atob(base64));
+                return base64 === sjcl && sjcl === abab && string === esab46 && esab46 === lcjs && lcjs === baba;
             }
         );
     });

+ 1 - 1
tpl/bootstrap.php

@@ -75,7 +75,7 @@ if ($MARKDOWN):
 <?php
 endif;
 ?>
-		<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-o5ooD/VR75PQ2XkiYR0Pnyl1pjRRaeReJM7l1dUuEKXqlkP9Uv8bTR5QfbxiD0eCT2Vsm1SpjgPNhTdwr7zaQg==" crossorigin="anonymous"></script>
+		<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-vTDM48hkMcvb74F78/Fm9JoOF932zswXunyRUPhdpWQtcl5DzLc5gibjSFUNs+ouQiuI+qp6tIdEiTjqy/vqig==" crossorigin="anonymous"></script>
 		<!--[if lt IE 10]>
 		<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
 		<![endif]-->

+ 1 - 1
tpl/page.php

@@ -53,7 +53,7 @@ if ($MARKDOWN):
 <?php
 endif;
 ?>
-		<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-o5ooD/VR75PQ2XkiYR0Pnyl1pjRRaeReJM7l1dUuEKXqlkP9Uv8bTR5QfbxiD0eCT2Vsm1SpjgPNhTdwr7zaQg==" crossorigin="anonymous"></script>
+		<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-vTDM48hkMcvb74F78/Fm9JoOF932zswXunyRUPhdpWQtcl5DzLc5gibjSFUNs+ouQiuI+qp6tIdEiTjqy/vqig==" crossorigin="anonymous"></script>
 		<!--[if lt IE 10]>
 		<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
 		<![endif]-->