diff options
Diffstat (limited to 'services/fxaccounts/tests/xpcshell/test_keys.js')
-rw-r--r-- | services/fxaccounts/tests/xpcshell/test_keys.js | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/services/fxaccounts/tests/xpcshell/test_keys.js b/services/fxaccounts/tests/xpcshell/test_keys.js new file mode 100644 index 0000000000..6e650a1609 --- /dev/null +++ b/services/fxaccounts/tests/xpcshell/test_keys.js @@ -0,0 +1,182 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { FxAccountsKeys } = ChromeUtils.importESModule( + "resource://gre/modules/FxAccountsKeys.sys.mjs" +); + +// Ref https://github.com/mozilla/fxa-crypto-relier/ for the details +// of these test vectors. + +add_task(async function test_derive_scoped_key_test_vector() { + const keys = new FxAccountsKeys(null); + const uid = "aeaa1725c7a24ff983c6295725d5fc9b"; + const kB = "8b2e1303e21eee06a945683b8d495b9bf079ca30baa37eb8392d9ffa4767be45"; + const scopedKeyMetadata = { + identifier: "app_key:https%3A//example.com", + keyRotationTimestamp: 1510726317000, + keyRotationSecret: + "517d478cb4f994aa69930416648a416fdaa1762c5abf401a2acf11a0f185e98d", + }; + + const scopedKey = await keys._deriveScopedKey( + uid, + CommonUtils.hexToBytes(kB), + "app_key", + scopedKeyMetadata + ); + + Assert.deepEqual(scopedKey, { + kty: "oct", + kid: "1510726317-Voc-Eb9IpoTINuo9ll7bjA", + k: "Kkbk1_Q0oCcTmggeDH6880bQrxin2RLu5D00NcJazdQ", + }); +}); + +add_task(async function test_derive_legacy_sync_key_test_vector() { + const keys = new FxAccountsKeys(null); + const uid = "aeaa1725c7a24ff983c6295725d5fc9b"; + const kB = "eaf9570b7219a4187d3d6bf3cec2770c2e0719b7cc0dfbb38243d6f1881675e9"; + const scopedKeyMetadata = { + identifier: "https://identity.mozilla.com/apps/oldsync", + keyRotationTimestamp: 1510726317123, + keyRotationSecret: + "0000000000000000000000000000000000000000000000000000000000000000", + }; + + const scopedKey = await keys._deriveLegacyScopedKey( + uid, + CommonUtils.hexToBytes(kB), + "https://identity.mozilla.com/apps/oldsync", + scopedKeyMetadata + ); + + Assert.deepEqual(scopedKey, { + kty: "oct", + kid: "1510726317123-IqQv4onc7VcVE1kTQkyyOw", + k: "DW_ll5GwX6SJ5GPqJVAuMUP2t6kDqhUulc2cbt26xbTcaKGQl-9l29FHAQ7kUiJETma4s9fIpEHrt909zgFang", + }); +}); + +add_task(async function test_derive_multiple_keys_at_once() { + const keys = new FxAccountsKeys(null); + const uid = "aeaa1725c7a24ff983c6295725d5fc9b"; + const kB = "eaf9570b7219a4187d3d6bf3cec2770c2e0719b7cc0dfbb38243d6f1881675e9"; + const scopedKeysMetadata = { + app_key: { + identifier: "app_key:https%3A//example.com", + keyRotationTimestamp: 1510726317000, + keyRotationSecret: + "517d478cb4f994aa69930416648a416fdaa1762c5abf401a2acf11a0f185e98d", + }, + "https://identity.mozilla.com/apps/oldsync": { + identifier: "https://identity.mozilla.com/apps/oldsync", + keyRotationTimestamp: 1510726318123, + keyRotationSecret: + "0000000000000000000000000000000000000000000000000000000000000000", + }, + }; + + const scopedKeys = await keys._deriveScopedKeys( + uid, + CommonUtils.hexToBytes(kB), + scopedKeysMetadata + ); + + Assert.deepEqual(scopedKeys, { + app_key: { + kty: "oct", + kid: "1510726317-tUkxiR1lTlFrTgkF0tJidA", + k: "TYK6Hmj86PfKiqsk9DZmX61nxk9VsExGrwo94HP-0wU", + }, + "https://identity.mozilla.com/apps/oldsync": { + kty: "oct", + kid: "1510726318123-IqQv4onc7VcVE1kTQkyyOw", + k: "DW_ll5GwX6SJ5GPqJVAuMUP2t6kDqhUulc2cbt26xbTcaKGQl-9l29FHAQ7kUiJETma4s9fIpEHrt909zgFang", + }, + }); +}); + +add_task(async function test_rejects_bad_scoped_key_data() { + const keys = new FxAccountsKeys(null); + const uid = "aeaa1725c7a24ff983c6295725d5fc9b"; + const kB = "8b2e1303e21eee06a945683b8d495b9bf079ca30baa37eb8392d9ffa4767be45"; + const scopedKeyMetadata = { + identifier: "app_key:https%3A//example.com", + keyRotationTimestamp: 1510726317000, + keyRotationSecret: + "517d478cb4f994aa69930416648a416fdaa1762c5abf401a2acf11a0f185e98d", + }; + + await Assert.rejects( + keys._deriveScopedKey( + uid.slice(0, -1), + CommonUtils.hexToBytes(kB), + "app_key", + scopedKeyMetadata + ), + /uid must be a 32-character hex string/ + ); + await Assert.rejects( + keys._deriveScopedKey( + uid.slice(0, -1) + "Q", + CommonUtils.hexToBytes(kB), + "app_key", + scopedKeyMetadata + ), + /uid must be a 32-character hex string/ + ); + await Assert.rejects( + keys._deriveScopedKey( + uid, + CommonUtils.hexToBytes(kB).slice(0, -1), + "app_key", + scopedKeyMetadata + ), + /kBbytes must be exactly 32 bytes/ + ); + await Assert.rejects( + keys._deriveScopedKey(uid, CommonUtils.hexToBytes(kB), "app_key", { + ...scopedKeyMetadata, + identifier: "foo", + }), + /identifier must be a string of length >= 10/ + ); + await Assert.rejects( + keys._deriveScopedKey(uid, CommonUtils.hexToBytes(kB), "app_key", { + ...scopedKeyMetadata, + identifier: {}, + }), + /identifier must be a string of length >= 10/ + ); + await Assert.rejects( + keys._deriveScopedKey(uid, CommonUtils.hexToBytes(kB), "app_key", { + ...scopedKeyMetadata, + keyRotationTimestamp: "xyz", + }), + /keyRotationTimestamp must be a number/ + ); + await Assert.rejects( + keys._deriveScopedKey(uid, CommonUtils.hexToBytes(kB), "app_key", { + ...scopedKeyMetadata, + keyRotationTimestamp: 12345, + }), + /keyRotationTimestamp must round to a 10-digit number/ + ); + await Assert.rejects( + keys._deriveScopedKey(uid, CommonUtils.hexToBytes(kB), "app_key", { + ...scopedKeyMetadata, + keyRotationSecret: scopedKeyMetadata.keyRotationSecret.slice(0, -1), + }), + /keyRotationSecret must be a 64-character hex string/ + ); + await Assert.rejects( + keys._deriveScopedKey(uid, CommonUtils.hexToBytes(kB), "app_key", { + ...scopedKeyMetadata, + keyRotationSecret: scopedKeyMetadata.keyRotationSecret.slice(0, -1) + "z", + }), + /keyRotationSecret must be a 64-character hex string/ + ); +}); |