toolkit/identity/tests/unit/test_jwcrypto.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* Any copyright is dedicated to the Public Domain.
     2    http://creativecommons.org/publicdomain/zero/1.0/ */
     4 "use strict"
     6 Cu.import('resource://gre/modules/identity/LogUtils.jsm');
     8 XPCOMUtils.defineLazyModuleGetter(this, "IDService",
     9                                   "resource://gre/modules/identity/Identity.jsm",
    10                                   "IdentityService");
    12 XPCOMUtils.defineLazyModuleGetter(this, "jwcrypto",
    13                                   "resource://gre/modules/identity/jwcrypto.jsm");
    15 XPCOMUtils.defineLazyServiceGetter(this,
    16                                    "CryptoService",
    17                                    "@mozilla.org/identity/crypto-service;1",
    18                                    "nsIIdentityCryptoService");
    20 const RP_ORIGIN = "http://123done.org";
    21 const INTERNAL_ORIGIN = "browserid://";
    23 const SECOND_MS = 1000;
    24 const MINUTE_MS = SECOND_MS * 60;
    25 const HOUR_MS = MINUTE_MS * 60;
    27 function test_sanity() {
    28   do_test_pending();
    30   jwcrypto.generateKeyPair("DS160", function(err, kp) {
    31     do_check_null(err);
    33     do_test_finished();
    34     run_next_test();
    35   });
    36 }
    38 function test_generate() {
    39   do_test_pending();
    40   jwcrypto.generateKeyPair("DS160", function(err, kp) {
    41     do_check_null(err);
    42     do_check_neq(kp, null);
    44     do_test_finished();
    45     run_next_test();
    46   });
    47 }
    49 function test_get_assertion() {
    50   do_test_pending();
    52   jwcrypto.generateKeyPair(
    53     "DS160",
    54     function(err, kp) {
    55       jwcrypto.generateAssertion("fake-cert", kp, RP_ORIGIN, (err, backedAssertion) => {
    56         do_check_null(err);
    58         do_check_eq(backedAssertion.split("~").length, 2);
    59         do_check_eq(backedAssertion.split(".").length, 3);
    61         do_test_finished();
    62         run_next_test();
    63       });
    64     });
    65 }
    67 function test_rsa() {
    68   do_test_pending();
    69   function checkRSA(err, kpo) {
    70     do_check_neq(kpo, undefined);
    71     log(kpo.serializedPublicKey);
    72     let pk = JSON.parse(kpo.serializedPublicKey);
    73     do_check_eq(pk.algorithm, "RS");
    74 /* TODO
    75     do_check_neq(kpo.sign, null);
    76     do_check_eq(typeof kpo.sign, "function");
    77     do_check_neq(kpo.userID, null);
    78     do_check_neq(kpo.url, null);
    79     do_check_eq(kpo.url, INTERNAL_ORIGIN);
    80     do_check_neq(kpo.exponent, null);
    81     do_check_neq(kpo.modulus, null);
    83     // TODO: should sign be async?
    84     let sig = kpo.sign("This is a message to sign");
    86     do_check_neq(sig, null);
    87     do_check_eq(typeof sig, "string");
    88     do_check_true(sig.length > 1);
    89 */
    90     do_test_finished();
    91     run_next_test();
    92   };
    94   jwcrypto.generateKeyPair("RS256", checkRSA);
    95 }
    97 function test_dsa() {
    98   do_test_pending();
    99   function checkDSA(err, kpo) {
   100     do_check_neq(kpo, undefined);
   101     log(kpo.serializedPublicKey);
   102     let pk = JSON.parse(kpo.serializedPublicKey);
   103     do_check_eq(pk.algorithm, "DS");
   104 /* TODO
   105     do_check_neq(kpo.sign, null);
   106     do_check_eq(typeof kpo.sign, "function");
   107     do_check_neq(kpo.userID, null);
   108     do_check_neq(kpo.url, null);
   109     do_check_eq(kpo.url, INTERNAL_ORIGIN);
   110     do_check_neq(kpo.generator, null);
   111     do_check_neq(kpo.prime, null);
   112     do_check_neq(kpo.subPrime, null);
   113     do_check_neq(kpo.publicValue, null);
   115     let sig = kpo.sign("This is a message to sign");
   117     do_check_neq(sig, null);
   118     do_check_eq(typeof sig, "string");
   119     do_check_true(sig.length > 1);
   120 */
   121     do_test_finished();
   122     run_next_test();
   123   };
   125   jwcrypto.generateKeyPair("DS160", checkDSA);
   126 }
   128 function test_get_assertion_with_offset() {
   129   do_test_pending();
   132   // Use an arbitrary date in the past to ensure we don't accidentally pass
   133   // this test with current dates, missing offsets, etc.
   134   let serverMsec = Date.parse("Tue Oct 31 2000 00:00:00 GMT-0800");
   136   // local clock skew
   137   // clock is 12 hours fast; -12 hours offset must be applied
   138   let localtimeOffsetMsec = -1 * 12 * HOUR_MS;
   139   let localMsec = serverMsec - localtimeOffsetMsec;
   141   jwcrypto.generateKeyPair(
   142     "DS160",
   143     function(err, kp) {
   144       jwcrypto.generateAssertion("fake-cert", kp, RP_ORIGIN,
   145         { duration: MINUTE_MS,
   146           localtimeOffsetMsec: localtimeOffsetMsec,
   147           now: localMsec},
   148           function(err, backedAssertion) {
   149             do_check_null(err);
   151             // properly formed
   152             let cert;
   153             let assertion;
   154             [cert, assertion] = backedAssertion.split("~");
   156             do_check_eq(cert, "fake-cert");
   157             do_check_eq(assertion.split(".").length, 3);
   159             let components = extractComponents(assertion);
   161             // Expiry is within two minutes, corrected for skew
   162             let exp = parseInt(components.payload.exp, 10);
   163             do_check_true(exp - serverMsec === MINUTE_MS);
   165             do_test_finished();
   166             run_next_test();
   167           }
   168       );
   169     }
   170   );
   171 }
   173 function test_assertion_lifetime() {
   174   do_test_pending();
   176   jwcrypto.generateKeyPair(
   177     "DS160",
   178     function(err, kp) {
   179       jwcrypto.generateAssertion("fake-cert", kp, RP_ORIGIN,
   180         {duration: MINUTE_MS},
   181         function(err, backedAssertion) {
   182           do_check_null(err);
   184           // properly formed
   185           let cert;
   186           let assertion;
   187           [cert, assertion] = backedAssertion.split("~");
   189           do_check_eq(cert, "fake-cert");
   190           do_check_eq(assertion.split(".").length, 3);
   192           let components = extractComponents(assertion);
   194           // Expiry is within one minute, as we specified above
   195           let exp = parseInt(components.payload.exp, 10);
   196           do_check_true(Math.abs(Date.now() - exp) > 50 * SECOND_MS);
   197           do_check_true(Math.abs(Date.now() - exp) <= MINUTE_MS);
   199           do_test_finished();
   200           run_next_test();
   201         }
   202       );
   203     }
   204   );
   205 }
   207 function test_audience_encoding_bug972582() {
   208   let audience = "i-like-pie.com";
   210   jwcrypto.generateKeyPair(
   211     "DS160",
   212     function(err, kp) {
   213       do_check_null(err);
   214       jwcrypto.generateAssertion("fake-cert", kp, audience,
   215         function(err, backedAssertion) {
   216           do_check_null(err);
   218           let [cert, assertion] = backedAssertion.split("~");
   219           let components = extractComponents(assertion);
   220           do_check_eq(components.payload.aud, audience);
   222           do_test_finished();
   223           run_next_test();
   224         }
   225       );
   226     }
   227   );
   228 }
   230 // End of tests
   231 // Helper function follow
   233 function extractComponents(signedObject) {
   234   if (typeof(signedObject) != 'string') {
   235     throw new Error("malformed signature " + typeof(signedObject));
   236   }
   238   let parts = signedObject.split(".");
   239   if (parts.length != 3) {
   240     throw new Error("signed object must have three parts, this one has " + parts.length);
   241   }
   243   let headerSegment = parts[0];
   244   let payloadSegment = parts[1];
   245   let cryptoSegment = parts[2];
   247   let header = JSON.parse(base64UrlDecode(headerSegment));
   248   let payload = JSON.parse(base64UrlDecode(payloadSegment));
   250   // Ensure well-formed header
   251   do_check_eq(Object.keys(header).length, 1);
   252   do_check_true(!!header.alg);
   254   // Ensure well-formed payload
   255   for (let field of ["exp", "aud"]) {
   256     do_check_true(!!payload[field]);
   257   }
   259   return {header: header,
   260           payload: payload,
   261           headerSegment: headerSegment,
   262           payloadSegment: payloadSegment,
   263           cryptoSegment: cryptoSegment};
   264 };
   266 let TESTS = [
   267   test_sanity,
   268   test_generate,
   269   test_get_assertion,
   270   test_get_assertion_with_offset,
   271   test_assertion_lifetime,
   272   test_audience_encoding_bug972582,
   273 ];
   275 TESTS = TESTS.concat([test_rsa, test_dsa]);
   277 TESTS.forEach(add_test);
   279 function run_test() {
   280   run_next_test();
   281 }

mercurial