dom/tests/mochitest/crypto/test_getRandomValues.html

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 <!DOCTYPE HTML>
     2 <html><head>
     3   <title>Test window.crypto.getRandomValues</title>
     4   <script type="text/javascript" src="/MochiKit/packed.js"></script>
     5   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
     6   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
     7 </head>
     8 <body onload="onWindowLoad()">
     9 <script class="testbody" type="text/javascript">
    10 SimpleTest.waitForExplicitFinish();
    12 var testData = [ { len: 32, type: "Int8", pass: true },
    13                  { len: 32, type: "Int16", pass: true },
    14                  { len: 32, type: "Int32", pass: true },
    15                  { len: 32, type: "Uint8", pass: true },
    16                  { len: 32, type: "Uint16", pass: true },
    17                  { len: 32, type: "Uint32", pass: true },
    18                  { len: 65536, type: "Uint8", pass: true },
    19                  { len: 32, type: "Uint8Clamped", pass: true },
    20                  { len: 65537, type: "Uint8", pass: false },
    21                  { len: 32, type: "Float32", pass: false },
    22                  { len: 32, type: "Float64", pass: false } ];
    25 var testCount = 0;
    27 function testNsCryptoGetRandomValues(aLength, aType)
    28 {
    29   var arrayTypes = {
    30     Int8:         Int8Array,
    31     Int16:        Int16Array,
    32     Int32:        Int32Array,
    33     Uint8:        Uint8Array,
    34     Uint16:       Uint16Array,
    35     Uint32:       Uint32Array,
    36     Float32:      Float32Array,
    37     Float64:      Float64Array,
    38     Uint8Clamped: Uint8ClampedArray,
    39   };
    41   testCount++;
    43   var buf = new ArrayBuffer(aLength);
    44   var arBuf = new arrayTypes[aType](buf);
    46   var pass = false;
    47   var b = window.crypto.getRandomValues(arBuf);
    48   ok(b === arBuf, "ArrayBuffer result is argument buffer");
    50   for (var i = 0; i < arBuf.length; i++) {
    51     if (arBuf.length > 6) {
    52       // XXXddahl: THIS MIGHT FAIL EVERY FULL MOON, SORRY QA!!!
    53       if (arBuf[i] != 0) {
    54         pass = true;
    55         break;
    56       }
    57     } 
    58     else {
    59       pass = true;
    60     }
    61   }
    62   is(pass, true,  "Non-zero result: " + i  +  " found in the  " + aType + ": " + aLength + " ArrayBufferView");
    63 }
    65 function onWindowLoad()
    66 {
    67   window.removeEventListener("load", onWindowLoad, false);
    68   var failedWithCorrectError = false;
    69   try {
    70     for (var i = 0; i < testData.length; i++) {
    71       if (testData[i].pass) {
    72         try {
    73           testNsCryptoGetRandomValues(testData[i].len, testData[i].type, testData[i].pass);
    74         } 
    75         catch (ex) {
    76           ok(false, "testNsCryptoGetRandomValues failed, test should have passed: " + testData[i].type);
    77         }
    78       }
    79       else {
    80         // failing tests are dealt with here
    81         if (i == 8) {
    82           try {
    83             testNsCryptoGetRandomValues(testData[i].len, testData[i].type, testData[i].pass);
    84           }
    85           catch (ex) {
    86             todo("QuotaExceededError" in window && ex instanceof QuotaExceededError,
    87                  "Exception was the correct type");
    88             failedWithCorrectError = ex.toString().search(/QUOTA_EXCEEDED_ERR/);
    89             ok(failedWithCorrectError, "Extended length array buffer fails, NS_ERROR_DOM_QUOTA_EXCEEDED_ERR thrown");
    90           }
    91         } // 8
    93         if (i == 9) {
    94           try {
    95             testNsCryptoGetRandomValues(testData[i].len, testData[i].type, testData[i].pass);
    96           }
    97           catch (ex) {
    98             failedWithCorrectError = ex.toString().search(/TYPE_MISMATCH_ERR/);
    99             ok(failedWithCorrectError,
   100                "Expected TYPE_MISMATCH_ERR: Float32Array is not valid, got " + ex + ".");
   101           }
   102         } // 9
   104         if (i == 10) {
   105           try {
   106             testNsCryptoGetRandomValues(testData[i].len, testData[i].type, testData[i].pass);
   107           }
   108           catch (ex) {
   109             failedWithCorrectError = ex.toString().search(/TYPE_MISMATCH_ERR/);
   110             ok(failedWithCorrectError,
   111                "Expected TYPE_MISMATCH_ERR: Float64Array is not valid, got " + ex + ".");
   112           }
   113         }
   114       }
   115     } // end main for loop
   116   }
   117   catch (ex) {
   118     ok(false, "Unexpected Error: " + ex);
   119   }
   120   // Count the tests in the testData array
   121   ok(testCount == 11, "11 tests run via testData");
   123   // Test a null argument
   124   try {
   125     window.crypto.getRandomValues(null);
   126   }
   127   catch (ex) {
   128     var test = ex.toString().search(/1003|TypeError/);
   129     ok((test > -1), "Expected TYPE_ERR, got " + ex + ".");
   130   }
   132   // Test a zero-length buffer view
   133   try {
   134     var a = new Int8Array(0);
   135     window.crypto.getRandomValues(a);
   136     ok(a[0] === undefined, "The array buffer is unchanged, still 0 length");
   137   }
   138   catch (ex) {
   139     ok(false, "A zero-length array buffer view should not fail");
   140   }
   142   // Test a one-length buffer view
   143   var randomVal = 0;
   144   // The probability of getRandomValues generating a zero value is 1/256 so we
   145   // run this in a loop until it returns a non-zero value to guard against
   146   // false failures
   147   do {
   148     try {
   149       var a = new Uint8Array(1);
   150       var b = window.crypto.getRandomValues(a);
   151       randomVal = a[0];
   152       ok(a === b, "ArrayBuffer result is argument buffer");
   153     }
   154     catch (ex) {
   155       ok(false, "A one-length array buffer view should not fail");
   156     }
   157   }
   158   while (randomVal == 0);
   159   ok(randomVal !== 0, "The array buffer eventually had one random value");
   161   // Test a 16 byte length buffer
   162   var testConfig = { len: 16, type: "Int8", pass: true };
   163   testNsCryptoGetRandomValues(testConfig.len,
   164                               testConfig.type,
   165                               testConfig.pass);
   167   // Test a 31 byte length buffer
   168   testConfig = { len: 31, type: "Int8", pass: true };
   169   testNsCryptoGetRandomValues(testConfig.len,
   170                               testConfig.type,
   171                               testConfig.pass);
   173   // Test a 33 byte length buffer
   174   testConfig = { len: 33, type: "Int8", pass: true };
   175   testNsCryptoGetRandomValues(testConfig.len,
   176                               testConfig.type,
   177                               testConfig.pass);
   179   // Test a range of an array buffer view
   180   var buffer = new ArrayBuffer(32);
   181   var view = new Int8Array(buffer, 0, 16);
   182   var view2 = new Int8Array(buffer, 16, 16);
   183   for (var i = 0; i < view2.byteLength; i++) {
   184     view2[i] = 1;
   185   }
   186   var b = window.crypto.getRandomValues(view);
   187   ok(b === view, "ArrayBuffer result is argument buffer");
   188   for (var i = 0; i < view.byteLength; i++) {
   189     is(view2[i], 1, "view2 is unchanged");
   190   }
   192   // test an offset view
   193   var result = false;
   194   var b = window.crypto.getRandomValues(view2);
   195   for (var i = 0; i < view2.length; i++) {
   196     if (view2[i] != 1) {
   197       result = true;
   198       break;
   199     }
   200   }
   201   ok(result, "view2 has been updated correctly");
   202   ok(b === view2, "ArrayBuffer result is argument buffer");
   203   // test the return value
   204   buffer = new ArrayBuffer(32);
   205   view = new Int8Array(buffer, 0, 16);
   206   var retval = window.crypto.getRandomValues(view);
   207   ok(view === retval, "The view and return value are the same");
   209   SimpleTest.finish();
   210 }
   211 </script>
   212 </body></html>

mercurial