From 503d325bbb71620d50941097f6839f977c76df7e Mon Sep 17 00:00:00 2001 From: "J.C. Jones" Date: Fri, 29 Mar 2019 15:55:54 +0000 Subject: [PATCH] Bug 1539578 - Add telemetry for DH use in WebCrypto API r=keeler Our WebCrypto implementation supports using DH as an algorithm in generateKey, which is not one of the recognized algorithms in the published specification [0]. We should seek to remove it from Firefox, but before we do, it'd be good to gather some telemetry on whether it's used at all, even in its' non-standard form. [0] https://www.w3.org/TR/WebCryptoAPI/#algorithm-overview Differential Revision: https://phabricator.services.mozilla.com/D25291 --HG-- extra : moz-landing-system : lando --- dom/crypto/WebCryptoTask.cpp | 2 + dom/crypto/moz.build | 1 + dom/crypto/test/browser/browser.ini | 7 +++ .../browser/browser_WebCrypto_telemetry.js | 60 +++++++++++++++++++ dom/crypto/test/browser/head.js | 18 ++++++ 5 files changed, 88 insertions(+) create mode 100644 dom/crypto/test/browser/browser.ini create mode 100644 dom/crypto/test/browser/browser_WebCrypto_telemetry.js create mode 100644 dom/crypto/test/browser/head.js diff --git a/dom/crypto/WebCryptoTask.cpp b/dom/crypto/WebCryptoTask.cpp index 6f71977ddda8..d6245ef6014f 100644 --- a/dom/crypto/WebCryptoTask.cpp +++ b/dom/crypto/WebCryptoTask.cpp @@ -85,6 +85,7 @@ enum TelemetryAlgorithm { TA_PBKDF2 = 21, TA_ECDSA = 22, TA_HKDF = 23, + TA_DH = 24, }; // Convenience functions for extracting / converting information @@ -2883,6 +2884,7 @@ class DeriveDhBitsTask : public ReturnArrayBufferViewTask { } void Init(JSContext* aCx, const ObjectOrString& aAlgorithm, CryptoKey& aKey) { + Telemetry::Accumulate(Telemetry::WEBCRYPTO_ALG, TA_DH); CHECK_KEY_ALGORITHM(aKey.Algorithm(), WEBCRYPTO_ALG_DH); // Check that we have a private key. diff --git a/dom/crypto/moz.build b/dom/crypto/moz.build index 15568974ff68..664469db0123 100644 --- a/dom/crypto/moz.build +++ b/dom/crypto/moz.build @@ -34,3 +34,4 @@ LOCAL_INCLUDES += [ ] MOCHITEST_MANIFESTS += ['test/mochitest.ini'] +BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini'] diff --git a/dom/crypto/test/browser/browser.ini b/dom/crypto/test/browser/browser.ini new file mode 100644 index 000000000000..a1889c519b2a --- /dev/null +++ b/dom/crypto/test/browser/browser.ini @@ -0,0 +1,7 @@ +[DEFAULT] +support-files = + head.js + ../test-vectors.js + ../util.js + +[browser_WebCrypto_telemetry.js] diff --git a/dom/crypto/test/browser/browser_WebCrypto_telemetry.js b/dom/crypto/test/browser/browser_WebCrypto_telemetry.js new file mode 100644 index 000000000000..af95b0367be6 --- /dev/null +++ b/dom/crypto/test/browser/browser_WebCrypto_telemetry.js @@ -0,0 +1,60 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +/* global tv */ + +const WEBCRYPTO_ALG_PROBE = "WEBCRYPTO_ALG"; + +ChromeUtils.defineModuleGetter(this, "TelemetryTestUtils", + "resource://testing-common/TelemetryTestUtils.jsm"); + +function validateHistogramEntryCount(aHistogramName, aExpectedTotalCount, aBucketCounts) { + let hist = Services.telemetry.getHistogramById(aHistogramName); + let resultIndexes = hist.snapshot(); + + let entriesSeen = Object.values(resultIndexes.values).reduce((a, b) => a + b, 0); + + is(entriesSeen, aExpectedTotalCount, `Expecting ${aExpectedTotalCount} histogram entries in ` + + aHistogramName); + + for (let bucket in aBucketCounts) { + is(resultIndexes.values[bucket], aBucketCounts[bucket], `Expecting bucket ${bucket} to be ` + + aBucketCounts[bucket]); + } +} + +function cleanupTelemetry() { + Services.telemetry.clearScalars(); + Services.telemetry.clearEvents(); + Services.telemetry.getHistogramById(WEBCRYPTO_ALG_PROBE).clear(); +} + +add_task(async function ecdh_key() { + cleanupTelemetry(); + + var alg = { name: "ECDH", namedCurve: "P-256" }; + + let x = await crypto.subtle.generateKey(alg, false, ["deriveKey", "deriveBits"]); + await crypto.subtle.deriveBits({ name: "ECDH", public: x.publicKey }, x.privateKey, 128); + + validateHistogramEntryCount(WEBCRYPTO_ALG_PROBE, 1, {20: 1}); +}); + + +add_task(async function dh_key() { + cleanupTelemetry(); + + var alg = { + name: "DH", + prime: tv.dh.prime, + generator: new Uint8Array([0x02]), + }; + + let x = await crypto.subtle.generateKey(alg, false, ["deriveKey", "deriveBits"]); + await crypto.subtle.deriveBits({ name: "DH", public: x.publicKey }, x.privateKey, 128); + + validateHistogramEntryCount(WEBCRYPTO_ALG_PROBE, 1, {24: 1}); +}); diff --git a/dom/crypto/test/browser/head.js b/dom/crypto/test/browser/head.js new file mode 100644 index 000000000000..b3ff71912165 --- /dev/null +++ b/dom/crypto/test/browser/head.js @@ -0,0 +1,18 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +let exports = this; + +const scripts = [ + "util.js", + "test-vectors.js", +]; + +for (let script of scripts) { + Services.scriptloader.loadSubScript( + `chrome://mochitests/content/browser/dom/crypto/test/browser/${script}`, + this); +}