Merge mozilla-central to autoland. a=merge CLOSED TREE

This commit is contained in:
Bogdan Tara 2019-05-23 07:43:36 +03:00
Родитель 69583ef6e0 662de518b1
Коммит 0043616f64
73 изменённых файлов: 1270 добавлений и 702 удалений

Просмотреть файл

@ -8902,35 +8902,6 @@ JitCode* JitRealm::generateStringConcatStub(JSContext* cx) {
return code; return code;
} }
void JitRuntime::generateMallocStub(MacroAssembler& masm) {
const Register regReturn = CallTempReg0;
const Register regZone = CallTempReg0;
const Register regNBytes = CallTempReg1;
mallocStubOffset_ = startTrampolineCode(masm);
AllocatableRegisterSet regs(RegisterSet::Volatile());
#ifdef JS_USE_LINK_REGISTER
masm.pushReturnAddress();
#endif
regs.takeUnchecked(regZone);
regs.takeUnchecked(regNBytes);
LiveRegisterSet save(regs.asLiveSet());
masm.PushRegsInMask(save);
const Register regTemp = regs.takeAnyGeneral();
MOZ_ASSERT(regTemp != regNBytes && regTemp != regZone);
masm.setupUnalignedABICall(regTemp);
masm.passABIArg(regZone);
masm.passABIArg(regNBytes);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, MallocWrapper));
masm.storeCallPointerResult(regReturn);
masm.PopRegsInMask(save);
masm.ret();
}
void JitRuntime::generateFreeStub(MacroAssembler& masm) { void JitRuntime::generateFreeStub(MacroAssembler& masm) {
const Register regSlots = CallTempReg0; const Register regSlots = CallTempReg0;

Просмотреть файл

@ -286,9 +286,6 @@ bool JitRuntime::generateTrampolines(JSContext* cx) {
objectGroupPreBarrierOffset_ = objectGroupPreBarrierOffset_ =
generatePreBarrier(cx, masm, MIRType::ObjectGroup); generatePreBarrier(cx, masm, MIRType::ObjectGroup);
JitSpew(JitSpew_Codegen, "# Emitting malloc stub");
generateMallocStub(masm);
JitSpew(JitSpew_Codegen, "# Emitting free stub"); JitSpew(JitSpew_Codegen, "# Emitting free stub");
generateFreeStub(masm); generateFreeStub(masm);

Просмотреть файл

@ -178,7 +178,6 @@ class JitRuntime {
WriteOnceData<uint32_t> objectGroupPreBarrierOffset_; WriteOnceData<uint32_t> objectGroupPreBarrierOffset_;
// Thunk to call malloc/free. // Thunk to call malloc/free.
WriteOnceData<uint32_t> mallocStubOffset_;
WriteOnceData<uint32_t> freeStubOffset_; WriteOnceData<uint32_t> freeStubOffset_;
// Thunk called to finish compilation of an IonScript. // Thunk called to finish compilation of an IonScript.
@ -266,7 +265,6 @@ class JitRuntime {
void generateInvalidator(MacroAssembler& masm, Label* bailoutTail); void generateInvalidator(MacroAssembler& masm, Label* bailoutTail);
uint32_t generatePreBarrier(JSContext* cx, MacroAssembler& masm, uint32_t generatePreBarrier(JSContext* cx, MacroAssembler& masm,
MIRType type); MIRType type);
void generateMallocStub(MacroAssembler& masm);
void generateFreeStub(MacroAssembler& masm); void generateFreeStub(MacroAssembler& masm);
JitCode* generateDebugTrapHandler(JSContext* cx, DebugTrapHandlerKind kind); JitCode* generateDebugTrapHandler(JSContext* cx, DebugTrapHandlerKind kind);
JitCode* generateBaselineDebugModeOSRHandler( JitCode* generateBaselineDebugModeOSRHandler(
@ -389,8 +387,6 @@ class JitRuntime {
} }
} }
TrampolinePtr mallocStub() const { return trampolineCode(mallocStubOffset_); }
TrampolinePtr freeStub() const { return trampolineCode(freeStubOffset_); } TrampolinePtr freeStub() const { return trampolineCode(freeStubOffset_); }
TrampolinePtr lazyLinkStub() const { TrampolinePtr lazyLinkStub() const {

Просмотреть файл

@ -625,40 +625,6 @@ void MacroAssembler::freeListAllocate(Register result, Register temp,
} }
} }
void MacroAssembler::callMallocStub(size_t nbytes, Register result,
Label* fail) {
// These registers must match the ones in JitRuntime::generateMallocStub.
const Register regReturn = CallTempReg0;
const Register regZone = CallTempReg0;
const Register regNBytes = CallTempReg1;
MOZ_ASSERT(nbytes > 0);
MOZ_ASSERT(nbytes <= INT32_MAX);
if (regZone != result) {
push(regZone);
}
if (regNBytes != result) {
push(regNBytes);
}
move32(Imm32(nbytes), regNBytes);
movePtr(ImmPtr(GetJitContext()->realm()->zone()), regZone);
call(GetJitContext()->runtime->jitRuntime()->mallocStub());
if (regReturn != result) {
movePtr(regReturn, result);
}
if (regNBytes != result) {
pop(regNBytes);
}
if (regZone != result) {
pop(regZone);
}
branchTest32(Assembler::Zero, result, result, fail);
}
void MacroAssembler::callFreeStub(Register slots) { void MacroAssembler::callFreeStub(Register slots) {
// This register must match the one in JitRuntime::generateFreeStub. // This register must match the one in JitRuntime::generateFreeStub.
const Register regSlots = CallTempReg0; const Register regSlots = CallTempReg0;
@ -683,31 +649,14 @@ void MacroAssembler::allocateObject(Register result, Register temp,
return nurseryAllocateObject(result, temp, allocKind, nDynamicSlots, fail); return nurseryAllocateObject(result, temp, allocKind, nDynamicSlots, fail);
} }
if (!nDynamicSlots) { // Fall back to calling into the VM to allocate objects in the tenured heap
return freeListAllocate(result, temp, allocKind, fail); // that have dynamic slots.
if (nDynamicSlots) {
jump(fail);
return;
} }
// Only NativeObject can have nDynamicSlots > 0 and reach here. return freeListAllocate(result, temp, allocKind, fail);
callMallocStub(nDynamicSlots * sizeof(GCPtrValue), temp, fail);
Label failAlloc;
Label success;
push(temp);
freeListAllocate(result, temp, allocKind, &failAlloc);
pop(temp);
storePtr(temp, Address(result, NativeObject::offsetOfSlots()));
jump(&success);
bind(&failAlloc);
pop(temp);
callFreeStub(temp);
jump(fail);
bind(&success);
} }
void MacroAssembler::createGCObject(Register obj, Register temp, void MacroAssembler::createGCObject(Register obj, Register temp,

Просмотреть файл

@ -2811,7 +2811,6 @@ class MacroAssembler : public MacroAssemblerSpecific {
const NativeTemplateObject& templateObj, bool initContents); const NativeTemplateObject& templateObj, bool initContents);
public: public:
void callMallocStub(size_t nbytes, Register result, Label* fail);
void callFreeStub(Register slots); void callFreeStub(Register slots);
void createGCObject(Register result, Register temp, void createGCObject(Register result, Register temp,
const TemplateObject& templateObj, const TemplateObject& templateObj,

Просмотреть файл

@ -643,11 +643,6 @@ bool InterruptCheck(JSContext* cx) {
return CheckForInterrupt(cx); return CheckForInterrupt(cx);
} }
void* MallocWrapper(JS::Zone* zone, size_t nbytes) {
AutoUnsafeCallWithABI unsafe;
return zone->pod_malloc<uint8_t>(nbytes);
}
JSObject* NewCallObject(JSContext* cx, HandleShape shape, JSObject* NewCallObject(JSContext* cx, HandleShape shape,
HandleObjectGroup group) { HandleObjectGroup group) {
JSObject* obj = CallObject::create(cx, shape, group); JSObject* obj = CallObject::create(cx, shape, group);

Просмотреть файл

@ -887,7 +887,6 @@ MOZ_MUST_USE bool SetProperty(JSContext* cx, HandleObject obj,
MOZ_MUST_USE bool InterruptCheck(JSContext* cx); MOZ_MUST_USE bool InterruptCheck(JSContext* cx);
void* MallocWrapper(JS::Zone* zone, size_t nbytes);
JSObject* NewCallObject(JSContext* cx, HandleShape shape, JSObject* NewCallObject(JSContext* cx, HandleShape shape,
HandleObjectGroup group); HandleObjectGroup group);
JSObject* NewStringObject(JSContext* cx, HandleString str); JSObject* NewStringObject(JSContext* cx, HandleString str);

Просмотреть файл

@ -7,7 +7,7 @@
#include "mozilla/Utf8.h" // mozilla::Utf8Unit #include "mozilla/Utf8.h" // mozilla::Utf8Unit
#include "js/CompilationAndEvaluation.h" // JS::Compile{,DontInflate,Utf8{FileDontInflate,Path}} #include "js/CompilationAndEvaluation.h" // JS::Compile{,{,Utf8{File,Path}}DontInflate}
#include "js/SourceText.h" // JS::Source{Ownership,Text} #include "js/SourceText.h" // JS::Source{Ownership,Text}
#include "jsapi-tests/tests.h" #include "jsapi-tests/tests.h"
@ -135,8 +135,8 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile) {
JS::CompileOptions options(cx); JS::CompileOptions options(cx);
options.setFileAndLine(script_filename, 1); options.setFileAndLine(script_filename, 1);
JS::RootedScript script(cx, JS::RootedScript script(
JS::CompileUtf8Path(cx, options, script_filename)); cx, JS::CompileUtf8PathDontInflate(cx, options, script_filename));
CHECK(script); CHECK(script);
tempScript.remove(); tempScript.remove();
@ -153,8 +153,8 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, bug438633_JS_CompileFile_empty) {
JS::CompileOptions options(cx); JS::CompileOptions options(cx);
options.setFileAndLine(script_filename, 1); options.setFileAndLine(script_filename, 1);
JS::RootedScript script(cx, JS::RootedScript script(
JS::CompileUtf8Path(cx, options, script_filename)); cx, JS::CompileUtf8PathDontInflate(cx, options, script_filename));
CHECK(script); CHECK(script);
tempScript.remove(); tempScript.remove();

Просмотреть файл

@ -983,7 +983,7 @@ static bool InitModuleLoader(JSContext* cx) {
} }
RootedValue rv(cx); RootedValue rv(cx);
return JS::Evaluate(cx, options, srcBuf, &rv); return JS::EvaluateDontInflate(cx, options, srcBuf, &rv);
} }
static bool GetModuleImportHook(JSContext* cx, static bool GetModuleImportHook(JSContext* cx,
@ -1768,9 +1768,10 @@ static bool LoadScript(JSContext* cx, unsigned argc, Value* vp,
.setNoScriptRval(true); .setNoScriptRval(true);
RootedValue unused(cx); RootedValue unused(cx);
if (!(compileOnly if (!(compileOnly ? JS::CompileUtf8PathDontInflate(
? JS::CompileUtf8Path(cx, opts, filename.get()) != nullptr cx, opts, filename.get()) != nullptr
: JS::EvaluateUtf8Path(cx, opts, filename.get(), &unused))) { : JS::EvaluateUtf8PathDontInflate(
cx, opts, filename.get(), &unused))) {
return false; return false;
} }
} }
@ -3498,7 +3499,7 @@ static bool DisassFile(JSContext* cx, unsigned argc, Value* vp) {
.setIsRunOnce(true) .setIsRunOnce(true)
.setNoScriptRval(true); .setNoScriptRval(true);
script = JS::CompileUtf8Path(cx, options, filename.get()); script = JS::CompileUtf8PathDontInflate(cx, options, filename.get());
if (!script) { if (!script) {
return false; return false;
} }
@ -10164,7 +10165,7 @@ static MOZ_MUST_USE bool ProcessArgs(JSContext* cx, OptionParser* op) {
} }
RootedValue rval(cx); RootedValue rval(cx);
if (!JS::Evaluate(cx, opts, srcBuf, &rval)) { if (!JS::EvaluateDontInflate(cx, opts, srcBuf, &rval)) {
return false; return false;
} }

Просмотреть файл

@ -2883,10 +2883,10 @@ void ScriptSource::codeRetrievableData(ScriptSource* ss) {
// There's nothing to code for retrievable data. Just be sure to set // There's nothing to code for retrievable data. Just be sure to set
// retrievable data when decoding. // retrievable data when decoding.
if (mode == XDR_ENCODE) { if (mode == XDR_ENCODE) {
MOZ_ASSERT(ss->data.is<Retrievable<char16_t>>()); MOZ_ASSERT(ss->data.is<Retrievable<Unit>>());
} else { } else {
MOZ_ASSERT(ss->data.is<Missing>()); MOZ_ASSERT(ss->data.is<Missing>());
ss->data = SourceType(Retrievable<char16_t>()); ss->data = SourceType(Retrievable<Unit>());
} }
} }

Просмотреть файл

@ -3111,7 +3111,7 @@ bool JSRuntime::initSelfHosting(JSContext* cx) {
} }
RootedValue rv(cx); RootedValue rv(cx);
if (!Evaluate(cx, options, srcBuf, &rv)) { if (!EvaluateDontInflate(cx, options, srcBuf, &rv)) {
return false; return false;
} }

Просмотреть файл

@ -994,7 +994,7 @@ static bool ProcessArgs(AutoJSAPI& jsapi, char** argv, int argc,
JS::SourceText<mozilla::Utf8Unit> srcBuf; JS::SourceText<mozilla::Utf8Unit> srcBuf;
if (srcBuf.init(cx, argv[i], strlen(argv[i]), if (srcBuf.init(cx, argv[i], strlen(argv[i]),
JS::SourceOwnership::Borrowed)) { JS::SourceOwnership::Borrowed)) {
JS::Evaluate(cx, opts, srcBuf, &rval); JS::EvaluateDontInflate(cx, opts, srcBuf, &rval);
} }
isInteractive = false; isInteractive = false;

Просмотреть файл

@ -1 +1 @@
NSS_3_44_RTM ec6843bc0ce7

Просмотреть файл

@ -1,21 +0,0 @@
1 Added function:
'function SECStatus CERT_GetCertificateDer(const CERTCertificate*, SECItem*)' {CERT_GetCertificateDer@@NSS_3.44}
1 function with some indirect sub-type change:
[C]'function SECStatus CERT_AddOCSPAcceptableResponses(CERTOCSPRequest*, SECOidTag, ...)' at ocsp.c:2203:1 has some indirect sub-type changes:
parameter 2 of type 'typedef SECOidTag' has sub-type changes:
underlying type 'enum __anonymous_enum__' at secoidt.h:34:1 changed:
type size hasn't changed
3 enumerator insertions:
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_END' value '361'
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_TUNNEL' value '362'
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_USER' value '363'
1 enumerator change:
'__anonymous_enum__::SEC_OID_TOTAL' from value '361' to '364' at secoidt.h:34:1

Просмотреть файл

@ -1,17 +0,0 @@
1 function with some indirect sub-type change:
[C]'function SECStatus NSS_GetAlgorithmPolicy(SECOidTag, PRUint32*)' at secoid.c:2234:1 has some indirect sub-type changes:
parameter 1 of type 'typedef SECOidTag' has sub-type changes:
underlying type 'enum __anonymous_enum__' at secoidt.h:34:1 changed:
type size hasn't changed
3 enumerator insertions:
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_END' value '361'
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_TUNNEL' value '362'
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_USER' value '363'
1 enumerator change:
'__anonymous_enum__::SEC_OID_TOTAL' from value '361' to '364' at secoidt.h:34:1

Просмотреть файл

@ -1,47 +0,0 @@
1 function with some indirect sub-type change:
[C]'function PK11SymKey* NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo*)' at cmscinfo.c:426:1 has some indirect sub-type changes:
parameter 1 of type 'NSSCMSContentInfo*' has sub-type changes:
in pointed to type 'typedef NSSCMSContentInfo' at cmst.h:54:1:
underlying type 'struct NSSCMSContentInfoStr' at cmst.h:126:1 changed:
type size hasn't changed
1 data member changes (2 filtered):
type of 'NSSCMSContent NSSCMSContentInfoStr::content' changed:
underlying type 'union NSSCMSContentUnion' at cmst.h:113:1 changed:
type size hasn't changed
1 data member changes (3 filtered):
type of 'NSSCMSEncryptedData* NSSCMSContentUnion::encryptedData' changed:
in pointed to type 'typedef NSSCMSEncryptedData' at cmst.h:65:1:
underlying type 'struct NSSCMSEncryptedDataStr' at cmst.h:463:1 changed:
type size hasn't changed
1 data member changes (1 filtered):
type of 'NSSCMSAttribute** NSSCMSEncryptedDataStr::unprotectedAttr' changed:
in pointed to type 'NSSCMSAttribute*':
in pointed to type 'typedef NSSCMSAttribute' at cmst.h:69:1:
underlying type 'struct NSSCMSAttributeStr' at cmst.h:482:1 changed:
type size hasn't changed
1 data member change:
type of 'SECOidData* NSSCMSAttributeStr::typeTag' changed:
in pointed to type 'typedef SECOidData' at secoidt.h:16:1:
underlying type 'struct SECOidDataStr' at secoidt.h:518:1 changed:
type size hasn't changed
1 data member change:
type of 'SECOidTag SECOidDataStr::offset' changed:
underlying type 'enum __anonymous_enum__' at secoidt.h:34:1 changed:
type size hasn't changed
3 enumerator insertions:
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_END' value '361'
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_TUNNEL' value '362'
'__anonymous_enum__::SEC_OID_EXT_KEY_USAGE_IPSEC_USER' value '363'
1 enumerator change:
'__anonymous_enum__::SEC_OID_TOTAL' from value '361' to '364' at secoidt.h:34:1

Просмотреть файл

@ -1 +1 @@
NSS_3_43_BRANCH NSS_3_44_BRANCH

Просмотреть файл

@ -103,15 +103,6 @@ queue.filter(task => {
return false; return false;
} }
if (task.group == "Test") {
// Don't run test builds on old make platforms, and not for fips gyp.
// Disable on aarch64, see bug 1488331.
if (task.collection == "make" || task.collection == "fips"
|| task.platform == "aarch64") {
return false;
}
}
// Don't run all additional hardware tests on ARM. // Don't run all additional hardware tests on ARM.
if (task.group == "Cipher" && task.platform == "aarch64" && task.env && if (task.group == "Cipher" && task.platform == "aarch64" && task.env &&
(task.env.NSS_DISABLE_PCLMUL == "1" || task.env.NSS_DISABLE_HW_AES == "1" (task.env.NSS_DISABLE_PCLMUL == "1" || task.env.NSS_DISABLE_HW_AES == "1"
@ -139,7 +130,8 @@ queue.map(task => {
} }
// Windows is slow. // Windows is slow.
if (task.platform == "windows2012-64" && task.tests == "chains") { if ((task.platform == "windows2012-32" || task.platform == "windows2012-64") &&
task.tests == "chains") {
task.maxRunTime = 7200; task.maxRunTime = 7200;
} }
@ -325,7 +317,7 @@ async function scheduleMac(name, base, args = "") {
command: [ command: [
MAC_CHECKOUT_CMD, MAC_CHECKOUT_CMD,
["bash", "-c", ["bash", "-c",
"nss/automation/taskcluster/scripts/build_gyp.sh", args] "nss/automation/taskcluster/scripts/build_gyp.sh " + args]
], ],
provisioner: "localprovisioner", provisioner: "localprovisioner",
workerType: "nss-macos-10-12", workerType: "nss-macos-10-12",
@ -528,8 +520,6 @@ async function scheduleLinux(name, overrides, args = "") {
symbol: "modular" symbol: "modular"
})); }));
await scheduleTestBuilds(name + " Test", merge(base, {group: "Test"}), args);
return queue.submit(); return queue.submit();
} }
@ -761,71 +751,6 @@ async function scheduleFuzzing32() {
return queue.submit(); return queue.submit();
} }
/*****************************************************************************/
async function scheduleTestBuilds(name, base, args = "") {
// Build base definition.
let build = merge(base, {
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && " +
"nss/automation/taskcluster/scripts/build_gyp.sh -g -v --test --ct-verif " + args
],
artifacts: {
public: {
expires: 24 * 7,
type: "directory",
path: "/home/worker/artifacts"
}
},
kind: "build",
symbol: "B",
name: `${name} build`,
});
// On linux we have a specialized build image for building.
if (build.platform === "linux32" || build.platform === "linux64") {
build = merge(build, {
image: LINUX_BUILDS_IMAGE,
});
}
// The task that builds NSPR+NSS.
let task_build = queue.scheduleTask(build);
// Schedule tests.
queue.scheduleTask(merge(base, {
parent: task_build,
name: `${name} mpi tests`,
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && nss/automation/taskcluster/scripts/run_tests.sh"
],
tests: "mpi",
cycle: "standard",
symbol: "mpi",
kind: "test"
}));
queue.scheduleTask(merge(base, {
parent: task_build,
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && nss/automation/taskcluster/scripts/run_tests.sh"
],
name: `${name} gtests`,
symbol: "Gtest",
tests: "gtests",
cycle: "standard",
kind: "test"
}));
return queue.submit();
}
/*****************************************************************************/ /*****************************************************************************/
async function scheduleWindows(name, base, build_script) { async function scheduleWindows(name, base, build_script) {
@ -951,6 +876,9 @@ function scheduleTests(task_build, task_cert, test_base) {
queue.scheduleTask(merge(no_cert_base, { queue.scheduleTask(merge(no_cert_base, {
name: "tlsfuzzer tests", symbol: "tlsfuzzer", tests: "tlsfuzzer", cycle: "standard" name: "tlsfuzzer tests", symbol: "tlsfuzzer", tests: "tlsfuzzer", cycle: "standard"
})); }));
queue.scheduleTask(merge(no_cert_base, {
name: "MPI tests", symbol: "MPI", tests: "mpi", cycle: "standard"
}));
queue.scheduleTask(merge(cert_base, { queue.scheduleTask(merge(cert_base, {
name: "Chains tests", symbol: "Chains", tests: "chains" name: "Chains tests", symbol: "Chains", tests: "chains"
})); }));

Просмотреть файл

@ -94,7 +94,6 @@ while [ $# -gt 0 ]; do
--sancov=?*) enable_sancov "${1#*=}" ;; --sancov=?*) enable_sancov "${1#*=}" ;;
--emit-llvm) gyp_params+=(-Demit_llvm=1 -Dsign_libs=0) ;; --emit-llvm) gyp_params+=(-Demit_llvm=1 -Dsign_libs=0) ;;
--no-zdefs) gyp_params+=(-Dno_zdefs=1) ;; --no-zdefs) gyp_params+=(-Dno_zdefs=1) ;;
--test) gyp_params+=(-Dtest_build=1 -Dstatic_libs=1) ;;
--static) gyp_params+=(-Dstatic_libs=1) ;; --static) gyp_params+=(-Dstatic_libs=1) ;;
--ct-verif) gyp_params+=(-Dct_verif=1) ;; --ct-verif) gyp_params+=(-Dct_verif=1) ;;
--nspr) nspr_clean; rebuild_nspr=1 ;; --nspr) nspr_clean; rebuild_nspr=1 ;;

