mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 617650: avoid unrooting string in makeSECItem. r=philiKON
This commit is contained in:
parent
56f91610cc
commit
0b37a22351
@ -419,6 +419,17 @@ WeaveCrypto.prototype = {
|
||||
this.nss.PK11_FreeSlot = nsslib.declare("PK11_FreeSlot",
|
||||
ctypes.default_abi, ctypes.void_t,
|
||||
this.nss_t.PK11SlotInfo.ptr);
|
||||
// security/nss/lib/util/secitem.h#49
|
||||
// extern SECItem *SECITEM_AllocItem(PRArenaPool *arena, SECItem *item, unsigned int len);
|
||||
this.nss.SECITEM_AllocItem = nsslib.declare("SECITEM_AllocItem",
|
||||
ctypes.default_abi, this.nss_t.SECItem.ptr,
|
||||
this.nss_t.PLArenaPool.ptr, // Not used.
|
||||
this.nss_t.SECItem.ptr, ctypes.unsigned_int);
|
||||
// security/nss/lib/util/secitem.h#274
|
||||
// extern void SECITEM_ZfreeItem(SECItem *zap, PRBool freeit);
|
||||
this.nss.SECITEM_ZfreeItem = nsslib.declare("SECITEM_ZfreeItem",
|
||||
ctypes.default_abi, ctypes.void_t,
|
||||
this.nss_t.SECItem.ptr, this.nss_t.PRBool);
|
||||
// security/nss/lib/util/secitem.h#114
|
||||
// extern void SECITEM_FreeItem(SECItem *zap, PRBool freeit);
|
||||
this.nss.SECITEM_FreeItem = nsslib.declare("SECITEM_FreeItem",
|
||||
@ -515,7 +526,7 @@ WeaveCrypto.prototype = {
|
||||
|
||||
let ctx, symKey, slot, ivParam;
|
||||
try {
|
||||
ivParam = this.nss.PK11_ParamFromIV(mechanism, ivItem.address());
|
||||
ivParam = this.nss.PK11_ParamFromIV(mechanism, ivItem);
|
||||
if (ivParam.isNull())
|
||||
throw Components.Exception("can't convert IV to param", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
@ -523,7 +534,7 @@ WeaveCrypto.prototype = {
|
||||
if (slot.isNull())
|
||||
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);
|
||||
symKey = this.nss.PK11_ImportSymKey(slot, mechanism, this.nss.PK11_OriginUnwrap, operation, keyItem, null);
|
||||
if (symKey.isNull())
|
||||
throw Components.Exception("symkey import failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
@ -563,6 +574,8 @@ WeaveCrypto.prototype = {
|
||||
this.nss.PK11_FreeSlot(slot);
|
||||
if (ivParam && !ivParam.isNull())
|
||||
this.nss.SECITEM_FreeItem(ivParam, true);
|
||||
this.freeSECItem(keyItem);
|
||||
this.freeSECItem(ivItem);
|
||||
}
|
||||
},
|
||||
|
||||
@ -684,15 +697,28 @@ WeaveCrypto.prototype = {
|
||||
return btoa(this.expandData(data, len));
|
||||
},
|
||||
|
||||
// Returns a filled SECItem *, as returned by SECITEM_AllocItem.
|
||||
//
|
||||
// Note that this must be released with freeSECItem, which will also
|
||||
// deallocate the internal buffer.
|
||||
makeSECItem : function(input, isEncoded) {
|
||||
if (isEncoded)
|
||||
input = atob(input);
|
||||
let outputData = new ctypes.ArrayType(ctypes.unsigned_char, input.length)();
|
||||
this.byteCompress(input, outputData);
|
||||
|
||||
return new this.nss_t.SECItem(this.nss.SIBUFFER, outputData, outputData.length);
|
||||
|
||||
let len = input.length;
|
||||
let item = this.nss.SECITEM_AllocItem(null, null, len);
|
||||
if (item.isNull())
|
||||
throw "SECITEM_AllocItem failed.";
|
||||
|
||||
let dest = ctypes.cast(item.contents.data, ctypes.unsigned_char.array(len).ptr);
|
||||
this.byteCompress(input, dest.contents);
|
||||
return item;
|
||||
},
|
||||
|
||||
freeSECItem : function(zap) {
|
||||
if (zap && !zap.isNull())
|
||||
this.nss.SECITEM_ZfreeItem(zap, true);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Returns the expanded data string for the derived key.
|
||||
@ -712,7 +738,8 @@ WeaveCrypto.prototype = {
|
||||
let algid, slot, symKey, keyData;
|
||||
try {
|
||||
algid = this.nss.PK11_CreatePBEV2AlgorithmID(pbeAlg, cipherAlg, prfAlg,
|
||||
keyLength, iterations, saltItem.address());
|
||||
keyLength, iterations,
|
||||
saltItem);
|
||||
if (algid.isNull())
|
||||
throw Components.Exception("PK11_CreatePBEV2AlgorithmID failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
@ -720,7 +747,7 @@ WeaveCrypto.prototype = {
|
||||
if (slot.isNull())
|
||||
throw Components.Exception("couldn't get internal slot", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
symKey = this.nss.PK11_PBEKeyGen(slot, algid, passItem.address(), false, null);
|
||||
symKey = this.nss.PK11_PBEKeyGen(slot, algid, passItem, false, null);
|
||||
if (symKey.isNull())
|
||||
throw Components.Exception("PK11_PBEKeyGen failed", Cr.NS_ERROR_FAILURE);
|
||||
|
||||
@ -748,6 +775,9 @@ WeaveCrypto.prototype = {
|
||||
this.nss.PK11_FreeSlot(slot);
|
||||
if (symKey && !symKey.isNull())
|
||||
this.nss.PK11_FreeSymKey(symKey);
|
||||
}
|
||||
|
||||
this.freeSECItem(passItem);
|
||||
this.freeSECItem(saltItem);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -8,7 +8,50 @@ try {
|
||||
.getService(Ci.IWeaveCrypto);
|
||||
}
|
||||
|
||||
function multiple_decrypts(iterations) {
|
||||
let iv = cryptoSvc.generateRandomIV();
|
||||
let key = cryptoSvc.generateRandomKey();
|
||||
let cipherText = cryptoSvc.encrypt("Hello, world.", key, iv);
|
||||
|
||||
for (let i = 0; i < iterations; ++i) {
|
||||
let clearText = cryptoSvc.decrypt(cipherText, key, iv);
|
||||
do_check_eq(clearText + " " + i, "Hello, world. " + i);
|
||||
}
|
||||
_("Done with multiple_decrypts.");
|
||||
}
|
||||
|
||||
function test_bug_617650() {
|
||||
if (this.gczeal) {
|
||||
gczeal(2);
|
||||
// Few iterations, because gczeal(2) is expensive... and makes it fail much faster!
|
||||
_("gczeal set to 2; attempting 10 iterations of multiple_decrypts.");
|
||||
multiple_decrypts(10);
|
||||
gczeal(0);
|
||||
} else {
|
||||
// We can't use gczeal on non-debug builds, so try lots of reps instead.
|
||||
_("No gczeal (non-debug build?); attempting 10,000 iterations of multiple_decrypts.");
|
||||
multiple_decrypts(10000);
|
||||
}
|
||||
}
|
||||
|
||||
// Just verify that it gets populated with the correct bytes.
|
||||
function test_makeSECItem() {
|
||||
Components.utils.import("resource://gre/modules/ctypes.jsm");
|
||||
|
||||
let item1 = cryptoSvc.makeSECItem("abcdefghi", false);
|
||||
do_check_true(!item1.isNull());
|
||||
let intData = ctypes.cast(item1.contents.data, ctypes.uint8_t.array(8).ptr).contents;
|
||||
for (let i = 0; i < 8; ++i)
|
||||
do_check_eq(intData[i], "abcdefghi".charCodeAt(i));
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
|
||||
if ("makeSECItem" in cryptoSvc) // Only for js-ctypes WeaveCrypto.
|
||||
test_makeSECItem();
|
||||
|
||||
test_bug_617650();
|
||||
|
||||
// First, do a normal run with expected usage... Generate a random key and
|
||||
// iv, encrypt and decrypt a string.
|
||||
var iv = cryptoSvc.generateRandomIV();
|
||||
|
Loading…
Reference in New Issue
Block a user