mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge with backed out changeset
This commit is contained in:
commit
1676f8958b
@ -179,46 +179,5 @@ interface IWeaveCrypto : nsISupports
|
|||||||
in ACString aPassphrase,
|
in ACString aPassphrase,
|
||||||
in ACString aSalt,
|
in ACString aSalt,
|
||||||
in ACString aIV);
|
in ACString aIV);
|
||||||
|
|
||||||
/**
|
|
||||||
* Rewrap a private key with a new user passphrase.
|
|
||||||
*
|
|
||||||
* @param aWrappedPrivateKey
|
|
||||||
* The base64 encoded string holding an encrypted private key.
|
|
||||||
* @param aPassphrase
|
|
||||||
* The passphrase to decrypt the private key.
|
|
||||||
* @param aSalt
|
|
||||||
* The salt for the passphrase.
|
|
||||||
* @param aIV
|
|
||||||
* The random IV used when unwrapping the private key.
|
|
||||||
* @param aNewPassphrase
|
|
||||||
* The new passphrase to wrap the private key with.
|
|
||||||
* @returns The (re)wrapped private key, base64 encoded
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
ACString rewrapPrivateKey(in ACString aWrappedPrivateKey,
|
|
||||||
in ACString aPassphrase,
|
|
||||||
in ACString aSalt,
|
|
||||||
in ACString aIV,
|
|
||||||
in ACString aNewPassphrase);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify a user's passphrase against a private key.
|
|
||||||
*
|
|
||||||
* @param aWrappedPrivateKey
|
|
||||||
* The base64 encoded string holding an encrypted private key.
|
|
||||||
* @param aPassphrase
|
|
||||||
* The passphrase to decrypt the private key.
|
|
||||||
* @param aSalt
|
|
||||||
* The salt for the passphrase.
|
|
||||||
* @param aIV
|
|
||||||
* The random IV used when unwrapping the private key.
|
|
||||||
* @returns Boolean true if the passphrase decrypted the key correctly.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
boolean verifyPassphrase(in ACString aWrappedPrivateKey,
|
|
||||||
in ACString aPassphrase,
|
|
||||||
in ACString aSalt,
|
|
||||||
in ACString aIV);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1005,194 +1005,3 @@ unwrap_done:
|
|||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* RewrapPrivateKey
|
|
||||||
*/
|
|
||||||
NS_IMETHODIMP
|
|
||||||
WeaveCrypto::RewrapPrivateKey(const nsACString& aWrappedPrivateKey,
|
|
||||||
const nsACString& aPassphrase,
|
|
||||||
const nsACString& aSalt,
|
|
||||||
const nsACString& aIV,
|
|
||||||
const nsACString& aNewPassphrase,
|
|
||||||
nsACString& aPrivateKey)
|
|
||||||
{
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
PK11SlotInfo *slot = nsnull;
|
|
||||||
PK11SymKey *pbeKey = nsnull;
|
|
||||||
SECKEYPrivateKey *privKey = nsnull;
|
|
||||||
SECItem *ivParam = nsnull;
|
|
||||||
SECItem *keyID = nsnull;
|
|
||||||
|
|
||||||
CK_ATTRIBUTE_TYPE privKeyUsage[] = { CKA_UNWRAP };
|
|
||||||
PRUint32 privKeyUsageLength = sizeof(privKeyUsage) / sizeof(CK_ATTRIBUTE_TYPE);
|
|
||||||
|
|
||||||
// Step 1. Get rid of the base64 encoding on the inputs.
|
|
||||||
char privateKeyBuffer[STACK_BUFFER_SIZE];
|
|
||||||
PRUint32 privateKeyBufferSize = sizeof(privateKeyBuffer);
|
|
||||||
rv = DecodeBase64(aWrappedPrivateKey, privateKeyBuffer, &privateKeyBufferSize);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
SECItem wrappedPrivKey = {siBuffer, (unsigned char *)privateKeyBuffer, privateKeyBufferSize};
|
|
||||||
|
|
||||||
|
|
||||||
// Step 2. Convert the passphrase to a symmetric key and get the IV in the proper form.
|
|
||||||
rv = DeriveKeyFromPassphrase(aPassphrase, aSalt, &pbeKey);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
char ivData[STACK_BUFFER_SIZE];
|
|
||||||
PRUint32 ivDataSize = sizeof(ivData);
|
|
||||||
rv = DecodeBase64(aIV, ivData, &ivDataSize);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
SECItem ivItem = {siBuffer, (unsigned char*)ivData, ivDataSize};
|
|
||||||
|
|
||||||
// AES_128_CBC --> CKM_AES_CBC --> CKM_AES_CBC_PAD
|
|
||||||
CK_MECHANISM_TYPE wrapMech = PK11_AlgtagToMechanism(mAlgorithm);
|
|
||||||
wrapMech = PK11_GetPadMechanism(wrapMech);
|
|
||||||
if (wrapMech == CKM_INVALID_MECHANISM) {
|
|
||||||
NS_WARNING("Unknown key mechanism");
|
|
||||||
rv = NS_ERROR_FAILURE;
|
|
||||||
goto rewrap_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
ivParam = PK11_ParamFromIV(wrapMech, &ivItem);
|
|
||||||
if (!ivParam) {
|
|
||||||
NS_WARNING("Couldn't create IV param");
|
|
||||||
rv = NS_ERROR_FAILURE;
|
|
||||||
goto rewrap_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3. Unwrap the private key with the key from the passphrase.
|
|
||||||
slot = PK11_GetInternalSlot();
|
|
||||||
if (!slot) {
|
|
||||||
NS_WARNING("Can't get internal PK11 slot");
|
|
||||||
rv = NS_ERROR_FAILURE;
|
|
||||||
goto rewrap_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
keyID = &ivItem;
|
|
||||||
privKey = PK11_UnwrapPrivKey(slot,
|
|
||||||
pbeKey, wrapMech, ivParam, &wrappedPrivKey,
|
|
||||||
nsnull,
|
|
||||||
keyID,
|
|
||||||
PR_FALSE,
|
|
||||||
PR_TRUE,
|
|
||||||
CKK_RSA,
|
|
||||||
privKeyUsage, privKeyUsageLength,
|
|
||||||
nsnull);
|
|
||||||
if (!privKey) {
|
|
||||||
NS_WARNING("PK11_UnwrapPrivKey failed");
|
|
||||||
rv = NS_ERROR_FAILURE;
|
|
||||||
goto rewrap_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 4. Rewrap the private key with the new passphrase.
|
|
||||||
rv = WrapPrivateKey(privKey, aNewPassphrase, aSalt, aIV, aPrivateKey);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
NS_WARNING("RewrapPrivateKey failed");
|
|
||||||
rv = NS_ERROR_FAILURE;
|
|
||||||
goto rewrap_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
rewrap_done:
|
|
||||||
if (privKey)
|
|
||||||
SECKEY_DestroyPrivateKey(privKey);
|
|
||||||
if (pbeKey)
|
|
||||||
PK11_FreeSymKey(pbeKey);
|
|
||||||
if (slot)
|
|
||||||
PK11_FreeSlot(slot);
|
|
||||||
if (ivParam)
|
|
||||||
SECITEM_FreeItem(ivParam, PR_TRUE);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* VerifyPassphrase
|
|
||||||
*/
|
|
||||||
NS_IMETHODIMP
|
|
||||||
WeaveCrypto::VerifyPassphrase(const nsACString& aWrappedPrivateKey,
|
|
||||||
const nsACString& aPassphrase,
|
|
||||||
const nsACString& aSalt,
|
|
||||||
const nsACString& aIV,
|
|
||||||
PRBool *result)
|
|
||||||
{
|
|
||||||
*result = PR_FALSE;
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
PK11SlotInfo *slot = nsnull;
|
|
||||||
PK11SymKey *pbeKey = nsnull;
|
|
||||||
SECKEYPrivateKey *privKey = nsnull;
|
|
||||||
SECItem *ivParam = nsnull;
|
|
||||||
SECItem *keyID = nsnull;
|
|
||||||
|
|
||||||
CK_ATTRIBUTE_TYPE privKeyUsage[] = { CKA_UNWRAP };
|
|
||||||
PRUint32 privKeyUsageLength = sizeof(privKeyUsage) / sizeof(CK_ATTRIBUTE_TYPE);
|
|
||||||
|
|
||||||
// Step 1. Get rid of the base64 encoding on the input.
|
|
||||||
char privateKeyBuffer[STACK_BUFFER_SIZE];
|
|
||||||
PRUint32 privateKeyBufferSize = sizeof(privateKeyBuffer);
|
|
||||||
rv = DecodeBase64(aWrappedPrivateKey, privateKeyBuffer, &privateKeyBufferSize);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
SECItem wrappedPrivKey = {siBuffer, (unsigned char *)privateKeyBuffer, privateKeyBufferSize};
|
|
||||||
|
|
||||||
// Step 2. Convert the passphrase to a symmetric key and get the IV in the proper form.
|
|
||||||
rv = DeriveKeyFromPassphrase(aPassphrase, aSalt, &pbeKey);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
char ivData[STACK_BUFFER_SIZE];
|
|
||||||
PRUint32 ivDataSize = sizeof(ivData);
|
|
||||||
rv = DecodeBase64(aIV, ivData, &ivDataSize);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
SECItem ivItem = {siBuffer, (unsigned char*)ivData, ivDataSize};
|
|
||||||
|
|
||||||
// AES_128_CBC --> CKM_AES_CBC --> CKM_AES_CBC_PAD
|
|
||||||
CK_MECHANISM_TYPE wrapMech = PK11_AlgtagToMechanism(mAlgorithm);
|
|
||||||
wrapMech = PK11_GetPadMechanism(wrapMech);
|
|
||||||
if (wrapMech == CKM_INVALID_MECHANISM) {
|
|
||||||
NS_WARNING("Unknown key mechanism");
|
|
||||||
rv = NS_ERROR_FAILURE;
|
|
||||||
goto verify_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
ivParam = PK11_ParamFromIV(wrapMech, &ivItem);
|
|
||||||
if (!ivParam) {
|
|
||||||
NS_WARNING("Couldn't create IV param");
|
|
||||||
rv = NS_ERROR_FAILURE;
|
|
||||||
goto verify_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3. Unwrap the private key with the key from the passphrase.
|
|
||||||
slot = PK11_GetInternalSlot();
|
|
||||||
if (!slot) {
|
|
||||||
NS_WARNING("Can't get internal PK11 slot");
|
|
||||||
rv = NS_ERROR_FAILURE;
|
|
||||||
goto verify_done;
|
|
||||||
}
|
|
||||||
|
|
||||||
keyID = &ivItem;
|
|
||||||
privKey = PK11_UnwrapPrivKey(slot,
|
|
||||||
pbeKey, wrapMech, ivParam, &wrappedPrivKey,
|
|
||||||
nsnull,
|
|
||||||
keyID,
|
|
||||||
PR_FALSE,
|
|
||||||
PR_TRUE,
|
|
||||||
CKK_RSA,
|
|
||||||
privKeyUsage, privKeyUsageLength,
|
|
||||||
nsnull);
|
|
||||||
if (!privKey) {
|
|
||||||
NS_WARNING("PK11_UnwrapPrivKey failed");
|
|
||||||
} else {
|
|
||||||
*result = PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
verify_done:
|
|
||||||
if (privKey)
|
|
||||||
SECKEY_DestroyPrivateKey(privKey);
|
|
||||||
if (pbeKey)
|
|
||||||
PK11_FreeSymKey(pbeKey);
|
|
||||||
if (slot)
|
|
||||||
PK11_FreeSlot(slot);
|
|
||||||
if (ivParam)
|
|
||||||
SECITEM_FreeItem(ivParam, PR_TRUE);
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -1,35 +0,0 @@
|
|||||||
function run_test() {
|
|
||||||
var cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"].
|
|
||||||
getService(Ci.IWeaveCrypto);
|
|
||||||
|
|
||||||
var salt = cryptoSvc.generateRandomBytes(16);
|
|
||||||
var iv = cryptoSvc.generateRandomIV();
|
|
||||||
var symKey = cryptoSvc.generateRandomKey();
|
|
||||||
|
|
||||||
// Tests with a 2048 bit key (the default)
|
|
||||||
do_check_eq(cryptoSvc.keypairBits, 2048)
|
|
||||||
var pubOut = {};
|
|
||||||
var privOut = {};
|
|
||||||
cryptoSvc.generateKeypair("old passphrase", salt, iv, pubOut, privOut);
|
|
||||||
var pubKey = pubOut.value;
|
|
||||||
var privKey = privOut.value;
|
|
||||||
|
|
||||||
// do some key wrapping
|
|
||||||
var wrappedKey = cryptoSvc.wrapSymmetricKey(symKey, pubKey);
|
|
||||||
var unwrappedKey = cryptoSvc.unwrapSymmetricKey(wrappedKey, privKey,
|
|
||||||
"old passphrase", salt, iv);
|
|
||||||
|
|
||||||
// Is our unwrapped key the same thing we started with?
|
|
||||||
do_check_eq(unwrappedKey, symKey);
|
|
||||||
|
|
||||||
// Rewrap key with a new passphrase
|
|
||||||
var newPrivKey = cryptoSvc.rewrapPrivateKey(privKey, "old passphrase",
|
|
||||||
salt, iv, "new passphrase");
|
|
||||||
|
|
||||||
// Unwrap symkey with new symkey
|
|
||||||
var newUnwrappedKey = cryptoSvc.unwrapSymmetricKey(wrappedKey, newPrivKey,
|
|
||||||
"new passphrase", salt, iv);
|
|
||||||
|
|
||||||
// The acid test... Is this unwrapped symkey the same as before?
|
|
||||||
do_check_eq(newUnwrappedKey, unwrappedKey);
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
function run_test() {
|
|
||||||
var cryptoSvc = Cc["@labs.mozilla.com/Weave/Crypto;1"].
|
|
||||||
getService(Ci.IWeaveCrypto);
|
|
||||||
|
|
||||||
var salt = cryptoSvc.generateRandomBytes(16);
|
|
||||||
var iv = cryptoSvc.generateRandomIV();
|
|
||||||
|
|
||||||
// Tests with a 2048 bit key (the default)
|
|
||||||
do_check_eq(cryptoSvc.keypairBits, 2048)
|
|
||||||
var privOut = {};
|
|
||||||
cryptoSvc.generateKeypair("passphrase", salt, iv, {}, privOut);
|
|
||||||
var privKey = privOut.value;
|
|
||||||
|
|
||||||
// Check with correct passphrase
|
|
||||||
var shouldBeTrue = cryptoSvc.verifyPassphrase(privKey, "passphrase",
|
|
||||||
salt, iv);
|
|
||||||
do_check_eq(shouldBeTrue, true);
|
|
||||||
|
|
||||||
// Check with incorrect passphrase
|
|
||||||
var shouldBeFalse = cryptoSvc.verifyPassphrase(privKey, "NotPassphrase",
|
|
||||||
salt, iv);
|
|
||||||
do_check_eq(shouldBeFalse, false);
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user