Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* Any copyright is dedicated to the Public Domain. |
michael@0 | 2 | http://creativecommons.org/publicdomain/zero/1.0/ */ |
michael@0 | 3 | |
michael@0 | 4 | "use strict"; |
michael@0 | 5 | |
michael@0 | 6 | Cu.import("resource://gre/modules/Services.jsm"); |
michael@0 | 7 | Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
michael@0 | 8 | Cu.import('resource://gre/modules/identity/LogUtils.jsm'); |
michael@0 | 9 | |
michael@0 | 10 | const idService = Cc["@mozilla.org/identity/crypto-service;1"] |
michael@0 | 11 | .getService(Ci.nsIIdentityCryptoService); |
michael@0 | 12 | |
michael@0 | 13 | const ALG_DSA = "DS160"; |
michael@0 | 14 | const ALG_RSA = "RS256"; |
michael@0 | 15 | |
michael@0 | 16 | const BASE64_URL_ENCODINGS = [ |
michael@0 | 17 | // The vectors from RFC 4648 are very silly, but we may as well include them. |
michael@0 | 18 | ["", ""], |
michael@0 | 19 | ["f", "Zg=="], |
michael@0 | 20 | ["fo", "Zm8="], |
michael@0 | 21 | ["foo", "Zm9v"], |
michael@0 | 22 | ["foob", "Zm9vYg=="], |
michael@0 | 23 | ["fooba", "Zm9vYmE="], |
michael@0 | 24 | ["foobar", "Zm9vYmFy"], |
michael@0 | 25 | |
michael@0 | 26 | // It's quite likely you could get a string like this in an assertion audience |
michael@0 | 27 | ["i-like-pie.com", "aS1saWtlLXBpZS5jb20="], |
michael@0 | 28 | |
michael@0 | 29 | // A few extra to be really sure |
michael@0 | 30 | ["andré@example.com", "YW5kcsOpQGV4YW1wbGUuY29t"], |
michael@0 | 31 | ["πόλλ' οἶδ' ἀλώπηξ, ἀλλ' ἐχῖνος ἓν μέγα", |
michael@0 | 32 | "z4DPjM67zrsnIM6_4by2zrQnIOG8gM67z47PgM63zr4sIOG8gM67zrsnIOG8kM-H4b-Wzr3Ov8-CIOG8k869IM68zq3Os86x"], |
michael@0 | 33 | ]; |
michael@0 | 34 | |
michael@0 | 35 | // When the output of an operation is a |
michael@0 | 36 | function do_check_eq_or_slightly_less(x, y) { |
michael@0 | 37 | do_check_true(x >= y - (3 * 8)); |
michael@0 | 38 | } |
michael@0 | 39 | |
michael@0 | 40 | function test_base64_roundtrip() { |
michael@0 | 41 | let message = "Attack at dawn!"; |
michael@0 | 42 | let encoded = idService.base64UrlEncode(message); |
michael@0 | 43 | let decoded = base64UrlDecode(encoded); |
michael@0 | 44 | do_check_neq(message, encoded); |
michael@0 | 45 | do_check_eq(decoded, message); |
michael@0 | 46 | run_next_test(); |
michael@0 | 47 | } |
michael@0 | 48 | |
michael@0 | 49 | function test_dsa() { |
michael@0 | 50 | idService.generateKeyPair(ALG_DSA, function (rv, keyPair) { |
michael@0 | 51 | log("DSA generateKeyPair finished ", rv); |
michael@0 | 52 | do_check_true(Components.isSuccessCode(rv)); |
michael@0 | 53 | do_check_eq(typeof keyPair.sign, "function"); |
michael@0 | 54 | do_check_eq(keyPair.keyType, ALG_DSA); |
michael@0 | 55 | do_check_eq_or_slightly_less(keyPair.hexDSAGenerator.length, 1024 / 8 * 2); |
michael@0 | 56 | do_check_eq_or_slightly_less(keyPair.hexDSAPrime.length, 1024 / 8 * 2); |
michael@0 | 57 | do_check_eq_or_slightly_less(keyPair.hexDSASubPrime.length, 160 / 8 * 2); |
michael@0 | 58 | do_check_eq_or_slightly_less(keyPair.hexDSAPublicValue.length, 1024 / 8 * 2); |
michael@0 | 59 | // XXX: test that RSA parameters throw the correct error |
michael@0 | 60 | |
michael@0 | 61 | log("about to sign with DSA key"); |
michael@0 | 62 | keyPair.sign("foo", function (rv, signature) { |
michael@0 | 63 | log("DSA sign finished ", rv, signature); |
michael@0 | 64 | do_check_true(Components.isSuccessCode(rv)); |
michael@0 | 65 | do_check_true(signature.length > 1); |
michael@0 | 66 | // TODO: verify the signature with the public key |
michael@0 | 67 | run_next_test(); |
michael@0 | 68 | }); |
michael@0 | 69 | }); |
michael@0 | 70 | } |
michael@0 | 71 | |
michael@0 | 72 | function test_rsa() { |
michael@0 | 73 | idService.generateKeyPair(ALG_RSA, function (rv, keyPair) { |
michael@0 | 74 | log("RSA generateKeyPair finished ", rv); |
michael@0 | 75 | do_check_true(Components.isSuccessCode(rv)); |
michael@0 | 76 | do_check_eq(typeof keyPair.sign, "function"); |
michael@0 | 77 | do_check_eq(keyPair.keyType, ALG_RSA); |
michael@0 | 78 | do_check_eq_or_slightly_less(keyPair.hexRSAPublicKeyModulus.length, |
michael@0 | 79 | 2048 / 8); |
michael@0 | 80 | do_check_true(keyPair.hexRSAPublicKeyExponent.length > 1); |
michael@0 | 81 | |
michael@0 | 82 | log("about to sign with RSA key"); |
michael@0 | 83 | keyPair.sign("foo", function (rv, signature) { |
michael@0 | 84 | log("RSA sign finished ", rv, signature); |
michael@0 | 85 | do_check_true(Components.isSuccessCode(rv)); |
michael@0 | 86 | do_check_true(signature.length > 1); |
michael@0 | 87 | run_next_test(); |
michael@0 | 88 | }); |
michael@0 | 89 | }); |
michael@0 | 90 | } |
michael@0 | 91 | |
michael@0 | 92 | function test_base64UrlEncode() { |
michael@0 | 93 | for (let [source, target] of BASE64_URL_ENCODINGS) { |
michael@0 | 94 | do_check_eq(target, idService.base64UrlEncode(source)); |
michael@0 | 95 | } |
michael@0 | 96 | run_next_test(); |
michael@0 | 97 | } |
michael@0 | 98 | |
michael@0 | 99 | function test_base64UrlDecode() { |
michael@0 | 100 | let utf8Converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] |
michael@0 | 101 | .createInstance(Ci.nsIScriptableUnicodeConverter); |
michael@0 | 102 | utf8Converter.charset = "UTF-8"; |
michael@0 | 103 | |
michael@0 | 104 | // We know the encoding of our inputs - on conversion back out again, make |
michael@0 | 105 | // sure they're the same. |
michael@0 | 106 | for (let [source, target] of BASE64_URL_ENCODINGS) { |
michael@0 | 107 | let result = utf8Converter.ConvertToUnicode(base64UrlDecode(target)); |
michael@0 | 108 | result += utf8Converter.Finish(); |
michael@0 | 109 | do_check_eq(source, result); |
michael@0 | 110 | } |
michael@0 | 111 | run_next_test(); |
michael@0 | 112 | } |
michael@0 | 113 | |
michael@0 | 114 | add_test(test_base64_roundtrip); |
michael@0 | 115 | add_test(test_dsa); |
michael@0 | 116 | add_test(test_rsa); |
michael@0 | 117 | add_test(test_base64UrlEncode); |
michael@0 | 118 | add_test(test_base64UrlDecode); |
michael@0 | 119 | |
michael@0 | 120 | function run_test() { |
michael@0 | 121 | run_next_test(); |
michael@0 | 122 | } |