зеркало из https://github.com/mozilla/gecko-dev.git
Bug 604603 - Merge fx-sync to mozilla-central. a=crashes,orange
This commit is contained in:
Коммит
03db1c2c34
|
@ -71,12 +71,6 @@ WeaveCrypto.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
// This is its own method so that it can be overridden.
|
||||
// (Components.Exception isn't thread-safe for instance)
|
||||
makeException : function makeException(message, result) {
|
||||
return Components.Exception(message, result);
|
||||
},
|
||||
|
||||
init : function() {
|
||||
try {
|
||||
// Preferences. Add observer so we get notified of changes.
|
||||
|
@ -108,34 +102,21 @@ WeaveCrypto.prototype = {
|
|||
Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports);
|
||||
|
||||
// Open the NSS library.
|
||||
let nssfile = Services.dirsvc.get("GreD", Ci.nsILocalFile);
|
||||
let os = Services.appinfo.OS;
|
||||
switch (os) {
|
||||
case "WINNT":
|
||||
case "WINMO":
|
||||
case "WINCE":
|
||||
nssfile.append("nss3.dll");
|
||||
break;
|
||||
case "Darwin":
|
||||
nssfile.append("libnss3.dylib");
|
||||
break;
|
||||
case "Linux":
|
||||
case "SunOS":
|
||||
case "WebOS": // Palm Pre
|
||||
nssfile.append("libnss3.so");
|
||||
break;
|
||||
case "Android":
|
||||
// Android uses a $GREDIR/lib/ subdir.
|
||||
nssfile.append("lib");
|
||||
nssfile.append("libnss3.so");
|
||||
break;
|
||||
default:
|
||||
throw this.makeException("unsupported platform: " + os, Cr.NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
this.log("Using NSS library " + nssfile.path);
|
||||
let path = ctypes.libraryName("nss3");
|
||||
|
||||
// XXX really want to be able to pass specific dlopen flags here.
|
||||
let nsslib = ctypes.open(nssfile.path);
|
||||
var nsslib;
|
||||
try {
|
||||
this.log("Trying NSS library without path");
|
||||
nsslib = ctypes.open(path);
|
||||
} catch(e) {
|
||||
// In case opening the library without a full path fails,
|
||||
// try again with a full path.
|
||||
let file = Services.dirsvc.get("GreD", Ci.nsILocalFile);
|
||||
file.append(path);
|
||||
this.log("Trying again with path " + file.path);
|
||||
nsslib = ctypes.open(file.path);
|
||||
}
|
||||
|
||||
this.log("Initializing NSS types and function declarations...");
|
||||
|
||||
|
@ -530,31 +511,31 @@ WeaveCrypto.prototype = {
|
|||
let mechanism = this.nss.PK11_AlgtagToMechanism(this.algorithm);
|
||||
mechanism = this.nss.PK11_GetPadMechanism(mechanism);
|
||||
if (mechanism == this.nss.CKM_INVALID_MECHANISM)
|
||||
throw this.makeException("invalid algorithm (can't pad)", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("invalid algorithm (can't pad)", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
let ctx, symKey, slot, ivParam;
|
||||
try {
|
||||
ivParam = this.nss.PK11_ParamFromIV(mechanism, ivItem.address());
|
||||
if (ivParam.isNull())
|
||||
throw this.makeException("can't convert IV to param", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("can't convert IV to param", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
slot = this.nss.PK11_GetInternalKeySlot();
|
||||
if (slot.isNull())
|
||||
throw this.makeException("can't get internal key slot", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("can't get internal key slot", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
symKey = this.nss.PK11_ImportSymKey(slot, mechanism, this.nss.PK11_OriginUnwrap, operation, keyItem.address(), null);
|
||||
if (symKey.isNull())
|
||||
throw this.makeException("symkey import failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("symkey import failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
ctx = this.nss.PK11_CreateContextBySymKey(mechanism, operation, symKey, ivParam);
|
||||
if (ctx.isNull())
|
||||
throw this.makeException("couldn't create context for symkey", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("couldn't create context for symkey", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
let maxOutputSize = output.length;
|
||||
let tmpOutputSize = new ctypes.int(); // Note 1: NSS uses a signed int here...
|
||||
|
||||
if (this.nss.PK11_CipherOp(ctx, output, tmpOutputSize.address(), maxOutputSize, input, input.length))
|
||||
throw this.makeException("cipher operation failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("cipher operation failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
let actualOutputSize = tmpOutputSize.value;
|
||||
let finalOutput = output.addressOfElement(actualOutputSize);
|
||||
|
@ -565,7 +546,7 @@ WeaveCrypto.prototype = {
|
|||
// cipher operation. You'd think it would be called PK11_CipherOpFinal...
|
||||
let tmpOutputSize2 = new ctypes.unsigned_int(); // Note 2: ...but an unsigned here!
|
||||
if (this.nss.PK11_DigestFinal(ctx, finalOutput, tmpOutputSize2.address(), maxOutputSize))
|
||||
throw this.makeException("cipher finalize failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("cipher finalize failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
actualOutputSize += tmpOutputSize2.value;
|
||||
let newOutput = ctypes.cast(output, ctypes.unsigned_char.array(actualOutputSize));
|
||||
|
@ -604,7 +585,7 @@ WeaveCrypto.prototype = {
|
|||
|
||||
slot = this.nss.PK11_GetInternalSlot();
|
||||
if (slot.isNull())
|
||||
throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
// Generate the keypair.
|
||||
privKey = this.nss.PK11_GenerateKeyPairWithFlags(slot,
|
||||
|
@ -613,18 +594,18 @@ WeaveCrypto.prototype = {
|
|||
pubKey.address(),
|
||||
attrFlags, null);
|
||||
if (privKey.isNull())
|
||||
throw this.makeException("keypair generation failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("keypair generation failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
let s = this.nss.PK11_SetPrivateKeyNickname(privKey, "Weave User PrivKey");
|
||||
if (s)
|
||||
throw this.makeException("key nickname failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("key nickname failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
let wrappedPrivateKey = this._wrapPrivateKey(privKey, passphrase, salt, iv);
|
||||
out_wrappedPrivateKey.value = wrappedPrivateKey; // outparam
|
||||
|
||||
let derKey = this.nss.SECKEY_EncodeDERSubjectPublicKeyInfo(pubKey);
|
||||
if (derKey.isNull())
|
||||
throw this.makeException("SECKEY_EncodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("SECKEY_EncodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
let encodedPublicKey = this.encodeBase64(derKey.contents.data, derKey.contents.len);
|
||||
out_encodedPublicKey.value = encodedPublicKey; // outparam
|
||||
|
@ -664,27 +645,27 @@ WeaveCrypto.prototype = {
|
|||
break;
|
||||
|
||||
default:
|
||||
throw this.makeException("unknown algorithm", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("unknown algorithm", Cr.NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
let slot, randKey, keydata;
|
||||
try {
|
||||
slot = this.nss.PK11_GetInternalSlot();
|
||||
if (slot.isNull())
|
||||
throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
randKey = this.nss.PK11_KeyGen(slot, keygenMech, null, keySize, null);
|
||||
if (randKey.isNull())
|
||||
throw this.makeException("PK11_KeyGen failed.", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("PK11_KeyGen failed.", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
// Slightly odd API, this call just prepares the key value for
|
||||
// extraction, we get the actual bits from the call to PK11_GetKeyData().
|
||||
if (this.nss.PK11_ExtractKeyValue(randKey))
|
||||
throw this.makeException("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
keydata = this.nss.PK11_GetKeyData(randKey);
|
||||
if (keydata.isNull())
|
||||
throw this.makeException("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
return this.encodeBase64(keydata.contents.data, keydata.contents.len);
|
||||
} catch (e) {
|
||||
|
@ -715,7 +696,7 @@ WeaveCrypto.prototype = {
|
|||
// Temporary buffer to hold the generated data.
|
||||
let scratch = new ctypes.ArrayType(ctypes.unsigned_char, byteCount)();
|
||||
if (this.nss.PK11_GenerateRandom(scratch, byteCount))
|
||||
throw this.makeException("PK11_GenrateRandom failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("PK11_GenrateRandom failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
return this.encodeBase64(scratch.address(), scratch.length);
|
||||
},
|
||||
|
@ -738,7 +719,7 @@ WeaveCrypto.prototype = {
|
|||
try {
|
||||
slot = this.nss.PK11_GetInternalSlot();
|
||||
if (slot.isNull())
|
||||
throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
// ImportSymKey wants a mechanism, from which it derives the key type.
|
||||
let keyMech = this.nss.PK11_AlgtagToMechanism(this.algorithm);
|
||||
|
@ -747,7 +728,7 @@ WeaveCrypto.prototype = {
|
|||
// really matter because we're just going to wrap it up and not use it.
|
||||
symKey = this.nss.PK11_ImportSymKey(slot, keyMech, this.nss.PK11_OriginUnwrap, this.nss.CKA_ENCRYPT, symKeyData.address(), null);
|
||||
if (symKey.isNull())
|
||||
throw this.makeException("symkey import failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("symkey import failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
// Step 3. Put the public key bits into a P11 key object.
|
||||
|
||||
|
@ -755,11 +736,11 @@ WeaveCrypto.prototype = {
|
|||
// pubKey = SECKEY_ImportDERPublicKey(&pubKeyData, CKK_RSA);
|
||||
pubKeyInfo = this.nss.SECKEY_DecodeDERSubjectPublicKeyInfo(pubKeyData.address());
|
||||
if (pubKeyInfo.isNull())
|
||||
throw this.makeException("SECKEY_DecodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("SECKEY_DecodeDERSubjectPublicKeyInfo failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
pubKey = this.nss.SECKEY_ExtractPublicKey(pubKeyInfo);
|
||||
if (pubKey.isNull())
|
||||
throw this.makeException("SECKEY_ExtractPublicKey failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("SECKEY_ExtractPublicKey failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
// Step 4. Wrap the symmetric key with the public key.
|
||||
|
||||
|
@ -767,7 +748,7 @@ WeaveCrypto.prototype = {
|
|||
|
||||
let s = this.nss.PK11_PubWrapSymKey(wrapMech, pubKey, symKey, wrappedKey.address());
|
||||
if (s)
|
||||
throw this.makeException("PK11_PubWrapSymKey failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("PK11_PubWrapSymKey failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
// Step 5. Base64 encode the wrapped key, cleanup, and return to caller.
|
||||
return this.encodeBase64(wrappedKey.data, wrappedKey.len);
|
||||
|
@ -807,16 +788,16 @@ WeaveCrypto.prototype = {
|
|||
let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm);
|
||||
wrapMech = this.nss.PK11_GetPadMechanism(wrapMech);
|
||||
if (wrapMech == this.nss.CKM_INVALID_MECHANISM)
|
||||
throw this.makeException("unwrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("unwrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address());
|
||||
if (ivParam.isNull())
|
||||
throw this.makeException("unwrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("unwrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
// Step 3. Unwrap the private key with the key from the passphrase.
|
||||
slot = this.nss.PK11_GetInternalSlot();
|
||||
if (slot.isNull())
|
||||
throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
// Normally, one wants to associate a private key with a public key.
|
||||
// P11_UnwrapPrivKey() passes its keyID arg to PK11_MakeIDFromPubKey(),
|
||||
|
@ -837,7 +818,7 @@ WeaveCrypto.prototype = {
|
|||
privKeyUsage.addressOfElement(0), privKeyUsageLength,
|
||||
null); // wincx
|
||||
if (privKey.isNull())
|
||||
throw this.makeException("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
// Step 4. Unwrap the symmetric key with the user's private key.
|
||||
|
||||
|
@ -846,15 +827,15 @@ WeaveCrypto.prototype = {
|
|||
symKey = this.nss.PK11_PubUnwrapSymKey(privKey, wrappedSymKey.address(), wrapMech,
|
||||
this.nss.CKA_DECRYPT, 0);
|
||||
if (symKey.isNull())
|
||||
throw this.makeException("PK11_PubUnwrapSymKey failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("PK11_PubUnwrapSymKey failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
// Step 5. Base64 encode the unwrapped key, cleanup, and return to caller.
|
||||
if (this.nss.PK11_ExtractKeyValue(symKey))
|
||||
throw this.makeException("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("PK11_ExtractKeyValue failed.", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
symKeyData = this.nss.PK11_GetKeyData(symKey);
|
||||
if (symKeyData.isNull())
|
||||
throw this.makeException("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("PK11_GetKeyData failed.", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
return this.encodeBase64(symKeyData.contents.data, symKeyData.contents.len);
|
||||
} catch (e) {
|
||||
|
@ -894,16 +875,16 @@ WeaveCrypto.prototype = {
|
|||
let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm);
|
||||
wrapMech = this.nss.PK11_GetPadMechanism(wrapMech);
|
||||
if (wrapMech == this.nss.CKM_INVALID_MECHANISM)
|
||||
throw this.makeException("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address());
|
||||
if (ivParam.isNull())
|
||||
throw this.makeException("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
// Step 3. Unwrap the private key with the key from the passphrase.
|
||||
slot = this.nss.PK11_GetInternalSlot();
|
||||
if (slot.isNull())
|
||||
throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
let keyID = ivItem.address();
|
||||
|
||||
|
@ -917,7 +898,7 @@ WeaveCrypto.prototype = {
|
|||
privKeyUsage.addressOfElement(0), privKeyUsageLength,
|
||||
null); // wincx
|
||||
if (privKey.isNull())
|
||||
throw this.makeException("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("PK11_UnwrapPrivKey failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
// Step 4. Rewrap the private key with the new passphrase.
|
||||
return this._wrapPrivateKey(privKey, newPassphrase, salt, iv);
|
||||
|
@ -956,16 +937,16 @@ WeaveCrypto.prototype = {
|
|||
let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm);
|
||||
wrapMech = this.nss.PK11_GetPadMechanism(wrapMech);
|
||||
if (wrapMech == this.nss.CKM_INVALID_MECHANISM)
|
||||
throw this.makeException("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("rewrapSymKey: unknown key mech", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address());
|
||||
if (ivParam.isNull())
|
||||
throw this.makeException("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("rewrapSymKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
// Step 3. Unwrap the private key with the key from the passphrase.
|
||||
slot = this.nss.PK11_GetInternalSlot();
|
||||
if (slot.isNull())
|
||||
throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
let keyID = ivItem.address();
|
||||
|
||||
|
@ -1059,15 +1040,15 @@ WeaveCrypto.prototype = {
|
|||
algid = this.nss.PK11_CreatePBEV2AlgorithmID(pbeAlg, cipherAlg, prfAlg,
|
||||
keyLength, iterations, saltItem.address());
|
||||
if (algid.isNull())
|
||||
throw this.makeException("PK11_CreatePBEV2AlgorithmID failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("PK11_CreatePBEV2AlgorithmID failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
slot = this.nss.PK11_GetInternalSlot();
|
||||
if (slot.isNull())
|
||||
throw this.makeException("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
symKey = this.nss.PK11_PBEKeyGen(slot, algid, passItem.address(), false, null);
|
||||
if (symKey.isNull())
|
||||
throw this.makeException("PK11_PBEKeyGen failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("PK11_PBEKeyGen failed", Cr.NS_ERROR_FAILURE);
|
||||
} catch (e) {
|
||||
this.log("_deriveKeyFromPassphrase: failed: " + e);
|
||||
throw e;
|
||||
|
@ -1095,11 +1076,11 @@ WeaveCrypto.prototype = {
|
|||
let wrapMech = this.nss.PK11_AlgtagToMechanism(this.algorithm);
|
||||
wrapMech = this.nss.PK11_GetPadMechanism(wrapMech);
|
||||
if (wrapMech == this.nss.CKM_INVALID_MECHANISM)
|
||||
throw this.makeException("wrapPrivKey: unknown key mech", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("wrapPrivKey: unknown key mech", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
let ivParam = this.nss.PK11_ParamFromIV(wrapMech, ivItem.address());
|
||||
if (ivParam.isNull())
|
||||
throw this.makeException("wrapPrivKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("wrapPrivKey: PK11_ParamFromIV failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
// Use a buffer to hold the wrapped key. NSS says about 1200 bytes for
|
||||
// a 2048-bit RSA key, so a 4096 byte buffer should be plenty.
|
||||
|
@ -1111,7 +1092,7 @@ WeaveCrypto.prototype = {
|
|||
wrapMech, ivParam,
|
||||
wrappedKey.address(), null);
|
||||
if (s)
|
||||
throw this.makeException("wrapPrivKey: PK11_WrapPrivKey failed", Cr.NS_ERROR_FAILURE);
|
||||
throw Components.Exception("wrapPrivKey: PK11_WrapPrivKey failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
return this.encodeBase64(wrappedKey.data, wrappedKey.len);
|
||||
} catch (e) {
|
||||
|
|
|
@ -1,150 +0,0 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Firefox Sync.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Philipp von Weitershausen <philipp@weitershausen>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
const EXPORTED_SYMBOLS = ["ThreadedCrypto"];
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://services-sync/ext/Sync.js");
|
||||
Cu.import("resource://services-crypto/WeaveCrypto.js");
|
||||
|
||||
/*
|
||||
* Execute a function in a thread.
|
||||
*/
|
||||
function Runner(func, thisObj, returnval, error) {
|
||||
this.func = func;
|
||||
this.thisObj = thisObj;
|
||||
this.returnval = returnval;
|
||||
this.error = error;
|
||||
}
|
||||
Runner.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRunnable]),
|
||||
|
||||
run: function run() {
|
||||
let ex = this.error;
|
||||
if (ex) {
|
||||
this.func.throw(ex);
|
||||
} else {
|
||||
this.func.call(this.thisObj, this.returnval);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Execute a function in a thread and notify a callback on another thread
|
||||
* afterward.
|
||||
*/
|
||||
function CallbackRunner(func, thisObj, args, callback, cbThread) {
|
||||
this.func = func;
|
||||
this.thisObj = thisObj;
|
||||
this.args = args;
|
||||
this.callback = callback;
|
||||
this.cbThread = cbThread;
|
||||
}
|
||||
CallbackRunner.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIRunnable]),
|
||||
|
||||
run: function run() {
|
||||
let returnval, error;
|
||||
try {
|
||||
returnval = this.func.apply(this.thisObj, this.args);
|
||||
} catch(ex) {
|
||||
error = ex;
|
||||
}
|
||||
this.cbThread.dispatch(new Runner(this.callback, this.thisObj,
|
||||
returnval, error),
|
||||
Ci.nsIThread.DISPATCH_NORMAL);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Implementation of IWeaveCrypto that defers method calls to another thread
|
||||
* but keeps the synchronous API. (Don't ask...)
|
||||
*/
|
||||
function ThreadedCrypto() {
|
||||
this.backgroundThread = Services.tm.newThread(0);
|
||||
this.crypto = new WeaveCrypto();
|
||||
|
||||
// Components.Exception isn't thread-safe.
|
||||
this.crypto.makeException = function makeException(message, result) {
|
||||
return result;
|
||||
};
|
||||
|
||||
// Make sure to kill the thread before XPCOM shuts down.
|
||||
Services.obs.addObserver(this, "profile-before-change", true);
|
||||
}
|
||||
ThreadedCrypto.deferToThread = function deferToThread(methodname) {
|
||||
return function threadMethod() {
|
||||
// Dispatch method call to background thread.
|
||||
let args = Array.slice(arguments);
|
||||
return Sync(function(callback) {
|
||||
let runner = new CallbackRunner(this.crypto[methodname], this.crypto,
|
||||
args, callback, Services.tm.mainThread);
|
||||
this.backgroundThread.dispatch(runner, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
}, this)();
|
||||
};
|
||||
};
|
||||
ThreadedCrypto.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.IWeaveCrypto,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
observe: function observe() {
|
||||
this.backgroundThread.shutdown();
|
||||
},
|
||||
|
||||
get algorithm() this.crypto.algorithm,
|
||||
set algorithm(value) this.crypto.algorithm = value,
|
||||
|
||||
get keypairBits() this.crypto.keypairBits,
|
||||
set keypairBits(value) this.crypto.keypairBits = value,
|
||||
|
||||
encrypt: ThreadedCrypto.deferToThread("encrypt"),
|
||||
decrypt: ThreadedCrypto.deferToThread("decrypt"),
|
||||
generateKeypair: ThreadedCrypto.deferToThread("generateKeypair"),
|
||||
generateRandomKey: ThreadedCrypto.deferToThread("generateRandomKey"),
|
||||
generateRandomIV: ThreadedCrypto.deferToThread("generateRandomIV"),
|
||||
generateRandomBytes: ThreadedCrypto.deferToThread("generateRandomBytes"),
|
||||
wrapSymmetricKey: ThreadedCrypto.deferToThread("wrapSymmetricKey"),
|
||||
unwrapSymmetricKey: ThreadedCrypto.deferToThread("unwrapSymmetricKey"),
|
||||
rewrapPrivateKey: ThreadedCrypto.deferToThread("rewrapPrivateKey"),
|
||||
verifyPassphrase: ThreadedCrypto.deferToThread("verifyPassphrase")
|
||||
};
|
|
@ -11,8 +11,6 @@ try {
|
|||
}
|
||||
catch(ex) {
|
||||
|
||||
do_get_profile();
|
||||
|
||||
// Make sure to provide the right OS so crypto loads the right binaries
|
||||
let OS = "XPCShell";
|
||||
if ("@mozilla.org/windows-registry-key;1" in Cc)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
let cryptoSvc;
|
||||
try {
|
||||
Components.utils.import("resource://services-crypto/threaded.js");
|
||||
cryptoSvc = new ThreadedCrypto();
|
||||
Components.utils.import("resource://services-crypto/WeaveCrypto.js");
|
||||
cryptoSvc = new WeaveCrypto();
|
||||
} catch (ex) {
|
||||
// Fallback to binary WeaveCrypto
|
||||
cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
let cryptoSvc;
|
||||
try {
|
||||
Components.utils.import("resource://services-crypto/threaded.js");
|
||||
cryptoSvc = new ThreadedCrypto();
|
||||
Components.utils.import("resource://services-crypto/WeaveCrypto.js");
|
||||
cryptoSvc = new WeaveCrypto();
|
||||
} catch (ex) {
|
||||
// Fallback to binary WeaveCrypto
|
||||
cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
let cryptoSvc;
|
||||
try {
|
||||
Components.utils.import("resource://services-crypto/threaded.js");
|
||||
cryptoSvc = new ThreadedCrypto();
|
||||
Components.utils.import("resource://services-crypto/WeaveCrypto.js");
|
||||
cryptoSvc = new WeaveCrypto();
|
||||
} catch (ex) {
|
||||
// Fallback to binary WeaveCrypto
|
||||
cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
let cryptoSvc;
|
||||
try {
|
||||
Components.utils.import("resource://services-crypto/threaded.js");
|
||||
cryptoSvc = new ThreadedCrypto();
|
||||
Components.utils.import("resource://services-crypto/WeaveCrypto.js");
|
||||
cryptoSvc = new WeaveCrypto();
|
||||
} catch (ex) {
|
||||
// Fallback to binary WeaveCrypto
|
||||
cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
let cryptoSvc;
|
||||
try {
|
||||
Components.utils.import("resource://services-crypto/threaded.js");
|
||||
cryptoSvc = new ThreadedCrypto();
|
||||
Components.utils.import("resource://services-crypto/WeaveCrypto.js");
|
||||
cryptoSvc = new WeaveCrypto();
|
||||
} catch (ex) {
|
||||
// Fallback to binary WeaveCrypto
|
||||
cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"]
|
||||
|
|
|
@ -1039,8 +1039,8 @@ Svc.__defineGetter__("Crypto", function() {
|
|||
let cryptoSvc;
|
||||
try {
|
||||
let ns = {};
|
||||
Cu.import("resource://services-crypto/threaded.js", ns);
|
||||
cryptoSvc = new ns.ThreadedCrypto();
|
||||
Cu.import("resource://services-crypto/WeaveCrypto.js", ns);
|
||||
cryptoSvc = new ns.WeaveCrypto();
|
||||
} catch (ex) {
|
||||
// Fallback to binary WeaveCrypto
|
||||
cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"].
|
||||
|
|
|
@ -3,6 +3,9 @@ Cu.import("resource://services-sync/util.js");
|
|||
Cu.import("resource://services-sync/log4moz.js");
|
||||
|
||||
function run_test() {
|
||||
if (DISABLE_TESTS_BUG_604565)
|
||||
return;
|
||||
|
||||
let logger = Log4Moz.repository.rootLogger;
|
||||
Log4Moz.repository.rootLogger.addAppender(new Log4Moz.DumpAppender());
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче