зеркало из https://github.com/mozilla/pjs.git
Merge services-central into mozilla-central
This commit is contained in:
Коммит
82fc671e3f
|
@ -3,7 +3,6 @@
|
|||
*/
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://services-sync/main.js");
|
||||
|
||||
let gTests = [ {
|
||||
|
|
|
@ -755,6 +755,130 @@ let Utils = {
|
|||
return Utils.encodeKeyBase32(atob(encodedKey));
|
||||
},
|
||||
|
||||
/**
|
||||
* Compute the HTTP MAC SHA-1 for an HTTP request.
|
||||
*
|
||||
* @param identifier
|
||||
* (string) MAC Key Identifier.
|
||||
* @param key
|
||||
* (string) MAC Key.
|
||||
* @param method
|
||||
* (string) HTTP request method.
|
||||
* @param URI
|
||||
* (nsIURI) HTTP request URI.
|
||||
* @param extra
|
||||
* (object) Optional extra parameters. Valid keys are:
|
||||
* nonce_bytes - How many bytes the nonce should be. This defaults
|
||||
* to 8. Note that this many bytes are Base64 encoded, so the
|
||||
* string length of the nonce will be longer than this value.
|
||||
* ts - Timestamp to use. Should only be defined for testing.
|
||||
* nonce - String nonce. Should only be defined for testing as this
|
||||
* function will generate a cryptographically secure random one
|
||||
* if not defined.
|
||||
* ext - Extra string to be included in MAC. Per the HTTP MAC spec,
|
||||
* the format is undefined and thus application specific.
|
||||
* @returns
|
||||
* (object) Contains results of operation and input arguments (for
|
||||
* symmetry). The object has the following keys:
|
||||
*
|
||||
* identifier - (string) MAC Key Identifier (from arguments).
|
||||
* key - (string) MAC Key (from arguments).
|
||||
* method - (string) HTTP request method (from arguments).
|
||||
* hostname - (string) HTTP hostname used (derived from arguments).
|
||||
* port - (string) HTTP port number used (derived from arguments).
|
||||
* mac - (string) Raw HMAC digest bytes.
|
||||
* getHeader - (function) Call to obtain the string Authorization
|
||||
* header value for this invocation.
|
||||
* nonce - (string) Nonce value used.
|
||||
* ts - (number) Integer seconds since Unix epoch that was used.
|
||||
*/
|
||||
computeHTTPMACSHA1: function computeHTTPMACSHA1(identifier, key, method,
|
||||
uri, extra) {
|
||||
let ts = (extra && extra.ts) ? extra.ts : Math.floor(Date.now() / 1000);
|
||||
let nonce_bytes = (extra && extra.nonce_bytes > 0) ? extra.nonce_bytes : 8;
|
||||
|
||||
// We are allowed to use more than the Base64 alphabet if we want.
|
||||
let nonce = (extra && extra.nonce)
|
||||
? extra.nonce
|
||||
: btoa(Utils.generateRandomBytes(nonce_bytes));
|
||||
|
||||
let host = uri.asciiHost;
|
||||
let port;
|
||||
let usedMethod = method.toUpperCase();
|
||||
|
||||
if (uri.port != -1) {
|
||||
port = uri.port;
|
||||
} else if (uri.scheme == "http") {
|
||||
port = "80";
|
||||
} else if (uri.scheme == "https") {
|
||||
port = "443";
|
||||
} else {
|
||||
throw new Error("Unsupported URI scheme: " + uri.scheme);
|
||||
}
|
||||
|
||||
let ext = (extra && extra.ext) ? extra.ext : "";
|
||||
|
||||
let requestString = ts.toString(10) + "\n" +
|
||||
nonce + "\n" +
|
||||
usedMethod + "\n" +
|
||||
uri.path + "\n" +
|
||||
host + "\n" +
|
||||
port + "\n" +
|
||||
ext + "\n";
|
||||
|
||||
let hasher = Utils.makeHMACHasher(Ci.nsICryptoHMAC.SHA1,
|
||||
Utils.makeHMACKey(key));
|
||||
let mac = Utils.digestBytes(requestString, hasher);
|
||||
|
||||
function getHeader() {
|
||||
return Utils.getHTTPMACSHA1Header(this.identifier, this.ts, this.nonce,
|
||||
this.mac, this.ext);
|
||||
}
|
||||
|
||||
return {
|
||||
identifier: identifier,
|
||||
key: key,
|
||||
method: usedMethod,
|
||||
hostname: host,
|
||||
port: port,
|
||||
mac: mac,
|
||||
nonce: nonce,
|
||||
ts: ts,
|
||||
ext: ext,
|
||||
getHeader: getHeader
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Obtain the HTTP MAC Authorization header value from fields.
|
||||
*
|
||||
* @param identifier
|
||||
* (string) MAC key identifier.
|
||||
* @param ts
|
||||
* (number) Integer seconds since Unix epoch.
|
||||
* @param nonce
|
||||
* (string) Nonce value.
|
||||
* @param mac
|
||||
* (string) Computed HMAC digest (raw bytes).
|
||||
* @param ext
|
||||
* (optional) (string) Extra string content.
|
||||
* @returns
|
||||
* (string) Value to put in Authorization header.
|
||||
*/
|
||||
getHTTPMACSHA1Header: function getHTTPMACSHA1Header(identifier, ts, nonce,
|
||||
mac, ext) {
|
||||
let header ='MAC id="' + identifier + '", ' +
|
||||
'ts="' + ts + '", ' +
|
||||
'nonce="' + nonce + '", ' +
|
||||
'mac="' + btoa(mac) + '"';
|
||||
|
||||
if (!ext) {
|
||||
return header;
|
||||
}
|
||||
|
||||
return header += ', ext="' + ext +'"';
|
||||
},
|
||||
|
||||
makeURI: function Weave_makeURI(URIString) {
|
||||
if (!URIString)
|
||||
return null;
|
||||
|
|
|
@ -5,7 +5,8 @@ Cu.import("resource://services-sync/async.js");
|
|||
Cu.import("resource://services-sync/util.js");
|
||||
Cu.import("resource://services-sync/record.js");
|
||||
Cu.import("resource://services-sync/engines.js");
|
||||
var btoa;
|
||||
let btoa;
|
||||
let atob;
|
||||
|
||||
let provider = {
|
||||
getFile: function(prop, persistent) {
|
||||
|
@ -39,6 +40,7 @@ function waitForZeroTimer(callback) {
|
|||
}
|
||||
|
||||
btoa = Cu.import("resource://services-sync/log4moz.js").btoa;
|
||||
atob = Cu.import("resource://services-sync/log4moz.js").atob;
|
||||
function getTestLogger(component) {
|
||||
return Log4Moz.repository.getLogger("Testing");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
const modules = [
|
||||
"addonsreconciler.js",
|
||||
"async.js",
|
||||
"constants.js",
|
||||
"engines/addons.js",
|
||||
"engines/bookmarks.js",
|
||||
"engines/clients.js",
|
||||
"engines/forms.js",
|
||||
|
@ -11,12 +14,16 @@ const modules = [
|
|||
"ext/Observers.js",
|
||||
"ext/Preferences.js",
|
||||
"identity.js",
|
||||
"jpakeclient.js",
|
||||
"log4moz.js",
|
||||
"main.js",
|
||||
"notifications.js",
|
||||
"policies.js",
|
||||
"record.js",
|
||||
"resource.js",
|
||||
"rest.js",
|
||||
"service.js",
|
||||
"status.js",
|
||||
"util.js",
|
||||
];
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://services-sync/util.js");
|
||||
|
||||
function run_test() {
|
||||
initTestLogging();
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_test(function test_sha1() {
|
||||
_("Ensure HTTP MAC SHA1 generation works as expected.");
|
||||
|
||||
let id = "vmo1txkttblmn51u2p3zk2xiy16hgvm5ok8qiv1yyi86ffjzy9zj0ez9x6wnvbx7";
|
||||
let key = "b8u1cc5iiio5o319og7hh8faf2gi5ym4aq0zwf112cv1287an65fudu5zj7zo7dz";
|
||||
let ts = 1329181221;
|
||||
let method = "GET";
|
||||
let nonce = "wGX71";
|
||||
let uri = Utils.makeURI("http://10.250.2.176/alias/");
|
||||
|
||||
let result = Utils.computeHTTPMACSHA1(id, key, method, uri, {ts: ts,
|
||||
nonce: nonce});
|
||||
|
||||
do_check_eq(btoa(result.mac), "jzh5chjQc2zFEvLbyHnPdX11Yck=");
|
||||
|
||||
do_check_eq(result.getHeader(),
|
||||
'MAC id="vmo1txkttblmn51u2p3zk2xiy16hgvm5ok8qiv1yyi86ffjzy9zj0ez9x6wnvbx7", ' +
|
||||
'ts="1329181221", nonce="wGX71", mac="jzh5chjQc2zFEvLbyHnPdX11Yck="');
|
||||
|
||||
let ext = "EXTRA DATA; foo,bar=1";
|
||||
|
||||
let result = Utils.computeHTTPMACSHA1(id, key, method, uri, {ts: ts,
|
||||
nonce: nonce,
|
||||
ext: ext});
|
||||
do_check_eq(btoa(result.mac), "bNf4Fnt5k6DnhmyipLPkuZroH68=");
|
||||
do_check_eq(result.getHeader(),
|
||||
'MAC id="vmo1txkttblmn51u2p3zk2xiy16hgvm5ok8qiv1yyi86ffjzy9zj0ez9x6wnvbx7", ' +
|
||||
'ts="1329181221", nonce="wGX71", mac="bNf4Fnt5k6DnhmyipLPkuZroH68=", ' +
|
||||
'ext="EXTRA DATA; foo,bar=1"');
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_nonce_length() {
|
||||
_("Ensure custom nonce lengths are honoured.");
|
||||
|
||||
function get_mac(length) {
|
||||
let uri = Utils.makeURI("http://example.com/");
|
||||
return Utils.computeHTTPMACSHA1("foo", "bar", "GET", uri, {
|
||||
nonce_bytes: length
|
||||
});
|
||||
}
|
||||
|
||||
let result = get_mac(12);
|
||||
do_check_eq(12, atob(result.nonce).length);
|
||||
|
||||
let result = get_mac(2);
|
||||
do_check_eq(2, atob(result.nonce).length);
|
||||
|
||||
let result = get_mac(0);
|
||||
do_check_eq(8, atob(result.nonce).length);
|
||||
|
||||
let result = get_mac(-1);
|
||||
do_check_eq(8, atob(result.nonce).length);
|
||||
|
||||
run_next_test();
|
||||
});
|
|
@ -1,6 +1,8 @@
|
|||
[DEFAULT]
|
||||
head = head_appinfo.js head_helpers.js head_http_server.js
|
||||
tail =
|
||||
tail =
|
||||
|
||||
[test_load_modules.js]
|
||||
|
||||
[test_Observers.js]
|
||||
[test_Preferences.js]
|
||||
|
@ -49,7 +51,6 @@ skip-if = os == "android"
|
|||
# Bug 676978: test hangs on Android (see also testing/xpcshell/xpcshell.ini)
|
||||
skip-if = os == "win" || os == "android"
|
||||
[test_keys.js]
|
||||
[test_load_modules.js]
|
||||
[test_log4moz.js]
|
||||
[test_node_reassignment.js]
|
||||
[test_notifications.js]
|
||||
|
@ -115,6 +116,7 @@ skip-if = os == "android"
|
|||
[test_utils_getErrorString.js]
|
||||
[test_utils_getIcon.js]
|
||||
[test_utils_hkdfExpand.js]
|
||||
[test_utils_httpmac.js]
|
||||
[test_utils_json.js]
|
||||
[test_utils_lazyStrings.js]
|
||||
[test_utils_lock.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче