summaryrefslogtreecommitdiffstats
path: root/services/crypto/tests/unit/test_crypto_service.js
diff options
context:
space:
mode:
Diffstat (limited to 'services/crypto/tests/unit/test_crypto_service.js')
-rw-r--r--services/crypto/tests/unit/test_crypto_service.js133
1 files changed, 133 insertions, 0 deletions
diff --git a/services/crypto/tests/unit/test_crypto_service.js b/services/crypto/tests/unit/test_crypto_service.js
new file mode 100644
index 0000000000..8488924113
--- /dev/null
+++ b/services/crypto/tests/unit/test_crypto_service.js
@@ -0,0 +1,133 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const idService = Cc["@mozilla.org/identity/crypto-service;1"].getService(
+ Ci.nsIIdentityCryptoService
+);
+
+const ALG_DSA = "DS160";
+const ALG_RSA = "RS256";
+
+const BASE64_URL_ENCODINGS = [
+ // The vectors from RFC 4648 are very silly, but we may as well include them.
+ ["", ""],
+ ["f", "Zg=="],
+ ["fo", "Zm8="],
+ ["foo", "Zm9v"],
+ ["foob", "Zm9vYg=="],
+ ["fooba", "Zm9vYmE="],
+ ["foobar", "Zm9vYmFy"],
+
+ // It's quite likely you could get a string like this in an assertion audience
+ ["i-like-pie.com", "aS1saWtlLXBpZS5jb20="],
+
+ // A few extra to be really sure
+ ["andré@example.com", "YW5kcsOpQGV4YW1wbGUuY29t"],
+ [
+ "πόλλ' οἶδ' ἀλώπηξ, ἀλλ' ἐχῖνος ἓν μέγα",
+ "z4DPjM67zrsnIM6_4by2zrQnIOG8gM67z47PgM63zr4sIOG8gM67zrsnIOG8kM-H4b-Wzr3Ov8-CIOG8k869IM68zq3Os86x",
+ ],
+];
+
+let log = Log.repository.getLogger("crypto.service.test");
+(function() {
+ let appender = new Log.DumpAppender();
+ log.level = Log.Level.Debug;
+ log.addAppender(appender);
+})();
+
+// When the output of an operation is a
+function do_check_eq_or_slightly_less(x, y) {
+ Assert.ok(x >= y - 3 * 8);
+}
+
+function test_base64_roundtrip() {
+ let message = "Attack at dawn!";
+ let encoded = idService.base64UrlEncode(message);
+ let decoded = base64UrlDecode(encoded);
+ Assert.notEqual(message, encoded);
+ Assert.equal(decoded, message);
+ run_next_test();
+}
+
+function test_dsa() {
+ idService.generateKeyPair(ALG_DSA, function(rv, keyPair) {
+ log.debug("DSA generateKeyPair finished " + rv);
+ Assert.ok(Components.isSuccessCode(rv));
+ Assert.equal(typeof keyPair.sign, "function");
+ Assert.equal(keyPair.keyType, ALG_DSA);
+ do_check_eq_or_slightly_less(
+ keyPair.hexDSAGenerator.length,
+ (1024 / 8) * 2
+ );
+ do_check_eq_or_slightly_less(keyPair.hexDSAPrime.length, (1024 / 8) * 2);
+ do_check_eq_or_slightly_less(keyPair.hexDSASubPrime.length, (160 / 8) * 2);
+ do_check_eq_or_slightly_less(
+ keyPair.hexDSAPublicValue.length,
+ (1024 / 8) * 2
+ );
+ // XXX: test that RSA parameters throw the correct error
+
+ log.debug("about to sign with DSA key");
+ keyPair.sign("foo", function(rv2, signature) {
+ log.debug("DSA sign finished " + rv2 + " " + signature);
+ Assert.ok(Components.isSuccessCode(rv2));
+ Assert.ok(signature.length > 1);
+ // TODO: verify the signature with the public key
+ run_next_test();
+ });
+ });
+}
+
+function test_rsa() {
+ idService.generateKeyPair(ALG_RSA, function(rv, keyPair) {
+ log.debug("RSA generateKeyPair finished " + rv);
+ Assert.ok(Components.isSuccessCode(rv));
+ Assert.equal(typeof keyPair.sign, "function");
+ Assert.equal(keyPair.keyType, ALG_RSA);
+ do_check_eq_or_slightly_less(
+ keyPair.hexRSAPublicKeyModulus.length,
+ 2048 / 8
+ );
+ Assert.ok(keyPair.hexRSAPublicKeyExponent.length > 1);
+
+ log.debug("about to sign with RSA key");
+ keyPair.sign("foo", function(rv2, signature) {
+ log.debug("RSA sign finished " + rv2 + " " + signature);
+ Assert.ok(Components.isSuccessCode(rv2));
+ Assert.ok(signature.length > 1);
+ run_next_test();
+ });
+ });
+}
+
+function test_base64UrlEncode() {
+ for (let [source, target] of BASE64_URL_ENCODINGS) {
+ Assert.equal(target, idService.base64UrlEncode(source));
+ }
+ run_next_test();
+}
+
+function test_base64UrlDecode() {
+ let utf8Converter = Cc[
+ "@mozilla.org/intl/scriptableunicodeconverter"
+ ].createInstance(Ci.nsIScriptableUnicodeConverter);
+ utf8Converter.charset = "UTF-8";
+
+ // We know the encoding of our inputs - on conversion back out again, make
+ // sure they're the same.
+ for (let [source, target] of BASE64_URL_ENCODINGS) {
+ let result = utf8Converter.ConvertToUnicode(base64UrlDecode(target));
+ result += utf8Converter.Finish();
+ Assert.equal(source, result);
+ }
+ run_next_test();
+}
+
+add_test(test_base64_roundtrip);
+add_test(test_dsa);
+add_test(test_rsa);
+add_test(test_base64UrlEncode);
+add_test(test_base64UrlDecode);