зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1772097 - Part 3: Use plain object for lazy getter in services/crypto/modules/. r=markh
Differential Revision: https://phabricator.services.mozilla.com/D147918
This commit is contained in:
Родитель
f3d348703f
Коммит
819c5382fe
|
@ -9,7 +9,9 @@ const { XPCOMUtils } = ChromeUtils.import(
|
|||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGlobalGetters(this, ["crypto"]);
|
||||
const lazy = {};
|
||||
|
||||
XPCOMUtils.defineLazyGlobalGetters(lazy, ["crypto"]);
|
||||
|
||||
const CRYPT_ALGO = "AES-CBC";
|
||||
const CRYPT_ALGO_LENGTH = 256;
|
||||
|
@ -76,7 +78,7 @@ WeaveCrypto.prototype = {
|
|||
|
||||
// /!\ Only use this for tests! /!\
|
||||
_getCrypto() {
|
||||
return crypto;
|
||||
return lazy.crypto;
|
||||
},
|
||||
|
||||
async encrypt(clearTextUCS2, symmetricKey, iv) {
|
||||
|
@ -133,12 +135,17 @@ WeaveCrypto.prototype = {
|
|||
let iv = this.byteCompressInts(ivStr);
|
||||
let symKey = await this.importSymKey(symKeyStr, operation);
|
||||
let cryptMethod = (operation === OPERATIONS.ENCRYPT
|
||||
? crypto.subtle.encrypt
|
||||
: crypto.subtle.decrypt
|
||||
).bind(crypto.subtle);
|
||||
? lazy.crypto.subtle.encrypt
|
||||
: lazy.crypto.subtle.decrypt
|
||||
).bind(lazy.crypto.subtle);
|
||||
let algo = { name: CRYPT_ALGO, iv };
|
||||
|
||||
let keyBytes = await cryptMethod.call(crypto.subtle, algo, symKey, data);
|
||||
let keyBytes = await cryptMethod.call(
|
||||
lazy.crypto.subtle,
|
||||
algo,
|
||||
symKey,
|
||||
data
|
||||
);
|
||||
return new Uint8Array(keyBytes);
|
||||
},
|
||||
|
||||
|
@ -148,8 +155,12 @@ WeaveCrypto.prototype = {
|
|||
name: CRYPT_ALGO,
|
||||
length: CRYPT_ALGO_LENGTH,
|
||||
};
|
||||
let key = await crypto.subtle.generateKey(algo, true, CRYPT_ALGO_USAGES);
|
||||
let keyBytes = await crypto.subtle.exportKey("raw", key);
|
||||
let key = await lazy.crypto.subtle.generateKey(
|
||||
algo,
|
||||
true,
|
||||
CRYPT_ALGO_USAGES
|
||||
);
|
||||
let keyBytes = await lazy.crypto.subtle.exportKey("raw", key);
|
||||
return this.encodeBase64(new Uint8Array(keyBytes));
|
||||
},
|
||||
|
||||
|
@ -161,7 +172,7 @@ WeaveCrypto.prototype = {
|
|||
this.log("generateRandomBytes() called");
|
||||
|
||||
let randBytes = new Uint8Array(byteCount);
|
||||
crypto.getRandomValues(randBytes);
|
||||
lazy.crypto.getRandomValues(randBytes);
|
||||
|
||||
return this.encodeBase64(randBytes);
|
||||
},
|
||||
|
@ -197,7 +208,7 @@ WeaveCrypto.prototype = {
|
|||
let symmetricKeyBuffer = this.makeUint8Array(encodedKeyString, true);
|
||||
let algo = { name: CRYPT_ALGO };
|
||||
let usages = [operation === OPERATIONS.ENCRYPT ? "encrypt" : "decrypt"];
|
||||
let symKey = await crypto.subtle.importKey(
|
||||
let symKey = await lazy.crypto.subtle.importKey(
|
||||
"raw",
|
||||
symmetricKeyBuffer,
|
||||
algo,
|
||||
|
|
|
@ -8,7 +8,9 @@ const { XPCOMUtils } = ChromeUtils.import(
|
|||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyGlobalGetters(this, ["crypto"]);
|
||||
const lazy = {};
|
||||
|
||||
XPCOMUtils.defineLazyGlobalGetters(lazy, ["crypto"]);
|
||||
|
||||
const EXPORTED_SYMBOLS = ["jwcrypto"];
|
||||
|
||||
|
@ -45,10 +47,13 @@ class JWCrypto {
|
|||
async generateJWE(key, data) {
|
||||
// Generate an ephemeral key to use just for this encryption.
|
||||
// The public component gets embedded in the JWE header.
|
||||
const epk = await crypto.subtle.generateKey(ECDH_PARAMS, true, [
|
||||
const epk = await lazy.crypto.subtle.generateKey(ECDH_PARAMS, true, [
|
||||
"deriveKey",
|
||||
]);
|
||||
const ownPublicJWK = await crypto.subtle.exportKey("jwk", epk.publicKey);
|
||||
const ownPublicJWK = await lazy.crypto.subtle.exportKey(
|
||||
"jwk",
|
||||
epk.publicKey
|
||||
);
|
||||
// Remove properties added by our WebCrypto implementation but that aren't typically
|
||||
// used with JWE in the wild. This saves space in the resulting JWE, and makes it easier
|
||||
// to re-import the resulting JWK.
|
||||
|
@ -56,7 +61,7 @@ class JWCrypto {
|
|||
delete ownPublicJWK.ext;
|
||||
let header = { alg: "ECDH-ES", enc: "A256GCM", epk: ownPublicJWK };
|
||||
// Import the peer's public key.
|
||||
const peerPublicKey = await crypto.subtle.importKey(
|
||||
const peerPublicKey = await lazy.crypto.subtle.importKey(
|
||||
"jwk",
|
||||
key,
|
||||
ECDH_PARAMS,
|
||||
|
@ -76,14 +81,14 @@ class JWCrypto {
|
|||
// Note that the IV is generated randomly, which *in general* is not safe to do with AES-GCM because
|
||||
// it's too short to guarantee uniqueness. But we know that the AES-GCM key itself is unique and will
|
||||
// only be used for this single encryption, making a random IV safe to use for this particular use-case.
|
||||
let iv = crypto.getRandomValues(new Uint8Array(AES_GCM_IV_SIZE));
|
||||
let iv = lazy.crypto.getRandomValues(new Uint8Array(AES_GCM_IV_SIZE));
|
||||
// Yes, additionalData is the byte representation of the base64 representation of the stringified header.
|
||||
const additionalData = UTF8_ENCODER.encode(
|
||||
ChromeUtils.base64URLEncode(UTF8_ENCODER.encode(JSON.stringify(header)), {
|
||||
pad: false,
|
||||
})
|
||||
);
|
||||
const encrypted = await crypto.subtle.encrypt(
|
||||
const encrypted = await lazy.crypto.subtle.encrypt(
|
||||
{
|
||||
name: "AES-GCM",
|
||||
iv,
|
||||
|
@ -138,7 +143,7 @@ class JWCrypto {
|
|||
if ("apu" in header || "apv" in header) {
|
||||
throw new Error("apu and apv header values are not supported.");
|
||||
}
|
||||
const peerPublicKey = await crypto.subtle.importKey(
|
||||
const peerPublicKey = await lazy.crypto.subtle.importKey(
|
||||
"jwk",
|
||||
header.epk,
|
||||
ECDH_PARAMS,
|
||||
|
@ -158,7 +163,7 @@ class JWCrypto {
|
|||
);
|
||||
const bundle = new Uint8Array([...ciphertext, ...authTag]);
|
||||
|
||||
const decrypted = await crypto.subtle.decrypt(
|
||||
const decrypted = await lazy.crypto.subtle.decrypt(
|
||||
{
|
||||
name: "AES-GCM",
|
||||
iv,
|
||||
|
@ -185,7 +190,7 @@ class JWCrypto {
|
|||
*/
|
||||
async function deriveECDHSharedAESKey(privateKey, publicKey, keyUsages) {
|
||||
const params = { ...ECDH_PARAMS, ...{ public: publicKey } };
|
||||
const sharedKey = await crypto.subtle.deriveKey(
|
||||
const sharedKey = await lazy.crypto.subtle.deriveKey(
|
||||
params,
|
||||
privateKey,
|
||||
AES_PARAMS,
|
||||
|
@ -195,7 +200,7 @@ async function deriveECDHSharedAESKey(privateKey, publicKey, keyUsages) {
|
|||
// This is the NIST Concat KDF specialized to a specific set of parameters,
|
||||
// which basically turn it into a single application of SHA256.
|
||||
// The details are from the JWA RFC.
|
||||
let sharedKeyBytes = await crypto.subtle.exportKey("raw", sharedKey);
|
||||
let sharedKeyBytes = await lazy.crypto.subtle.exportKey("raw", sharedKey);
|
||||
sharedKeyBytes = new Uint8Array(sharedKeyBytes);
|
||||
const info = [
|
||||
"\x00\x00\x00\x07A256GCM", // 7-byte algorithm identifier
|
||||
|
@ -210,13 +215,13 @@ async function deriveECDHSharedAESKey(privateKey, publicKey, keyUsages) {
|
|||
const pkcsBuf = Uint8Array.from(
|
||||
Array.prototype.map.call(pkcs, c => c.charCodeAt(0))
|
||||
);
|
||||
const derivedKeyBytes = await crypto.subtle.digest(
|
||||
const derivedKeyBytes = await lazy.crypto.subtle.digest(
|
||||
{
|
||||
name: "SHA-256",
|
||||
},
|
||||
pkcsBuf
|
||||
);
|
||||
return crypto.subtle.importKey(
|
||||
return lazy.crypto.subtle.importKey(
|
||||
"raw",
|
||||
derivedKeyBytes,
|
||||
AES_PARAMS,
|
||||
|
|
|
@ -13,9 +13,10 @@ const { CommonUtils } = ChromeUtils.import(
|
|||
const { XPCOMUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/XPCOMUtils.jsm"
|
||||
);
|
||||
XPCOMUtils.defineLazyGlobalGetters(this, ["crypto"]);
|
||||
const lazy = {};
|
||||
XPCOMUtils.defineLazyGlobalGetters(lazy, ["crypto"]);
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "textEncoder", function() {
|
||||
XPCOMUtils.defineLazyGetter(lazy, "textEncoder", function() {
|
||||
return new TextEncoder();
|
||||
});
|
||||
|
||||
|
@ -51,7 +52,7 @@ var CryptoUtils = {
|
|||
},
|
||||
|
||||
generateRandomBytes(length) {
|
||||
return crypto.getRandomValues(new Uint8Array(length));
|
||||
return lazy.crypto.getRandomValues(new Uint8Array(length));
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -135,7 +136,7 @@ var CryptoUtils = {
|
|||
async hkdfLegacy(ikm, xts, info, len) {
|
||||
ikm = CommonUtils.byteStringToArrayBuffer(ikm);
|
||||
xts = CommonUtils.byteStringToArrayBuffer(xts);
|
||||
info = textEncoder.encode(info);
|
||||
info = lazy.textEncoder.encode(info);
|
||||
const okm = await CryptoUtils.hkdf(ikm, xts, info, len);
|
||||
return CommonUtils.arrayBufferToByteString(okm);
|
||||
},
|
||||
|
@ -148,14 +149,14 @@ var CryptoUtils = {
|
|||
* @returns {Uint8Array}
|
||||
*/
|
||||
async hmac(alg, key, data) {
|
||||
const hmacKey = await crypto.subtle.importKey(
|
||||
const hmacKey = await lazy.crypto.subtle.importKey(
|
||||
"raw",
|
||||
key,
|
||||
{ name: "HMAC", hash: alg },
|
||||
false,
|
||||
["sign"]
|
||||
);
|
||||
const result = await crypto.subtle.sign("HMAC", hmacKey, data);
|
||||
const result = await lazy.crypto.subtle.sign("HMAC", hmacKey, data);
|
||||
return new Uint8Array(result);
|
||||
},
|
||||
|
||||
|
@ -167,14 +168,14 @@ var CryptoUtils = {
|
|||
* @returns {Uint8Array}
|
||||
*/
|
||||
async hkdf(ikm, salt, info, len) {
|
||||
const key = await crypto.subtle.importKey(
|
||||
const key = await lazy.crypto.subtle.importKey(
|
||||
"raw",
|
||||
ikm,
|
||||
{ name: "HKDF" },
|
||||
false,
|
||||
["deriveBits"]
|
||||
);
|
||||
const okm = await crypto.subtle.deriveBits(
|
||||
const okm = await lazy.crypto.subtle.deriveBits(
|
||||
{
|
||||
name: "HKDF",
|
||||
hash: "SHA-256",
|
||||
|
@ -198,14 +199,14 @@ var CryptoUtils = {
|
|||
async pbkdf2Generate(passphrase, salt, iterations, len) {
|
||||
passphrase = CommonUtils.byteStringToArrayBuffer(passphrase);
|
||||
salt = CommonUtils.byteStringToArrayBuffer(salt);
|
||||
const key = await crypto.subtle.importKey(
|
||||
const key = await lazy.crypto.subtle.importKey(
|
||||
"raw",
|
||||
passphrase,
|
||||
{ name: "PBKDF2" },
|
||||
false,
|
||||
["deriveBits"]
|
||||
);
|
||||
const output = await crypto.subtle.deriveBits(
|
||||
const output = await lazy.crypto.subtle.deriveBits(
|
||||
{
|
||||
name: "PBKDF2",
|
||||
hash: "SHA-256",
|
||||
|
@ -469,10 +470,10 @@ var CryptoUtils = {
|
|||
options.hasOwnProperty("payload") &&
|
||||
options.payload
|
||||
) {
|
||||
const buffer = textEncoder.encode(
|
||||
const buffer = lazy.textEncoder.encode(
|
||||
`hawk.1.payload\n${contentType}\n${options.payload}\n`
|
||||
);
|
||||
const hash = await crypto.subtle.digest("SHA-256", buffer);
|
||||
const hash = await lazy.crypto.subtle.digest("SHA-256", buffer);
|
||||
// HAWK specifies this .hash to use +/ (not _-) and include the
|
||||
// trailing "==" padding.
|
||||
artifacts.hash = ChromeUtils.base64URLEncode(hash, { pad: true })
|
||||
|
|
Загрузка…
Ссылка в новой задаче