toolkit/identity/tests/unit/test_crypto_service.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/identity/tests/unit/test_crypto_service.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,122 @@
     1.4 +/* Any copyright is dedicated to the Public Domain.
     1.5 +   http://creativecommons.org/publicdomain/zero/1.0/ */
     1.6 +
     1.7 +"use strict";
     1.8 +
     1.9 +Cu.import("resource://gre/modules/Services.jsm");
    1.10 +Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    1.11 +Cu.import('resource://gre/modules/identity/LogUtils.jsm');
    1.12 +
    1.13 +const idService = Cc["@mozilla.org/identity/crypto-service;1"]
    1.14 +                    .getService(Ci.nsIIdentityCryptoService);
    1.15 +
    1.16 +const ALG_DSA = "DS160";
    1.17 +const ALG_RSA = "RS256";
    1.18 +
    1.19 +const BASE64_URL_ENCODINGS = [
    1.20 +  // The vectors from RFC 4648 are very silly, but we may as well include them.
    1.21 +  ["", ""],
    1.22 +  ["f", "Zg=="],
    1.23 +  ["fo", "Zm8="],
    1.24 +  ["foo", "Zm9v"],
    1.25 +  ["foob", "Zm9vYg=="],
    1.26 +  ["fooba", "Zm9vYmE="],
    1.27 +  ["foobar", "Zm9vYmFy"],
    1.28 +
    1.29 +  // It's quite likely you could get a string like this in an assertion audience
    1.30 +  ["i-like-pie.com", "aS1saWtlLXBpZS5jb20="],
    1.31 +
    1.32 +  // A few extra to be really sure
    1.33 +  ["andré@example.com", "YW5kcsOpQGV4YW1wbGUuY29t"],
    1.34 +  ["πόλλ' οἶδ' ἀλώπηξ, ἀλλ' ἐχῖνος ἓν μέγα",
    1.35 +   "z4DPjM67zrsnIM6_4by2zrQnIOG8gM67z47PgM63zr4sIOG8gM67zrsnIOG8kM-H4b-Wzr3Ov8-CIOG8k869IM68zq3Os86x"],
    1.36 +];
    1.37 +
    1.38 +// When the output of an operation is a
    1.39 +function do_check_eq_or_slightly_less(x, y) {
    1.40 +  do_check_true(x >= y - (3 * 8));
    1.41 +}
    1.42 +
    1.43 +function test_base64_roundtrip() {
    1.44 +  let message = "Attack at dawn!";
    1.45 +  let encoded = idService.base64UrlEncode(message);
    1.46 +  let decoded = base64UrlDecode(encoded);
    1.47 +  do_check_neq(message, encoded);
    1.48 +  do_check_eq(decoded, message);
    1.49 +  run_next_test();
    1.50 +}
    1.51 +
    1.52 +function test_dsa() {
    1.53 +  idService.generateKeyPair(ALG_DSA, function (rv, keyPair) {
    1.54 +    log("DSA generateKeyPair finished ", rv);
    1.55 +    do_check_true(Components.isSuccessCode(rv));
    1.56 +    do_check_eq(typeof keyPair.sign, "function");
    1.57 +    do_check_eq(keyPair.keyType, ALG_DSA);
    1.58 +    do_check_eq_or_slightly_less(keyPair.hexDSAGenerator.length, 1024 / 8 * 2);
    1.59 +    do_check_eq_or_slightly_less(keyPair.hexDSAPrime.length, 1024 / 8 * 2);
    1.60 +    do_check_eq_or_slightly_less(keyPair.hexDSASubPrime.length, 160 / 8 * 2);
    1.61 +    do_check_eq_or_slightly_less(keyPair.hexDSAPublicValue.length, 1024 / 8 * 2);
    1.62 +    // XXX: test that RSA parameters throw the correct error
    1.63 +
    1.64 +    log("about to sign with DSA key");
    1.65 +    keyPair.sign("foo", function (rv, signature) {
    1.66 +      log("DSA sign finished ", rv, signature);
    1.67 +      do_check_true(Components.isSuccessCode(rv));
    1.68 +      do_check_true(signature.length > 1);
    1.69 +      // TODO: verify the signature with the public key
    1.70 +      run_next_test();
    1.71 +    });
    1.72 +  });
    1.73 +}
    1.74 +
    1.75 +function test_rsa() {
    1.76 +  idService.generateKeyPair(ALG_RSA, function (rv, keyPair) {
    1.77 +    log("RSA generateKeyPair finished ", rv);
    1.78 +    do_check_true(Components.isSuccessCode(rv));
    1.79 +    do_check_eq(typeof keyPair.sign, "function");
    1.80 +    do_check_eq(keyPair.keyType, ALG_RSA);
    1.81 +    do_check_eq_or_slightly_less(keyPair.hexRSAPublicKeyModulus.length,
    1.82 +                                 2048 / 8);
    1.83 +    do_check_true(keyPair.hexRSAPublicKeyExponent.length > 1);
    1.84 +
    1.85 +    log("about to sign with RSA key");
    1.86 +    keyPair.sign("foo", function (rv, signature) {
    1.87 +      log("RSA sign finished ", rv, signature);
    1.88 +      do_check_true(Components.isSuccessCode(rv));
    1.89 +      do_check_true(signature.length > 1);
    1.90 +      run_next_test();
    1.91 +    });
    1.92 +  });
    1.93 +}
    1.94 +
    1.95 +function test_base64UrlEncode() {
    1.96 +  for (let [source, target] of BASE64_URL_ENCODINGS) {
    1.97 +    do_check_eq(target, idService.base64UrlEncode(source));
    1.98 +  }
    1.99 +  run_next_test();
   1.100 +}
   1.101 +
   1.102 +function test_base64UrlDecode() {
   1.103 +  let utf8Converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
   1.104 +                        .createInstance(Ci.nsIScriptableUnicodeConverter);
   1.105 +  utf8Converter.charset = "UTF-8";
   1.106 +
   1.107 +  // We know the encoding of our inputs - on conversion back out again, make
   1.108 +  // sure they're the same.
   1.109 +  for (let [source, target] of BASE64_URL_ENCODINGS) {
   1.110 +    let result = utf8Converter.ConvertToUnicode(base64UrlDecode(target));
   1.111 +    result += utf8Converter.Finish();
   1.112 +    do_check_eq(source, result);
   1.113 +  }
   1.114 +  run_next_test();
   1.115 +}
   1.116 +
   1.117 +add_test(test_base64_roundtrip);
   1.118 +add_test(test_dsa);
   1.119 +add_test(test_rsa);
   1.120 +add_test(test_base64UrlEncode);
   1.121 +add_test(test_base64UrlDecode);
   1.122 +
   1.123 +function run_test() {
   1.124 +  run_next_test();
   1.125 +}

mercurial