mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-12 10:17:31 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
19
services/crypto/component/moz.build
Normal file
19
services/crypto/component/moz.build
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsISyncJPAKE.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'services-crypto-component'
|
||||
|
||||
SOURCES += [
|
||||
'nsSyncJPAKE.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
103
services/crypto/component/nsISyncJPAKE.idl
Normal file
103
services/crypto/component/nsISyncJPAKE.idl
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(5ab02a98-5122-4b90-93cd-f259c4b42e3a)]
|
||||
interface nsISyncJPAKE : nsISupports
|
||||
{
|
||||
/**
|
||||
* Perform first round of the JPAKE exchange.
|
||||
*
|
||||
* @param aSignerID
|
||||
* String identifying the signer.
|
||||
* @param aGX1
|
||||
* Schnorr signature value g^x1, in hex representation.
|
||||
* @param aGV1
|
||||
* Schnorr signature value g^v1 (v1 is a random value), in hex
|
||||
* representation.
|
||||
* @param aR1
|
||||
* Schnorr signature value r1 = v1 - x1 * h, in hex representation.
|
||||
* @param aGX2
|
||||
* Schnorr signature value g^x2, in hex representation.
|
||||
* @param aGV2
|
||||
* Schnorr signature value g^v2 (v2 is a random value), in hex
|
||||
* representation.
|
||||
* @param aR2
|
||||
* Schnorr signature value r2 = v2 - x2 * h, in hex representation.
|
||||
*/
|
||||
void round1(in ACString aSignerID,
|
||||
out ACString aGX1,
|
||||
out ACString aGV1,
|
||||
out ACString aR1,
|
||||
out ACString aGX2,
|
||||
out ACString aGV2,
|
||||
out ACString aR2);
|
||||
|
||||
/**
|
||||
* Perform second round of the JPAKE exchange.
|
||||
*
|
||||
* @param aPeerID
|
||||
* String identifying the peer.
|
||||
* @param aPIN
|
||||
* String containing the weak secret (PIN).
|
||||
* @param aGX3
|
||||
* Schnorr signature value g^x3, in hex representation.
|
||||
* @param aGV3
|
||||
* Schnorr signature value g^v3 (v3 is a random value), in hex
|
||||
* representation.
|
||||
* @param aR3
|
||||
* Schnorr signature value r3 = v3 - x3 * h, in hex representation.
|
||||
* @param aGX4
|
||||
* Schnorr signature value g^x4, in hex representation.
|
||||
* @param aGV4
|
||||
* Schnorr signature value g^v4 (v4 is a random value), in hex
|
||||
* representation.
|
||||
* @param aR4
|
||||
* Schnorr signature value r4 = v4 - x4 * h, in hex representation.
|
||||
* @param aA
|
||||
* Schnorr signature value A, in hex representation.
|
||||
* @param aGVA
|
||||
* Schnorr signature value g^va (va is a random value), in hex
|
||||
* representation.
|
||||
* @param aRA
|
||||
* Schnorr signature value ra = va - xa * h, in hex representation.
|
||||
*/
|
||||
void round2(in ACString aPeerID,
|
||||
in ACString aPIN,
|
||||
in ACString aGX3,
|
||||
in ACString aGV3,
|
||||
in ACString aR3,
|
||||
in ACString aGX4,
|
||||
in ACString aGV4,
|
||||
in ACString aR4,
|
||||
out ACString aA,
|
||||
out ACString aGVA,
|
||||
out ACString aRA);
|
||||
|
||||
/**
|
||||
* Perform the final step of the JPAKE exchange. This will compute
|
||||
* the key and expand the key to two keys, an AES256 encryption key
|
||||
* and a 256 bit HMAC key. It returns a key confirmation value
|
||||
* (SHA256d of the key) and the encryption and HMAC keys.
|
||||
*
|
||||
* @param aB
|
||||
* Schnorr signature value B, in hex representation.
|
||||
* @param aGVB
|
||||
* Schnorr signature value g^vb (vb is a random value), in hex
|
||||
* representation.
|
||||
* @param aRB
|
||||
* Schnorr signature value rb = vb - xb * h, in hex representation.
|
||||
* @param aAES256Key
|
||||
* The AES 256 encryption key, in base64 representation.
|
||||
* @param aHMAC256Key
|
||||
* The 256 bit HMAC key, in base64 representation.
|
||||
*/
|
||||
void final(in ACString aB,
|
||||
in ACString aGVB,
|
||||
in ACString aRB,
|
||||
in ACString aHkdfInfo,
|
||||
out ACString aAES256Key,
|
||||
out ACString aHMAC256Key);
|
||||
};
|
||||
484
services/crypto/component/nsSyncJPAKE.cpp
Normal file
484
services/crypto/component/nsSyncJPAKE.cpp
Normal file
|
|
@ -0,0 +1,484 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsSyncJPAKE.h"
|
||||
|
||||
#include "base64.h"
|
||||
#include "keyhi.h"
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsError.h"
|
||||
#include "nsString.h"
|
||||
#include "nscore.h"
|
||||
#include "pk11pub.h"
|
||||
#include "pkcs11.h"
|
||||
#include "secerr.h"
|
||||
#include "secmodt.h"
|
||||
#include "secport.h"
|
||||
|
||||
using mozilla::fallible;
|
||||
|
||||
static bool
|
||||
hex_from_2char(const unsigned char *c2, unsigned char *byteval)
|
||||
{
|
||||
int i;
|
||||
unsigned char offset;
|
||||
*byteval = 0;
|
||||
for (i=0; i<2; i++) {
|
||||
if (c2[i] >= '0' && c2[i] <= '9') {
|
||||
offset = c2[i] - '0';
|
||||
*byteval |= offset << 4*(1-i);
|
||||
} else if (c2[i] >= 'a' && c2[i] <= 'f') {
|
||||
offset = c2[i] - 'a';
|
||||
*byteval |= (offset + 10) << 4*(1-i);
|
||||
} else if (c2[i] >= 'A' && c2[i] <= 'F') {
|
||||
offset = c2[i] - 'A';
|
||||
*byteval |= (offset + 10) << 4*(1-i);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
fromHex(const char * str, unsigned char * p, size_t sLen)
|
||||
{
|
||||
size_t i;
|
||||
if (sLen & 1)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < sLen / 2; ++i) {
|
||||
if (!hex_from_2char((const unsigned char *) str + (2*i),
|
||||
(unsigned char *) p + i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
fromHexString(const nsACString & str, unsigned char * p, size_t pMaxLen)
|
||||
{
|
||||
char * strData = (char *) str.Data();
|
||||
unsigned len = str.Length();
|
||||
NS_ENSURE_ARG(len / 2 <= pMaxLen);
|
||||
if (!fromHex(strData, p, len)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool
|
||||
toHexString(const unsigned char * str, unsigned len, nsACString & out)
|
||||
{
|
||||
static const char digits[] = "0123456789ABCDEF";
|
||||
if (!out.SetCapacity(2 * len, fallible))
|
||||
return false;
|
||||
out.SetLength(0);
|
||||
for (unsigned i = 0; i < len; ++i) {
|
||||
out.Append(digits[str[i] >> 4]);
|
||||
out.Append(digits[str[i] & 0x0f]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
mapErrno()
|
||||
{
|
||||
int err = PORT_GetError();
|
||||
switch (err) {
|
||||
case SEC_ERROR_NO_MEMORY: return NS_ERROR_OUT_OF_MEMORY;
|
||||
default: return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
#define NUM_ELEM(x) (sizeof(x) / sizeof (x)[0])
|
||||
|
||||
static const char p[] =
|
||||
"90066455B5CFC38F9CAA4A48B4281F292C260FEEF01FD61037E56258A7795A1C"
|
||||
"7AD46076982CE6BB956936C6AB4DCFE05E6784586940CA544B9B2140E1EB523F"
|
||||
"009D20A7E7880E4E5BFA690F1B9004A27811CD9904AF70420EEFD6EA11EF7DA1"
|
||||
"29F58835FF56B89FAA637BC9AC2EFAAB903402229F491D8D3485261CD068699B"
|
||||
"6BA58A1DDBBEF6DB51E8FE34E8A78E542D7BA351C21EA8D8F1D29F5D5D159394"
|
||||
"87E27F4416B0CA632C59EFD1B1EB66511A5A0FBF615B766C5862D0BD8A3FE7A0"
|
||||
"E0DA0FB2FE1FCB19E8F9996A8EA0FCCDE538175238FC8B0EE6F29AF7F642773E"
|
||||
"BE8CD5402415A01451A840476B2FCEB0E388D30D4B376C37FE401C2A2C2F941D"
|
||||
"AD179C540C1C8CE030D460C4D983BE9AB0B20F69144C1AE13F9383EA1C08504F"
|
||||
"B0BF321503EFE43488310DD8DC77EC5B8349B8BFE97C2C560EA878DE87C11E3D"
|
||||
"597F1FEA742D73EEC7F37BE43949EF1A0D15C3F3E3FC0A8335617055AC91328E"
|
||||
"C22B50FC15B941D3D1624CD88BC25F3E941FDDC6200689581BFEC416B4B2CB73";
|
||||
static const char q[] =
|
||||
"CFA0478A54717B08CE64805B76E5B14249A77A4838469DF7F7DC987EFCCFB11D";
|
||||
static const char g[] =
|
||||
"5E5CBA992E0A680D885EB903AEA78E4A45A469103D448EDE3B7ACCC54D521E37"
|
||||
"F84A4BDD5B06B0970CC2D2BBB715F7B82846F9A0C393914C792E6A923E2117AB"
|
||||
"805276A975AADB5261D91673EA9AAFFEECBFA6183DFCB5D3B7332AA19275AFA1"
|
||||
"F8EC0B60FB6F66CC23AE4870791D5982AAD1AA9485FD8F4A60126FEB2CF05DB8"
|
||||
"A7F0F09B3397F3937F2E90B9E5B9C9B6EFEF642BC48351C46FB171B9BFA9EF17"
|
||||
"A961CE96C7E7A7CC3D3D03DFAD1078BA21DA425198F07D2481622BCE45969D9C"
|
||||
"4D6063D72AB7A0F08B2F49A7CC6AF335E08C4720E31476B67299E231F8BD90B3"
|
||||
"9AC3AE3BE0C6B6CACEF8289A2E2873D58E51E029CAFBD55E6841489AB66B5B4B"
|
||||
"9BA6E2F784660896AFF387D92844CCB8B69475496DE19DA2E58259B090489AC8"
|
||||
"E62363CDF82CFD8EF2A427ABCD65750B506F56DDE3B988567A88126B914D7828"
|
||||
"E2B63A6D7ED0747EC59E0E0A23CE7D8A74C1D2C2A7AFB6A29799620F00E11C33"
|
||||
"787F7DED3B30E1A22D09F1FBDA1ABBBFBF25CAE05A13F812E34563F99410E73B";
|
||||
|
||||
NS_IMETHODIMP nsSyncJPAKE::Round1(const nsACString & aSignerID,
|
||||
nsACString & aGX1,
|
||||
nsACString & aGV1,
|
||||
nsACString & aR1,
|
||||
nsACString & aGX2,
|
||||
nsACString & aGV2,
|
||||
nsACString & aR2)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
if (isAlreadyShutDown()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_ENSURE_STATE(round == JPAKENotStarted);
|
||||
NS_ENSURE_STATE(key == nullptr);
|
||||
|
||||
static CK_MECHANISM_TYPE mechanisms[] = {
|
||||
CKM_NSS_JPAKE_ROUND1_SHA256,
|
||||
CKM_NSS_JPAKE_ROUND2_SHA256,
|
||||
CKM_NSS_JPAKE_FINAL_SHA256
|
||||
};
|
||||
|
||||
UniquePK11SlotInfo slot(PK11_GetBestSlotMultiple(mechanisms,
|
||||
NUM_ELEM(mechanisms),
|
||||
nullptr));
|
||||
NS_ENSURE_STATE(slot != nullptr);
|
||||
|
||||
CK_BYTE pBuf[(NUM_ELEM(p) - 1) / 2];
|
||||
CK_BYTE qBuf[(NUM_ELEM(q) - 1) / 2];
|
||||
CK_BYTE gBuf[(NUM_ELEM(g) - 1) / 2];
|
||||
|
||||
CK_KEY_TYPE keyType = CKK_NSS_JPAKE_ROUND1;
|
||||
NS_ENSURE_STATE(fromHex(p, pBuf, (NUM_ELEM(p) - 1)));
|
||||
NS_ENSURE_STATE(fromHex(q, qBuf, (NUM_ELEM(q) - 1)));
|
||||
NS_ENSURE_STATE(fromHex(g, gBuf, (NUM_ELEM(g) - 1)));
|
||||
CK_ATTRIBUTE keyTemplate[] = {
|
||||
{ CKA_NSS_JPAKE_SIGNERID, (CK_BYTE *) aSignerID.Data(),
|
||||
aSignerID.Length() },
|
||||
{ CKA_KEY_TYPE, &keyType, sizeof keyType },
|
||||
{ CKA_PRIME, pBuf, sizeof pBuf },
|
||||
{ CKA_SUBPRIME, qBuf, sizeof qBuf },
|
||||
{ CKA_BASE, gBuf, sizeof gBuf }
|
||||
};
|
||||
|
||||
CK_BYTE gx1Buf[NUM_ELEM(p) / 2];
|
||||
CK_BYTE gv1Buf[NUM_ELEM(p) / 2];
|
||||
CK_BYTE r1Buf [NUM_ELEM(p) / 2];
|
||||
CK_BYTE gx2Buf[NUM_ELEM(p) / 2];
|
||||
CK_BYTE gv2Buf[NUM_ELEM(p) / 2];
|
||||
CK_BYTE r2Buf [NUM_ELEM(p) / 2];
|
||||
CK_NSS_JPAKERound1Params rp = {
|
||||
{ gx1Buf, sizeof gx1Buf, gv1Buf, sizeof gv1Buf, r1Buf, sizeof r1Buf },
|
||||
{ gx2Buf, sizeof gx2Buf, gv2Buf, sizeof gv2Buf, r2Buf, sizeof r2Buf }
|
||||
};
|
||||
SECItem paramsItem;
|
||||
paramsItem.data = (unsigned char *) &rp;
|
||||
paramsItem.len = sizeof rp;
|
||||
key = UniquePK11SymKey(
|
||||
PK11_KeyGenWithTemplate(slot.get(), CKM_NSS_JPAKE_ROUND1_SHA256,
|
||||
CKM_NSS_JPAKE_ROUND1_SHA256, ¶msItem,
|
||||
keyTemplate, NUM_ELEM(keyTemplate), nullptr));
|
||||
nsresult rv = key != nullptr
|
||||
? NS_OK
|
||||
: mapErrno();
|
||||
if (rv == NS_OK) {
|
||||
NS_ENSURE_TRUE(toHexString(rp.gx1.pGX, rp.gx1.ulGXLen, aGX1) &&
|
||||
toHexString(rp.gx1.pGV, rp.gx1.ulGVLen, aGV1) &&
|
||||
toHexString(rp.gx1.pR, rp.gx1.ulRLen, aR1) &&
|
||||
toHexString(rp.gx2.pGX, rp.gx2.ulGXLen, aGX2) &&
|
||||
toHexString(rp.gx2.pGV, rp.gx2.ulGVLen, aGV2) &&
|
||||
toHexString(rp.gx2.pR, rp.gx2.ulRLen, aR2),
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
round = JPAKEBeforeRound2;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsSyncJPAKE::Round2(const nsACString & aPeerID,
|
||||
const nsACString & aPIN,
|
||||
const nsACString & aGX3,
|
||||
const nsACString & aGV3,
|
||||
const nsACString & aR3,
|
||||
const nsACString & aGX4,
|
||||
const nsACString & aGV4,
|
||||
const nsACString & aR4,
|
||||
nsACString & aA,
|
||||
nsACString & aGVA,
|
||||
nsACString & aRA)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
if (isAlreadyShutDown()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_ENSURE_STATE(round == JPAKEBeforeRound2);
|
||||
NS_ENSURE_STATE(key != nullptr);
|
||||
NS_ENSURE_ARG(!aPeerID.IsEmpty());
|
||||
|
||||
/* PIN cannot be equal to zero when converted to a bignum. NSS 3.12.9 J-PAKE
|
||||
assumes that the caller has already done this check. Future versions of
|
||||
NSS J-PAKE will do this check internally. See Bug 609068 Comment 4 */
|
||||
bool foundNonZero = false;
|
||||
for (size_t i = 0; i < aPIN.Length(); ++i) {
|
||||
if (aPIN[i] != 0) {
|
||||
foundNonZero = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_ENSURE_ARG(foundNonZero);
|
||||
|
||||
CK_BYTE gx3Buf[NUM_ELEM(p)/2], gv3Buf[NUM_ELEM(p)/2], r3Buf [NUM_ELEM(p)/2];
|
||||
CK_BYTE gx4Buf[NUM_ELEM(p)/2], gv4Buf[NUM_ELEM(p)/2], r4Buf [NUM_ELEM(p)/2];
|
||||
CK_BYTE gxABuf[NUM_ELEM(p)/2], gvABuf[NUM_ELEM(p)/2], rABuf [NUM_ELEM(p)/2];
|
||||
nsresult rv = fromHexString(aGX3, gx3Buf, sizeof gx3Buf);
|
||||
if (rv == NS_OK) rv = fromHexString(aGV3, gv3Buf, sizeof gv3Buf);
|
||||
if (rv == NS_OK) rv = fromHexString(aR3, r3Buf, sizeof r3Buf);
|
||||
if (rv == NS_OK) rv = fromHexString(aGX4, gx4Buf, sizeof gx4Buf);
|
||||
if (rv == NS_OK) rv = fromHexString(aGV4, gv4Buf, sizeof gv4Buf);
|
||||
if (rv == NS_OK) rv = fromHexString(aR4, r4Buf, sizeof r4Buf);
|
||||
if (rv != NS_OK)
|
||||
return rv;
|
||||
|
||||
CK_NSS_JPAKERound2Params rp;
|
||||
rp.pSharedKey = (CK_BYTE *) aPIN.Data();
|
||||
rp.ulSharedKeyLen = aPIN.Length();
|
||||
rp.gx3.pGX = gx3Buf; rp.gx3.ulGXLen = aGX3.Length() / 2;
|
||||
rp.gx3.pGV = gv3Buf; rp.gx3.ulGVLen = aGV3.Length() / 2;
|
||||
rp.gx3.pR = r3Buf; rp.gx3.ulRLen = aR3 .Length() / 2;
|
||||
rp.gx4.pGX = gx4Buf; rp.gx4.ulGXLen = aGX4.Length() / 2;
|
||||
rp.gx4.pGV = gv4Buf; rp.gx4.ulGVLen = aGV4.Length() / 2;
|
||||
rp.gx4.pR = r4Buf; rp.gx4.ulRLen = aR4 .Length() / 2;
|
||||
rp.A.pGX = gxABuf; rp.A .ulGXLen = sizeof gxABuf;
|
||||
rp.A.pGV = gvABuf; rp.A .ulGVLen = sizeof gxABuf;
|
||||
rp.A.pR = rABuf; rp.A .ulRLen = sizeof gxABuf;
|
||||
|
||||
// Bug 629090: NSS 3.12.9 J-PAKE fails to check that gx^4 != 1, so check here.
|
||||
bool gx4Good = false;
|
||||
for (unsigned i = 0; i < rp.gx4.ulGXLen; ++i) {
|
||||
if (rp.gx4.pGX[i] > 1 || (rp.gx4.pGX[i] != 0 && i < rp.gx4.ulGXLen - 1)) {
|
||||
gx4Good = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
NS_ENSURE_ARG(gx4Good);
|
||||
|
||||
SECItem paramsItem;
|
||||
paramsItem.data = (unsigned char *) &rp;
|
||||
paramsItem.len = sizeof rp;
|
||||
CK_KEY_TYPE keyType = CKK_NSS_JPAKE_ROUND2;
|
||||
CK_ATTRIBUTE keyTemplate[] = {
|
||||
{ CKA_NSS_JPAKE_PEERID, (CK_BYTE *) aPeerID.Data(), aPeerID.Length(), },
|
||||
{ CKA_KEY_TYPE, &keyType, sizeof keyType }
|
||||
};
|
||||
UniquePK11SymKey newKey(PK11_DeriveWithTemplate(key.get(),
|
||||
CKM_NSS_JPAKE_ROUND2_SHA256,
|
||||
¶msItem,
|
||||
CKM_NSS_JPAKE_FINAL_SHA256,
|
||||
CKA_DERIVE, 0,
|
||||
keyTemplate,
|
||||
NUM_ELEM(keyTemplate),
|
||||
false));
|
||||
if (newKey != nullptr) {
|
||||
if (toHexString(rp.A.pGX, rp.A.ulGXLen, aA) &&
|
||||
toHexString(rp.A.pGV, rp.A.ulGVLen, aGVA) &&
|
||||
toHexString(rp.A.pR, rp.A.ulRLen, aRA)) {
|
||||
round = JPAKEAfterRound2;
|
||||
key = Move(newKey);
|
||||
return NS_OK;
|
||||
} else {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
} else {
|
||||
rv = mapErrno();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
setBase64(const unsigned char * data, unsigned len, nsACString & out)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
const char * base64 = BTOA_DataToAscii(data, len);
|
||||
|
||||
if (base64 != nullptr) {
|
||||
size_t len = PORT_Strlen(base64);
|
||||
if (out.SetCapacity(len, fallible)) {
|
||||
out.SetLength(0);
|
||||
out.Append(base64, len);
|
||||
} else {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
PORT_Free((void*) base64);
|
||||
} else {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
base64KeyValue(PK11SymKey * key, nsACString & keyString)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (PK11_ExtractKeyValue(key) == SECSuccess) {
|
||||
const SECItem * value = PK11_GetKeyData(key);
|
||||
rv = value != nullptr && value->data != nullptr && value->len > 0
|
||||
? setBase64(value->data, value->len, keyString)
|
||||
: NS_ERROR_UNEXPECTED;
|
||||
} else {
|
||||
rv = mapErrno();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
extractBase64KeyValue(UniquePK11SymKey & keyBlock, CK_ULONG bitPosition,
|
||||
CK_MECHANISM_TYPE destMech, int keySize,
|
||||
nsACString & keyString)
|
||||
{
|
||||
SECItem paramsItem;
|
||||
paramsItem.data = (CK_BYTE *) &bitPosition;
|
||||
paramsItem.len = sizeof bitPosition;
|
||||
PK11SymKey * key = PK11_Derive(keyBlock.get(), CKM_EXTRACT_KEY_FROM_KEY,
|
||||
¶msItem, destMech,
|
||||
CKA_SIGN, keySize);
|
||||
if (key == nullptr)
|
||||
return mapErrno();
|
||||
nsresult rv = base64KeyValue(key, keyString);
|
||||
PK11_FreeSymKey(key);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsSyncJPAKE::Final(const nsACString & aB,
|
||||
const nsACString & aGVB,
|
||||
const nsACString & aRB,
|
||||
const nsACString & aHKDFInfo,
|
||||
nsACString & aAES256Key,
|
||||
nsACString & aHMAC256Key)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
if (isAlreadyShutDown()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
static const unsigned AES256_KEY_SIZE = 256 / 8;
|
||||
static const unsigned HMAC_SHA256_KEY_SIZE = 256 / 8;
|
||||
CK_EXTRACT_PARAMS aesBitPosition = 0;
|
||||
CK_EXTRACT_PARAMS hmacBitPosition = aesBitPosition + (AES256_KEY_SIZE * 8);
|
||||
|
||||
NS_ENSURE_STATE(round == JPAKEAfterRound2);
|
||||
NS_ENSURE_STATE(key != nullptr);
|
||||
|
||||
CK_BYTE gxBBuf[NUM_ELEM(p)/2], gvBBuf[NUM_ELEM(p)/2], rBBuf [NUM_ELEM(p)/2];
|
||||
nsresult rv = fromHexString(aB, gxBBuf, sizeof gxBBuf);
|
||||
if (rv == NS_OK) rv = fromHexString(aGVB, gvBBuf, sizeof gvBBuf);
|
||||
if (rv == NS_OK) rv = fromHexString(aRB, rBBuf, sizeof rBBuf);
|
||||
if (rv != NS_OK)
|
||||
return rv;
|
||||
|
||||
CK_NSS_JPAKEFinalParams rp;
|
||||
rp.B.pGX = gxBBuf; rp.B.ulGXLen = aB .Length() / 2;
|
||||
rp.B.pGV = gvBBuf; rp.B.ulGVLen = aGVB.Length() / 2;
|
||||
rp.B.pR = rBBuf; rp.B.ulRLen = aRB .Length() / 2;
|
||||
SECItem paramsItem;
|
||||
paramsItem.data = (unsigned char *) &rp;
|
||||
paramsItem.len = sizeof rp;
|
||||
UniquePK11SymKey keyMaterial(PK11_Derive(key.get(), CKM_NSS_JPAKE_FINAL_SHA256,
|
||||
¶msItem, CKM_NSS_HKDF_SHA256,
|
||||
CKA_DERIVE, 0));
|
||||
UniquePK11SymKey keyBlock;
|
||||
|
||||
if (keyMaterial == nullptr)
|
||||
rv = mapErrno();
|
||||
|
||||
if (rv == NS_OK) {
|
||||
CK_NSS_HKDFParams hkdfParams;
|
||||
hkdfParams.bExtract = CK_TRUE;
|
||||
hkdfParams.pSalt = nullptr;
|
||||
hkdfParams.ulSaltLen = 0;
|
||||
hkdfParams.bExpand = CK_TRUE;
|
||||
hkdfParams.pInfo = (CK_BYTE *) aHKDFInfo.Data();
|
||||
hkdfParams.ulInfoLen = aHKDFInfo.Length();
|
||||
paramsItem.data = (unsigned char *) &hkdfParams;
|
||||
paramsItem.len = sizeof hkdfParams;
|
||||
keyBlock = UniquePK11SymKey(
|
||||
PK11_Derive(keyMaterial.get(), CKM_NSS_HKDF_SHA256, ¶msItem,
|
||||
CKM_EXTRACT_KEY_FROM_KEY, CKA_DERIVE,
|
||||
AES256_KEY_SIZE + HMAC_SHA256_KEY_SIZE));
|
||||
if (keyBlock == nullptr)
|
||||
rv = mapErrno();
|
||||
}
|
||||
|
||||
if (rv == NS_OK) {
|
||||
rv = extractBase64KeyValue(keyBlock, aesBitPosition, CKM_AES_CBC,
|
||||
AES256_KEY_SIZE, aAES256Key);
|
||||
}
|
||||
if (rv == NS_OK) {
|
||||
rv = extractBase64KeyValue(keyBlock, hmacBitPosition, CKM_SHA256_HMAC,
|
||||
HMAC_SHA256_KEY_SIZE, aHMAC256Key);
|
||||
}
|
||||
|
||||
if (rv == NS_OK) {
|
||||
SECStatus srv = PK11_ExtractKeyValue(keyMaterial.get());
|
||||
NS_ENSURE_TRUE(srv == SECSuccess, NS_ERROR_UNEXPECTED);
|
||||
SECItem * keyMaterialBytes = PK11_GetKeyData(keyMaterial.get());
|
||||
NS_ENSURE_TRUE(keyMaterialBytes != nullptr, NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSyncJPAKE)
|
||||
NS_DEFINE_NAMED_CID(NS_SYNCJPAKE_CID);
|
||||
|
||||
nsSyncJPAKE::nsSyncJPAKE() : round(JPAKENotStarted), key(nullptr) { }
|
||||
|
||||
nsSyncJPAKE::~nsSyncJPAKE()
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
if (isAlreadyShutDown()) {
|
||||
return;
|
||||
}
|
||||
destructorSafeDestroyNSSReference();
|
||||
shutdown(ShutdownCalledFrom::Object);
|
||||
}
|
||||
|
||||
void
|
||||
nsSyncJPAKE::virtualDestroyNSSReference()
|
||||
{
|
||||
destructorSafeDestroyNSSReference();
|
||||
}
|
||||
|
||||
void
|
||||
nsSyncJPAKE::destructorSafeDestroyNSSReference()
|
||||
{
|
||||
key = nullptr;
|
||||
}
|
||||
|
||||
static const mozilla::Module::CIDEntry kServicesCryptoCIDs[] = {
|
||||
{ &kNS_SYNCJPAKE_CID, false, nullptr, nsSyncJPAKEConstructor },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
static const mozilla::Module::ContractIDEntry kServicesCryptoContracts[] = {
|
||||
{ NS_SYNCJPAKE_CONTRACTID, &kNS_SYNCJPAKE_CID },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
static const mozilla::Module kServicesCryptoModule = {
|
||||
mozilla::Module::kVersion,
|
||||
kServicesCryptoCIDs,
|
||||
kServicesCryptoContracts
|
||||
};
|
||||
|
||||
NSMODULE_DEFN(nsServicesCryptoModule) = &kServicesCryptoModule;
|
||||
38
services/crypto/component/nsSyncJPAKE.h
Normal file
38
services/crypto/component/nsSyncJPAKE.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef nsSyncJPAKE_h__
|
||||
#define nsSyncJPAKE_h__
|
||||
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "nsISyncJPAKE.h"
|
||||
#include "nsNSSShutDown.h"
|
||||
|
||||
#define NS_SYNCJPAKE_CONTRACTID \
|
||||
"@mozilla.org/services-crypto/sync-jpake;1"
|
||||
|
||||
#define NS_SYNCJPAKE_CID \
|
||||
{0x0b9721c0, 0x1805, 0x47c3, {0x86, 0xce, 0x68, 0x13, 0x79, 0x5a, 0x78, 0x3f}}
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
class nsSyncJPAKE : public nsISyncJPAKE
|
||||
, public nsNSSShutDownObject
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISYNCJPAKE
|
||||
nsSyncJPAKE();
|
||||
protected:
|
||||
virtual ~nsSyncJPAKE();
|
||||
private:
|
||||
virtual void virtualDestroyNSSReference() override;
|
||||
void destructorSafeDestroyNSSReference();
|
||||
|
||||
enum { JPAKENotStarted, JPAKEBeforeRound2, JPAKEAfterRound2 } round;
|
||||
UniquePK11SymKey key;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsSyncJPAKE, nsISyncJPAKE)
|
||||
|
||||
#endif // nsSyncJPAKE_h__
|
||||
289
services/crypto/component/tests/unit/test_jpake.js
Normal file
289
services/crypto/component/tests/unit/test_jpake.js
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
|
||||
// Ensure PSM is initialized.
|
||||
Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports);
|
||||
|
||||
function do_check_throws(func) {
|
||||
let have_error = false;
|
||||
try {
|
||||
func();
|
||||
} catch(ex) {
|
||||
dump("Was expecting an exception. Caught: " + ex + "\n");
|
||||
have_error = true;
|
||||
}
|
||||
do_check_true(have_error);
|
||||
}
|
||||
|
||||
function test_success() {
|
||||
let a = Cc["@mozilla.org/services-crypto/sync-jpake;1"]
|
||||
.createInstance(Ci.nsISyncJPAKE);
|
||||
let b = Cc["@mozilla.org/services-crypto/sync-jpake;1"]
|
||||
.createInstance(Ci.nsISyncJPAKE);
|
||||
|
||||
let a_gx1 = {};
|
||||
let a_gv1 = {};
|
||||
let a_r1 = {};
|
||||
let a_gx2 = {};
|
||||
let a_gv2 = {};
|
||||
let a_r2 = {};
|
||||
|
||||
let b_gx1 = {};
|
||||
let b_gv1 = {};
|
||||
let b_r1 = {};
|
||||
let b_gx2 = {};
|
||||
let b_gv2 = {};
|
||||
let b_r2 = {};
|
||||
|
||||
a.round1("alice", a_gx1, a_gv1, a_r1, a_gx2, a_gv2, a_r2);
|
||||
b.round1("bob", b_gx1, b_gv1, b_r1, b_gx2, b_gv2, b_r2);
|
||||
|
||||
let a_A = {};
|
||||
let a_gva = {};
|
||||
let a_ra = {};
|
||||
|
||||
let b_A = {};
|
||||
let b_gva = {};
|
||||
let b_ra = {};
|
||||
|
||||
a.round2("bob", "sekrit", b_gx1.value, b_gv1.value, b_r1.value,
|
||||
b_gx2.value, b_gv2.value, b_r2.value, a_A, a_gva, a_ra);
|
||||
b.round2("alice", "sekrit", a_gx1.value, a_gv1.value, a_r1.value,
|
||||
a_gx2.value, a_gv2.value, a_r2.value, b_A, b_gva, b_ra);
|
||||
|
||||
let a_aes = {};
|
||||
let a_hmac = {};
|
||||
let b_aes = {};
|
||||
let b_hmac = {};
|
||||
|
||||
a.final(b_A.value, b_gva.value, b_ra.value, "ohai", a_aes, a_hmac);
|
||||
b.final(a_A.value, a_gva.value, a_ra.value, "ohai", b_aes, b_hmac);
|
||||
|
||||
do_check_eq(a_aes.value, b_aes.value);
|
||||
do_check_eq(a_hmac.value, b_hmac.value);
|
||||
}
|
||||
|
||||
function test_failure(modlen) {
|
||||
let a = Cc["@mozilla.org/services-crypto/sync-jpake;1"]
|
||||
.createInstance(Ci.nsISyncJPAKE);
|
||||
let b = Cc["@mozilla.org/services-crypto/sync-jpake;1"]
|
||||
.createInstance(Ci.nsISyncJPAKE);
|
||||
|
||||
let a_gx1 = {};
|
||||
let a_gv1 = {};
|
||||
let a_r1 = {};
|
||||
let a_gx2 = {};
|
||||
let a_gv2 = {};
|
||||
let a_r2 = {};
|
||||
|
||||
let b_gx1 = {};
|
||||
let b_gv1 = {};
|
||||
let b_r1 = {};
|
||||
let b_gx2 = {};
|
||||
let b_gv2 = {};
|
||||
let b_r2 = {};
|
||||
|
||||
a.round1("alice", a_gx1, a_gv1, a_r1, a_gx2, a_gv2, a_r2);
|
||||
b.round1("bob", b_gx1, b_gv1, b_r1, b_gx2, b_gv2, b_r2);
|
||||
|
||||
let a_A = {};
|
||||
let a_gva = {};
|
||||
let a_ra = {};
|
||||
|
||||
let b_A = {};
|
||||
let b_gva = {};
|
||||
let b_ra = {};
|
||||
|
||||
// Note how the PINs are different (secret vs. sekrit)
|
||||
a.round2("bob", "secret", b_gx1.value, b_gv1.value, b_r1.value,
|
||||
b_gx2.value, b_gv2.value, b_r2.value, a_A, a_gva, a_ra);
|
||||
b.round2("alice", "sekrit", a_gx1.value, a_gv1.value, a_r1.value,
|
||||
a_gx2.value, a_gv2.value, a_r2.value, b_A, b_gva, b_ra);
|
||||
|
||||
let a_aes = {};
|
||||
let a_hmac = {};
|
||||
let b_aes = {};
|
||||
let b_hmac = {};
|
||||
|
||||
a.final(b_A.value, b_gva.value, b_ra.value, "ohai", a_aes, a_hmac);
|
||||
b.final(a_A.value, a_gva.value, a_ra.value, "ohai", b_aes, b_hmac);
|
||||
|
||||
do_check_neq(a_aes.value, b_aes.value);
|
||||
do_check_neq(a_hmac.value, b_hmac.value);
|
||||
}
|
||||
|
||||
function test_same_signerids() {
|
||||
let a = Cc["@mozilla.org/services-crypto/sync-jpake;1"]
|
||||
.createInstance(Ci.nsISyncJPAKE);
|
||||
let b = Cc["@mozilla.org/services-crypto/sync-jpake;1"]
|
||||
.createInstance(Ci.nsISyncJPAKE);
|
||||
|
||||
let gx1 = {};
|
||||
let gv1 = {};
|
||||
let r1 = {};
|
||||
let gx2 = {};
|
||||
let gv2 = {};
|
||||
let r2 = {};
|
||||
|
||||
a.round1("alice", {}, {}, {}, {}, {}, {});
|
||||
b.round1("alice", gx1, gv1, r1, gx2, gv2, r2);
|
||||
do_check_throws(function() {
|
||||
a.round2("alice", "sekrit", gx1.value, gv1.value, r1.value,
|
||||
gx2.value, gv2.value, r2.value, {}, {}, {});
|
||||
});
|
||||
}
|
||||
|
||||
function test_bad_zkp() {
|
||||
let a = Cc["@mozilla.org/services-crypto/sync-jpake;1"]
|
||||
.createInstance(Ci.nsISyncJPAKE);
|
||||
let b = Cc["@mozilla.org/services-crypto/sync-jpake;1"]
|
||||
.createInstance(Ci.nsISyncJPAKE);
|
||||
|
||||
let gx1 = {};
|
||||
let gv1 = {};
|
||||
let r1 = {};
|
||||
let gx2 = {};
|
||||
let gv2 = {};
|
||||
let r2 = {};
|
||||
|
||||
a.round1("alice", {}, {}, {}, {}, {}, {});
|
||||
b.round1("bob", gx1, gv1, r1, gx2, gv2, r2);
|
||||
do_check_throws(function() {
|
||||
a.round2("invalid", "sekrit", gx1.value, gv1.value, r1.value,
|
||||
gx2.value, gv2.value, r2.value, {}, {}, {});
|
||||
});
|
||||
}
|
||||
|
||||
function test_x4_zero() {
|
||||
// The PKCS#11 API for J-PAKE does not allow us to choose any of the nonces.
|
||||
// In order to test the defence against x4 (mod p) == 1, we had to generate
|
||||
// our own signed nonces using a the FreeBL JPAKE_Sign function directly.
|
||||
// To verify the signatures are accurate, pass the given value of R as the
|
||||
// "testRandom" parameter to FreeBL's JPAKE_Sign, along with the given values
|
||||
// for X and GX, using signerID "alice". Then verify that each GV returned
|
||||
// from JPAKE_Sign matches the value specified here.
|
||||
let test = function(badGX, badX_GV, badX_R) {
|
||||
let a = Cc["@mozilla.org/services-crypto/sync-jpake;1"]
|
||||
.createInstance(Ci.nsISyncJPAKE);
|
||||
let b = Cc["@mozilla.org/services-crypto/sync-jpake;1"]
|
||||
.createInstance(Ci.nsISyncJPAKE);
|
||||
|
||||
let a_gx1 = {};
|
||||
let a_gv1 = {};
|
||||
let a_r1 = {};
|
||||
let a_gx2 = {};
|
||||
let a_gv2 = {};
|
||||
let a_r2 = {};
|
||||
|
||||
let b_gx1 = {};
|
||||
let b_gv1 = {};
|
||||
let b_r1 = {};
|
||||
let b_gx2 = {};
|
||||
let b_gv2 = {};
|
||||
let b_r2 = {};
|
||||
|
||||
a.round1("alice", a_gx1, a_gv1, a_r1, a_gx2, a_gv2, a_r2);
|
||||
b.round1("bob", b_gx1, b_gv1, b_r1, b_gx2, b_gv2, b_r2);
|
||||
|
||||
// Replace the g^x2 generated by A with the given illegal value.
|
||||
a_gx2.value = badGX;
|
||||
a_gv2.value = badX_GV;
|
||||
a_r2.value = badX_R;
|
||||
|
||||
let b_A = {};
|
||||
let b_gva = {};
|
||||
let b_ra = {};
|
||||
|
||||
do_check_throws(function() {
|
||||
b.round2("alice", "secret", a_gx1.value, a_gv1.value, a_r1.value,
|
||||
a_gx2.value, a_gv2.value, a_r2.value, b_A, b_gva, b_ra);
|
||||
});
|
||||
};
|
||||
|
||||
// g^x is NIST 3072's p + 1, (p + 1) mod p == 1, x == 0
|
||||
test("90066455B5CFC38F9CAA4A48B4281F292C260FEEF01FD61037E56258A7795A1C"
|
||||
+ "7AD46076982CE6BB956936C6AB4DCFE05E6784586940CA544B9B2140E1EB523F"
|
||||
+ "009D20A7E7880E4E5BFA690F1B9004A27811CD9904AF70420EEFD6EA11EF7DA1"
|
||||
+ "29F58835FF56B89FAA637BC9AC2EFAAB903402229F491D8D3485261CD068699B"
|
||||
+ "6BA58A1DDBBEF6DB51E8FE34E8A78E542D7BA351C21EA8D8F1D29F5D5D159394"
|
||||
+ "87E27F4416B0CA632C59EFD1B1EB66511A5A0FBF615B766C5862D0BD8A3FE7A0"
|
||||
+ "E0DA0FB2FE1FCB19E8F9996A8EA0FCCDE538175238FC8B0EE6F29AF7F642773E"
|
||||
+ "BE8CD5402415A01451A840476B2FCEB0E388D30D4B376C37FE401C2A2C2F941D"
|
||||
+ "AD179C540C1C8CE030D460C4D983BE9AB0B20F69144C1AE13F9383EA1C08504F"
|
||||
+ "B0BF321503EFE43488310DD8DC77EC5B8349B8BFE97C2C560EA878DE87C11E3D"
|
||||
+ "597F1FEA742D73EEC7F37BE43949EF1A0D15C3F3E3FC0A8335617055AC91328E"
|
||||
+ "C22B50FC15B941D3D1624CD88BC25F3E941FDDC6200689581BFEC416B4B2CB74",
|
||||
"5386107A0DD4A96ECF8D9BCF864BDE23AAEF13351F5550D777A32C1FEC165ED67AE51"
|
||||
+ "66C3876AABC1FED1A0993754F3AEE256530F529548F8FE010BC0D070175569845"
|
||||
+ "CF009AD24BC897A9CA1F18E1A9CE421DD54FD93AB528BC2594B47791713165276"
|
||||
+ "7B76903190C3DCD2076FEC1E61FFFC32D1B07273B06EA2889E66FCBFD41FE8984"
|
||||
+ "5FCE36056B09D1F20E58BB6BAA07A32796F11998BEF0AB3D387E2FB4FE3073FEB"
|
||||
+ "634BA91709010A70DA29C06F8F92D638C4F158680EAFEB5E0E323BD7DACB671C0"
|
||||
+ "BA3EDEEAB5CAA243CABAB28E7205AC9A0AAEAFE132635DAC7FE001C19F880A96E"
|
||||
+ "395C42536D694F81B4F44DC66D7D6FBE933C56ABF585837291D8751C18EB1F3FB"
|
||||
+ "620582E6A7B795D699E38C270863A289583CB9D07651E6BA3B82BC656B49BD09B"
|
||||
+ "6B8C27F370120C7CB89D0829BE51D56356EA836012E9204FF4D1CA8B1B7F9C768"
|
||||
+ "4BB2B0F226FD4042EEBAD931FDBD4F81F8425B305752F5E37FFA2B73BB5A034EC"
|
||||
+ "7EEF5AAC92EA212897E3A2B8961D2147710ECCE127B942AB2",
|
||||
"05CC4DF005FE006C11111624E14806E4A904A4D1D6A53E795AC7867A960CD4FD");
|
||||
|
||||
// x == 0 implies g^x == 1
|
||||
test("01",
|
||||
"488759644532FA7C53E5239F2A365D4B9189582BDD2967A1852FE56568382B65"
|
||||
+ "C66BDFCD9B581EAEF4BB497CAF1290ECDFA47A1D1658DC5DC9248D9A4135"
|
||||
+ "DC70B6A8497CDF117236841FA18500DC696A92EEF5000ABE68E9C75B37BC"
|
||||
+ "6A722126BE728163AA90A6B03D5585994D3403557EEF08E819C72D143BBC"
|
||||
+ "CDF74559645066CB3607E1B0430365356389FC8FB3D66FD2B6E2E834EC23"
|
||||
+ "0B0234956752D07F983C918488C8E5A124B062D50B44C5E6FB36BCB03E39"
|
||||
+ "0385B17CF8062B6688371E6AF5915C2B1AAA31C9294943CC6DC1B994FC09"
|
||||
+ "49CA31828B83F3D6DFB081B26045DFD9F10092588B63F1D6E68881A06522"
|
||||
+ "5A417CA9555B036DE89D349AC794A43EB28FE320F9A321F06A9364C88B54"
|
||||
+ "99EEF4816375B119824ACC9AA56D1340B6A49D05F855DE699B351012028C"
|
||||
+ "CA43001F708CC61E71CA3849935BEEBABC0D268CD41B8D2B8DCA705FDFF8"
|
||||
+ "1DAA772DA96EDEA0B291FD5C0C1B8EFE5318D37EBC1BFF53A9DDEC4171A6"
|
||||
+ "479E341438970058E25C8F2BCDA6166C8BF1B065C174",
|
||||
"8B2BACE575179D762F6F2FFDBFF00B497C07766AB3EED9961447CF6F43D06A97");
|
||||
}
|
||||
|
||||
function test_invalid_input_round2() {
|
||||
let a = Cc["@mozilla.org/services-crypto/sync-jpake;1"]
|
||||
.createInstance(Ci.nsISyncJPAKE);
|
||||
|
||||
a.round1("alice", {}, {}, {}, {}, {}, {});
|
||||
do_check_throws(function() {
|
||||
a.round2("invalid", "sekrit", "some", "real", "garbage",
|
||||
"even", "more", "garbage", {}, {}, {});
|
||||
});
|
||||
}
|
||||
|
||||
function test_invalid_input_final() {
|
||||
let a = Cc["@mozilla.org/services-crypto/sync-jpake;1"]
|
||||
.createInstance(Ci.nsISyncJPAKE);
|
||||
let b = Cc["@mozilla.org/services-crypto/sync-jpake;1"]
|
||||
.createInstance(Ci.nsISyncJPAKE);
|
||||
|
||||
let gx1 = {};
|
||||
let gv1 = {};
|
||||
let r1 = {};
|
||||
let gx2 = {};
|
||||
let gv2 = {};
|
||||
let r2 = {};
|
||||
|
||||
a.round1("alice", {}, {}, {}, {}, {}, {});
|
||||
b.round1("bob", gx1, gv1, r1, gx2, gv2, r2);
|
||||
a.round2("bob", "sekrit", gx1.value, gv1.value, r1.value,
|
||||
gx2.value, gv2.value, r2.value, {}, {}, {});
|
||||
do_check_throws(function() {
|
||||
a.final("some", "garbage", "alright", "foobar-info", {}, {});
|
||||
});
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
test_x4_zero();
|
||||
test_success();
|
||||
test_failure();
|
||||
test_same_signerids();
|
||||
test_bad_zkp();
|
||||
test_invalid_input_round2();
|
||||
test_invalid_input_final();
|
||||
}
|
||||
6
services/crypto/component/tests/unit/xpcshell.ini
Normal file
6
services/crypto/component/tests/unit/xpcshell.ini
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[DEFAULT]
|
||||
head =
|
||||
tail =
|
||||
firefox-appdir = browser
|
||||
|
||||
[test_jpake.js]
|
||||
Loading…
Add table
Add a link
Reference in a new issue