Просмотреть файл

@ -1954,7 +1954,7 @@ server_main(
if (enabledVersions.max < SSL_LIBRARY_VERSION_TLS_1_3) { if (enabledVersions.max < SSL_LIBRARY_VERSION_TLS_1_3) {
errExit("You tried enabling 0RTT without enabling TLS 1.3!"); errExit("You tried enabling 0RTT without enabling TLS 1.3!");
} }
rv = SSL_SetupAntiReplay(10 * PR_USEC_PER_SEC, 7, 14); rv = SSL_InitAntiReplay(PR_Now(), 10L * PR_USEC_PER_SEC, 7, 14);
if (rv != SECSuccess) { if (rv != SECSuccess) {
errExit("error configuring anti-replay "); errExit("error configuring anti-replay ");
} }

Просмотреть файл

@ -106,7 +106,6 @@
'moz_fold_libs%': 0, 'moz_fold_libs%': 0,
'moz_folded_library_name%': '', 'moz_folded_library_name%': '',
'sanitizer_flags%': 0, 'sanitizer_flags%': 0,
'test_build%': 0,
'static_libs%': 0, 'static_libs%': 0,
'no_zdefs%': 0, 'no_zdefs%': 0,
'fuzz%': 0, 'fuzz%': 0,
@ -130,7 +129,6 @@
# This is mostly for linking to libraries. # This is mostly for linking to libraries.
'variables': { 'variables': {
'mapfile%': '', 'mapfile%': '',
'test_build%': 0,
'static_libs%': 0, 'static_libs%': 0,
'debug_optimization_level%': '0', 'debug_optimization_level%': '0',
'release_optimization_level%': '2', 'release_optimization_level%': '2',
@ -152,11 +150,6 @@
'NSS_NO_INIT_SUPPORT', 'NSS_NO_INIT_SUPPORT',
], ],
}], }],
[ 'static_libs==1', {
'variables': {
'standalone_static_library': '1',
},
}],
[ 'OS!="android" and OS!="mac" and OS!="ios" and OS!="win"', { [ 'OS!="android" and OS!="mac" and OS!="ios" and OS!="win"', {
'libraries': [ 'libraries': [
'-lpthread', '-lpthread',
@ -233,7 +226,7 @@
'product_dir': '<(nss_dist_obj_dir)/lib' 'product_dir': '<(nss_dist_obj_dir)/lib'
}, '_type=="executable"', { }, '_type=="executable"', {
'product_dir': '<(nss_dist_obj_dir)/bin' 'product_dir': '<(nss_dist_obj_dir)/bin'
}, '_standalone_static_library==1', { }, 'static_libs==1 or _standalone_static_library==1', {
'product_dir': '<(nss_dist_obj_dir)/lib' 'product_dir': '<(nss_dist_obj_dir)/lib'
}], }],
# mapfile handling # mapfile handling
@ -324,6 +317,9 @@
}, },
}, },
}], }],
[ '_type=="static_library" and static_libs==1', {
'standalone_static_library': 1,
}],
], ],
'default_configuration': 'Debug', 'default_configuration': 'Debug',
'configurations': { 'configurations': {

Просмотреть файл

@ -10,3 +10,4 @@
*/ */
#error "Do not include this header file." #error "Do not include this header file."

Просмотреть файл

@ -14,7 +14,7 @@ if [ -z "$CC" ]; then
export CXX=clang++ export CXX=clang++
fi fi
gyp_params+=(-Dtest_build=1 -Dstatic_libs=1 -Dfuzz=1 -Dsign_libs=0) gyp_params+=(-Dstatic_libs=1 -Dfuzz=1 -Dsign_libs=0)
# Add debug symbols even for opt builds. # Add debug symbols even for opt builds.
nspr_params+=(--enable-debug-symbols) nspr_params+=(--enable-debug-symbols)

Просмотреть файл

@ -91,7 +91,7 @@
'-lcrypto', '-lcrypto',
], ],
}], }],
# For test builds we have to set MPI defines. # For static builds we have to set MPI defines.
[ 'target_arch=="ia32"', { [ 'target_arch=="ia32"', {
'defines': [ 'defines': [
'MP_USE_UINT_DIGIT', 'MP_USE_UINT_DIGIT',

Просмотреть файл

@ -106,6 +106,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
// Probably not too important for clients. // Probably not too important for clients.
SSL_SetURL(ssl_fd, "server"); SSL_SetURL(ssl_fd, "server");
FixTime(ssl_fd);
SetSocketOptions(ssl_fd, config); SetSocketOptions(ssl_fd, config);
EnableAllCipherSuites(ssl_fd); EnableAllCipherSuites(ssl_fd);
SetupCallbacks(ssl_fd, config.get()); SetupCallbacks(ssl_fd, config.get());

Просмотреть файл

@ -5,9 +5,18 @@
#include <assert.h> #include <assert.h>
#include "ssl.h" #include "ssl.h"
#include "sslexp.h"
#include "tls_common.h" #include "tls_common.h"
static PRTime FixedTime(void*) { return 1234; }
// Fix the time input, to avoid any time-based variation.
void FixTime(PRFileDesc* fd) {
SECStatus rv = SSL_SetTimeFunc(fd, FixedTime, nullptr);
assert(rv == SECSuccess);
}
PRStatus EnableAllProtocolVersions() { PRStatus EnableAllProtocolVersions() {
SSLVersionRange supported; SSLVersionRange supported;

Просмотреть файл

@ -7,6 +7,7 @@
#include "prinit.h" #include "prinit.h"
void FixTime(PRFileDesc* fd);
PRStatus EnableAllProtocolVersions(); PRStatus EnableAllProtocolVersions();
void EnableAllCipherSuites(PRFileDesc* fd); void EnableAllCipherSuites(PRFileDesc* fd);
void DoHandshake(PRFileDesc* fd, bool isServer); void DoHandshake(PRFileDesc* fd, bool isServer);

Просмотреть файл

@ -118,6 +118,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
PRFileDesc* ssl_fd = ImportFD(model.get(), fd.get()); PRFileDesc* ssl_fd = ImportFD(model.get(), fd.get());
assert(ssl_fd == fd.get()); assert(ssl_fd == fd.get());
FixTime(ssl_fd);
SetSocketOptions(ssl_fd, config); SetSocketOptions(ssl_fd, config);
DoHandshake(ssl_fd, true); DoHandshake(ssl_fd, true);

Просмотреть файл

@ -21,6 +21,13 @@
'libraries': [ 'libraries': [
'-lws2_32', '-lws2_32',
], ],
'conditions': [
['static_libs==1', {
'libraries': [
'-ladvapi32',
],
}],
],
}], }],
['OS=="android"', { ['OS=="android"', {
'libraries': [ 'libraries': [

Просмотреть файл

@ -1,6 +1,5 @@
#include "nspr.h" #include "nspr.h"
#include "nss.h" #include "nss.h"
#include "ssl.h"
#include <cstdlib> #include <cstdlib>
@ -29,9 +28,6 @@ int main(int argc, char **argv) {
if (NSS_Initialize(workdir, "", "", SECMOD_DB, flags) != SECSuccess) { if (NSS_Initialize(workdir, "", "", SECMOD_DB, flags) != SECSuccess) {
return 1; return 1;
} }
if (NSS_SetDomesticPolicy() != SECSuccess) {
return 1;
}
int rv = RUN_ALL_TESTS(); int rv = RUN_ALL_TESTS();
if (NSS_Shutdown() != SECSuccess) { if (NSS_Shutdown() != SECSuccess) {

Просмотреть файл

@ -13,22 +13,22 @@
#include <string> #include <string>
#include <vector> #include <vector>
typedef struct chacha_testvector_str { typedef struct chaChaTestVectorStr {
uint32_t id; uint32_t id;
std::vector<uint8_t> Data; std::vector<uint8_t> Data;
std::vector<uint8_t> AAD; std::vector<uint8_t> AAD;
std::vector<uint8_t> Key; std::vector<uint8_t> Key;
std::vector<uint8_t> IV; std::vector<uint8_t> IV;
std::vector<uint8_t> CT; std::vector<uint8_t> CT;
bool invalid_tag; bool invalidTag;
bool invalid_iv; bool invalidIV;
} chacha_testvector; } chaChaTestVector;
// ChaCha20/Poly1305 Test Vector 1, RFC 7539 // ChaCha20/Poly1305 Test Vector 1, RFC 7539
// <http://tools.ietf.org/html/rfc7539#section-2.8.2> // <http://tools.ietf.org/html/rfc7539#section-2.8.2>
// ChaCha20/Poly1305 Test Vector 2, RFC 7539 // ChaCha20/Poly1305 Test Vector 2, RFC 7539
// <http://tools.ietf.org/html/rfc7539#appendix-A.5> // <http://tools.ietf.org/html/rfc7539#appendix-A.5>
const chacha_testvector kChaCha20Vectors[] = { const chaChaTestVector kChaCha20Vectors[] = {
{0, {0,
{0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, {0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47,
0x65, 0x6e, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x6e, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20,
@ -116,7 +116,7 @@ const chacha_testvector kChaCha20Vectors[] = {
// Testvectors from project wycheproof // Testvectors from project wycheproof
// <https://github.com/google/wycheproof> // <https://github.com/google/wycheproof>
const chacha_testvector kChaCha20WycheproofVectors[] = { const chaChaTestVector kChaCha20WycheproofVectors[] = {
// Comment: rfc7539 // Comment: rfc7539
{0, {0,
@ -149,6 +149,32 @@ const chacha_testvector kChaCha20WycheproofVectors[] = {
false, false,
false}, false},
// Comment:
{1,
{},
{},
{0x80, 0xba, 0x31, 0x92, 0xc8, 0x03, 0xce, 0x96, 0x5e, 0xa3, 0x71,
0xd5, 0xff, 0x07, 0x3c, 0xf0, 0xf4, 0x3b, 0x6a, 0x2a, 0xb5, 0x76,
0xb2, 0x08, 0x42, 0x6e, 0x11, 0x40, 0x9c, 0x09, 0xb9, 0xb0},
{0x4d, 0xa5, 0xbf, 0x8d, 0xfd, 0x58, 0x52, 0xc1, 0xea, 0x12, 0x37, 0x9d},
{0x76, 0xac, 0xb3, 0x42, 0xcf, 0x31, 0x66, 0xa5, 0xb6, 0x3c, 0x0c, 0x0e,
0xa1, 0x38, 0x3c, 0x8d},
false,
false},
// Comment:
{2,
{},
{0xbd, 0x50, 0x67, 0x64, 0xf2, 0xd2, 0xc4, 0x10},
{0x7a, 0x4c, 0xd7, 0x59, 0x17, 0x2e, 0x02, 0xeb, 0x20, 0x4d, 0xb2,
0xc3, 0xf5, 0xc7, 0x46, 0x22, 0x7d, 0xf5, 0x84, 0xfc, 0x13, 0x45,
0x19, 0x63, 0x91, 0xdb, 0xb9, 0x57, 0x7a, 0x25, 0x07, 0x42},
{0xa9, 0x2e, 0xf0, 0xac, 0x99, 0x1d, 0xd5, 0x16, 0xa3, 0xc6, 0xf6, 0x89},
{0x90, 0x6f, 0xa6, 0x28, 0x4b, 0x52, 0xf8, 0x7b, 0x73, 0x59, 0xcb, 0xaa,
0x75, 0x63, 0xc7, 0x09},
false,
false},
// Comment: // Comment:
{3, {3,
{0x2a}, {0x2a},
@ -1294,6 +1320,286 @@ const chacha_testvector kChaCha20WycheproofVectors[] = {
false, false,
false}, false},
// Comment: Flipped bit 0 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{61,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa2, 0xe3, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x1b, 0x5a, 0xd2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0x47},
true,
false},
// Comment: Flipped bit 1 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{62,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa1, 0xe3, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x1b, 0x5a, 0xd2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0x47},
true,
false},
// Comment: Flipped bit 7 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{63,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0x23, 0xe3, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x1b, 0x5a, 0xd2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0x47},
true,
false},
// Comment: Flipped bit 8 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{64,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe2, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x1b, 0x5a, 0xd2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0x47},
true,
false},
// Comment: Flipped bit 31 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{65,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe3, 0xfd, 0x79, 0xfb, 0xa6, 0x86, 0x1b, 0x5a, 0xd2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0x47},
true,
false},
// Comment: Flipped bit 32 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{66,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe3, 0xfd, 0xf9, 0xfa, 0xa6, 0x86, 0x1b, 0x5a, 0xd2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0x47},
true,
false},
// Comment: Flipped bit 33 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{67,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe3, 0xfd, 0xf9, 0xf9, 0xa6, 0x86, 0x1b, 0x5a, 0xd2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0x47},
true,
false},
// Comment: Flipped bit 63 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{68,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe3, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x9b, 0x5a, 0xd2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0x47},
true,
false},
// Comment: Flipped bit 64 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{69,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe3, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x1b, 0x5b, 0xd2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0x47},
true,
false},
// Comment: Flipped bit 77 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{70,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe3, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x1b, 0x5a, 0xf2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0x47},
true,
false},
// Comment: Flipped bit 80 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{71,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe3, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x1b, 0x5a, 0xd2, 0x61, 0x7f,
0x40, 0xb7, 0xf4, 0x47},
true,
false},
// Comment: Flipped bit 96 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{72,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe3, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x1b, 0x5a, 0xd2, 0x60, 0x7f,
0x41, 0xb7, 0xf4, 0x47},
true,
false},
// Comment: Flipped bit 97 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{73,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe3, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x1b, 0x5a, 0xd2, 0x60, 0x7f,
0x42, 0xb7, 0xf4, 0x47},
true,
false},
// Comment: Flipped bit 120 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{74,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe3, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x1b, 0x5a, 0xd2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0x46},
true,
false},
// Comment: Flipped bit 121 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{75,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe3, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x1b, 0x5a, 0xd2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0x45},
true,
false},
// Comment: Flipped bit 126 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{76,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe3, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x1b, 0x5a, 0xd2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0x07},
true,
false},
// Comment: Flipped bit 127 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{77,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe3, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x1b, 0x5a, 0xd2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0xc7},
true,
false},
// Comment: Flipped bit 63 and 127 in tag expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{78,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xa3, 0xe3, 0xfd, 0xf9, 0xfb, 0xa6, 0x86, 0x9b, 0x5a, 0xd2, 0x60, 0x7f,
0x40, 0xb7, 0xf4, 0xc7},
true,
false},
// Comment: Tag changed to all zero expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{79,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00},
true,
false},
// Comment: tag change to all 1 expected
// tag:a3e3fdf9fba6861b5ad2607f40b7f447
{80,
{},
{0x61, 0x61, 0x64},
{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b},
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff},
true,
false},
// Comment: Flipped bit 0 in tag expected // Comment: Flipped bit 0 in tag expected
// tag:27da374f17b7f1b23844a5490bfc4001 // tag:27da374f17b7f1b23844a5490bfc4001
{81, {81,

Просмотреть файл

@ -13,22 +13,22 @@
#include <string> #include <string>
#include <vector> #include <vector>
typedef struct chacha_testvector_str { typedef struct chaChaTestVectorStr {
uint32_t id; uint32_t id;
std::vector<uint8_t> Data; std::vector<uint8_t> Data;
std::vector<uint8_t> AAD; std::vector<uint8_t> AAD;
std::vector<uint8_t> Key; std::vector<uint8_t> Key;
std::vector<uint8_t> IV; std::vector<uint8_t> IV;
std::vector<uint8_t> CT; std::vector<uint8_t> CT;
bool invalid_tag; bool invalidTag;
bool invalid_iv; bool invalidIV;
} chacha_testvector; } chaChaTestVector;
// ChaCha20/Poly1305 Test Vector 1, RFC 7539 // ChaCha20/Poly1305 Test Vector 1, RFC 7539
// <http://tools.ietf.org/html/rfc7539#section-2.8.2> // <http://tools.ietf.org/html/rfc7539#section-2.8.2>
// ChaCha20/Poly1305 Test Vector 2, RFC 7539 // ChaCha20/Poly1305 Test Vector 2, RFC 7539
// <http://tools.ietf.org/html/rfc7539#appendix-A.5> // <http://tools.ietf.org/html/rfc7539#appendix-A.5>
const chacha_testvector kChaCha20Vectors[] = { const chaChaTestVector kChaCha20Vectors[] = {
{0, {0,
{0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, {0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47,
0x65, 0x6e, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x6e, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20,

Просмотреть файл

@ -85,7 +85,7 @@
'defines': [ 'defines': [
'NSS_USE_STATIC_LIBS', 'NSS_USE_STATIC_LIBS',
], ],
# For test builds we have to set MPI defines. # For static builds we have to set MPI defines.
'conditions': [ 'conditions': [
[ 'ct_verif==1', { [ 'ct_verif==1', {
'defines': [ 'defines': [

Просмотреть файл

@ -148,6 +148,41 @@ TEST_F(MPITest, MpiCmpUnalignedTest) {
} }
#endif #endif
// The two follow tests ensure very similar mp_set_* functions are ok.
TEST_F(MPITest, MpiSetUlong) {
mp_int a, b, c;
MP_DIGITS(&a) = 0;
MP_DIGITS(&b) = 0;
MP_DIGITS(&c) = 0;
ASSERT_EQ(MP_OKAY, mp_init(&a));
ASSERT_EQ(MP_OKAY, mp_init(&b));
ASSERT_EQ(MP_OKAY, mp_init(&c));
EXPECT_EQ(MP_OKAY, mp_set_ulong(&a, 1));
EXPECT_EQ(MP_OKAY, mp_set_ulong(&b, 0));
EXPECT_EQ(MP_OKAY, mp_set_ulong(&c, -1));
mp_clear(&a);
mp_clear(&b);
mp_clear(&c);
}
TEST_F(MPITest, MpiSetInt) {
mp_int a, b, c;
MP_DIGITS(&a) = 0;
MP_DIGITS(&b) = 0;
MP_DIGITS(&c) = 0;
ASSERT_EQ(MP_OKAY, mp_init(&a));
ASSERT_EQ(MP_OKAY, mp_init(&b));
ASSERT_EQ(MP_OKAY, mp_init(&c));
EXPECT_EQ(MP_OKAY, mp_set_int(&a, 1));
EXPECT_EQ(MP_OKAY, mp_set_int(&b, 0));
EXPECT_EQ(MP_OKAY, mp_set_int(&c, -1));
mp_clear(&a);
mp_clear(&b);
mp_clear(&c);
}
TEST_F(MPITest, MpiFixlenOctetsZero) { TEST_F(MPITest, MpiFixlenOctetsZero) {
std::vector<uint8_t> zero = {0}; std::vector<uint8_t> zero = {0};
TestToFixedOctets(zero, 1); TestToFixedOctets(zero, 1);

Просмотреть файл

@ -8,6 +8,7 @@ MODULE = nss
CPPSRCS = \ CPPSRCS = \
pk11_aeskeywrap_unittest.cc \ pk11_aeskeywrap_unittest.cc \
pk11_cbc_unittest.cc \
pk11_chacha20poly1305_unittest.cc \ pk11_chacha20poly1305_unittest.cc \
pk11_curve25519_unittest.cc \ pk11_curve25519_unittest.cc \
pk11_ecdsa_unittest.cc \ pk11_ecdsa_unittest.cc \

Просмотреть файл

@ -56,18 +56,26 @@ class Pkcs11AesGcmTest : public ::testing::TestWithParam<gcm_kat_value> {
slot.get(), mech, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, nullptr)); slot.get(), mech, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, nullptr));
ASSERT_TRUE(!!symKey) << msg; ASSERT_TRUE(!!symKey) << msg;
// Encrypt. // Encrypt with bogus parameters.
unsigned int outputLen = 0; unsigned int outputLen = 0;
std::vector<uint8_t> output(plaintext.size() + gcmParams.ulTagBits / 8); std::vector<uint8_t> output(plaintext.size() + gcmParams.ulTagBits / 8);
gcmParams.ulTagBits = 159082344;
SECStatus rv = SECStatus rv =
PK11_Encrypt(symKey.get(), mech, &params, output.data(), &outputLen, PK11_Encrypt(symKey.get(), mech, &params, output.data(), &outputLen,
output.size(), plaintext.data(), plaintext.size()); output.size(), plaintext.data(), plaintext.size());
EXPECT_EQ(SECFailure, rv);
EXPECT_EQ(0U, outputLen);
gcmParams.ulTagBits = 128;
// Encrypt.
rv = PK11_Encrypt(symKey.get(), mech, &params, output.data(), &outputLen,
output.size(), plaintext.data(), plaintext.size());
if (invalid_iv) { if (invalid_iv) {
EXPECT_EQ(rv, SECFailure) << msg; EXPECT_EQ(rv, SECFailure) << msg;
EXPECT_EQ(0U, outputLen);
return; return;
} else {
EXPECT_EQ(rv, SECSuccess) << msg;
} }
EXPECT_EQ(rv, SECSuccess) << msg;
ASSERT_EQ(outputLen, output.size()) << msg; ASSERT_EQ(outputLen, output.size()) << msg;

Просмотреть файл

@ -0,0 +1,274 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 <memory>
#include "nss.h"
#include "pk11pub.h"
#include "secerr.h"
#include "nss_scoped_ptrs.h"
#include "gtest/gtest.h"
namespace nss_test {
static const uint8_t kInput[99] = {1, 2, 3};
static const uint8_t kKeyData[24] = {'K', 'E', 'Y'};
static SECItem* GetIv() {
static const uint8_t kIvData[16] = {'I', 'V'};
static const SECItem kIv = {siBuffer, const_cast<uint8_t*>(kIvData),
static_cast<unsigned int>(sizeof(kIvData))};
return const_cast<SECItem*>(&kIv);
}
class Pkcs11CbcPadTest : public ::testing::TestWithParam<CK_MECHANISM_TYPE> {
protected:
bool is_padded() const {
switch (GetParam()) {
case CKM_AES_CBC_PAD:
case CKM_DES3_CBC_PAD:
return true;
case CKM_AES_CBC:
case CKM_DES3_CBC:
return false;
default:
ADD_FAILURE() << "Unknown mechanism " << GetParam();
}
return false;
}
size_t block_size() const {
return static_cast<size_t>(PK11_GetBlockSize(GetParam(), nullptr));
}
size_t GetInputLen(CK_ATTRIBUTE_TYPE op) const {
if (is_padded() && op == CKA_ENCRYPT) {
// Anything goes for encryption when padded.
return sizeof(kInput);
}
// Otherwise, use a strict multiple of the block size.
size_t block_count = sizeof(kInput) / block_size();
EXPECT_LT(1U, block_count) << "need 2 blocks for tests";
return block_count * block_size();
}
ScopedPK11SymKey MakeKey(CK_ATTRIBUTE_TYPE op) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
EXPECT_NE(nullptr, slot);
if (!slot) {
return nullptr;
}
unsigned int key_len = 0;
switch (GetParam()) {
case CKM_AES_CBC_PAD:
case CKM_AES_CBC:
key_len = 16; // This doesn't do AES-256 to keep it simple.
break;
case CKM_DES3_CBC_PAD:
case CKM_DES3_CBC:
key_len = 24;
break;
default:
ADD_FAILURE() << "Unknown mechanism " << GetParam();
return nullptr;
}
SECItem key_item = {siBuffer, const_cast<uint8_t*>(kKeyData), key_len};
PK11SymKey* p = PK11_ImportSymKey(slot.get(), GetParam(), PK11_OriginUnwrap,
op, &key_item, nullptr);
EXPECT_NE(nullptr, p);
return ScopedPK11SymKey(p);
}
ScopedPK11Context MakeContext(CK_ATTRIBUTE_TYPE op) {
ScopedPK11SymKey k = MakeKey(op);
PK11Context* ctx =
PK11_CreateContextBySymKey(GetParam(), op, k.get(), GetIv());
EXPECT_NE(nullptr, ctx);
return ScopedPK11Context(ctx);
}
};
TEST_P(Pkcs11CbcPadTest, EncryptDecrypt) {
uint8_t encrypted[sizeof(kInput) + 64]; // Allow for padding and expansion.
size_t input_len = GetInputLen(CKA_ENCRYPT);
ScopedPK11SymKey ek = MakeKey(CKA_ENCRYPT);
unsigned int encrypted_len = 0;
SECStatus rv =
PK11_Encrypt(ek.get(), GetParam(), GetIv(), encrypted, &encrypted_len,
sizeof(encrypted), kInput, input_len);
ASSERT_EQ(SECSuccess, rv);
EXPECT_LE(input_len, static_cast<size_t>(encrypted_len));
// Though the decrypted result can't be larger than the input we provided,
// NSS needs extra space to put the padding in.
uint8_t decrypted[sizeof(kInput) + 64];
unsigned int decrypted_len = 0;
ScopedPK11SymKey dk = MakeKey(CKA_DECRYPT);
rv = PK11_Decrypt(dk.get(), GetParam(), GetIv(), decrypted, &decrypted_len,
sizeof(decrypted), encrypted, encrypted_len);
ASSERT_EQ(SECSuccess, rv);
EXPECT_EQ(input_len, static_cast<size_t>(decrypted_len));
EXPECT_EQ(0, memcmp(kInput, decrypted, input_len));
}
TEST_P(Pkcs11CbcPadTest, ContextEncryptDecrypt) {
uint8_t encrypted[sizeof(kInput) + 64]; // Allow for padding and expansion.
size_t input_len = GetInputLen(CKA_ENCRYPT);
ScopedPK11Context ectx = MakeContext(CKA_ENCRYPT);
int encrypted_len = 0;
SECStatus rv = PK11_CipherOp(ectx.get(), encrypted, &encrypted_len,
sizeof(encrypted), kInput, input_len);
ASSERT_EQ(SECSuccess, rv);
EXPECT_LE(0, encrypted_len); // Stupid signed parameters.
unsigned int final_len = 0;
rv = PK11_CipherFinal(ectx.get(), encrypted + encrypted_len, &final_len,
sizeof(encrypted) - encrypted_len);
ASSERT_EQ(SECSuccess, rv);
encrypted_len += final_len;
EXPECT_LE(input_len, static_cast<size_t>(encrypted_len));
uint8_t decrypted[sizeof(kInput) + 64];
int decrypted_len = 0;
ScopedPK11Context dctx = MakeContext(CKA_DECRYPT);
rv = PK11_CipherOp(dctx.get(), decrypted, &decrypted_len, sizeof(decrypted),
encrypted, encrypted_len);
ASSERT_EQ(SECSuccess, rv);
EXPECT_LE(0, decrypted_len);
rv = PK11_CipherFinal(dctx.get(), decrypted + decrypted_len, &final_len,
sizeof(decrypted) - decrypted_len);
ASSERT_EQ(SECSuccess, rv);
decrypted_len += final_len;
EXPECT_EQ(input_len, static_cast<size_t>(decrypted_len));
EXPECT_EQ(0, memcmp(kInput, decrypted, input_len));
}
TEST_P(Pkcs11CbcPadTest, ContextEncryptDecryptTwoParts) {
uint8_t encrypted[sizeof(kInput) + 64];
size_t input_len = GetInputLen(CKA_ENCRYPT);
ScopedPK11Context ectx = MakeContext(CKA_ENCRYPT);
int first_len = 0;
SECStatus rv = PK11_CipherOp(ectx.get(), encrypted, &first_len,
sizeof(encrypted), kInput, block_size());
ASSERT_EQ(SECSuccess, rv);
ASSERT_LE(0, first_len);
int second_len = 0;
rv = PK11_CipherOp(ectx.get(), encrypted + first_len, &second_len,
sizeof(encrypted) - first_len, kInput + block_size(),
input_len - block_size());
ASSERT_EQ(SECSuccess, rv);
ASSERT_LE(0, second_len);
unsigned int final_len = 0;
rv = PK11_CipherFinal(ectx.get(), encrypted + first_len + second_len,
&final_len, sizeof(encrypted) - first_len - second_len);
ASSERT_EQ(SECSuccess, rv);
unsigned int encrypted_len = first_len + second_len + final_len;
ASSERT_LE(input_len, static_cast<size_t>(encrypted_len));
// Now decrypt this in a similar fashion.
uint8_t decrypted[sizeof(kInput) + 64];
ScopedPK11Context dctx = MakeContext(CKA_DECRYPT);
rv = PK11_CipherOp(dctx.get(), decrypted, &first_len, sizeof(decrypted),
encrypted, block_size());
ASSERT_EQ(SECSuccess, rv);
EXPECT_LE(0, first_len);
rv = PK11_CipherOp(dctx.get(), decrypted + first_len, &second_len,
sizeof(decrypted) - first_len, encrypted + block_size(),
encrypted_len - block_size());
ASSERT_EQ(SECSuccess, rv);
EXPECT_LE(0, second_len);
unsigned int decrypted_len = 0;
rv = PK11_CipherFinal(dctx.get(), decrypted + first_len + second_len,
&decrypted_len,
sizeof(decrypted) - first_len - second_len);
ASSERT_EQ(SECSuccess, rv);
decrypted_len += first_len + second_len;
EXPECT_EQ(input_len, static_cast<size_t>(decrypted_len));
EXPECT_EQ(0, memcmp(kInput, decrypted, input_len));
}
TEST_P(Pkcs11CbcPadTest, FailDecryptSimple) {
ScopedPK11SymKey dk = MakeKey(CKA_DECRYPT);
uint8_t output[sizeof(kInput) + 64];
unsigned int output_len = 999;
SECStatus rv =
PK11_Decrypt(dk.get(), GetParam(), GetIv(), output, &output_len,
sizeof(output), kInput, GetInputLen(CKA_DECRYPT));
if (is_padded()) {
EXPECT_EQ(SECFailure, rv);
EXPECT_EQ(999U, output_len);
} else {
// Unpadded decryption can't really fail.
EXPECT_EQ(SECSuccess, rv);
}
}
TEST_P(Pkcs11CbcPadTest, FailEncryptSimple) {
ScopedPK11SymKey ek = MakeKey(CKA_ENCRYPT);
uint8_t output[3]; // Too small for anything.
unsigned int output_len = 333;
SECStatus rv =
PK11_Encrypt(ek.get(), GetParam(), GetIv(), output, &output_len,
sizeof(output), kInput, GetInputLen(CKA_ENCRYPT));
EXPECT_EQ(SECFailure, rv);
EXPECT_EQ(333U, output_len);
}
TEST_P(Pkcs11CbcPadTest, ContextFailDecryptSimple) {
ScopedPK11Context dctx = MakeContext(CKA_DECRYPT);
uint8_t output[sizeof(kInput) + 64];
int output_len = 77;
SECStatus rv = PK11_CipherOp(dctx.get(), output, &output_len, sizeof(output),
kInput, GetInputLen(CKA_DECRYPT));
EXPECT_EQ(SECSuccess, rv);
EXPECT_LE(0, output_len) << "this is not an AEAD, so content leaks";
unsigned int final_len = 88;
rv = PK11_CipherFinal(dctx.get(), output, &final_len, sizeof(output));
if (is_padded()) {
EXPECT_EQ(SECFailure, rv);
ASSERT_EQ(88U, final_len) << "final_len should be untouched";
} else {
// Unpadded decryption can't really fail.
EXPECT_EQ(SECSuccess, rv);
}
}
TEST_P(Pkcs11CbcPadTest, ContextFailDecryptInvalidBlockSize) {
ScopedPK11Context dctx = MakeContext(CKA_DECRYPT);
uint8_t output[sizeof(kInput) + 64];
int output_len = 888;
SECStatus rv = PK11_CipherOp(dctx.get(), output, &output_len, sizeof(output),
kInput, GetInputLen(CKA_DECRYPT) - 1);
EXPECT_EQ(SECFailure, rv);
// Because PK11_CipherOp is partial, it can return data on failure.
// This means that it needs to reset its output length to 0 when it starts.
EXPECT_EQ(0, output_len) << "output_len is reset";
}
INSTANTIATE_TEST_CASE_P(EncryptDecrypt, Pkcs11CbcPadTest,
::testing::Values(CKM_AES_CBC_PAD, CKM_AES_CBC,
CKM_DES3_CBC_PAD, CKM_DES3_CBC));
} // namespace nss_test

Просмотреть файл

@ -26,7 +26,7 @@ static const uint8_t kCtrNonce[16] = {'c', 0, 0, 0, 'n'};
static const uint8_t kData[16] = {'d'}; static const uint8_t kData[16] = {'d'};
class Pkcs11ChaCha20Poly1305Test class Pkcs11ChaCha20Poly1305Test
: public ::testing::TestWithParam<chacha_testvector> { : public ::testing::TestWithParam<chaChaTestVector> {
public: public:
void EncryptDecrypt(const ScopedPK11SymKey& key, const bool invalid_iv, void EncryptDecrypt(const ScopedPK11SymKey& key, const bool invalid_iv,
const bool invalid_tag, const uint8_t* data, const bool invalid_tag, const uint8_t* data,
@ -44,108 +44,141 @@ class Pkcs11ChaCha20Poly1305Test
SECItem params = {siBuffer, reinterpret_cast<unsigned char*>(&aead_params), SECItem params = {siBuffer, reinterpret_cast<unsigned char*>(&aead_params),
sizeof(aead_params)}; sizeof(aead_params)};
// Encrypt with bad parameters.
unsigned int encrypted_len = 0;
std::vector<uint8_t> encrypted(data_len + aead_params.ulTagLen);
aead_params.ulTagLen = 158072;
SECStatus rv =
PK11_Encrypt(key.get(), kMech, &params, encrypted.data(),
&encrypted_len, encrypted.size(), data, data_len);
EXPECT_EQ(SECFailure, rv);
EXPECT_EQ(0U, encrypted_len);
aead_params.ulTagLen = 16;
// Encrypt. // Encrypt.
unsigned int outputLen = 0; rv = PK11_Encrypt(key.get(), kMech, &params, encrypted.data(),
std::vector<uint8_t> output(data_len + aead_params.ulTagLen); &encrypted_len, encrypted.size(), data, data_len);
SECStatus rv = PK11_Encrypt(key.get(), kMech, &params, output.data(),
&outputLen, output.size(), data, data_len);
// Return if encryption failure was expected due to invalid IV. // Return if encryption failure was expected due to invalid IV.
// Without valid ciphertext, all further tests can be skipped. // Without valid ciphertext, all further tests can be skipped.
if (invalid_iv) { if (invalid_iv) {
EXPECT_EQ(rv, SECFailure); EXPECT_EQ(rv, SECFailure);
EXPECT_EQ(0U, encrypted_len)
<< "encrypted_len is unmodified after failure";
return; return;
} else {
EXPECT_EQ(rv, SECSuccess);
} }
EXPECT_EQ(rv, SECSuccess);
EXPECT_EQ(encrypted.size(), static_cast<size_t>(encrypted_len));
// Check ciphertext and tag. // Check ciphertext and tag.
if (ct) { if (ct) {
ASSERT_EQ(ct_len, outputLen); ASSERT_EQ(ct_len, encrypted_len);
EXPECT_TRUE(!memcmp(ct, output.data(), outputLen) != invalid_tag); EXPECT_TRUE(!memcmp(ct, encrypted.data(), encrypted.size()) !=
invalid_tag);
} }
// Decrypt. // Get the *estimated* plaintext length. This value should
unsigned int decryptedLen = 0; // never be zero as it could lead to a NULL outPtr being
std::vector<uint8_t> decrypted(data_len); // passed to a subsequent decryption call (for AEAD we
rv = // must authenticate even when the pt is zero-length).
PK11_Decrypt(key.get(), kMech, &params, decrypted.data(), &decryptedLen, unsigned int decrypt_bytes_needed = 0;
decrypted.size(), output.data(), outputLen); rv = PK11_Decrypt(key.get(), kMech, &params, nullptr, &decrypt_bytes_needed,
0, encrypted.data(), encrypted_len);
EXPECT_EQ(rv, SECSuccess);
EXPECT_GT(decrypt_bytes_needed, data_len);
// Now decrypt it
std::vector<uint8_t> decrypted(decrypt_bytes_needed);
unsigned int decrypted_len = 0;
rv = PK11_Decrypt(key.get(), kMech, &params, decrypted.data(),
&decrypted_len, decrypted.size(), encrypted.data(),
encrypted.size());
EXPECT_EQ(rv, SECSuccess); EXPECT_EQ(rv, SECSuccess);
// Check the plaintext. // Check the plaintext.
ASSERT_EQ(data_len, decryptedLen); ASSERT_EQ(data_len, decrypted_len);
EXPECT_TRUE(!memcmp(data, decrypted.data(), decryptedLen)); EXPECT_TRUE(!memcmp(data, decrypted.data(), decrypted_len));
// Decrypt with bogus data. // Decrypt with bogus data.
// Skip if there's no data to modify. // Skip if there's no data to modify.
if (outputLen != 0) { if (encrypted_len > 0) {
std::vector<uint8_t> bogusCiphertext(output); decrypted_len = 0;
bogusCiphertext[0] ^= 0xff; std::vector<uint8_t> bogus_ciphertext(encrypted);
bogus_ciphertext[0] ^= 0xff;
rv = PK11_Decrypt(key.get(), kMech, &params, decrypted.data(), rv = PK11_Decrypt(key.get(), kMech, &params, decrypted.data(),
&decryptedLen, decrypted.size(), bogusCiphertext.data(), &decrypted_len, decrypted.size(),
outputLen); bogus_ciphertext.data(), encrypted_len);
EXPECT_NE(rv, SECSuccess); EXPECT_EQ(rv, SECFailure);
EXPECT_EQ(0U, decrypted_len);
} }
// Decrypt with bogus tag. // Decrypt with bogus tag.
// Skip if there's no tag to modify. // Skip if there's no tag to modify.
if (outputLen != 0) { if (encrypted_len > 0) {
std::vector<uint8_t> bogusTag(output); decrypted_len = 0;
bogusTag[outputLen - 1] ^= 0xff; std::vector<uint8_t> bogus_tag(encrypted);
bogus_tag[encrypted_len - 1] ^= 0xff;
rv = PK11_Decrypt(key.get(), kMech, &params, decrypted.data(), rv = PK11_Decrypt(key.get(), kMech, &params, decrypted.data(),
&decryptedLen, decrypted.size(), bogusTag.data(), &decrypted_len, decrypted.size(), bogus_tag.data(),
outputLen); encrypted_len);
EXPECT_NE(rv, SECSuccess); EXPECT_EQ(rv, SECFailure);
EXPECT_EQ(0U, decrypted_len);
} }
// Decrypt with bogus IV. // Decrypt with bogus IV.
// iv_len == 0 is invalid and should be caught earlier. // iv_len == 0 is invalid and should be caught earlier.
// Still skip, if there's no IV to modify. // Still skip, if there's no IV to modify.
if (iv_len != 0) { if (iv_len != 0) {
SECItem bogusParams(params); decrypted_len = 0;
SECItem bogus_params(params);
CK_NSS_AEAD_PARAMS bogusAeadParams(aead_params); CK_NSS_AEAD_PARAMS bogusAeadParams(aead_params);
bogusParams.data = reinterpret_cast<unsigned char*>(&bogusAeadParams); bogus_params.data = reinterpret_cast<unsigned char*>(&bogusAeadParams);
std::vector<uint8_t> bogusIV(iv, iv + iv_len); std::vector<uint8_t> bogusIV(iv, iv + iv_len);
bogusAeadParams.pNonce = toUcharPtr(bogusIV.data()); bogusAeadParams.pNonce = toUcharPtr(bogusIV.data());
bogusIV[0] ^= 0xff; bogusIV[0] ^= 0xff;
rv = PK11_Decrypt(key.get(), kMech, &bogusParams, decrypted.data(), rv = PK11_Decrypt(key.get(), kMech, &bogus_params, decrypted.data(),
&decryptedLen, data_len, output.data(), outputLen); &decrypted_len, data_len, encrypted.data(),
EXPECT_NE(rv, SECSuccess); encrypted.size());
EXPECT_EQ(rv, SECFailure);
EXPECT_EQ(0U, decrypted_len);
} }
// Decrypt with bogus additional data. // Decrypt with bogus additional data.
// Skip when AAD was empty and can't be modified. // Skip when AAD was empty and can't be modified.
// Alternatively we could generate random aad. // Alternatively we could generate random aad.
if (aad_len != 0) { if (aad_len != 0) {
SECItem bogusParams(params); decrypted_len = 0;
CK_NSS_AEAD_PARAMS bogusAeadParams(aead_params); SECItem bogus_params(params);
bogusParams.data = reinterpret_cast<unsigned char*>(&bogusAeadParams); CK_NSS_AEAD_PARAMS bogus_aead_params(aead_params);
bogus_params.data = reinterpret_cast<unsigned char*>(&bogus_aead_params);
std::vector<uint8_t> bogusAAD(aad, aad + aad_len); std::vector<uint8_t> bogus_aad(aad, aad + aad_len);
bogusAeadParams.pAAD = toUcharPtr(bogusAAD.data()); bogus_aead_params.pAAD = toUcharPtr(bogus_aad.data());
bogusAAD[0] ^= 0xff; bogus_aad[0] ^= 0xff;
rv = PK11_Decrypt(key.get(), kMech, &bogusParams, decrypted.data(), rv = PK11_Decrypt(key.get(), kMech, &bogus_params, decrypted.data(),
&decryptedLen, data_len, output.data(), outputLen); &decrypted_len, data_len, encrypted.data(),
EXPECT_NE(rv, SECSuccess); encrypted.size());
EXPECT_EQ(rv, SECFailure);
EXPECT_EQ(0U, decrypted_len);
} }
} }
void EncryptDecrypt(const chacha_testvector testvector) { void EncryptDecrypt(const chaChaTestVector testvector) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
SECItem key_item = {siBuffer, toUcharPtr(testvector.Key.data()), SECItem keyItem = {siBuffer, toUcharPtr(testvector.Key.data()),
static_cast<unsigned int>(testvector.Key.size())}; static_cast<unsigned int>(testvector.Key.size())};
// Import key. // Import key.
ScopedPK11SymKey key(PK11_ImportSymKey(slot.get(), kMech, PK11_OriginUnwrap, ScopedPK11SymKey key(PK11_ImportSymKey(slot.get(), kMech, PK11_OriginUnwrap,
CKA_ENCRYPT, &key_item, nullptr)); CKA_ENCRYPT, &keyItem, nullptr));
EXPECT_TRUE(!!key); EXPECT_TRUE(!!key);
// Check. // Check.
EncryptDecrypt(key, testvector.invalid_iv, testvector.invalid_tag, EncryptDecrypt(key, testvector.invalidIV, testvector.invalidTag,
testvector.Data.data(), testvector.Data.size(), testvector.Data.data(), testvector.Data.size(),
testvector.AAD.data(), testvector.AAD.size(), testvector.AAD.data(), testvector.AAD.size(),
testvector.IV.data(), testvector.IV.size(), testvector.IV.data(), testvector.IV.size(),
@ -162,9 +195,9 @@ TEST_F(Pkcs11ChaCha20Poly1305Test, GenerateEncryptDecrypt) {
EXPECT_TRUE(!!key); EXPECT_TRUE(!!key);
// Generate random data. // Generate random data.
std::vector<uint8_t> data(512); std::vector<uint8_t> input(512);
SECStatus rv = SECStatus rv =
PK11_GenerateRandomOnSlot(slot.get(), data.data(), data.size()); PK11_GenerateRandomOnSlot(slot.get(), input.data(), input.size());
EXPECT_EQ(rv, SECSuccess); EXPECT_EQ(rv, SECSuccess);
// Generate random AAD. // Generate random AAD.
@ -178,7 +211,7 @@ TEST_F(Pkcs11ChaCha20Poly1305Test, GenerateEncryptDecrypt) {
EXPECT_EQ(rv, SECSuccess); EXPECT_EQ(rv, SECSuccess);
// Check. // Check.
EncryptDecrypt(key, false, false, data.data(), data.size(), aad.data(), EncryptDecrypt(key, false, false, input.data(), input.size(), aad.data(),
aad.size(), iv.data(), iv.size()); aad.size(), iv.data(), iv.size());
} }
@ -194,30 +227,31 @@ TEST_F(Pkcs11ChaCha20Poly1305Test, Xor) {
slot.get(), kMechXor, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, nullptr)); slot.get(), kMechXor, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, nullptr));
EXPECT_TRUE(!!key); EXPECT_TRUE(!!key);
SECItem ctr_nonce_item = {siBuffer, toUcharPtr(kCtrNonce), SECItem ctrNonceItem = {siBuffer, toUcharPtr(kCtrNonce),
static_cast<unsigned int>(sizeof(kCtrNonce))}; static_cast<unsigned int>(sizeof(kCtrNonce))};
uint8_t output[sizeof(kData)]; uint8_t encrypted[sizeof(kData)];
unsigned int output_len = 88; // This should be overwritten. unsigned int encrypted_len = 88; // This should be overwritten.
SECStatus rv = SECStatus rv =
PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len, PK11_Encrypt(key.get(), kMechXor, &ctrNonceItem, encrypted,
sizeof(output), kData, sizeof(kData)); &encrypted_len, sizeof(encrypted), kData, sizeof(kData));
ASSERT_EQ(SECSuccess, rv); ASSERT_EQ(SECSuccess, rv);
ASSERT_EQ(sizeof(kExpected), static_cast<size_t>(output_len)); ASSERT_EQ(sizeof(kExpected), static_cast<size_t>(encrypted_len));
EXPECT_EQ(0, memcmp(kExpected, output, sizeof(kExpected))); EXPECT_EQ(0, memcmp(kExpected, encrypted, sizeof(kExpected)));
// Decrypting has the same effect. // Decrypting has the same effect.
rv = PK11_Decrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len, rv = PK11_Decrypt(key.get(), kMechXor, &ctrNonceItem, encrypted,
sizeof(output), kData, sizeof(kData)); &encrypted_len, sizeof(encrypted), kData, sizeof(kData));
ASSERT_EQ(SECSuccess, rv); ASSERT_EQ(SECSuccess, rv);
ASSERT_EQ(sizeof(kData), static_cast<size_t>(output_len)); ASSERT_EQ(sizeof(kData), static_cast<size_t>(encrypted_len));
EXPECT_EQ(0, memcmp(kExpected, output, sizeof(kExpected))); EXPECT_EQ(0, memcmp(kExpected, encrypted, sizeof(kExpected)));
// Operating in reverse too. // Operating in reverse too.
rv = PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len, rv = PK11_Encrypt(key.get(), kMechXor, &ctrNonceItem, encrypted,
sizeof(output), kExpected, sizeof(kExpected)); &encrypted_len, sizeof(encrypted), kExpected,
sizeof(kExpected));
ASSERT_EQ(SECSuccess, rv); ASSERT_EQ(SECSuccess, rv);
ASSERT_EQ(sizeof(kExpected), static_cast<size_t>(output_len)); ASSERT_EQ(sizeof(kExpected), static_cast<size_t>(encrypted_len));
EXPECT_EQ(0, memcmp(kData, output, sizeof(kData))); EXPECT_EQ(0, memcmp(kData, encrypted, sizeof(kData)));
} }
// This test just ensures that a key can be generated for use with the XOR // This test just ensures that a key can be generated for use with the XOR
@ -227,15 +261,15 @@ TEST_F(Pkcs11ChaCha20Poly1305Test, GenerateXor) {
ScopedPK11SymKey key(PK11_KeyGen(slot.get(), kMech, nullptr, 32, nullptr)); ScopedPK11SymKey key(PK11_KeyGen(slot.get(), kMech, nullptr, 32, nullptr));
EXPECT_TRUE(!!key); EXPECT_TRUE(!!key);
SECItem ctr_nonce_item = {siBuffer, toUcharPtr(kCtrNonce), SECItem ctrNonceItem = {siBuffer, toUcharPtr(kCtrNonce),
static_cast<unsigned int>(sizeof(kCtrNonce))}; static_cast<unsigned int>(sizeof(kCtrNonce))};
uint8_t output[sizeof(kData)]; uint8_t encrypted[sizeof(kData)];
unsigned int output_len = 88; // This should be overwritten. unsigned int encrypted_len = 88; // This should be overwritten.
SECStatus rv = SECStatus rv =
PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len, PK11_Encrypt(key.get(), kMechXor, &ctrNonceItem, encrypted,
sizeof(output), kData, sizeof(kData)); &encrypted_len, sizeof(encrypted), kData, sizeof(kData));
ASSERT_EQ(SECSuccess, rv); ASSERT_EQ(SECSuccess, rv);
ASSERT_EQ(sizeof(kData), static_cast<size_t>(output_len)); ASSERT_EQ(sizeof(kData), static_cast<size_t>(encrypted_len));
} }
TEST_F(Pkcs11ChaCha20Poly1305Test, XorInvalidParams) { TEST_F(Pkcs11ChaCha20Poly1305Test, XorInvalidParams) {
@ -243,18 +277,18 @@ TEST_F(Pkcs11ChaCha20Poly1305Test, XorInvalidParams) {
ScopedPK11SymKey key(PK11_KeyGen(slot.get(), kMech, nullptr, 32, nullptr)); ScopedPK11SymKey key(PK11_KeyGen(slot.get(), kMech, nullptr, 32, nullptr));
EXPECT_TRUE(!!key); EXPECT_TRUE(!!key);
SECItem ctr_nonce_item = {siBuffer, toUcharPtr(kCtrNonce), SECItem ctrNonceItem = {siBuffer, toUcharPtr(kCtrNonce),
static_cast<unsigned int>(sizeof(kCtrNonce)) - 1}; static_cast<unsigned int>(sizeof(kCtrNonce)) - 1};
uint8_t output[sizeof(kData)]; uint8_t encrypted[sizeof(kData)];
unsigned int output_len = 88; unsigned int encrypted_len = 88;
SECStatus rv = SECStatus rv =
PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len, PK11_Encrypt(key.get(), kMechXor, &ctrNonceItem, encrypted,
sizeof(output), kData, sizeof(kData)); &encrypted_len, sizeof(encrypted), kData, sizeof(kData));
EXPECT_EQ(SECFailure, rv); EXPECT_EQ(SECFailure, rv);
ctr_nonce_item.data = nullptr; ctrNonceItem.data = nullptr;
rv = PK11_Encrypt(key.get(), kMechXor, &ctr_nonce_item, output, &output_len, rv = PK11_Encrypt(key.get(), kMechXor, &ctrNonceItem, encrypted,
sizeof(output), kData, sizeof(kData)); &encrypted_len, sizeof(encrypted), kData, sizeof(kData));
EXPECT_EQ(SECFailure, rv); EXPECT_EQ(SECFailure, rv);
EXPECT_EQ(SEC_ERROR_BAD_DATA, PORT_GetError()); EXPECT_EQ(SEC_ERROR_BAD_DATA, PORT_GetError());
} }

Просмотреть файл

@ -13,6 +13,7 @@
'sources': [ 'sources': [
'pk11_aeskeywrap_unittest.cc', 'pk11_aeskeywrap_unittest.cc',
'pk11_aes_gcm_unittest.cc', 'pk11_aes_gcm_unittest.cc',
'pk11_cbc_unittest.cc',
'pk11_chacha20poly1305_unittest.cc', 'pk11_chacha20poly1305_unittest.cc',
'pk11_cipherop_unittest.cc', 'pk11_cipherop_unittest.cc',
'pk11_curve25519_unittest.cc', 'pk11_curve25519_unittest.cc',

Просмотреть файл

@ -109,9 +109,10 @@ void SSLInt_PrintCipherSpecs(const char *label, PRFileDesc *fd) {
} }
} }
/* Force a timer expiry by backdating when all active timers were started. We /* DTLS timers are separate from the time that the rest of the stack uses.
* could set the remaining time to 0 but then backoff would not work properly if * Force a timer expiry by backdating when all active timers were started.
* we decide to test it. */ * We could set the remaining time to 0 but then backoff would not work properly
* if we decide to test it. */
SECStatus SSLInt_ShiftDtlsTimers(PRFileDesc *fd, PRIntervalTime shift) { SECStatus SSLInt_ShiftDtlsTimers(PRFileDesc *fd, PRIntervalTime shift) {
size_t i; size_t i;
sslSocket *ss = ssl_FindSocket(fd); sslSocket *ss = ssl_FindSocket(fd);
@ -297,10 +298,6 @@ SSLKEAType SSLInt_GetKEAType(SSLNamedGroup group) {
return groupDef->keaType; return groupDef->keaType;
} }
void SSLInt_SetTicketLifetime(uint32_t lifetime) {
ssl_ticket_lifetime = lifetime;
}
SECStatus SSLInt_SetSocketMaxEarlyDataSize(PRFileDesc *fd, uint32_t size) { SECStatus SSLInt_SetSocketMaxEarlyDataSize(PRFileDesc *fd, uint32_t size) {
sslSocket *ss; sslSocket *ss;
@ -324,10 +321,6 @@ SECStatus SSLInt_SetSocketMaxEarlyDataSize(PRFileDesc *fd, uint32_t size) {
return SECSuccess; return SECSuccess;
} }
void SSLInt_RolloverAntiReplay(void) {
tls13_AntiReplayRollover(ssl_TimeUsec());
}
SECStatus SSLInt_HasPendingHandshakeData(PRFileDesc *fd, PRBool *pending) { SECStatus SSLInt_HasPendingHandshakeData(PRFileDesc *fd, PRBool *pending) {
sslSocket *ss = ssl_FindSocket(fd); sslSocket *ss = ssl_FindSocket(fd);
if (!ss) { if (!ss) {

Просмотреть файл

@ -40,8 +40,6 @@ SECStatus SSLInt_AdvanceReadSeqNum(PRFileDesc *fd, PRUint64 to);
SECStatus SSLInt_AdvanceWriteSeqByAWindow(PRFileDesc *fd, PRInt32 extra); SECStatus SSLInt_AdvanceWriteSeqByAWindow(PRFileDesc *fd, PRInt32 extra);
SSLKEAType SSLInt_GetKEAType(SSLNamedGroup group); SSLKEAType SSLInt_GetKEAType(SSLNamedGroup group);
SECStatus SSLInt_HasPendingHandshakeData(PRFileDesc *fd, PRBool *pending); SECStatus SSLInt_HasPendingHandshakeData(PRFileDesc *fd, PRBool *pending);
void SSLInt_SetTicketLifetime(uint32_t lifetime);
SECStatus SSLInt_SetSocketMaxEarlyDataSize(PRFileDesc *fd, uint32_t size); SECStatus SSLInt_SetSocketMaxEarlyDataSize(PRFileDesc *fd, uint32_t size);
void SSLInt_RolloverAntiReplay(void);
#endif // ndef libssl_internals_h_ #endif // ndef libssl_internals_h_

Просмотреть файл

@ -46,7 +46,7 @@ TEST_P(TlsConnectTls13, ZeroRttServerRejectByOption) {
} }
TEST_P(TlsConnectTls13, ZeroRttApparentReplayAfterRestart) { TEST_P(TlsConnectTls13, ZeroRttApparentReplayAfterRestart) {
// The test fixtures call SSL_SetupAntiReplay() in SetUp(). This results in // The test fixtures call SSL_InitAntiReplay() in SetUp(). This results in
// 0-RTT being rejected until at least one window passes. SetupFor0Rtt() // 0-RTT being rejected until at least one window passes. SetupFor0Rtt()
// forces a rollover of the anti-replay filters, which clears this state. // forces a rollover of the anti-replay filters, which clears this state.
// Here, we do the setup manually here without that forced rollover. // Here, we do the setup manually here without that forced rollover.
@ -106,7 +106,7 @@ class TlsZeroRttReplayTest : public TlsConnectTls13 {
SendReceive(); SendReceive();
if (rollover) { if (rollover) {
SSLInt_RolloverAntiReplay(); RolloverAntiReplay();
} }
// Now replay that packet against the server. // Now replay that packet against the server.
@ -184,20 +184,21 @@ TEST_P(TlsConnectTls13, ZeroRttServerOnly) {
CheckKeys(); CheckKeys();
} }
// A small sleep after sending the ClientHello means that the ticket age that // Advancing time after sending the ClientHello means that the ticket age that
// arrives at the server is too low. With a small tolerance for variation in // arrives at the server is too low. The server then rejects early data if this
// ticket age (which is determined by the |window| parameter that is passed to // delay exceeds half the anti-replay window.
// SSL_SetupAntiReplay()), the server then rejects early data.
TEST_P(TlsConnectTls13, ZeroRttRejectOldTicket) { TEST_P(TlsConnectTls13, ZeroRttRejectOldTicket) {
static const PRTime kWindow = 10 * PR_USEC_PER_SEC;
EXPECT_EQ(SECSuccess, SSL_InitAntiReplay(now(), kWindow, 1, 3));
SetupForZeroRtt(); SetupForZeroRtt();
Reset();
StartConnect();
client_->Set0RttEnabled(true); client_->Set0RttEnabled(true);
server_->Set0RttEnabled(true); server_->Set0RttEnabled(true);
EXPECT_EQ(SECSuccess, SSL_SetupAntiReplay(1, 1, 3));
SSLInt_RolloverAntiReplay(); // Make sure to flush replay state.
SSLInt_RolloverAntiReplay();
ExpectResumption(RESUME_TICKET); ExpectResumption(RESUME_TICKET);
ZeroRttSendReceive(true, false, []() { ZeroRttSendReceive(true, false, [this]() {
PR_Sleep(PR_MillisecondsToInterval(10)); AdvanceTime(1 + kWindow / 2);
return true; return true;
}); });
Handshake(); Handshake();
@ -212,13 +213,15 @@ TEST_P(TlsConnectTls13, ZeroRttRejectOldTicket) {
// small tolerance for variation in ticket age and the ticket will appear to // small tolerance for variation in ticket age and the ticket will appear to
// arrive prematurely, causing the server to reject early data. // arrive prematurely, causing the server to reject early data.
TEST_P(TlsConnectTls13, ZeroRttRejectPrematureTicket) { TEST_P(TlsConnectTls13, ZeroRttRejectPrematureTicket) {
static const PRTime kWindow = 10 * PR_USEC_PER_SEC;
EXPECT_EQ(SECSuccess, SSL_InitAntiReplay(now(), kWindow, 1, 3));
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
server_->Set0RttEnabled(true); server_->Set0RttEnabled(true);
StartConnect(); StartConnect();
client_->Handshake(); // ClientHello client_->Handshake(); // ClientHello
server_->Handshake(); // ServerHello server_->Handshake(); // ServerHello
PR_Sleep(PR_MillisecondsToInterval(10)); AdvanceTime(1 + kWindow / 2);
Handshake(); // Remainder of handshake Handshake(); // Remainder of handshake
CheckConnected(); CheckConnected();
SendReceive(); SendReceive();
@ -227,9 +230,6 @@ TEST_P(TlsConnectTls13, ZeroRttRejectPrematureTicket) {
Reset(); Reset();
client_->Set0RttEnabled(true); client_->Set0RttEnabled(true);
server_->Set0RttEnabled(true); server_->Set0RttEnabled(true);
EXPECT_EQ(SECSuccess, SSL_SetupAntiReplay(1, 1, 3));
SSLInt_RolloverAntiReplay(); // Make sure to flush replay state.
SSLInt_RolloverAntiReplay();
ExpectResumption(RESUME_TICKET); ExpectResumption(RESUME_TICKET);
ExpectEarlyDataAccepted(false); ExpectEarlyDataAccepted(false);
StartConnect(); StartConnect();
@ -870,6 +870,59 @@ TEST_F(TlsConnectDatagram13, ZeroRttShortReadDtls) {
CheckConnected(); CheckConnected();
} }
// There are few ways in which TLS uses the clock and most of those operate on
// timescales that would be ridiculous to wait for in a test. This is the one
// test we have that uses the real clock. It tests that time passes by checking
// that a small sleep results in rejection of early data. 0-RTT has a
// configurable timer, which makes it ideal for this.
TEST_F(TlsConnectStreamTls13, TimePassesByDefault) {
// Set a tiny anti-replay window. This has to be at least 2 milliseconds to
// have any chance of being relevant as that is the smallest window that we
// can detect. Anything smaller rounds to zero.
static const unsigned int kTinyWindowMs = 5;
EXPECT_EQ(SECSuccess, SSL_InitAntiReplay(
PR_Now(), kTinyWindowMs * PR_USEC_PER_MSEC, 1, 5));
// Calling EnsureTlsSetup() replaces the time function on client and server,
// which we don't want, so initialize each directly.
client_->EnsureTlsSetup();
server_->EnsureTlsSetup();
client_->StartConnect(); // Also avoid StartConnect().
server_->StartConnect();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
server_->Set0RttEnabled(true);
Handshake();
CheckConnected();
SendReceive(); // Absorb a session ticket.
CheckKeys();
// Clear the first window.
PR_Sleep(PR_MillisecondsToInterval(kTinyWindowMs));
Reset();
client_->EnsureTlsSetup();
server_->EnsureTlsSetup();
client_->StartConnect();
server_->StartConnect();
// Early data is rejected by the server only if time passes for it as well.
client_->Set0RttEnabled(true);
server_->Set0RttEnabled(true);
ExpectResumption(RESUME_TICKET);
ZeroRttSendReceive(true, false, []() {
// Sleep long enough that we minimize the risk of our RTT estimation being
// duped by stutters in test execution. This is very long to allow for
// flaky and low-end hardware, especially what our CI runs on.
PR_Sleep(PR_MillisecondsToInterval(1000));
return true;
});
Handshake();
ExpectEarlyDataAccepted(false);
CheckConnected();
}
#ifndef NSS_DISABLE_TLS_1_3 #ifndef NSS_DISABLE_TLS_1_3
INSTANTIATE_TEST_CASE_P(Tls13ZeroRttReplayTest, TlsZeroRttReplayTest, INSTANTIATE_TEST_CASE_P(Tls13ZeroRttReplayTest, TlsZeroRttReplayTest,
TlsConnectTestBase::kTlsVariantsAll); TlsConnectTestBase::kTlsVariantsAll);

Просмотреть файл

@ -22,7 +22,7 @@ namespace nss_test {
const uint8_t kShortEmptyFinished[8] = {0}; const uint8_t kShortEmptyFinished[8] = {0};
const uint8_t kLongEmptyFinished[128] = {0}; const uint8_t kLongEmptyFinished[128] = {0};
class TlsFuzzTest : public ::testing::Test {}; class TlsFuzzTest : public TlsConnectGeneric {};
// Record the application data stream. // Record the application data stream.
class TlsApplicationDataRecorder : public TlsRecordFilter { class TlsApplicationDataRecorder : public TlsRecordFilter {
@ -46,16 +46,9 @@ class TlsApplicationDataRecorder : public TlsRecordFilter {
DataBuffer buffer_; DataBuffer buffer_;
}; };
// Ensure that ssl_Time() returns a constant value.
FUZZ_F(TlsFuzzTest, SSL_Time_Constant) {
PRUint32 now = ssl_TimeSec();
PR_Sleep(PR_SecondsToInterval(2));
EXPECT_EQ(ssl_TimeSec(), now);
}
// Check that due to the deterministic PRNG we derive // Check that due to the deterministic PRNG we derive
// the same master secret in two consecutive TLS sessions. // the same master secret in two consecutive TLS sessions.
FUZZ_P(TlsConnectGeneric, DeterministicExporter) { FUZZ_P(TlsFuzzTest, DeterministicExporter) {
const char kLabel[] = "label"; const char kLabel[] = "label";
std::vector<unsigned char> out1(32), out2(32); std::vector<unsigned char> out1(32), out2(32);
@ -95,7 +88,7 @@ FUZZ_P(TlsConnectGeneric, DeterministicExporter) {
// Check that due to the deterministic RNG two consecutive // Check that due to the deterministic RNG two consecutive
// TLS sessions will have the exact same transcript. // TLS sessions will have the exact same transcript.
FUZZ_P(TlsConnectGeneric, DeterministicTranscript) { FUZZ_P(TlsFuzzTest, DeterministicTranscript) {
// Make sure we have RSA blinding params. // Make sure we have RSA blinding params.
Connect(); Connect();
@ -130,9 +123,7 @@ FUZZ_P(TlsConnectGeneric, DeterministicTranscript) {
// with all supported TLS versions, STREAM and DGRAM. // with all supported TLS versions, STREAM and DGRAM.
// Check that records are NOT encrypted. // Check that records are NOT encrypted.
// Check that records don't have a MAC. // Check that records don't have a MAC.
FUZZ_P(TlsConnectGeneric, ConnectSendReceive_NullCipher) { FUZZ_P(TlsFuzzTest, ConnectSendReceive_NullCipher) {
EnsureTlsSetup();
// Set up app data filters. // Set up app data filters.
auto client_recorder = MakeTlsFilter<TlsApplicationDataRecorder>(client_); auto client_recorder = MakeTlsFilter<TlsApplicationDataRecorder>(client_);
auto server_recorder = MakeTlsFilter<TlsApplicationDataRecorder>(server_); auto server_recorder = MakeTlsFilter<TlsApplicationDataRecorder>(server_);
@ -157,7 +148,7 @@ FUZZ_P(TlsConnectGeneric, ConnectSendReceive_NullCipher) {
} }
// Check that an invalid Finished message doesn't abort the connection. // Check that an invalid Finished message doesn't abort the connection.
FUZZ_P(TlsConnectGeneric, BogusClientFinished) { FUZZ_P(TlsFuzzTest, BogusClientFinished) {
EnsureTlsSetup(); EnsureTlsSetup();
MakeTlsFilter<TlsInspectorReplaceHandshakeMessage>( MakeTlsFilter<TlsInspectorReplaceHandshakeMessage>(
@ -168,7 +159,7 @@ FUZZ_P(TlsConnectGeneric, BogusClientFinished) {
} }
// Check that an invalid Finished message doesn't abort the connection. // Check that an invalid Finished message doesn't abort the connection.
FUZZ_P(TlsConnectGeneric, BogusServerFinished) { FUZZ_P(TlsFuzzTest, BogusServerFinished) {
EnsureTlsSetup(); EnsureTlsSetup();
MakeTlsFilter<TlsInspectorReplaceHandshakeMessage>( MakeTlsFilter<TlsInspectorReplaceHandshakeMessage>(
@ -179,7 +170,7 @@ FUZZ_P(TlsConnectGeneric, BogusServerFinished) {
} }
// Check that an invalid server auth signature doesn't abort the connection. // Check that an invalid server auth signature doesn't abort the connection.
FUZZ_P(TlsConnectGeneric, BogusServerAuthSignature) { FUZZ_P(TlsFuzzTest, BogusServerAuthSignature) {
EnsureTlsSetup(); EnsureTlsSetup();
uint8_t msg_type = version_ == SSL_LIBRARY_VERSION_TLS_1_3 uint8_t msg_type = version_ == SSL_LIBRARY_VERSION_TLS_1_3
? kTlsHandshakeCertificateVerify ? kTlsHandshakeCertificateVerify
@ -190,7 +181,7 @@ FUZZ_P(TlsConnectGeneric, BogusServerAuthSignature) {
} }
// Check that an invalid client auth signature doesn't abort the connection. // Check that an invalid client auth signature doesn't abort the connection.
FUZZ_P(TlsConnectGeneric, BogusClientAuthSignature) { FUZZ_P(TlsFuzzTest, BogusClientAuthSignature) {
EnsureTlsSetup(); EnsureTlsSetup();
client_->SetupClientAuth(); client_->SetupClientAuth();
server_->RequestClientAuth(true); server_->RequestClientAuth(true);
@ -199,7 +190,7 @@ FUZZ_P(TlsConnectGeneric, BogusClientAuthSignature) {
} }
// Check that session ticket resumption works. // Check that session ticket resumption works.
FUZZ_P(TlsConnectGeneric, SessionTicketResumption) { FUZZ_P(TlsFuzzTest, SessionTicketResumption) {
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
Connect(); Connect();
SendReceive(); SendReceive();
@ -212,7 +203,7 @@ FUZZ_P(TlsConnectGeneric, SessionTicketResumption) {
} }
// Check that session tickets are not encrypted. // Check that session tickets are not encrypted.
FUZZ_P(TlsConnectGeneric, UnencryptedSessionTickets) { FUZZ_P(TlsFuzzTest, UnencryptedSessionTickets) {
ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET); ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET);
auto filter = MakeTlsFilter<TlsHandshakeRecorder>( auto filter = MakeTlsFilter<TlsHandshakeRecorder>(
@ -220,23 +211,45 @@ FUZZ_P(TlsConnectGeneric, UnencryptedSessionTickets) {
Connect(); Connect();
std::cerr << "ticket" << filter->buffer() << std::endl; std::cerr << "ticket" << filter->buffer() << std::endl;
size_t offset = 4; /* lifetime */ size_t offset = 4; // Skip lifetime.
if (version_ == SSL_LIBRARY_VERSION_TLS_1_3) { if (version_ == SSL_LIBRARY_VERSION_TLS_1_3) {
offset += 4; /* ticket_age_add */ offset += 4; // Skip ticket_age_add.
uint32_t nonce_len = 0; uint32_t nonce_len = 0;
EXPECT_TRUE(filter->buffer().Read(offset, 1, &nonce_len)); EXPECT_TRUE(filter->buffer().Read(offset, 1, &nonce_len));
offset += 1 + nonce_len; offset += 1 + nonce_len;
} }
offset += 2 + /* ticket length */
2; /* TLS_EX_SESS_TICKET_VERSION */ offset += 2; // Skip the ticket length.
// This bit parses the contents of the ticket, which would ordinarily be
// encrypted. Start by checking that we have the right version. This needs
// to be updated every time that TLS_EX_SESS_TICKET_VERSION is changed. But
// we don't use the #define. That way, any time that code is updated, this
// test will fail unless it is manually checked.
uint32_t ticket_version;
EXPECT_TRUE(filter->buffer().Read(offset, 2, &ticket_version));
EXPECT_EQ(0x010aU, ticket_version);
offset += 2;
// Check the protocol version number. // Check the protocol version number.
uint32_t tls_version = 0; uint32_t tls_version = 0;
EXPECT_TRUE(filter->buffer().Read(offset, sizeof(version_), &tls_version)); EXPECT_TRUE(filter->buffer().Read(offset, sizeof(version_), &tls_version));
EXPECT_EQ(version_, static_cast<decltype(version_)>(tls_version)); EXPECT_EQ(version_, static_cast<decltype(version_)>(tls_version));
offset += sizeof(version_);
// Check the cipher suite. // Check the cipher suite.
uint32_t suite = 0; uint32_t suite = 0;
EXPECT_TRUE(filter->buffer().Read(offset + sizeof(version_), 2, &suite)); EXPECT_TRUE(filter->buffer().Read(offset, 2, &suite));
client_->CheckCipherSuite(static_cast<uint16_t>(suite)); client_->CheckCipherSuite(static_cast<uint16_t>(suite));
} }
INSTANTIATE_TEST_CASE_P(
FuzzStream, TlsFuzzTest,
::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
TlsConnectTestBase::kTlsVAll));
INSTANTIATE_TEST_CASE_P(
FuzzDatagram, TlsFuzzTest,
::testing::Combine(TlsConnectTestBase::kTlsVariantsDatagram,
TlsConnectTestBase::kTlsV11Plus));
} }

Просмотреть файл

@ -325,14 +325,17 @@ TEST_P(TlsConnectGeneric, ConnectResumeClientBothTicketServerTicketForget) {
SendReceive(); SendReceive();
} }
// Tickets last two days maximum; this is a time longer than that.
static const PRTime kLongerThanTicketLifetime =
3LL * 24 * 60 * 60 * PR_USEC_PER_SEC;
TEST_P(TlsConnectGenericResumption, ConnectWithExpiredTicketAtClient) { TEST_P(TlsConnectGenericResumption, ConnectWithExpiredTicketAtClient) {
SSLInt_SetTicketLifetime(1); // one second
// This causes a ticket resumption. // This causes a ticket resumption.
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
Connect(); Connect();
SendReceive(); SendReceive();
WAIT_(false, 1000); AdvanceTime(kLongerThanTicketLifetime);
Reset(); Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
@ -354,7 +357,6 @@ TEST_P(TlsConnectGenericResumption, ConnectWithExpiredTicketAtClient) {
} }
TEST_P(TlsConnectGeneric, ConnectWithExpiredTicketAtServer) { TEST_P(TlsConnectGeneric, ConnectWithExpiredTicketAtServer) {
SSLInt_SetTicketLifetime(1); // one second
// This causes a ticket resumption. // This causes a ticket resumption.
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
Connect(); Connect();
@ -373,7 +375,7 @@ TEST_P(TlsConnectGeneric, ConnectWithExpiredTicketAtServer) {
EXPECT_TRUE(capture->captured()); EXPECT_TRUE(capture->captured());
EXPECT_LT(0U, capture->extension().len()); EXPECT_LT(0U, capture->extension().len());
WAIT_(false, 1000); // Let the ticket expire on the server. AdvanceTime(kLongerThanTicketLifetime);
Handshake(); Handshake();
CheckConnected(); CheckConnected();
@ -1109,7 +1111,7 @@ TEST_P(TlsConnectGenericResumption, ReConnectAgainTicket) {
ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256); ssl_auth_rsa_sign, ssl_sig_rsa_pss_rsae_sha256);
} }
void CheckGetInfoResult(uint32_t alpnSize, uint32_t earlyDataSize, void CheckGetInfoResult(PRTime now, uint32_t alpnSize, uint32_t earlyDataSize,
ScopedCERTCertificate& cert, ScopedCERTCertificate& cert,
ScopedSSLResumptionTokenInfo& token) { ScopedSSLResumptionTokenInfo& token) {
ASSERT_TRUE(cert); ASSERT_TRUE(cert);
@ -1125,7 +1127,7 @@ void CheckGetInfoResult(uint32_t alpnSize, uint32_t earlyDataSize,
ASSERT_EQ(earlyDataSize, token->maxEarlyDataSize); ASSERT_EQ(earlyDataSize, token->maxEarlyDataSize);
ASSERT_LT(ssl_TimeUsec(), token->expirationTime); ASSERT_LT(now, token->expirationTime);
} }
// The client should generate a new, randomized session_id // The client should generate a new, randomized session_id
@ -1175,7 +1177,7 @@ TEST_P(TlsConnectGenericResumptionToken, ConnectResumeGetInfo) {
ScopedCERTCertificate cert( ScopedCERTCertificate cert(
PK11_FindCertFromNickname(server_->name().c_str(), nullptr)); PK11_FindCertFromNickname(server_->name().c_str(), nullptr));
CheckGetInfoResult(0, 0, cert, token); CheckGetInfoResult(now(), 0, 0, cert, token);
Handshake(); Handshake();
CheckConnected(); CheckConnected();
@ -1183,6 +1185,56 @@ TEST_P(TlsConnectGenericResumptionToken, ConnectResumeGetInfo) {
SendReceive(); SendReceive();
} }
TEST_P(TlsConnectGenericResumptionToken, RefuseExpiredTicketClient) {
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
Connect();
SendReceive();
// Move the clock to the expiration time of the ticket.
SSLResumptionTokenInfo tokenInfo = {0};
ScopedSSLResumptionTokenInfo token(&tokenInfo);
client_->GetTokenInfo(token);
AdvanceTime(token->expirationTime - now());
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
ExpectResumption(RESUME_TICKET);
StartConnect();
ASSERT_EQ(SECFailure,
SSL_SetResumptionToken(client_->ssl_fd(),
client_->GetResumptionToken().data(),
client_->GetResumptionToken().size()));
EXPECT_EQ(SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR, PORT_GetError());
}
TEST_P(TlsConnectGenericResumptionToken, RefuseExpiredTicketServer) {
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
Connect();
SendReceive();
Reset();
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
ExpectResumption(RESUME_NONE);
// Start the handshake and send the ClientHello.
StartConnect();
ASSERT_EQ(SECSuccess,
SSL_SetResumptionToken(client_->ssl_fd(),
client_->GetResumptionToken().data(),
client_->GetResumptionToken().size()));
client_->Handshake();
// Move the clock to the expiration time of the ticket.
SSLResumptionTokenInfo tokenInfo = {0};
ScopedSSLResumptionTokenInfo token(&tokenInfo);
client_->GetTokenInfo(token);
AdvanceTime(token->expirationTime - now());
Handshake();
CheckConnected();
}
TEST_P(TlsConnectGenericResumptionToken, ConnectResumeGetInfoAlpn) { TEST_P(TlsConnectGenericResumptionToken, ConnectResumeGetInfoAlpn) {
EnableAlpn(); EnableAlpn();
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
@ -1205,7 +1257,7 @@ TEST_P(TlsConnectGenericResumptionToken, ConnectResumeGetInfoAlpn) {
ScopedCERTCertificate cert( ScopedCERTCertificate cert(
PK11_FindCertFromNickname(server_->name().c_str(), nullptr)); PK11_FindCertFromNickname(server_->name().c_str(), nullptr));
CheckGetInfoResult(1, 0, cert, token); CheckGetInfoResult(now(), 1, 0, cert, token);
Handshake(); Handshake();
CheckConnected(); CheckConnected();
@ -1216,7 +1268,7 @@ TEST_P(TlsConnectGenericResumptionToken, ConnectResumeGetInfoAlpn) {
TEST_P(TlsConnectTls13ResumptionToken, ConnectResumeGetInfoZeroRtt) { TEST_P(TlsConnectTls13ResumptionToken, ConnectResumeGetInfoZeroRtt) {
EnableAlpn(); EnableAlpn();
SSLInt_RolloverAntiReplay(); RolloverAntiReplay();
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH); ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
server_->Set0RttEnabled(true); server_->Set0RttEnabled(true);
Connect(); Connect();
@ -1240,7 +1292,7 @@ TEST_P(TlsConnectTls13ResumptionToken, ConnectResumeGetInfoZeroRtt) {
ScopedCERTCertificate cert( ScopedCERTCertificate cert(
PK11_FindCertFromNickname(server_->name().c_str(), nullptr)); PK11_FindCertFromNickname(server_->name().c_str(), nullptr));
CheckGetInfoResult(1, 1024, cert, token); CheckGetInfoResult(now(), 1, 1024, cert, token);
ZeroRttSendReceive(true, true); ZeroRttSendReceive(true, true);
Handshake(); Handshake();

Просмотреть файл

@ -106,6 +106,10 @@ std::string VersionString(uint16_t version) {
} }
} }
// The default anti-replay window for tests. Tests that rely on a different
// value call SSL_InitAntiReplay directly.
static PRTime kAntiReplayWindow = 100 * PR_USEC_PER_SEC;
TlsConnectTestBase::TlsConnectTestBase(SSLProtocolVariant variant, TlsConnectTestBase::TlsConnectTestBase(SSLProtocolVariant variant,
uint16_t version) uint16_t version)
: variant_(variant), : variant_(variant),
@ -203,11 +207,15 @@ void TlsConnectTestBase::RestoreAlgorithmPolicy() {
} }
} }
PRTime TlsConnectTestBase::TimeFunc(void* arg) {
return *reinterpret_cast<PRTime*>(arg);
}
void TlsConnectTestBase::SetUp() { void TlsConnectTestBase::SetUp() {
SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str()); SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str());
SSLInt_ClearSelfEncryptKey(); SSLInt_ClearSelfEncryptKey();
SSLInt_SetTicketLifetime(30); now_ = PR_Now();
SSL_SetupAntiReplay(1 * PR_USEC_PER_SEC, 1, 3); SSL_InitAntiReplay(now_, kAntiReplayWindow, 1, 3);
ClearStats(); ClearStats();
SaveAlgorithmPolicy(); SaveAlgorithmPolicy();
Init(); Init();
@ -282,10 +290,13 @@ void TlsConnectTestBase::EnsureTlsSetup() {
: nullptr)); : nullptr));
EXPECT_TRUE(client_->EnsureTlsSetup(client_model_ ? client_model_->ssl_fd() EXPECT_TRUE(client_->EnsureTlsSetup(client_model_ ? client_model_->ssl_fd()
: nullptr)); : nullptr));
EXPECT_EQ(SECSuccess, SSL_SetTimeFunc(client_->ssl_fd(),
TlsConnectTestBase::TimeFunc, &now_));
EXPECT_EQ(SECSuccess, SSL_SetTimeFunc(server_->ssl_fd(),
TlsConnectTestBase::TimeFunc, &now_));
} }
void TlsConnectTestBase::Handshake() { void TlsConnectTestBase::Handshake() {
EnsureTlsSetup();
client_->SetServerKeyBits(server_->server_key_bits()); client_->SetServerKeyBits(server_->server_key_bits());
client_->Handshake(); client_->Handshake();
server_->Handshake(); server_->Handshake();
@ -302,16 +313,16 @@ void TlsConnectTestBase::EnableExtendedMasterSecret() {
} }
void TlsConnectTestBase::Connect() { void TlsConnectTestBase::Connect() {
server_->StartConnect(server_model_ ? server_model_->ssl_fd() : nullptr); StartConnect();
client_->StartConnect(client_model_ ? client_model_->ssl_fd() : nullptr);
client_->MaybeSetResumptionToken(); client_->MaybeSetResumptionToken();
Handshake(); Handshake();
CheckConnected(); CheckConnected();
} }
void TlsConnectTestBase::StartConnect() { void TlsConnectTestBase::StartConnect() {
server_->StartConnect(server_model_ ? server_model_->ssl_fd() : nullptr); EnsureTlsSetup();
client_->StartConnect(client_model_ ? client_model_->ssl_fd() : nullptr); server_->StartConnect();
client_->StartConnect();
} }
void TlsConnectTestBase::ConnectWithCipherSuite(uint16_t cipher_suite) { void TlsConnectTestBase::ConnectWithCipherSuite(uint16_t cipher_suite) {
@ -679,8 +690,9 @@ void TlsConnectTestBase::SendReceive(size_t total) {
// Do a first connection so we can do 0-RTT on the second one. // Do a first connection so we can do 0-RTT on the second one.
void TlsConnectTestBase::SetupForZeroRtt() { void TlsConnectTestBase::SetupForZeroRtt() {
// Force rollover of the anti-replay window.
// If we don't do this, then all 0-RTT attempts will be rejected. // If we don't do this, then all 0-RTT attempts will be rejected.
SSLInt_RolloverAntiReplay(); RolloverAntiReplay();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET); ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3); ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
@ -792,12 +804,20 @@ void TlsConnectTestBase::ShiftDtlsTimers() {
time_shift = time; time_shift = time;
} }
if (time_shift == PR_INTERVAL_NO_TIMEOUT) { if (time_shift != PR_INTERVAL_NO_TIMEOUT) {
return; AdvanceTime(PR_IntervalToMicroseconds(time_shift));
EXPECT_EQ(SECSuccess,
SSLInt_ShiftDtlsTimers(client_->ssl_fd(), time_shift));
EXPECT_EQ(SECSuccess,
SSLInt_ShiftDtlsTimers(server_->ssl_fd(), time_shift));
} }
}
EXPECT_EQ(SECSuccess, SSLInt_ShiftDtlsTimers(client_->ssl_fd(), time_shift)); void TlsConnectTestBase::AdvanceTime(PRTime time_shift) { now_ += time_shift; }
EXPECT_EQ(SECSuccess, SSLInt_ShiftDtlsTimers(server_->ssl_fd(), time_shift));
// Advance time by a full anti-replay window.
void TlsConnectTestBase::RolloverAntiReplay() {
AdvanceTime(kAntiReplayWindow);
} }
TlsConnectGeneric::TlsConnectGeneric() TlsConnectGeneric::TlsConnectGeneric()

Просмотреть файл

@ -48,6 +48,8 @@ class TlsConnectTestBase : public ::testing::Test {
virtual void SetUp(); virtual void SetUp();
virtual void TearDown(); virtual void TearDown();
PRTime now() const { return now_; }
// Initialize client and server. // Initialize client and server.
void Init(); void Init();
// Clear the statistics. // Clear the statistics.
@ -131,6 +133,8 @@ class TlsConnectTestBase : public ::testing::Test {
// Move the DTLS timers for both endpoints to pop the next timer. // Move the DTLS timers for both endpoints to pop the next timer.
void ShiftDtlsTimers(); void ShiftDtlsTimers();
void AdvanceTime(PRTime time_shift);
void RolloverAntiReplay();
void SaveAlgorithmPolicy(); void SaveAlgorithmPolicy();
void RestoreAlgorithmPolicy(); void RestoreAlgorithmPolicy();
@ -164,10 +168,12 @@ class TlsConnectTestBase : public ::testing::Test {
void CheckResumption(SessionResumptionMode expected); void CheckResumption(SessionResumptionMode expected);
void CheckExtendedMasterSecret(); void CheckExtendedMasterSecret();
void CheckEarlyDataAccepted(); void CheckEarlyDataAccepted();
static PRTime TimeFunc(void* arg);
bool expect_extended_master_secret_; bool expect_extended_master_secret_;
bool expect_early_data_accepted_; bool expect_early_data_accepted_;
bool skip_version_checks_; bool skip_version_checks_;
PRTime now_;
// Track groups and make sure that there are no duplicates. // Track groups and make sure that there are no duplicates.
class DuplicateGroupChecker { class DuplicateGroupChecker {

Просмотреть файл

@ -3,7 +3,7 @@ Usage: build.sh [-h] [-c|-cc] [-v] [-j <n>] [--gyp|-g] [--opt|-o]
[--clang|--gcc|--msvc] [--scan-build[=dir]] [--disable-tests] [--clang|--gcc|--msvc] [--scan-build[=dir]] [--disable-tests]
[--pprof] [--asan] [--msan] [--ubsan[=bool,shift,...] [--pprof] [--asan] [--msan] [--ubsan[=bool,shift,...]
[--fuzz[=tls|oss]] [--sancov[=edge|bb|func|...]] [--fuzz[=tls|oss]] [--sancov[=edge|bb|func|...]]
[--emit-llvm] [--no-zdefs] [--test] [--ct-verif] [--emit-llvm] [--no-zdefs] [--static] [--ct-verif]
[--nspr|--with-nspr=<include>:<lib>|--system-nspr] [--nspr|--with-nspr=<include>:<lib>|--system-nspr]
[--system-sqlite] [--enable-fips] [--enable-libpkix] [--system-sqlite] [--enable-fips] [--enable-libpkix]
[--mozpkix-only] [-D<gyp-option>] [--mozpkix-only] [-D<gyp-option>]
@ -31,7 +31,7 @@ NSS build tool options:
--msan enable memory sanitizer --msan enable memory sanitizer
--ubsan enable undefined behavior sanitizer --ubsan enable undefined behavior sanitizer
--ubsan=bool,shift,... sets specific UB sanitizers --ubsan=bool,shift,... sets specific UB sanitizers
--fuzz build fuzzing targets (this always enables test builds) --fuzz build fuzzing targets (this always enables static builds)
--fuzz=tls to enable TLS fuzzing mode --fuzz=tls to enable TLS fuzzing mode
--fuzz=oss to build for OSS-Fuzz --fuzz=oss to build for OSS-Fuzz
--sancov do sanitize coverage builds --sancov do sanitize coverage builds
@ -39,7 +39,6 @@ NSS build tool options:
--emit-llvm emit LLVM bitcode while building --emit-llvm emit LLVM bitcode while building
(requires the gold linker, use clang-3.8 for SAW) (requires the gold linker, use clang-3.8 for SAW)
--no-zdefs don't set -Wl,-z,defs --no-zdefs don't set -Wl,-z,defs
--test ignore map files and export everything we have
--static create static libraries and use static linking --static create static libraries and use static linking
--ct-verif build with valgrind for ct-verif --ct-verif build with valgrind for ct-verif
--nspr force a rebuild of NSPR --nspr force a rebuild of NSPR

Просмотреть файл

@ -210,8 +210,7 @@ ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output,
PORT_SetError(SEC_ERROR_INPUT_LEN); PORT_SetError(SEC_ERROR_INPUT_LEN);
return SECFailure; return SECFailure;
} }
*outputLen = inputLen + ctx->tagLen; if (maxOutputLen < inputLen + ctx->tagLen) {
if (maxOutputLen < *outputLen) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN); PORT_SetError(SEC_ERROR_OUTPUT_LEN);
return SECFailure; return SECFailure;
} }
@ -227,6 +226,7 @@ ChaCha20Poly1305_Seal(const ChaCha20Poly1305Context *ctx, unsigned char *output,
Poly1305Do(tag, ad, adLen, output, inputLen, block); Poly1305Do(tag, ad, adLen, output, inputLen, block);
PORT_Memcpy(output + inputLen, tag, ctx->tagLen); PORT_Memcpy(output + inputLen, tag, ctx->tagLen);
*outputLen = inputLen + ctx->tagLen;
return SECSuccess; return SECSuccess;
#endif #endif
} }
@ -254,8 +254,7 @@ ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx, unsigned char *output,
return SECFailure; return SECFailure;
} }
ciphertextLen = inputLen - ctx->tagLen; ciphertextLen = inputLen - ctx->tagLen;
*outputLen = ciphertextLen; if (maxOutputLen < ciphertextLen) {
if (maxOutputLen < *outputLen) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN); PORT_SetError(SEC_ERROR_OUTPUT_LEN);
return SECFailure; return SECFailure;
} }
@ -274,6 +273,7 @@ ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx, unsigned char *output,
ChaCha20Xor(output, (uint8_t *)input, ciphertextLen, (uint8_t *)ctx->key, ChaCha20Xor(output, (uint8_t *)input, ciphertextLen, (uint8_t *)ctx->key,
(uint8_t *)nonce, 1); (uint8_t *)nonce, 1);
*outputLen = ciphertextLen;
return SECSuccess; return SECSuccess;
#endif #endif
} }

Просмотреть файл

@ -126,9 +126,9 @@
'<(DEPTH)/exports.gyp:nss_exports' '<(DEPTH)/exports.gyp:nss_exports'
] ]
}, },
# For test builds, build a static freebl library so we can statically # Build a static freebl library so we can statically link it into
# link it into the test build binary. This way we don't have to # the binary. This way we don't have to dlopen() the shared lib
# dlopen() the shared lib but can directly call freebl functions. # but can directly call freebl functions.
{ {
'target_name': 'freebl_static', 'target_name': 'freebl_static',
'type': 'static_library', 'type': 'static_library',
@ -154,7 +154,7 @@
], ],
'conditions': [ 'conditions': [
[ 'target_arch=="x64"', { [ 'target_arch=="x64"', {
# The AES assembler code doesn't work in static test builds. # The AES assembler code doesn't work in static builds.
# The linker complains about non-relocatable code, and I # The linker complains about non-relocatable code, and I
# currently don't know how to fix this properly. # currently don't know how to fix this properly.
'sources!': [ 'sources!': [
@ -182,7 +182,7 @@
'gcm-aes-x86_c_lib', 'gcm-aes-x86_c_lib',
] ]
}], }],
[ 'OS!="linux" and OS!="android"', { [ 'OS!="linux"', {
'conditions': [ 'conditions': [
[ 'moz_fold_libs==0', { [ 'moz_fold_libs==0', {
'dependencies': [ 'dependencies': [
@ -194,7 +194,8 @@
], ],
}], }],
], ],
}, 'target_arch=="x64"', { }],
[ '(OS=="linux" or OS=="android") and target_arch=="x64"', {
'dependencies': [ 'dependencies': [
'intel-gcm-wrap_c_lib', 'intel-gcm-wrap_c_lib',
], ],

Просмотреть файл

@ -99,7 +99,7 @@
}], }],
[ 'OS=="win"', { [ 'OS=="win"', {
'libraries': [ 'libraries': [
'advapi32.lib', '-ladvapi32',
], ],
'conditions': [ 'conditions': [
[ 'cc_use_gnu_ld!=1 and target_arch=="x64"', { [ 'cc_use_gnu_ld!=1 and target_arch=="x64"', {

Просмотреть файл

@ -341,33 +341,19 @@ mp_set(mp_int *mp, mp_digit d)
mp_err mp_err
mp_set_int(mp_int *mp, long z) mp_set_int(mp_int *mp, long z)
{ {
int ix;
unsigned long v = labs(z); unsigned long v = labs(z);
mp_err res; mp_err res;
ARGCHK(mp != NULL, MP_BADARG); /* https://bugzilla.mozilla.org/show_bug.cgi?id=1509432 */
if ((res = mp_set_ulong(mp, v)) != MP_OKAY) { /* avoids duplicated code */
mp_zero(mp); return res;
if (z == 0)
return MP_OKAY; /* shortcut for zero */
if (sizeof v <= sizeof(mp_digit)) {
DIGIT(mp, 0) = v;
} else {
for (ix = sizeof(long) - 1; ix >= 0; ix--) {
if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
return res;
res = s_mp_add_d(mp, (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX));
if (res != MP_OKAY)
return res;
}
} }
if (z < 0)
if (z < 0) {
SIGN(mp) = NEG; SIGN(mp) = NEG;
}
return MP_OKAY; return MP_OKAY;
} /* end mp_set_int() */ } /* end mp_set_int() */
/* }}} */ /* }}} */

Просмотреть файл

@ -1015,6 +1015,8 @@ makePfromQandSeed(
hashlen = HASH_ResultLen(hashtype); hashlen = HASH_ResultLen(hashtype);
outlen = hashlen * PR_BITS_PER_BYTE; outlen = hashlen * PR_BITS_PER_BYTE;
PORT_Assert(outlen > 0);
/* L - 1 = n*outlen + b */ /* L - 1 = n*outlen + b */
n = (L - 1) / outlen; n = (L - 1) / outlen;
b = (L - 1) % outlen; b = (L - 1) % outlen;
@ -1768,6 +1770,7 @@ PQG_VerifyParams(const PQGParams *params,
/* 10. P generated from (L, counter, g, SEED, Q) matches P /* 10. P generated from (L, counter, g, SEED, Q) matches P
* in PQGParams. */ * in PQGParams. */
outlen = HASH_ResultLen(hashtype) * PR_BITS_PER_BYTE; outlen = HASH_ResultLen(hashtype) * PR_BITS_PER_BYTE;
PORT_Assert(outlen > 0);
n = (L - 1) / outlen; n = (L - 1) / outlen;
offset = vfy->counter * (n + 1) + ((type == FIPS186_1_TYPE) ? 2 : 1); offset = vfy->counter * (n + 1) + ((type == FIPS186_1_TYPE) ? 2 : 1);
CHECK_SEC_OK(makePfromQandSeed(hashtype, L, N, offset, g, &vfy->seed, CHECK_SEC_OK(makePfromQandSeed(hashtype, L, N, offset, g, &vfy->seed,

Просмотреть файл

@ -22,12 +22,12 @@
* The format of the version string should be * The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]" * "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/ */
#define NSS_VERSION "3.44" _NSS_CUSTOMIZED #define NSS_VERSION "3.45" _NSS_CUSTOMIZED " Beta"
#define NSS_VMAJOR 3 #define NSS_VMAJOR 3
#define NSS_VMINOR 44 #define NSS_VMINOR 45
#define NSS_VPATCH 0 #define NSS_VPATCH 0
#define NSS_VBUILD 0 #define NSS_VBUILD 0
#define NSS_BETA PR_FALSE #define NSS_BETA PR_TRUE
#ifndef RC_INVOKED #ifndef RC_INVOKED

Просмотреть файл

@ -1008,12 +1008,12 @@ PK11_DigestFinal(PK11Context *context, unsigned char *data,
} }
PK11_ExitContextMonitor(context); PK11_ExitContextMonitor(context);
*outLen = (unsigned int)len;
context->init = PR_FALSE; /* allow Begin to start up again */ context->init = PR_FALSE; /* allow Begin to start up again */
if (crv != CKR_OK) { if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv)); PORT_SetError(PK11_MapError(crv));
return SECFailure; return SECFailure;
} }
*outLen = (unsigned int)len;
return SECSuccess; return SECSuccess;
} }

Просмотреть файл

@ -933,11 +933,11 @@ PK11_Decrypt(PK11SymKey *symKey,
if (haslock) if (haslock)
PK11_ExitSlotMonitor(slot); PK11_ExitSlotMonitor(slot);
pk11_CloseSession(slot, session, owner); pk11_CloseSession(slot, session, owner);
*outLen = len;
if (crv != CKR_OK) { if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv)); PORT_SetError(PK11_MapError(crv));
return SECFailure; return SECFailure;
} }
*outLen = len;
return SECSuccess; return SECSuccess;
} }
@ -979,11 +979,11 @@ PK11_Encrypt(PK11SymKey *symKey,
if (haslock) if (haslock)
PK11_ExitSlotMonitor(slot); PK11_ExitSlotMonitor(slot);
pk11_CloseSession(slot, session, owner); pk11_CloseSession(slot, session, owner);
*outLen = len;
if (crv != CKR_OK) { if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv)); PORT_SetError(PK11_MapError(crv));
return SECFailure; return SECFailure;
} }
*outLen = len;
return SECSuccess; return SECSuccess;
} }
@ -1665,10 +1665,10 @@ pk11_CreateGenericObjectHelper(PK11SlotInfo *slot,
/* This is the classic interface. Applications would call this function to /* This is the classic interface. Applications would call this function to
* create new object that would not be destroyed later. This lead to resource * create new object that would not be destroyed later. This lead to resource
* leaks (and thus memory leaks in the PKCS #11 module). To solve this we have * leaks (and thus memory leaks in the PKCS #11 module). To solve this we have
* a new interface that automatically marks objects created on the fly to be * a new interface that automatically marks objects created on the fly to be
* destroyed later. * destroyed later.
* The old interface is preserved because applications like Mozilla purposefully * The old interface is preserved because applications like Mozilla purposefully
* leak the reference to be found later with PK11_FindGenericObjects. New * leak the reference to be found later with PK11_FindGenericObjects. New
* applications should use the new interface PK11_CreateManagedGenericObject */ * applications should use the new interface PK11_CreateManagedGenericObject */
PK11GenericObject * PK11GenericObject *
PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate, PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate,
@ -1678,8 +1678,8 @@ PK11_CreateGenericObject(PK11SlotInfo *slot, const CK_ATTRIBUTE *pTemplate,
PR_FALSE); PR_FALSE);
} }
/* Use this interface. It will automatically destroy any temporary objects /* Use this interface. It will automatically destroy any temporary objects
* (token = PR_FALSE) when the PK11GenericObject is freed. Permanent objects still * (token = PR_FALSE) when the PK11GenericObject is freed. Permanent objects still
* need to be destroyed by hand with PK11_DestroyTokenObject. * need to be destroyed by hand with PK11_DestroyTokenObject.
*/ */
PK11GenericObject * PK11GenericObject *

Просмотреть файл

@ -1439,6 +1439,11 @@ PK11_InitSlot(SECMODModule *mod, CK_SLOT_ID slotID, PK11SlotInfo *slot)
slot->slotID = slotID; slot->slotID = slotID;
slot->isThreadSafe = mod->isThreadSafe; slot->isThreadSafe = mod->isThreadSafe;
slot->hasRSAInfo = PR_FALSE; slot->hasRSAInfo = PR_FALSE;
slot->module = mod; /* NOTE: we don't make a reference here because
* modules have references to their slots. This
* works because modules keep implicit references
* from their slots, and won't unload and disappear
* until all their slots have been freed */
if (PK11_GETTAB(slot)->C_GetSlotInfo(slotID, &slotInfo) != CKR_OK) { if (PK11_GETTAB(slot)->C_GetSlotInfo(slotID, &slotInfo) != CKR_OK) {
slot->disabled = PR_TRUE; slot->disabled = PR_TRUE;
@ -1448,11 +1453,6 @@ PK11_InitSlot(SECMODModule *mod, CK_SLOT_ID slotID, PK11SlotInfo *slot)
/* test to make sure claimed mechanism work */ /* test to make sure claimed mechanism work */
slot->needTest = mod->internal ? PR_FALSE : PR_TRUE; slot->needTest = mod->internal ? PR_FALSE : PR_TRUE;
slot->module = mod; /* NOTE: we don't make a reference here because
* modules have references to their slots. This
* works because modules keep implicit references
* from their slots, and won't unload and disappear
* until all their slots have been freed */
(void)PK11_MakeString(NULL, slot->slot_name, (void)PK11_MakeString(NULL, slot->slot_name,
(char *)slotInfo.slotDescription, sizeof(slotInfo.slotDescription)); (char *)slotInfo.slotDescription, sizeof(slotInfo.slotDescription));
slot->isHW = (PRBool)((slotInfo.flags & CKF_HW_SLOT) == CKF_HW_SLOT); slot->isHW = (PRBool)((slotInfo.flags & CKF_HW_SLOT) == CKF_HW_SLOT);

Просмотреть файл

@ -1379,8 +1379,11 @@ NSC_EncryptUpdate(CK_SESSION_HANDLE hSession,
/* do it: NOTE: this assumes buf size in is >= buf size out! */ /* do it: NOTE: this assumes buf size in is >= buf size out! */
rv = (*context->update)(context->cipherInfo, pEncryptedPart, rv = (*context->update)(context->cipherInfo, pEncryptedPart,
&outlen, maxout, pPart, ulPartLen); &outlen, maxout, pPart, ulPartLen);
if (rv != SECSuccess) {
return sftk_MapCryptError(PORT_GetError());
}
*pulEncryptedPartLen = (CK_ULONG)(outlen + padoutlen); *pulEncryptedPartLen = (CK_ULONG)(outlen + padoutlen);
return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError()); return CKR_OK;
} }
/* NSC_EncryptFinal finishes a multiple-part encryption operation. */ /* NSC_EncryptFinal finishes a multiple-part encryption operation. */
@ -1460,26 +1463,29 @@ NSC_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
return crv; return crv;
if (!pEncryptedData) { if (!pEncryptedData) {
*pulEncryptedDataLen = context->rsa ? context->maxLen : ulDataLen + 2 * context->blockSize; outlen = context->rsa ? context->maxLen : ulDataLen + 2 * context->blockSize;
goto finish; goto done;
} }
if (context->doPad) { if (context->doPad) {
if (context->multi) { if (context->multi) {
CK_ULONG updateLen = maxoutlen;
CK_ULONG finalLen; CK_ULONG finalLen;
/* padding is fairly complicated, have the update and final /* padding is fairly complicated, have the update and final
* code deal with it */ * code deal with it */
sftk_FreeSession(session); sftk_FreeSession(session);
crv = NSC_EncryptUpdate(hSession, pData, ulDataLen, pEncryptedData, crv = NSC_EncryptUpdate(hSession, pData, ulDataLen, pEncryptedData,
pulEncryptedDataLen); &updateLen);
if (crv != CKR_OK) if (crv != CKR_OK) {
*pulEncryptedDataLen = 0; updateLen = 0;
maxoutlen -= *pulEncryptedDataLen; }
pEncryptedData += *pulEncryptedDataLen; maxoutlen -= updateLen;
pEncryptedData += updateLen;
finalLen = maxoutlen; finalLen = maxoutlen;
crv2 = NSC_EncryptFinal(hSession, pEncryptedData, &finalLen); crv2 = NSC_EncryptFinal(hSession, pEncryptedData, &finalLen);
if (crv2 == CKR_OK) if (crv == CKR_OK && crv2 == CKR_OK) {
*pulEncryptedDataLen += finalLen; *pulEncryptedDataLen = updateLen + finalLen;
}
return crv == CKR_OK ? crv2 : crv; return crv == CKR_OK ? crv2 : crv;
} }
/* doPad without multi means that padding must be done on the first /* doPad without multi means that padding must be done on the first
@ -1505,14 +1511,15 @@ NSC_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
rv = (*context->update)(context->cipherInfo, pEncryptedData, rv = (*context->update)(context->cipherInfo, pEncryptedData,
&outlen, maxoutlen, pText.data, pText.len); &outlen, maxoutlen, pText.data, pText.len);
crv = (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError()); crv = (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError());
*pulEncryptedDataLen = (CK_ULONG)outlen;
if (pText.data != pData) if (pText.data != pData)
PORT_ZFree(pText.data, pText.len); PORT_ZFree(pText.data, pText.len);
fail: fail:
sftk_TerminateOp(session, SFTK_ENCRYPT, context); sftk_TerminateOp(session, SFTK_ENCRYPT, context);
finish: done:
sftk_FreeSession(session); sftk_FreeSession(session);
if (crv == CKR_OK) {
*pulEncryptedDataLen = (CK_ULONG)outlen;
}
return crv; return crv;
} }
@ -1601,8 +1608,11 @@ NSC_DecryptUpdate(CK_SESSION_HANDLE hSession,
/* do it: NOTE: this assumes buf size in is >= buf size out! */ /* do it: NOTE: this assumes buf size in is >= buf size out! */
rv = (*context->update)(context->cipherInfo, pPart, &outlen, rv = (*context->update)(context->cipherInfo, pPart, &outlen,
maxout, pEncryptedPart, ulEncryptedPartLen); maxout, pEncryptedPart, ulEncryptedPartLen);
if (rv != SECSuccess) {
return sftk_MapDecryptError(PORT_GetError());
}
*pulPartLen = (CK_ULONG)(outlen + padoutlen); *pulPartLen = (CK_ULONG)(outlen + padoutlen);
return (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError()); return CKR_OK;
} }
/* NSC_DecryptFinal finishes a multiple-part decryption operation. */ /* NSC_DecryptFinal finishes a multiple-part decryption operation. */
@ -1693,25 +1703,27 @@ NSC_Decrypt(CK_SESSION_HANDLE hSession,
return crv; return crv;
if (!pData) { if (!pData) {
*pulDataLen = ulEncryptedDataLen + context->blockSize; outlen = ulEncryptedDataLen + context->blockSize;
goto finish; goto done;
} }
if (context->doPad && context->multi) { if (context->doPad && context->multi) {
CK_ULONG updateLen = maxoutlen;
CK_ULONG finalLen; CK_ULONG finalLen;
/* padding is fairly complicated, have the update and final /* padding is fairly complicated, have the update and final
* code deal with it */ * code deal with it */
sftk_FreeSession(session); sftk_FreeSession(session);
crv = NSC_DecryptUpdate(hSession, pEncryptedData, ulEncryptedDataLen, crv = NSC_DecryptUpdate(hSession, pEncryptedData, ulEncryptedDataLen,
pData, pulDataLen); pData, &updateLen);
if (crv != CKR_OK) if (crv == CKR_OK) {
*pulDataLen = 0; maxoutlen -= updateLen;
maxoutlen -= *pulDataLen; pData += updateLen;
pData += *pulDataLen; }
finalLen = maxoutlen; finalLen = maxoutlen;
crv2 = NSC_DecryptFinal(hSession, pData, &finalLen); crv2 = NSC_DecryptFinal(hSession, pData, &finalLen);
if (crv2 == CKR_OK) if (crv == CKR_OK && crv2 == CKR_OK) {
*pulDataLen += finalLen; *pulDataLen = updateLen + finalLen;
}
return crv == CKR_OK ? crv2 : crv; return crv == CKR_OK ? crv2 : crv;
} }
@ -1736,10 +1748,12 @@ NSC_Decrypt(CK_SESSION_HANDLE hSession,
} }
} }
} }
*pulDataLen = (CK_ULONG)outlen;
sftk_TerminateOp(session, SFTK_DECRYPT, context); sftk_TerminateOp(session, SFTK_DECRYPT, context);
finish: done:
sftk_FreeSession(session); sftk_FreeSession(session);
if (crv == CKR_OK) {
*pulDataLen = (CK_ULONG)outlen;
}
return crv; return crv;
} }

Просмотреть файл

@ -17,11 +17,11 @@
* The format of the version string should be * The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]" * "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/ */
#define SOFTOKEN_VERSION "3.44" SOFTOKEN_ECC_STRING #define SOFTOKEN_VERSION "3.45" SOFTOKEN_ECC_STRING " Beta"
#define SOFTOKEN_VMAJOR 3 #define SOFTOKEN_VMAJOR 3
#define SOFTOKEN_VMINOR 44 #define SOFTOKEN_VMINOR 45
#define SOFTOKEN_VPATCH 0 #define SOFTOKEN_VPATCH 0
#define SOFTOKEN_VBUILD 0 #define SOFTOKEN_VBUILD 0
#define SOFTOKEN_BETA PR_FALSE #define SOFTOKEN_BETA PR_TRUE
#endif /* _SOFTKVER_H_ */ #endif /* _SOFTKVER_H_ */

Просмотреть файл

@ -20,12 +20,12 @@
#include "sslimpl.h" #include "sslimpl.h"
/* /*
* This callback used by SSL to pull client sertificate upon * This callback used by SSL to pull client certificate upon
* server request * server request
*/ */
SECStatus SECStatus
NSS_GetClientAuthData(void *arg, NSS_GetClientAuthData(void *arg,
PRFileDesc *socket, PRFileDesc *fd,
struct CERTDistNamesStr *caNames, struct CERTDistNamesStr *caNames,
struct CERTCertificateStr **pRetCert, struct CERTCertificateStr **pRetCert,
struct SECKEYPrivateKeyStr **pRetKey) struct SECKEYPrivateKeyStr **pRetKey)
@ -33,10 +33,14 @@ NSS_GetClientAuthData(void *arg,
CERTCertificate *cert = NULL; CERTCertificate *cert = NULL;
SECKEYPrivateKey *privkey = NULL; SECKEYPrivateKey *privkey = NULL;
char *chosenNickName = (char *)arg; /* CONST */ char *chosenNickName = (char *)arg; /* CONST */
void *proto_win = NULL;
SECStatus rv = SECFailure; SECStatus rv = SECFailure;
proto_win = SSL_RevealPinArg(socket); sslSocket *ss = ssl_FindSocket(fd);
if (!ss) {
return SECFailure;
}
void *proto_win = SSL_RevealPinArg(fd);
PRTime now = ssl_Time(ss);
if (chosenNickName) { if (chosenNickName) {
cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(), cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(),
@ -64,7 +68,7 @@ NSS_GetClientAuthData(void *arg,
if (!cert) if (!cert)
continue; continue;
/* Only check unexpired certs */ /* Only check unexpired certs */
if (CERT_CheckCertValidTimes(cert, ssl_TimeUsec(), PR_TRUE) != if (CERT_CheckCertValidTimes(cert, now, PR_TRUE) !=
secCertTimeValid) { secCertTimeValid) {
CERT_DestroyCertificate(cert); CERT_DestroyCertificate(cert);
continue; continue;

Просмотреть файл

@ -4841,7 +4841,8 @@ ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type)
* XXX If we've been called from ssl_BeginClientHandshake, then * XXX If we've been called from ssl_BeginClientHandshake, then
* this lookup is duplicative and wasteful. * this lookup is duplicative and wasteful.
*/ */
sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, ss->url); sid = ssl_LookupSID(ssl_Time(ss), &ss->sec.ci.peer,
ss->sec.ci.port, ss->peerID, ss->url);
} else { } else {
sid = NULL; sid = NULL;
} }
@ -8578,8 +8579,8 @@ ssl3_HandleClientHello(sslSocket *ss, PRUint8 *b, PRUint32 length)
ss->sec.ci.peer.pr_s6_addr32[2], ss->sec.ci.peer.pr_s6_addr32[2],
ss->sec.ci.peer.pr_s6_addr32[3])); ss->sec.ci.peer.pr_s6_addr32[3]));
if (ssl_sid_lookup) { if (ssl_sid_lookup) {
sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sidBytes.data, sid = (*ssl_sid_lookup)(ssl_Time(ss), &ss->sec.ci.peer,
sidBytes.len, ss->dbHandle); sidBytes.data, sidBytes.len, ss->dbHandle);
} else { } else {
errCode = SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED; errCode = SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED;
goto loser; goto loser;
@ -10276,7 +10277,7 @@ ssl3_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length)
* until it has verified the server's Finished message." See the comment in * until it has verified the server's Finished message." See the comment in
* ssl3_FinishHandshake for more details. * ssl3_FinishHandshake for more details.
*/ */
ss->ssl3.hs.newSessionTicket.received_timestamp = ssl_TimeUsec(); ss->ssl3.hs.newSessionTicket.received_timestamp = ssl_Time(ss);
if (length < 4) { if (length < 4) {
(void)SSL3_SendAlert(ss, alert_fatal, decode_error); (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET); PORT_SetError(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET);
@ -11584,8 +11585,8 @@ ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid, PK11SymKey *secret)
sid->keaGroup = ssl_grp_none; sid->keaGroup = ssl_grp_none;
} }
sid->sigScheme = ss->sec.signatureScheme; sid->sigScheme = ss->sec.signatureScheme;
sid->lastAccessTime = sid->creationTime = ssl_TimeUsec(); sid->lastAccessTime = sid->creationTime = ssl_Time(ss);
sid->expirationTime = sid->creationTime + ssl3_sid_timeout * PR_USEC_PER_SEC; sid->expirationTime = sid->creationTime + (ssl_ticket_lifetime * PR_USEC_PER_SEC);
sid->localCert = CERT_DupCertificate(ss->sec.localCert); sid->localCert = CERT_DupCertificate(ss->sec.localCert);
if (ss->sec.isServer) { if (ss->sec.isServer) {
sid->namedCurve = ss->sec.serverCert->namedCurve; sid->namedCurve = ss->sec.serverCert->namedCurve;

Просмотреть файл

@ -246,7 +246,7 @@ ssl3_ClientSendSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData,
session_ticket = &sid->u.ssl3.locked.sessionTicket; session_ticket = &sid->u.ssl3.locked.sessionTicket;
if (session_ticket->ticket.data && if (session_ticket->ticket.data &&
(xtnData->ticketTimestampVerified || (xtnData->ticketTimestampVerified ||
ssl_TicketTimeValid(session_ticket))) { ssl_TicketTimeValid(ss, session_ticket))) {
xtnData->ticketTimestampVerified = PR_FALSE; xtnData->ticketTimestampVerified = PR_FALSE;
@ -608,7 +608,6 @@ ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData
return SECSuccess; return SECSuccess;
} }
PRUint32 ssl_ticket_lifetime = 2 * 24 * 60 * 60; /* 2 days in seconds */
#define TLS_EX_SESS_TICKET_VERSION (0x010a) #define TLS_EX_SESS_TICKET_VERSION (0x010a)
/* /*
@ -742,7 +741,7 @@ ssl3_EncodeSessionTicket(sslSocket *ss, const NewSessionTicket *ticket,
} }
/* timestamp */ /* timestamp */
now = ssl_TimeUsec(); now = ssl_Time(ss);
PORT_Assert(sizeof(now) == 8); PORT_Assert(sizeof(now) == 8);
rv = sslBuffer_AppendNumber(&plaintext, now, 8); rv = sslBuffer_AppendNumber(&plaintext, now, 8);
if (rv != SECSuccess) if (rv != SECSuccess)
@ -797,7 +796,7 @@ ssl3_EncodeSessionTicket(sslSocket *ss, const NewSessionTicket *ticket,
* This is compared to the expected time, which should differ only as a * This is compared to the expected time, which should differ only as a
* result of clock errors or errors in the RTT estimate. * result of clock errors or errors in the RTT estimate.
*/ */
ticketAgeBaseline = (ssl_TimeUsec() - ss->ssl3.hs.serverHelloTime) / PR_USEC_PER_MSEC; ticketAgeBaseline = (ssl_Time(ss) - ss->ssl3.hs.serverHelloTime) / PR_USEC_PER_MSEC;
ticketAgeBaseline -= ticket->ticket_age_add; ticketAgeBaseline -= ticket->ticket_age_add;
rv = sslBuffer_AppendNumber(&plaintext, ticketAgeBaseline, 4); rv = sslBuffer_AppendNumber(&plaintext, ticketAgeBaseline, 4);
if (rv != SECSuccess) if (rv != SECSuccess)
@ -1242,8 +1241,8 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, const SECItem *ticket,
} }
/* Use the ticket if it is valid and unexpired. */ /* Use the ticket if it is valid and unexpired. */
if (parsedTicket.timestamp + ssl_ticket_lifetime * PR_USEC_PER_SEC > PRTime end = parsedTicket.timestamp + (ssl_ticket_lifetime * PR_USEC_PER_SEC);
ssl_TimeUsec()) { if (end > ssl_Time(ss)) {
rv = ssl_CreateSIDFromTicket(ss, ticket, &parsedTicket, &sid); rv = ssl_CreateSIDFromTicket(ss, ticket, &parsedTicket, &sid);
if (rv != SECSuccess) { if (rv != SECSuccess) {

Просмотреть файл

@ -155,8 +155,8 @@ ssl_BeginClientHandshake(sslSocket *ss)
SSL_TRC(3, ("%d: SSL[%d]: using external token", SSL_GETPID(), ss->fd)); SSL_TRC(3, ("%d: SSL[%d]: using external token", SSL_GETPID(), ss->fd));
} else if (!ss->opt.noCache) { } else if (!ss->opt.noCache) {
/* Try to find server in our session-id cache */ /* Try to find server in our session-id cache */
sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, sid = ssl_LookupSID(ssl_Time(ss), &ss->sec.ci.peer,
ss->url); ss->sec.ci.port, ss->peerID, ss->url);
} }
if (sid) { if (sid) {
@ -170,25 +170,15 @@ ssl_BeginClientHandshake(sslSocket *ss)
} }
} }
if (!sid) { if (!sid) {
sid = PORT_ZNew(sslSessionID); sid = ssl3_NewSessionID(ss, PR_FALSE);
if (!sid) { if (!sid) {
goto loser; goto loser;
} }
sid->references = 1; /* This session is a dummy, which we don't want to resume. */
sid->cached = never_cached; sid->u.ssl3.keys.resumable = PR_FALSE;
sid->addr = ss->sec.ci.peer;
sid->port = ss->sec.ci.port;
if (ss->peerID != NULL) {
sid->peerID = PORT_Strdup(ss->peerID);
}
if (ss->url != NULL) {
sid->urlSvrName = PORT_Strdup(ss->url);
}
} }
ss->sec.ci.sid = sid; ss->sec.ci.sid = sid;
PORT_Assert(sid != NULL);
ss->gs.state = GS_INIT; ss->gs.state = GS_INIT;
ss->handshake = ssl_GatherRecord1stHandshake; ss->handshake = ssl_GatherRecord1stHandshake;

Просмотреть файл

@ -159,7 +159,7 @@ typedef SECStatus(PR_CALLBACK *SSLExtensionHandler)(
handler, handlerArg)) handler, handlerArg))
/* /*
* Setup the anti-replay buffer for supporting 0-RTT in TLS 1.3 on servers. * Initialize the anti-replay buffer for supporting 0-RTT in TLS 1.3 on servers.
* *
* To use 0-RTT on a server, you must call this function. Failing to call this * To use 0-RTT on a server, you must call this function. Failing to call this
* function will result in all 0-RTT being rejected. Connections will complete, * function will result in all 0-RTT being rejected. Connections will complete,
@ -181,11 +181,11 @@ typedef SECStatus(PR_CALLBACK *SSLExtensionHandler)(
* The first tuning parameter to consider is |window|, which determines the * The first tuning parameter to consider is |window|, which determines the
* window over which ClientHello messages will be tracked. This also causes * window over which ClientHello messages will be tracked. This also causes
* early data to be rejected if a ClientHello contains a ticket age parameter * early data to be rejected if a ClientHello contains a ticket age parameter
* that is outside of this window (see Section 4.2.10.4 of * that is outside of this window (see Section 8.3 of RFC 8446 for details).
* draft-ietf-tls-tls13-20 for details). Set |window| to account for any * Set |window| to account for any potential sources of clock error. |window|
* potential sources of clock error. |window| is the entire width of the * is the entire width of the window, which is symmetrical. Therefore to allow
* window, which is symmetrical. Therefore to allow 5 seconds of clock error in * 5 seconds of clock error in both directions, set the value to 10 seconds
* both directions, set the value to 10 seconds (i.e., 10 * PR_USEC_PER_SEC). * (i.e., 10 * PR_USEC_PER_SEC).
* *
* After calling this function, early data will be rejected until |window| * After calling this function, early data will be rejected until |window|
* elapses. This prevents replay across crashes and restarts. Only call this * elapses. This prevents replay across crashes and restarts. Only call this
@ -219,10 +219,11 @@ typedef SECStatus(PR_CALLBACK *SSLExtensionHandler)(
* Early data can be replayed at least once with every server instance that will * Early data can be replayed at least once with every server instance that will
* accept tickets that are encrypted with the same key. * accept tickets that are encrypted with the same key.
*/ */
#define SSL_SetupAntiReplay(window, k, bits) \ #define SSL_InitAntiReplay(now, window, k, bits) \
SSL_EXPERIMENTAL_API("SSL_SetupAntiReplay", \ SSL_EXPERIMENTAL_API("SSL_InitAntiReplay", \
(PRTime _window, unsigned int _k, unsigned int _bits), \ (PRTime _now, PRTime _window, \
(window, k, bits)) unsigned int _k, unsigned int _bits), \
(now, window, k, bits))
/* /*
* This function allows a server application to generate a session ticket that * This function allows a server application to generate a session ticket that
@ -723,8 +724,20 @@ typedef struct SSLAeadContextStr SSLAeadContext;
hsHash, hsHashLen, label, labelLen, \ hsHash, hsHashLen, label, labelLen, \
mech, keySize, keyp)) mech, keySize, keyp))
/* SSL_SetTimeFunc overrides the default time function (PR_Now()) and provides
* an alternative source of time for the socket. This is used in testing, and in
* applications that need better control over how the clock is accessed. Set the
* function to NULL to use PR_Now().*/
typedef PRTime(PR_CALLBACK *SSLTimeFunc)(void *arg);
#define SSL_SetTimeFunc(fd, f, arg) \
SSL_EXPERIMENTAL_API("SSL_SetTimeFunc", \
(PRFileDesc * _fd, SSLTimeFunc _f, void *_arg), \
(fd, f, arg))
/* Deprecated experimental APIs */ /* Deprecated experimental APIs */
#define SSL_UseAltServerHelloType(fd, enable) SSL_DEPRECATED_EXPERIMENTAL_API #define SSL_UseAltServerHelloType(fd, enable) SSL_DEPRECATED_EXPERIMENTAL_API
#define SSL_SetupAntiReplay(a, b, c) SSL_DEPRECATED_EXPERIMENTAL_API
SEC_END_PROTOS SEC_END_PROTOS

Просмотреть файл

@ -183,10 +183,11 @@ typedef SECStatus (*sslHandshakeFunc)(sslSocket *ss);
void ssl_CacheSessionID(sslSocket *ss); void ssl_CacheSessionID(sslSocket *ss);
void ssl_UncacheSessionID(sslSocket *ss); void ssl_UncacheSessionID(sslSocket *ss);
void ssl_ServerCacheSessionID(sslSessionID *sid); void ssl_ServerCacheSessionID(sslSessionID *sid, PRTime creationTime);
void ssl_ServerUncacheSessionID(sslSessionID *sid); void ssl_ServerUncacheSessionID(sslSessionID *sid);
typedef sslSessionID *(*sslSessionIDLookupFunc)(const PRIPv6Addr *addr, typedef sslSessionID *(*sslSessionIDLookupFunc)(PRTime ssl_now,
const PRIPv6Addr *addr,
unsigned char *sid, unsigned char *sid,
unsigned int sidLen, unsigned int sidLen,
CERTCertDBHandle *dbHandle); CERTCertDBHandle *dbHandle);
@ -946,6 +947,10 @@ struct sslSocketStr {
/* Enabled version range */ /* Enabled version range */
SSLVersionRange vrange; SSLVersionRange vrange;
/* A function that returns the current time. */
SSLTimeFunc now;
void *nowArg;
/* State flags */ /* State flags */
unsigned long clientAuthRequested; unsigned long clientAuthRequested;
unsigned long delayDisabled; /* Nagle delay disabled */ unsigned long delayDisabled; /* Nagle delay disabled */
@ -1104,8 +1109,7 @@ extern char ssl_trace;
extern FILE *ssl_trace_iob; extern FILE *ssl_trace_iob;
extern FILE *ssl_keylog_iob; extern FILE *ssl_keylog_iob;
extern PZLock *ssl_keylog_lock; extern PZLock *ssl_keylog_lock;
extern PRUint32 ssl3_sid_timeout; static const PRUint32 ssl_ticket_lifetime = 2 * 24 * 60 * 60; // 2 days.
extern PRUint32 ssl_ticket_lifetime;
extern const char *const ssl3_cipherName[]; extern const char *const ssl3_cipherName[];
@ -1195,8 +1199,9 @@ extern SECStatus ssl3_InitPendingCipherSpecs(sslSocket *ss, PK11SymKey *secret,
PRBool derive); PRBool derive);
extern void ssl_DestroyKeyMaterial(ssl3KeyMaterial *keyMaterial); extern void ssl_DestroyKeyMaterial(ssl3KeyMaterial *keyMaterial);
extern sslSessionID *ssl3_NewSessionID(sslSocket *ss, PRBool is_server); extern sslSessionID *ssl3_NewSessionID(sslSocket *ss, PRBool is_server);
extern sslSessionID *ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, extern sslSessionID *ssl_LookupSID(PRTime now, const PRIPv6Addr *addr,
const char *peerID, const char *urlSvrName); PRUint16 port, const char *peerID,
const char *urlSvrName);
extern void ssl_FreeSID(sslSessionID *sid); extern void ssl_FreeSID(sslSessionID *sid);
extern void ssl_DestroySID(sslSessionID *sid, PRBool freeIt); extern void ssl_DestroySID(sslSessionID *sid, PRBool freeIt);
extern sslSessionID *ssl_ReferenceSID(sslSessionID *sid); extern sslSessionID *ssl_ReferenceSID(sslSessionID *sid);
@ -1606,8 +1611,8 @@ PRBool ssl3_config_match(const ssl3CipherSuiteCfg *suite, PRUint8 policy,
/* calls for accessing wrapping keys across processes. */ /* calls for accessing wrapping keys across processes. */
extern SECStatus extern SECStatus
ssl_GetWrappingKey(unsigned int symWrapMechIndex, unsigned int wrapKeyIndex, ssl_GetWrappingKey(unsigned int symWrapMechIndex,
SSLWrappedSymWrappingKey *wswk); unsigned int wrapKeyIndex, SSLWrappedSymWrappingKey *wswk);
/* The caller passes in the new value it wants /* The caller passes in the new value it wants
* to set. This code tests the wrapped sym key entry in the file on disk. * to set. This code tests the wrapped sym key entry in the file on disk.
@ -1719,13 +1724,8 @@ extern void ssl3_CheckCipherSuiteOrderConsistency();
extern int ssl_MapLowLevelError(int hiLevelError); extern int ssl_MapLowLevelError(int hiLevelError);
extern PRUint32 ssl_TimeSec(void); PRTime ssl_Time(const sslSocket *ss);
#ifdef UNSAFE_FUZZER_MODE PRBool ssl_TicketTimeValid(const sslSocket *ss, const NewSessionTicket *ticket);
#define ssl_TimeUsec() ((PRTime)12345678)
#else
#define ssl_TimeUsec() (PR_Now())
#endif
extern PRBool ssl_TicketTimeValid(const NewSessionTicket *ticket);
extern void SSL_AtomicIncrementLong(long *x); extern void SSL_AtomicIncrementLong(long *x);
@ -1763,7 +1763,7 @@ PK11SymKey *ssl_unwrapSymKey(PK11SymKey *wrapKey,
CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation,
int keySize, CK_FLAGS keyFlags, void *pinArg); int keySize, CK_FLAGS keyFlags, void *pinArg);
/* Remove when stable. */ /* Experimental APIs. Remove when stable. */
SECStatus SSLExp_SetResumptionTokenCallback(PRFileDesc *fd, SECStatus SSLExp_SetResumptionTokenCallback(PRFileDesc *fd,
SSLResumptionTokenCallback cb, SSLResumptionTokenCallback cb,
@ -1815,6 +1815,8 @@ SSLExp_HkdfExpandLabelWithMech(PRUint16 version, PRUint16 cipherSuite, PK11SymKe
CK_MECHANISM_TYPE mech, unsigned int keySize, CK_MECHANISM_TYPE mech, unsigned int keySize,
PK11SymKey **keyp); PK11SymKey **keyp);
SECStatus SSLExp_SetTimeFunc(PRFileDesc *fd, SSLTimeFunc f, void *arg);
SEC_END_PROTOS SEC_END_PROTOS
#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS) #if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)

Просмотреть файл

@ -20,8 +20,6 @@
#include <time.h> #include <time.h>
#endif #endif
PRUint32 ssl3_sid_timeout = 86400L; /* 24 hours */
static sslSessionID *cache = NULL; static sslSessionID *cache = NULL;
static PZLock *cacheLock = NULL; static PZLock *cacheLock = NULL;
@ -259,30 +257,28 @@ ssl_ReferenceSID(sslSessionID *sid)
*/ */
sslSessionID * sslSessionID *
ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID, ssl_LookupSID(PRTime now, const PRIPv6Addr *addr, PRUint16 port, const char *peerID,
const char *urlSvrName) const char *urlSvrName)
{ {
sslSessionID **sidp; sslSessionID **sidp;
sslSessionID *sid; sslSessionID *sid;
PRUint32 now;
if (!urlSvrName) if (!urlSvrName)
return NULL; return NULL;
now = ssl_TimeSec();
LOCK_CACHE; LOCK_CACHE;
sidp = &cache; sidp = &cache;
while ((sid = *sidp) != 0) { while ((sid = *sidp) != 0) {
PORT_Assert(sid->cached == in_client_cache); PORT_Assert(sid->cached == in_client_cache);
PORT_Assert(sid->references >= 1); PORT_Assert(sid->references >= 1);
SSL_TRC(8, ("SSL: Lookup1: sid=0x%x", sid)); SSL_TRC(8, ("SSL: lookup: sid=0x%x", sid));
if (sid->expirationTime < now) { if (sid->expirationTime < now) {
/* /*
** This session-id timed out. ** This session-id timed out.
** Don't even care who it belongs to, blow it out of our cache. ** Don't even care who it belongs to, blow it out of our cache.
*/ */
SSL_TRC(7, ("SSL: lookup1, throwing sid out, age=%d refs=%d", SSL_TRC(7, ("SSL: lookup, throwing sid out, age=%d refs=%d",
now - sid->creationTime, sid->references)); now - sid->creationTime, sid->references));
*sidp = sid->next; /* delink it from the list. */ *sidp = sid->next; /* delink it from the list. */
@ -316,7 +312,7 @@ ssl_LookupSID(const PRIPv6Addr *addr, PRUint16 port, const char *peerID,
** Although this is static, it is called via ss->sec.cache(). ** Although this is static, it is called via ss->sec.cache().
*/ */
static void static void
CacheSID(sslSessionID *sid) CacheSID(sslSessionID *sid, PRTime creationTime)
{ {
PORT_Assert(sid); PORT_Assert(sid);
PORT_Assert(sid->cached == never_cached); PORT_Assert(sid->cached == never_cached);
@ -353,11 +349,16 @@ CacheSID(sslSessionID *sid)
if (!sid->u.ssl3.lock) { if (!sid->u.ssl3.lock) {
return; return;
} }
PORT_Assert(sid->creationTime != 0 && sid->expirationTime != 0); PORT_Assert(sid->creationTime != 0);
if (!sid->creationTime) if (!sid->creationTime) {
sid->lastAccessTime = sid->creationTime = ssl_TimeUsec(); sid->lastAccessTime = sid->creationTime = creationTime;
if (!sid->expirationTime) }
sid->expirationTime = sid->creationTime + ssl3_sid_timeout * PR_USEC_PER_SEC; PORT_Assert(sid->expirationTime != 0);
if (!sid->expirationTime) {
sid->expirationTime = sid->creationTime + (PR_MIN(ssl_ticket_lifetime,
sid->u.ssl3.locked.sessionTicket.ticket_lifetime_hint) *
PR_USEC_PER_SEC);
}
/* /*
* Put sid into the cache. Bump reference count to indicate that * Put sid into the cache. Bump reference count to indicate that
@ -726,13 +727,13 @@ ssl_IsResumptionTokenUsable(sslSocket *ss, sslSessionID *sid)
if (ticket->ticket_lifetime_hint != 0) { if (ticket->ticket_lifetime_hint != 0) {
endTime = ticket->received_timestamp + endTime = ticket->received_timestamp +
(PRTime)(ticket->ticket_lifetime_hint * PR_USEC_PER_SEC); (PRTime)(ticket->ticket_lifetime_hint * PR_USEC_PER_SEC);
if (endTime < ssl_TimeUsec()) { if (endTime <= ssl_Time(ss)) {
return PR_FALSE; return PR_FALSE;
} }
} }
// Check that the session entry didn't expire. // Check that the session entry didn't expire.
if (sid->expirationTime < ssl_TimeUsec()) { if (sid->expirationTime < ssl_Time(ss)) {
return PR_FALSE; return PR_FALSE;
} }
@ -1087,10 +1088,12 @@ ssl_CacheExternalToken(sslSocket *ss)
} }
if (!sid->creationTime) { if (!sid->creationTime) {
sid->lastAccessTime = sid->creationTime = ssl_TimeUsec(); sid->lastAccessTime = sid->creationTime = ssl_Time(ss);
} }
if (!sid->expirationTime) { if (!sid->expirationTime) {
sid->expirationTime = sid->creationTime + ssl3_sid_timeout; sid->expirationTime = sid->creationTime + (PR_MIN(ssl_ticket_lifetime,
sid->u.ssl3.locked.sessionTicket.ticket_lifetime_hint) *
PR_USEC_PER_SEC);
} }
sslBuffer encodedToken = SSL_BUFFER_EMPTY; sslBuffer encodedToken = SSL_BUFFER_EMPTY;
@ -1129,11 +1132,11 @@ ssl_CacheSessionID(sslSocket *ss)
PORT_Assert(!ss->resumptionTokenCallback); PORT_Assert(!ss->resumptionTokenCallback);
if (sec->isServer) { if (sec->isServer) {
ssl_ServerCacheSessionID(sec->ci.sid); ssl_ServerCacheSessionID(sec->ci.sid, ssl_Time(ss));
return; return;
} }
CacheSID(sec->ci.sid); CacheSID(sec->ci.sid, ssl_Time(ss));
} }
void void
@ -1165,32 +1168,8 @@ SSL_ClearSessionCache(void)
UNLOCK_CACHE; UNLOCK_CACHE;
} }
/* returns an unsigned int containing the number of seconds in PR_Now() */
PRUint32
ssl_TimeSec(void)
{
#ifdef UNSAFE_FUZZER_MODE
return 1234;
#endif
PRUint32 myTime;
#if defined(XP_UNIX) || defined(XP_WIN) || defined(_WINDOWS) || defined(XP_BEOS)
myTime = time(NULL); /* accurate until the year 2038. */
#else
/* portable, but possibly slower */
PRTime now;
PRInt64 ll;
now = PR_Now();
LL_I2L(ll, 1000000L);
LL_DIV(now, now, ll);
LL_L2UI(myTime, now);
#endif
return myTime;
}
PRBool PRBool
ssl_TicketTimeValid(const NewSessionTicket *ticket) ssl_TicketTimeValid(const sslSocket *ss, const NewSessionTicket *ticket)
{ {
PRTime endTime; PRTime endTime;
@ -1200,7 +1179,7 @@ ssl_TicketTimeValid(const NewSessionTicket *ticket)
endTime = ticket->received_timestamp + endTime = ticket->received_timestamp +
(PRTime)(ticket->ticket_lifetime_hint * PR_USEC_PER_SEC); (PRTime)(ticket->ticket_lifetime_hint * PR_USEC_PER_SEC);
return endTime > ssl_TimeUsec(); return endTime > ssl_Time(ss);
} }
void void

Просмотреть файл

@ -276,14 +276,24 @@ typedef struct inheritanceStr inheritance;
/************************************************************************/ /************************************************************************/
/* This is used to set locking times for the cache. It is not used to set the
* PRTime attributes of sessions, which are driven by ss->now(). */
static PRUint32
ssl_CacheNow()
{
return PR_Now() / PR_USEC_PER_SEC;
}
static PRUint32 static PRUint32
LockSidCacheLock(sidCacheLock *lock, PRUint32 now) LockSidCacheLock(sidCacheLock *lock, PRUint32 now)
{ {
SECStatus rv = sslMutex_Lock(&lock->mutex); SECStatus rv = sslMutex_Lock(&lock->mutex);
if (rv != SECSuccess) if (rv != SECSuccess)
return 0; return 0;
if (!now) if (!now) {
now = ssl_TimeSec(); now = ssl_CacheNow();
}
lock->timeStamp = now; lock->timeStamp = now;
lock->pid = myPid; lock->pid = myPid;
return now; return now;
@ -299,7 +309,7 @@ UnlockSidCacheLock(sidCacheLock *lock)
return rv; return rv;
} }
/* returns the value of ssl_TimeSec on success, zero on failure. */ /* Returns non-zero |now| or ssl_CacheNow() on success, zero on failure. */
static PRUint32 static PRUint32
LockSet(cacheDesc *cache, PRUint32 set, PRUint32 now) LockSet(cacheDesc *cache, PRUint32 set, PRUint32 now)
{ {
@ -630,9 +640,12 @@ FindSID(cacheDesc *cache, PRUint32 setNum, PRUint32 now,
/* This is the primary function for finding entries in the server's sid cache. /* This is the primary function for finding entries in the server's sid cache.
* Although it is static, this function is called via the global function * Although it is static, this function is called via the global function
* pointer ssl_sid_lookup. * pointer ssl_sid_lookup.
*
* sslNow is the time that the calling socket understands, which might be
* different than what the cache uses to maintain its locks.
*/ */
static sslSessionID * static sslSessionID *
ServerSessionIDLookup(const PRIPv6Addr *addr, ServerSessionIDLookup(PRTime sslNow, const PRIPv6Addr *addr,
unsigned char *sessionID, unsigned char *sessionID,
unsigned int sessionIDLength, unsigned int sessionIDLength,
CERTCertDBHandle *dbHandle) CERTCertDBHandle *dbHandle)
@ -712,7 +725,7 @@ ServerSessionIDLookup(const PRIPv6Addr *addr,
} }
} }
if (psce) { if (psce) {
psce->lastAccessTime = now; psce->lastAccessTime = sslNow;
sce = *psce; /* grab a copy while holding the lock */ sce = *psce; /* grab a copy while holding the lock */
} }
} }
@ -730,7 +743,7 @@ ServerSessionIDLookup(const PRIPv6Addr *addr,
** Place a sid into the cache, if it isn't already there. ** Place a sid into the cache, if it isn't already there.
*/ */
void void
ssl_ServerCacheSessionID(sslSessionID *sid) ssl_ServerCacheSessionID(sslSessionID *sid, PRTime creationTime)
{ {
PORT_Assert(sid); PORT_Assert(sid);
@ -748,7 +761,7 @@ ssl_ServerCacheSessionID(sslSessionID *sid)
PORT_Assert(sid->creationTime != 0); PORT_Assert(sid->creationTime != 0);
if (!sid->creationTime) if (!sid->creationTime)
sid->lastAccessTime = sid->creationTime = ssl_TimeUsec(); sid->lastAccessTime = sid->creationTime = creationTime;
/* override caller's expiration time, which uses client timeout /* override caller's expiration time, which uses client timeout
* duration, not server timeout duration. * duration, not server timeout duration.
*/ */
@ -1089,7 +1102,7 @@ InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries,
cache->srvNameCacheData = (srvNameCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache->srvNameCacheData); cache->srvNameCacheData = (srvNameCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache->srvNameCacheData);
/* initialize the locks */ /* initialize the locks */
init_time = ssl_TimeSec(); init_time = ssl_CacheNow();
pLock = cache->sidCacheLocks; pLock = cache->sidCacheLocks;
for (locks_to_initialize = cache->numSIDCacheLocks + 3; for (locks_to_initialize = cache->numSIDCacheLocks + 3;
locks_initialized < locks_to_initialize; locks_initialized < locks_to_initialize;
@ -1518,7 +1531,7 @@ LockPoller(void *arg)
if (sharedCache->stopPolling) if (sharedCache->stopPolling)
break; break;
now = ssl_TimeSec(); now = ssl_CacheNow();
then = now - expiration; then = now - expiration;
for (pLock = cache->sidCacheLocks, locks_polled = 0; for (pLock = cache->sidCacheLocks, locks_polled = 0;
locks_to_poll > locks_polled && !sharedCache->stopPolling; locks_to_poll > locks_polled && !sharedCache->stopPolling;

Просмотреть файл

@ -277,6 +277,8 @@ ssl_DupSocket(sslSocket *os)
goto loser; goto loser;
} }
ss->vrange = os->vrange; ss->vrange = os->vrange;
ss->now = os->now;
ss->nowArg = os->nowArg;
ss->peerID = !os->peerID ? NULL : PORT_Strdup(os->peerID); ss->peerID = !os->peerID ? NULL : PORT_Strdup(os->peerID);
ss->url = !os->url ? NULL : PORT_Strdup(os->url); ss->url = !os->url ? NULL : PORT_Strdup(os->url);
@ -2215,6 +2217,8 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
ss->opt = sm->opt; ss->opt = sm->opt;
ss->vrange = sm->vrange; ss->vrange = sm->vrange;
ss->now = sm->now;
ss->nowArg = sm->nowArg;
PORT_Memcpy(ss->cipherSuites, sm->cipherSuites, sizeof sm->cipherSuites); PORT_Memcpy(ss->cipherSuites, sm->cipherSuites, sizeof sm->cipherSuites);
PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, sm->ssl3.dtlsSRTPCiphers, PORT_Memcpy(ss->ssl3.dtlsSRTPCiphers, sm->ssl3.dtlsSRTPCiphers,
sizeof(PRUint16) * sm->ssl3.dtlsSRTPCipherCount); sizeof(PRUint16) * sm->ssl3.dtlsSRTPCipherCount);
@ -3902,6 +3906,15 @@ ssl_FreeEphemeralKeyPairs(sslSocket *ss)
} }
} }
PRTime
ssl_Time(const sslSocket *ss)
{
if (!ss->now) {
return PR_Now();
}
return ss->now(ss->nowArg);
}
/* /*
** Create a newsocket structure for a file descriptor. ** Create a newsocket structure for a file descriptor.
*/ */
@ -3917,7 +3930,7 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
makeLocks = PR_TRUE; makeLocks = PR_TRUE;
/* Make a new socket and get it ready */ /* Make a new socket and get it ready */
ss = (sslSocket *)PORT_ZAlloc(sizeof(sslSocket)); ss = PORT_ZNew(sslSocket);
if (!ss) { if (!ss) {
return NULL; return NULL;
} }
@ -4051,6 +4064,7 @@ struct {
EXP(GetExtensionSupport), EXP(GetExtensionSupport),
EXP(GetResumptionTokenInfo), EXP(GetResumptionTokenInfo),
EXP(HelloRetryRequestCallback), EXP(HelloRetryRequestCallback),
EXP(InitAntiReplay),
EXP(InstallExtensionHooks), EXP(InstallExtensionHooks),
EXP(HkdfExtract), EXP(HkdfExtract),
EXP(HkdfExpandLabel), EXP(HkdfExpandLabel),
@ -4066,7 +4080,7 @@ struct {
EXP(SetMaxEarlyDataSize), EXP(SetMaxEarlyDataSize),
EXP(SetResumptionTokenCallback), EXP(SetResumptionTokenCallback),
EXP(SetResumptionToken), EXP(SetResumptionToken),
EXP(SetupAntiReplay), EXP(SetTimeFunc),
#endif #endif
{ "", NULL } { "", NULL }
}; };
@ -4102,6 +4116,21 @@ ssl_ClearPRCList(PRCList *list, void (*f)(void *))
} }
} }
SECStatus
SSLExp_SetTimeFunc(PRFileDesc *fd, SSLTimeFunc f, void *arg)
{
sslSocket *ss = ssl_FindSocket(fd);
if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetTimeFunc",
SSL_GETPID(), fd));
return SECFailure;
}
ss->now = f;
ss->nowArg = arg;
return SECSuccess;
}
/* Experimental APIs for session cache handling. */ /* Experimental APIs for session cache handling. */
SECStatus SECStatus
@ -4185,7 +4214,7 @@ SSLExp_SetResumptionToken(PRFileDesc *fd, const PRUint8 *token,
/* Use the sid->cached as marker that this is from an external cache and /* Use the sid->cached as marker that this is from an external cache and
* we don't have to look up anything in the NSS internal cache. */ * we don't have to look up anything in the NSS internal cache. */
sid->cached = in_external_cache; sid->cached = in_external_cache;
sid->lastAccessTime = ssl_TimeSec(); sid->lastAccessTime = ssl_Time(ss);
ss->sec.ci.sid = sid; ss->sec.ci.sid = sid;

Просмотреть файл

@ -479,7 +479,7 @@ tls13_SetupClientHello(sslSocket *ss, sslClientHelloType chType)
session_ticket = &sid->u.ssl3.locked.sessionTicket; session_ticket = &sid->u.ssl3.locked.sessionTicket;
PORT_Assert(session_ticket && session_ticket->ticket.data); PORT_Assert(session_ticket && session_ticket->ticket.data);
if (ssl_TicketTimeValid(session_ticket)) { if (ssl_TicketTimeValid(ss, session_ticket)) {
ss->statelessResume = PR_TRUE; ss->statelessResume = PR_TRUE;
} }
@ -2724,7 +2724,7 @@ tls13_SendServerHelloSequence(sslSocket *ss)
} }
} }
ss->ssl3.hs.serverHelloTime = ssl_TimeUsec(); ss->ssl3.hs.serverHelloTime = ssl_Time(ss);
return SECSuccess; return SECSuccess;
} }
@ -4981,7 +4981,7 @@ tls13_HandleNewSessionTicket(sslSocket *ss, PRUint8 *b, PRUint32 length)
return SECFailure; return SECFailure;
} }
ticket.received_timestamp = ssl_TimeUsec(); ticket.received_timestamp = ssl_Time(ss);
rv = ssl3_ConsumeHandshakeNumber(ss, &ticket.ticket_lifetime_hint, 4, &b, rv = ssl3_ConsumeHandshakeNumber(ss, &ticket.ticket_lifetime_hint, 4, &b,
&length); &length);
if (rv != SECSuccess) { if (rv != SECSuccess) {

Просмотреть файл

@ -117,8 +117,8 @@ PRBool tls13_ShouldRequestClientAuth(sslSocket *ss);
PRBool tls13_IsReplay(const sslSocket *ss, const sslSessionID *sid); PRBool tls13_IsReplay(const sslSocket *ss, const sslSessionID *sid);
void tls13_AntiReplayRollover(PRTime now); void tls13_AntiReplayRollover(PRTime now);
SECStatus SSLExp_SetupAntiReplay(PRTime window, unsigned int k, SECStatus SSLExp_InitAntiReplay(PRTime now, PRTime window, unsigned int k,
unsigned int bits); unsigned int bits);
SECStatus SSLExp_HelloRetryRequestCallback(PRFileDesc *fd, SECStatus SSLExp_HelloRetryRequestCallback(PRFileDesc *fd,
SSLHelloRetryRequestCallback cb, SSLHelloRetryRequestCallback cb,

Просмотреть файл

@ -448,7 +448,7 @@ tls13_ClientSendPreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData,
goto loser; goto loser;
/* Obfuscated age. */ /* Obfuscated age. */
age = ssl_TimeUsec() - session_ticket->received_timestamp; age = ssl_Time(ss) - session_ticket->received_timestamp;
age /= PR_USEC_PER_MSEC; age /= PR_USEC_PER_MSEC;
age += session_ticket->ticket_age_add; age += session_ticket->ticket_age_add;
rv = sslBuffer_AppendNumber(buf, age, 4); rv = sslBuffer_AppendNumber(buf, age, 4);

Просмотреть файл

@ -109,7 +109,7 @@ loser:
* memory barrier between the setup and use of this function. * memory barrier between the setup and use of this function.
*/ */
SECStatus SECStatus
SSLExp_SetupAntiReplay(PRTime window, unsigned int k, unsigned int bits) SSLExp_InitAntiReplay(PRTime now, PRTime window, unsigned int k, unsigned int bits)
{ {
SECStatus rv; SECStatus rv;
@ -153,7 +153,7 @@ SSLExp_SetupAntiReplay(PRTime window, unsigned int k, unsigned int bits)
sslBloom_Fill(&ssl_anti_replay.filters[1]); sslBloom_Fill(&ssl_anti_replay.filters[1]);
ssl_anti_replay.current = 0; ssl_anti_replay.current = 0;
ssl_anti_replay.nextUpdate = ssl_TimeUsec() + window; ssl_anti_replay.nextUpdate = now + window;
ssl_anti_replay.window = window; ssl_anti_replay.window = window;
return SECSuccess; return SECSuccess;
@ -162,29 +162,15 @@ loser:
return SECFailure; return SECFailure;
} }
/* This is exposed to tests. Though it could, this doesn't take the lock on the
* basis that those tests use thread confinement. */
void
tls13_AntiReplayRollover(PRTime now)
{
ssl_anti_replay.current ^= 1;
ssl_anti_replay.nextUpdate = now + ssl_anti_replay.window;
sslBloom_Zero(ssl_anti_replay.filters + ssl_anti_replay.current);
}
static void static void
tls13_AntiReplayUpdate() tls13_AntiReplayUpdate(PRTime now)
{ {
PRTime now;
PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ssl_anti_replay.lock); PR_ASSERT_CURRENT_THREAD_IN_MONITOR(ssl_anti_replay.lock);
if (now >= ssl_anti_replay.nextUpdate) {
now = ssl_TimeUsec(); ssl_anti_replay.current ^= 1;
if (now < ssl_anti_replay.nextUpdate) { ssl_anti_replay.nextUpdate = now + ssl_anti_replay.window;
return; sslBloom_Zero(ssl_anti_replay.filters + ssl_anti_replay.current);
} }
tls13_AntiReplayRollover(now);
} }
PRBool PRBool
@ -197,7 +183,7 @@ tls13_InWindow(const sslSocket *ss, const sslSessionID *sid)
* calculate. The result should be close to zero. timeDelta is signed to * calculate. The result should be close to zero. timeDelta is signed to
* make the comparisons below easier. */ * make the comparisons below easier. */
timeDelta = ss->xtnData.ticketAge - timeDelta = ss->xtnData.ticketAge -
((ssl_TimeUsec() - sid->creationTime) / PR_USEC_PER_MSEC); ((ssl_Time(ss) - sid->creationTime) / PR_USEC_PER_MSEC);
/* Only allow the time delta to be at most half of our window. This is /* Only allow the time delta to be at most half of our window. This is
* symmetrical, though it doesn't need to be; this assumes that clock errors * symmetrical, though it doesn't need to be; this assumes that clock errors
@ -221,7 +207,7 @@ tls13_InWindow(const sslSocket *ss, const sslSessionID *sid)
* prevent the same 0-RTT attempt from being accepted during window 1 and * prevent the same 0-RTT attempt from being accepted during window 1 and
* later window 3. * later window 3.
*/ */
return PR_ABS(timeDelta) < (ssl_anti_replay.window / 2); return PR_ABS(timeDelta) < (ssl_anti_replay.window / (PR_USEC_PER_MSEC * 2));
} }
/* Checks for a duplicate in the two filters we have. Performs maintenance on /* Checks for a duplicate in the two filters we have. Performs maintenance on
@ -262,13 +248,12 @@ tls13_IsReplay(const sslSocket *ss, const sslSessionID *sid)
} }
PZ_EnterMonitor(ssl_anti_replay.lock); PZ_EnterMonitor(ssl_anti_replay.lock);
tls13_AntiReplayUpdate(); tls13_AntiReplayUpdate(ssl_Time(ss));
index = ssl_anti_replay.current; index = ssl_anti_replay.current;
replay = sslBloom_Add(&ssl_anti_replay.filters[index], buf); replay = sslBloom_Add(&ssl_anti_replay.filters[index], buf);
if (!replay) { if (!replay) {
replay = sslBloom_Check(&ssl_anti_replay.filters[index ^ 1], replay = sslBloom_Check(&ssl_anti_replay.filters[index ^ 1], buf);
buf);
} }
PZ_ExitMonitor(ssl_anti_replay.lock); PZ_ExitMonitor(ssl_anti_replay.lock);

Просмотреть файл

@ -19,12 +19,12 @@
* The format of the version string should be * The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]" * "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
*/ */
#define NSSUTIL_VERSION "3.44" #define NSSUTIL_VERSION "3.45 Beta"
#define NSSUTIL_VMAJOR 3 #define NSSUTIL_VMAJOR 3
#define NSSUTIL_VMINOR 44 #define NSSUTIL_VMINOR 45
#define NSSUTIL_VPATCH 0 #define NSSUTIL_VPATCH 0
#define NSSUTIL_VBUILD 0 #define NSSUTIL_VBUILD 0
#define NSSUTIL_BETA PR_FALSE #define NSSUTIL_BETA PR_TRUE
SEC_BEGIN_PROTOS SEC_BEGIN_PROTOS

Просмотреть файл

@ -192,6 +192,7 @@
'cmd/tstclnt/tstclnt.gyp:tstclnt', 'cmd/tstclnt/tstclnt.gyp:tstclnt',
'cmd/vfychain/vfychain.gyp:vfychain', 'cmd/vfychain/vfychain.gyp:vfychain',
'cmd/vfyserv/vfyserv.gyp:vfyserv', 'cmd/vfyserv/vfyserv.gyp:vfyserv',
'cmd/mpitests/mpitests.gyp:mpi_tests',
'gtests/certhigh_gtest/certhigh_gtest.gyp:certhigh_gtest', 'gtests/certhigh_gtest/certhigh_gtest.gyp:certhigh_gtest',
'gtests/cryptohi_gtest/cryptohi_gtest.gyp:cryptohi_gtest', 'gtests/cryptohi_gtest/cryptohi_gtest.gyp:cryptohi_gtest',
'gtests/der_gtest/der_gtest.gyp:der_gtest', 'gtests/der_gtest/der_gtest.gyp:der_gtest',
@ -223,12 +224,6 @@
'cmd/pkix-errcodes/pkix-errcodes.gyp:pkix-errcodes', 'cmd/pkix-errcodes/pkix-errcodes.gyp:pkix-errcodes',
], ],
}], }],
[ 'test_build==1', {
'dependencies': [
'cmd/mpitests/mpitests.gyp:mpi_tests',
'gtests/freebl_gtest/freebl_gtest.gyp:freebl_gtest',
],
}],
[ 'disable_fips==0', { [ 'disable_fips==0', {
'dependencies': [ 'dependencies': [
'cmd/fipstest/fipstest.gyp:fipstest', 'cmd/fipstest/fipstest.gyp:fipstest',