mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 1345368 - land NSS 236a06d9c3c4, r=me
--HG-- extra : rebase_source : b097dd39571750acd76656e275e6899c95d52269
This commit is contained in:
parent
dddf3fc25d
commit
66955a7251
@ -1 +1 @@
|
||||
fa15eb3ce158
|
||||
236a06d9c3c4
|
||||
|
@ -26,6 +26,7 @@ apt_packages+=('zlib1g-dev')
|
||||
apt_packages+=('ninja-build')
|
||||
apt_packages+=('gyp')
|
||||
apt_packages+=('mercurial')
|
||||
apt_packages+=('locales')
|
||||
|
||||
# Install packages.
|
||||
apt-get install -y --no-install-recommends ${apt_packages[@]}
|
||||
|
@ -12,6 +12,7 @@ apt_packages=()
|
||||
apt_packages+=('build-essential')
|
||||
apt_packages+=('ca-certificates')
|
||||
apt_packages+=('curl')
|
||||
apt_packages+=('locales')
|
||||
apt_packages+=('python-dev')
|
||||
apt_packages+=('python-pip')
|
||||
apt_packages+=('python-setuptools')
|
||||
|
@ -12,6 +12,7 @@ apt-get install -y --no-install-recommends apt-utils
|
||||
apt_packages=()
|
||||
apt_packages+=('ca-certificates')
|
||||
apt_packages+=('curl')
|
||||
apt_packages+=('locales')
|
||||
apt_packages+=('xz-utils')
|
||||
|
||||
# Latest Mercurial.
|
||||
|
@ -7,7 +7,7 @@ export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get -y update && apt-get -y upgrade
|
||||
|
||||
# Need those to install newer packages below.
|
||||
apt-get install -y --no-install-recommends apt-utils curl ca-certificates
|
||||
apt-get install -y --no-install-recommends apt-utils curl ca-certificates locales
|
||||
|
||||
# Latest Mercurial.
|
||||
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 41BD8711B1F0EC2B0D85B91CF59CE3A8323293EE
|
||||
|
@ -17,6 +17,7 @@ apt_packages+=('git')
|
||||
apt_packages+=('gyp')
|
||||
apt_packages+=('libssl-dev')
|
||||
apt_packages+=('libxml2-utils')
|
||||
apt_packages+=('locales')
|
||||
apt_packages+=('ninja-build')
|
||||
apt_packages+=('pkg-config')
|
||||
apt_packages+=('zlib1g-dev')
|
||||
@ -37,7 +38,6 @@ git -C clang-tmp/clang checkout HEAD scripts/update.py
|
||||
clang-tmp/clang/scripts/update.py
|
||||
rm -fr clang-tmp
|
||||
|
||||
# Generate locales.
|
||||
locale-gen en_US.UTF-8
|
||||
dpkg-reconfigure locales
|
||||
|
||||
|
@ -17,6 +17,7 @@ apt_packages+=('npm')
|
||||
apt_packages+=('git')
|
||||
apt_packages+=('golang-1.6')
|
||||
apt_packages+=('libxml2-utils')
|
||||
apt_packages+=('locales')
|
||||
apt_packages+=('ninja-build')
|
||||
apt_packages+=('pkg-config')
|
||||
apt_packages+=('zlib1g-dev')
|
||||
|
@ -34,14 +34,8 @@ queue.filter(task => {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove extra builds w/o libpkix for non-linux64-debug.
|
||||
if (task.symbol == "noLibpkix" &&
|
||||
(task.platform != "linux64" || task.collection != "debug")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make modular builds only on Linux x64.
|
||||
if (task.symbol == "modular" && task.platform != "linux64") {
|
||||
// Make modular builds only on Linux make.
|
||||
if (task.symbol == "modular" && task.collection != "make") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -58,9 +52,29 @@ queue.filter(task => {
|
||||
}
|
||||
}
|
||||
|
||||
// GYP builds with -Ddisable_libpkix=1 by default.
|
||||
if ((task.collection == "gyp" || task.collection == "asan"
|
||||
|| task.platform == "aarch64") && task.tests == "chains") {
|
||||
// Only old make builds have -Ddisable_libpkix=0 and can run chain tests.
|
||||
if (task.tests == "chains" && task.collection != "make" &&
|
||||
task.platform != "windows2012-64") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (task.group == "Test") {
|
||||
// Don't run test builds on old make platforms
|
||||
if (task.collection == "make") {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Disable mpi tests for now on 32-bit builds (bug 1362392)
|
||||
if (task.platform == "linux32") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Don't run additional hardware tests on ARM (we don't have anything there).
|
||||
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_AVX == "1")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -87,47 +101,51 @@ queue.map(task => {
|
||||
|
||||
export default async function main() {
|
||||
await scheduleLinux("Linux 32 (opt)", {
|
||||
env: {BUILD_OPT: "1"},
|
||||
platform: "linux32",
|
||||
image: LINUX_IMAGE
|
||||
});
|
||||
}, "-m32 --opt");
|
||||
|
||||
await scheduleLinux("Linux 32 (debug)", {
|
||||
platform: "linux32",
|
||||
collection: "debug",
|
||||
image: LINUX_IMAGE
|
||||
});
|
||||
}, "-m32");
|
||||
|
||||
await scheduleLinux("Linux 64 (opt)", {
|
||||
env: {USE_64: "1", BUILD_OPT: "1"},
|
||||
platform: "linux64",
|
||||
image: LINUX_IMAGE
|
||||
});
|
||||
}, "--opt");
|
||||
|
||||
await scheduleLinux("Linux 64 (debug)", {
|
||||
env: {USE_64: "1"},
|
||||
platform: "linux64",
|
||||
collection: "debug",
|
||||
image: LINUX_IMAGE
|
||||
});
|
||||
|
||||
await scheduleLinux("Linux 64 (debug, gyp)", {
|
||||
command: [
|
||||
"/bin/bash",
|
||||
"-c",
|
||||
"bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh"
|
||||
],
|
||||
await scheduleLinux("Linux 64 (debug, make)", {
|
||||
env: {USE_64: "1"},
|
||||
platform: "linux64",
|
||||
collection: "gyp",
|
||||
image: LINUX_IMAGE
|
||||
image: LINUX_IMAGE,
|
||||
collection: "make",
|
||||
command: [
|
||||
"/bin/bash",
|
||||
"-c",
|
||||
"bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh"
|
||||
],
|
||||
});
|
||||
|
||||
await scheduleLinux("Linux 64 (GYP, ASan, debug)", {
|
||||
await scheduleLinux("Linux 32 (debug, make)", {
|
||||
platform: "linux32",
|
||||
image: LINUX_IMAGE,
|
||||
collection: "make",
|
||||
command: [
|
||||
"/bin/bash",
|
||||
"-c",
|
||||
"bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh -g -v --ubsan --asan"
|
||||
"/bin/bash",
|
||||
"-c",
|
||||
"bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh"
|
||||
],
|
||||
});
|
||||
|
||||
await scheduleLinux("Linux 64 (ASan, debug)", {
|
||||
env: {
|
||||
UBSAN_OPTIONS: "print_stacktrace=1",
|
||||
NSS_DISABLE_ARENA_FREE_LIST: "1",
|
||||
@ -139,7 +157,7 @@ export default async function main() {
|
||||
collection: "asan",
|
||||
image: LINUX_IMAGE,
|
||||
features: ["allowPtrace"],
|
||||
});
|
||||
}, "--ubsan --asan");
|
||||
|
||||
await scheduleWindows("Windows 2012 64 (opt)", {
|
||||
env: {BUILD_OPT: "1"}
|
||||
@ -151,8 +169,6 @@ export default async function main() {
|
||||
|
||||
await scheduleFuzzing();
|
||||
|
||||
await scheduleTestBuilds();
|
||||
|
||||
await scheduleTools();
|
||||
|
||||
let aarch64_base = {
|
||||
@ -188,13 +204,13 @@ export default async function main() {
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
async function scheduleLinux(name, base) {
|
||||
async function scheduleLinux(name, base, args = "") {
|
||||
// Build base definition.
|
||||
let build_base = merge({
|
||||
command: [
|
||||
"/bin/bash",
|
||||
"-c",
|
||||
"bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh"
|
||||
"bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh " + args
|
||||
],
|
||||
artifacts: {
|
||||
public: {
|
||||
@ -260,18 +276,19 @@ async function scheduleLinux(name, base) {
|
||||
symbol: "gcc-6.1"
|
||||
}));
|
||||
|
||||
queue.scheduleTask(merge(extra_base, {
|
||||
name: `${name} w/ NSS_DISABLE_LIBPKIX=1`,
|
||||
env: {NSS_DISABLE_LIBPKIX: "1"},
|
||||
symbol: "noLibpkix"
|
||||
}));
|
||||
|
||||
queue.scheduleTask(merge(extra_base, {
|
||||
name: `${name} w/ modular builds`,
|
||||
env: {NSS_BUILD_MODULAR: "1"},
|
||||
command: [
|
||||
"/bin/bash",
|
||||
"-c",
|
||||
"bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh",
|
||||
],
|
||||
symbol: "modular"
|
||||
}));
|
||||
|
||||
await scheduleTestBuilds(merge(base, {group: "Test"}), args);
|
||||
|
||||
return queue.submit();
|
||||
}
|
||||
|
||||
@ -400,21 +417,14 @@ async function scheduleFuzzing() {
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
async function scheduleTestBuilds() {
|
||||
let base = {
|
||||
platform: "linux64",
|
||||
collection: "gyp",
|
||||
group: "Test",
|
||||
image: LINUX_IMAGE
|
||||
};
|
||||
|
||||
async function scheduleTestBuilds(base, args = "") {
|
||||
// Build base definition.
|
||||
let build = merge({
|
||||
command: [
|
||||
"/bin/bash",
|
||||
"-c",
|
||||
"bin/checkout.sh && " +
|
||||
"nss/automation/taskcluster/scripts/build_gyp.sh -g -v --test --ct-verif"
|
||||
"nss/automation/taskcluster/scripts/build_gyp.sh -g -v --test --ct-verif " + args
|
||||
],
|
||||
artifacts: {
|
||||
public: {
|
||||
@ -425,7 +435,7 @@ async function scheduleTestBuilds() {
|
||||
},
|
||||
kind: "build",
|
||||
symbol: "B",
|
||||
name: "Linux 64 (debug, gyp, test)"
|
||||
name: "Linux 64 (debug, test)"
|
||||
}, base);
|
||||
|
||||
// The task that builds NSPR+NSS.
|
||||
@ -529,7 +539,19 @@ function scheduleTests(task_build, task_cert, test_base) {
|
||||
name: "Chains tests", symbol: "Chains", tests: "chains"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
name: "Cipher tests", symbol: "Cipher", tests: "cipher"
|
||||
name: "Cipher tests", symbol: "Default", tests: "cipher", group: "Cipher"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
name: "Cipher tests", symbol: "NoAESNI", tests: "cipher",
|
||||
env: {NSS_DISABLE_HW_AES: "1"}, group: "Cipher"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
name: "Cipher tests", symbol: "NoPCLMUL", tests: "cipher",
|
||||
env: {NSS_DISABLE_PCLMUL: "1"}, group: "Cipher"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
name: "Cipher tests", symbol: "NoAVX", tests: "cipher",
|
||||
env: {NSS_DISABLE_AVX: "1"}, group: "Cipher"
|
||||
}));
|
||||
queue.scheduleTask(merge(no_cert_base, {
|
||||
name: "EC tests", symbol: "EC", tests: "ec"
|
||||
|
@ -23,7 +23,7 @@ function parseOptions(opts) {
|
||||
|
||||
// Parse platforms.
|
||||
let allPlatforms = ["linux", "linux64", "linux64-asan", "win64",
|
||||
"linux64-gyp", "linux64-fuzz", "aarch64"];
|
||||
"linux64-make", "linux-make", "linux64-fuzz", "aarch64"];
|
||||
let platforms = intersect(opts.platform.split(/\s*,\s*/), allPlatforms);
|
||||
|
||||
// If the given value is nonsense or "none" default to all platforms.
|
||||
@ -82,11 +82,10 @@ function filter(opts) {
|
||||
// Filter unit tests.
|
||||
if (task.tests) {
|
||||
let found = opts.unittests.some(test => {
|
||||
// TODO: think of something more intelligent here.
|
||||
if (task.symbol.toLowerCase().startsWith("mpi") && test == "mpi") {
|
||||
if (task.group && task.group.toLowerCase() == "ssl" && test == "ssl") {
|
||||
return true;
|
||||
}
|
||||
return (task.group || task.symbol).toLowerCase().startsWith(test);
|
||||
return task.symbol.toLowerCase().startsWith(test);
|
||||
});
|
||||
|
||||
if (!found) {
|
||||
@ -107,7 +106,8 @@ function filter(opts) {
|
||||
"linux": "linux32",
|
||||
"linux64-asan": "linux64",
|
||||
"linux64-fuzz": "linux64",
|
||||
"linux64-gyp": "linux64",
|
||||
"linux64-make": "linux64",
|
||||
"linux-make": "linux32",
|
||||
"win64": "windows2012-64"
|
||||
};
|
||||
|
||||
@ -117,8 +117,8 @@ function filter(opts) {
|
||||
// Additional checks.
|
||||
if (platform == "linux64-asan") {
|
||||
keep &= coll("asan");
|
||||
} else if (platform == "linux64-gyp") {
|
||||
keep &= coll("gyp");
|
||||
} else if (platform == "linux64-make" || platform == "linux-make") {
|
||||
keep &= coll("make");
|
||||
} else if (platform == "linux64-fuzz") {
|
||||
keep &= coll("fuzz");
|
||||
} else {
|
||||
@ -133,7 +133,7 @@ function filter(opts) {
|
||||
}
|
||||
|
||||
// Finally, filter by build type.
|
||||
let isDebug = coll("debug") || coll("asan") || coll("gyp") ||
|
||||
let isDebug = coll("debug") || coll("asan") || coll("make") ||
|
||||
coll("fuzz");
|
||||
return (isDebug && opts.builds.includes("d")) ||
|
||||
(!isDebug && opts.builds.includes("o"));
|
||||
|
@ -49,6 +49,7 @@ fuzz=0
|
||||
fuzz_tls=0
|
||||
fuzz_oss=0
|
||||
no_local_nspr=0
|
||||
armhf=0
|
||||
|
||||
gyp_params=(--depth="$cwd" --generator-output=".")
|
||||
nspr_params=()
|
||||
@ -58,6 +59,8 @@ ninja_params=()
|
||||
arch=$(python "$cwd"/coreconf/detect_host_arch.py)
|
||||
if [ "$arch" = "x64" -o "$arch" = "aarch64" ]; then
|
||||
build_64=1
|
||||
elif [ "$arch" = "arm" ]; then
|
||||
armhf=1
|
||||
fi
|
||||
|
||||
# parse command line arguments
|
||||
@ -101,7 +104,7 @@ else
|
||||
fi
|
||||
if [ "$build_64" = 1 ]; then
|
||||
nspr_params+=(--enable-64bit)
|
||||
else
|
||||
elif [ ! "$armhf" = 1 ]; then
|
||||
gyp_params+=(-Dtarget_arch=ia32)
|
||||
fi
|
||||
if [ "$fuzz" = 1 ]; then
|
||||
|
@ -148,7 +148,7 @@ DSO_LDOPTS = -shared $(ARCHFLAG) -Wl,--gc-sections
|
||||
# against the libsanitizer runtime built into the main executable.
|
||||
ZDEFS_FLAG = -Wl,-z,defs
|
||||
DSO_LDOPTS += $(if $(findstring 2.11.90.0.8,$(shell ld -v)),,$(ZDEFS_FLAG))
|
||||
LDFLAGS += $(ARCHFLAG)
|
||||
LDFLAGS += $(ARCHFLAG) -z noexecstack
|
||||
|
||||
# On Maemo, we need to use the -rpath-link flag for even the standard system
|
||||
# library directories.
|
||||
|
@ -141,6 +141,52 @@
|
||||
'debug_optimization_level%': '1',
|
||||
},
|
||||
}],
|
||||
[ 'target_arch=="ia32" or target_arch=="x64"', {
|
||||
'defines': [
|
||||
'NSS_X86_OR_X64',
|
||||
],
|
||||
# For Windows.
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'PreprocessorDefinitions': [
|
||||
'NSS_X86_OR_X64',
|
||||
],
|
||||
},
|
||||
},
|
||||
}],
|
||||
[ 'target_arch=="ia32"', {
|
||||
'defines': [
|
||||
'NSS_X86',
|
||||
],
|
||||
# For Windows.
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'PreprocessorDefinitions': [
|
||||
'NSS_X86',
|
||||
],
|
||||
},
|
||||
},
|
||||
}],
|
||||
[ 'target_arch=="arm64" or target_arch=="aarch64"', {
|
||||
'defines': [
|
||||
'NSS_USE_64',
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="x64"', {
|
||||
'defines': [
|
||||
'NSS_X64',
|
||||
'NSS_USE_64',
|
||||
],
|
||||
# For Windows.
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'PreprocessorDefinitions': [
|
||||
'NSS_X64',
|
||||
'NSS_USE_64',
|
||||
],
|
||||
},
|
||||
},
|
||||
}],
|
||||
],
|
||||
'target_conditions': [
|
||||
# If we want to properly export a static library, and copy it to lib,
|
||||
@ -315,6 +361,9 @@
|
||||
'cflags_cc': [
|
||||
'-std=c++0x',
|
||||
],
|
||||
'ldflags': [
|
||||
'-z', 'noexecstack',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'target_arch=="ia32"', {
|
||||
'cflags': ['-m32'],
|
||||
|
@ -10,4 +10,3 @@
|
||||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
@ -46,7 +46,7 @@ class DataBuffer {
|
||||
len_ = len;
|
||||
}
|
||||
|
||||
void Truncate(size_t len) { len_ = std::min(len_, len); }
|
||||
void Truncate(size_t len) { len_ = (std::min)(len_, len); }
|
||||
|
||||
void Assign(const DataBuffer& other) { Assign(other.data(), other.len()); }
|
||||
|
||||
@ -126,14 +126,14 @@ class DataBuffer {
|
||||
size_t old_len = len_;
|
||||
|
||||
// The amount of stuff remaining from the tail of the old.
|
||||
size_t tail_len = old_len - std::min(old_len, index + remove);
|
||||
size_t tail_len = old_len - (std::min)(old_len, index + remove);
|
||||
// The new length: the head of the old, the new, and the tail of the old.
|
||||
len_ = index + ins_len + tail_len;
|
||||
data_ = new uint8_t[len_ ? len_ : 1];
|
||||
|
||||
// The head of the old.
|
||||
if (old_value) {
|
||||
Write(0, old_value, std::min(old_len, index));
|
||||
Write(0, old_value, (std::min)(old_len, index));
|
||||
}
|
||||
// Maybe a gap.
|
||||
if (old_value && index > old_len) {
|
||||
|
@ -17,6 +17,8 @@
|
||||
#endif
|
||||
#include "databuffer.h"
|
||||
|
||||
#include "sslt.h"
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
const uint8_t kTlsChangeCipherSpecType = 20;
|
||||
@ -133,6 +135,10 @@ class TlsParser {
|
||||
size_t offset_;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, SSLProtocolVariant v) {
|
||||
return os << ((v == ssl_variant_stream) ? "TLS" : "DTLS");
|
||||
}
|
||||
|
||||
} // namespace nss_test
|
||||
|
||||
#endif
|
||||
|
@ -1,46 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
LIBFUZZER_REVISION=8837e6cbbc842ab7524b06a2f7360c36add316b3
|
||||
|
||||
d=$(dirname $0)
|
||||
$d/git-copy.sh https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer b96a41ac6bbc3824fc7c7977662bebacac8f0983 $d/../libFuzzer
|
||||
|
||||
# [https://llvm.org/bugs/show_bug.cgi?id=31318]
|
||||
# This prevents a known buffer overrun that won't be fixed as the affected code
|
||||
# will go away in the near future. Until that is we have to patch it as we seem
|
||||
# to constantly run into it.
|
||||
cat <<EOF | patch -p0 -d $d/..
|
||||
diff --git libFuzzer/FuzzerLoop.cpp libFuzzer/FuzzerLoop.cpp
|
||||
--- libFuzzer/FuzzerLoop.cpp
|
||||
+++ libFuzzer/FuzzerLoop.cpp
|
||||
@@ -476,6 +476,9 @@
|
||||
uint8_t dummy;
|
||||
ExecuteCallback(&dummy, 0);
|
||||
|
||||
+ // Number of counters might have changed.
|
||||
+ PrepareCounters(&MaxCoverage);
|
||||
+
|
||||
for (const auto &U : *InitialCorpus) {
|
||||
if (size_t NumFeatures = RunOne(U)) {
|
||||
CheckExitOnSrcPosOrItem();
|
||||
EOF
|
||||
|
||||
# Latest Libfuzzer uses __sanitizer_dump_coverage(), a symbol to be introduced
|
||||
# with LLVM 4.0. To keep our code working with LLVM 3.x to simplify development
|
||||
# of fuzzers we'll just provide it ourselves.
|
||||
cat <<EOF | patch -p0 -d $d/..
|
||||
diff --git libFuzzer/FuzzerTracePC.cpp libFuzzer/FuzzerTracePC.cpp
|
||||
--- libFuzzer/FuzzerTracePC.cpp
|
||||
+++ libFuzzer/FuzzerTracePC.cpp
|
||||
@@ -33,6 +33,12 @@
|
||||
ATTRIBUTE_INTERFACE
|
||||
uintptr_t __sancov_trace_pc_pcs[fuzzer::TracePC::kNumPCs];
|
||||
|
||||
+#if defined(__clang_major__) && (__clang_major__ == 3)
|
||||
+void __sanitizer_dump_coverage(const uintptr_t *pcs, uintptr_t len) {
|
||||
+ // SanCov in LLVM 4.x will provide this symbol. Make 3.x work.
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
namespace fuzzer {
|
||||
|
||||
TracePC TPC;
|
||||
EOF
|
||||
$d/git-copy.sh https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer $LIBFUZZER_REVISION $d/../libFuzzer
|
||||
|
@ -265,6 +265,12 @@ class TestAgent {
|
||||
rv = SSL_VersionRangeSet(ssl_fd_, &vrange);
|
||||
if (rv != SECSuccess) return false;
|
||||
|
||||
SSLVersionRange verify_vrange;
|
||||
rv = SSL_VersionRangeGet(ssl_fd_, &verify_vrange);
|
||||
if (rv != SECSuccess) return false;
|
||||
if (vrange.min != verify_vrange.min || vrange.max != verify_vrange.max)
|
||||
return false;
|
||||
|
||||
rv = SSL_OptionSet(ssl_fd_, SSL_NO_CACHE, false);
|
||||
if (rv != SECSuccess) return false;
|
||||
|
||||
|
@ -39,6 +39,7 @@ CPPSRCS = \
|
||||
ssl_staticrsa_unittest.cc \
|
||||
ssl_v2_client_hello_unittest.cc \
|
||||
ssl_version_unittest.cc \
|
||||
ssl_versionpolicy_unittest.cc \
|
||||
test_io.cc \
|
||||
tls_agent.cc \
|
||||
tls_connect.cc \
|
||||
|
@ -70,11 +70,7 @@ TEST_P(TlsConnectGenericPre13, DamageServerSignature) {
|
||||
server_->SetTlsRecordFilter(filter);
|
||||
ExpectAlert(client_, kTlsAlertDecryptError);
|
||||
ConnectExpectFail();
|
||||
// TODO(ttaubert@mozilla.com): This is the wrong error code in
|
||||
// 1.1 and below. Bug 1354488.
|
||||
client_->CheckErrorCode(version_ >= SSL_LIBRARY_VERSION_TLS_1_2
|
||||
? SEC_ERROR_BAD_SIGNATURE
|
||||
: SEC_ERROR_PKCS11_DEVICE_ERROR);
|
||||
client_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
|
||||
server_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
|
||||
}
|
||||
|
||||
@ -117,11 +113,7 @@ TEST_P(TlsConnectGeneric, DamageClientSignature) {
|
||||
? TlsAgent::STATE_CONNECTED
|
||||
: TlsAgent::STATE_CONNECTING,
|
||||
client_->state());
|
||||
// TODO(ttaubert@mozilla.com): This is the wrong error code in
|
||||
// 1.1 and below. Bug 1354488.
|
||||
server_->CheckErrorCode(version_ >= SSL_LIBRARY_VERSION_TLS_1_2
|
||||
? SEC_ERROR_BAD_SIGNATURE
|
||||
: SEC_ERROR_PKCS11_DEVICE_ERROR);
|
||||
server_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
|
||||
}
|
||||
|
||||
} // namespace nspr_test
|
||||
|
@ -36,6 +36,7 @@
|
||||
'ssl_staticrsa_unittest.cc',
|
||||
'ssl_v2_client_hello_unittest.cc',
|
||||
'ssl_version_unittest.cc',
|
||||
'ssl_versionpolicy_unittest.cc',
|
||||
'test_io.cc',
|
||||
'tls_agent.cc',
|
||||
'tls_connect.cc',
|
||||
|
404
security/nss/gtests/ssl_gtest/ssl_versionpolicy_unittest.cc
Normal file
404
security/nss/gtests/ssl_gtest/ssl_versionpolicy_unittest.cc
Normal file
@ -0,0 +1,404 @@
|
||||
/* -*- 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 "nss.h"
|
||||
#include "secerr.h"
|
||||
#include "ssl.h"
|
||||
#include "ssl3prot.h"
|
||||
#include "sslerr.h"
|
||||
#include "sslproto.h"
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
std::string GetSSLVersionString(uint16_t v) {
|
||||
switch (v) {
|
||||
case SSL_LIBRARY_VERSION_3_0:
|
||||
return "ssl3";
|
||||
case SSL_LIBRARY_VERSION_TLS_1_0:
|
||||
return "tls1.0";
|
||||
case SSL_LIBRARY_VERSION_TLS_1_1:
|
||||
return "tls1.1";
|
||||
case SSL_LIBRARY_VERSION_TLS_1_2:
|
||||
return "tls1.2";
|
||||
case SSL_LIBRARY_VERSION_TLS_1_3:
|
||||
return "tls1.3";
|
||||
case SSL_LIBRARY_VERSION_NONE:
|
||||
return "NONE";
|
||||
}
|
||||
if (v < SSL_LIBRARY_VERSION_3_0) {
|
||||
return "undefined-too-low";
|
||||
}
|
||||
return "undefined-too-high";
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& stream,
|
||||
const SSLVersionRange& vr) {
|
||||
return stream << GetSSLVersionString(vr.min) << ","
|
||||
<< GetSSLVersionString(vr.max);
|
||||
}
|
||||
|
||||
class VersionRangeWithLabel {
|
||||
public:
|
||||
VersionRangeWithLabel(const std::string& label, const SSLVersionRange& vr)
|
||||
: label_(label), vr_(vr) {}
|
||||
VersionRangeWithLabel(const std::string& label, uint16_t min, uint16_t max)
|
||||
: label_(label) {
|
||||
vr_.min = min;
|
||||
vr_.max = max;
|
||||
}
|
||||
VersionRangeWithLabel(const std::string& label) : label_(label) {
|
||||
vr_.min = vr_.max = SSL_LIBRARY_VERSION_NONE;
|
||||
}
|
||||
|
||||
void WriteStream(std::ostream& stream) const {
|
||||
stream << " " << label_ << ": " << vr_;
|
||||
}
|
||||
|
||||
uint16_t min() const { return vr_.min; }
|
||||
uint16_t max() const { return vr_.max; }
|
||||
SSLVersionRange range() const { return vr_; }
|
||||
|
||||
private:
|
||||
std::string label_;
|
||||
SSLVersionRange vr_;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& stream,
|
||||
const VersionRangeWithLabel& vrwl) {
|
||||
vrwl.WriteStream(stream);
|
||||
return stream;
|
||||
}
|
||||
|
||||
typedef std::tuple<SSLProtocolVariant, // variant
|
||||
uint16_t, // policy min
|
||||
uint16_t, // policy max
|
||||
uint16_t, // input min
|
||||
uint16_t> // input max
|
||||
PolicyVersionRangeInput;
|
||||
|
||||
class TestPolicyVersionRange
|
||||
: public TlsConnectTestBase,
|
||||
public ::testing::WithParamInterface<PolicyVersionRangeInput> {
|
||||
public:
|
||||
TestPolicyVersionRange()
|
||||
: TlsConnectTestBase(((static_cast<SSLProtocolVariant>(
|
||||
std::get<0>(GetParam())) == ssl_variant_stream)
|
||||
? STREAM
|
||||
: DGRAM),
|
||||
0),
|
||||
variant_(static_cast<SSLProtocolVariant>(std::get<0>(GetParam()))),
|
||||
policy_("policy", std::get<1>(GetParam()), std::get<2>(GetParam())),
|
||||
input_("input", std::get<3>(GetParam()), std::get<4>(GetParam())),
|
||||
library_("supported-by-library",
|
||||
((variant_ == ssl_variant_stream)
|
||||
? SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM
|
||||
: SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM),
|
||||
SSL_LIBRARY_VERSION_MAX_SUPPORTED) {
|
||||
TlsConnectTestBase::SkipVersionChecks();
|
||||
}
|
||||
|
||||
void SetPolicy(const SSLVersionRange& policy) {
|
||||
NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, NSS_USE_POLICY_IN_SSL, 0);
|
||||
|
||||
SECStatus rv;
|
||||
rv = NSS_OptionSet(NSS_TLS_VERSION_MIN_POLICY, policy.min);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = NSS_OptionSet(NSS_TLS_VERSION_MAX_POLICY, policy.max);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = NSS_OptionSet(NSS_DTLS_VERSION_MIN_POLICY, policy.min);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = NSS_OptionSet(NSS_DTLS_VERSION_MAX_POLICY, policy.max);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
}
|
||||
|
||||
void CreateDummySocket(std::shared_ptr<DummyPrSocket>* dummy_socket,
|
||||
ScopedPRFileDesc* ssl_fd) {
|
||||
(*dummy_socket)
|
||||
.reset(new DummyPrSocket(
|
||||
"dummy", (variant_ == ssl_variant_stream) ? STREAM : DGRAM));
|
||||
*ssl_fd = (*dummy_socket)->CreateFD();
|
||||
if (variant_ == ssl_variant_stream) {
|
||||
SSL_ImportFD(nullptr, ssl_fd->get());
|
||||
} else {
|
||||
DTLS_ImportFD(nullptr, ssl_fd->get());
|
||||
}
|
||||
}
|
||||
|
||||
bool GetOverlap(const SSLVersionRange& r1, const SSLVersionRange& r2,
|
||||
SSLVersionRange* overlap) {
|
||||
if (r1.min == SSL_LIBRARY_VERSION_NONE ||
|
||||
r1.max == SSL_LIBRARY_VERSION_NONE ||
|
||||
r2.min == SSL_LIBRARY_VERSION_NONE ||
|
||||
r2.max == SSL_LIBRARY_VERSION_NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SSLVersionRange temp;
|
||||
temp.min = PR_MAX(r1.min, r2.min);
|
||||
temp.max = PR_MIN(r1.max, r2.max);
|
||||
|
||||
if (temp.min > temp.max) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*overlap = temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsValidInputForVersionRangeSet(SSLVersionRange* expectedEffectiveRange) {
|
||||
if (input_.min() <= SSL_LIBRARY_VERSION_3_0 &&
|
||||
input_.max() >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
// This is always invalid input, independent of policy
|
||||
return false;
|
||||
}
|
||||
|
||||
if (input_.min() < library_.min() || input_.max() > library_.max() ||
|
||||
input_.min() > input_.max()) {
|
||||
// Asking for unsupported ranges is invalid input for VersionRangeSet
|
||||
// APIs, regardless of overlap.
|
||||
return false;
|
||||
}
|
||||
|
||||
SSLVersionRange overlap_with_library;
|
||||
if (!GetOverlap(input_.range(), library_.range(), &overlap_with_library)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SSLVersionRange overlap_with_library_and_policy;
|
||||
if (!GetOverlap(overlap_with_library, policy_.range(),
|
||||
&overlap_with_library_and_policy)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RemoveConflictingVersions(variant_, &overlap_with_library_and_policy);
|
||||
*expectedEffectiveRange = overlap_with_library_and_policy;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RemoveConflictingVersions(SSLProtocolVariant variant,
|
||||
SSLVersionRange* r) {
|
||||
ASSERT_TRUE(r != nullptr);
|
||||
if (r->max >= SSL_LIBRARY_VERSION_TLS_1_3 &&
|
||||
r->min < SSL_LIBRARY_VERSION_TLS_1_0) {
|
||||
r->min = SSL_LIBRARY_VERSION_TLS_1_0;
|
||||
}
|
||||
}
|
||||
|
||||
void SetUp() {
|
||||
SetPolicy(policy_.range());
|
||||
TlsConnectTestBase::SetUp();
|
||||
}
|
||||
|
||||
void TearDown() {
|
||||
TlsConnectTestBase::TearDown();
|
||||
saved_version_policy_.RestoreOriginalPolicy();
|
||||
}
|
||||
|
||||
protected:
|
||||
class VersionPolicy {
|
||||
public:
|
||||
VersionPolicy() { SaveOriginalPolicy(); }
|
||||
|
||||
void RestoreOriginalPolicy() {
|
||||
SECStatus rv;
|
||||
rv = NSS_OptionSet(NSS_TLS_VERSION_MIN_POLICY, saved_min_tls_);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = NSS_OptionSet(NSS_TLS_VERSION_MAX_POLICY, saved_max_tls_);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = NSS_OptionSet(NSS_DTLS_VERSION_MIN_POLICY, saved_min_dtls_);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = NSS_OptionSet(NSS_DTLS_VERSION_MAX_POLICY, saved_max_dtls_);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
// If it wasn't set initially, clear the bit that we set.
|
||||
if (!(saved_algorithm_policy_ & NSS_USE_POLICY_IN_SSL)) {
|
||||
rv = NSS_SetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, 0,
|
||||
NSS_USE_POLICY_IN_SSL);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void SaveOriginalPolicy() {
|
||||
SECStatus rv;
|
||||
rv = NSS_OptionGet(NSS_TLS_VERSION_MIN_POLICY, &saved_min_tls_);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = NSS_OptionGet(NSS_TLS_VERSION_MAX_POLICY, &saved_max_tls_);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = NSS_OptionGet(NSS_DTLS_VERSION_MIN_POLICY, &saved_min_dtls_);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = NSS_OptionGet(NSS_DTLS_VERSION_MAX_POLICY, &saved_max_dtls_);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = NSS_GetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY,
|
||||
&saved_algorithm_policy_);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
}
|
||||
|
||||
int32_t saved_min_tls_;
|
||||
int32_t saved_max_tls_;
|
||||
int32_t saved_min_dtls_;
|
||||
int32_t saved_max_dtls_;
|
||||
uint32_t saved_algorithm_policy_;
|
||||
};
|
||||
|
||||
VersionPolicy saved_version_policy_;
|
||||
|
||||
SSLProtocolVariant variant_;
|
||||
const VersionRangeWithLabel policy_;
|
||||
const VersionRangeWithLabel input_;
|
||||
const VersionRangeWithLabel library_;
|
||||
};
|
||||
|
||||
static const uint16_t kExpandedVersionsArr[] = {
|
||||
/* clang-format off */
|
||||
SSL_LIBRARY_VERSION_3_0 - 1,
|
||||
SSL_LIBRARY_VERSION_3_0,
|
||||
SSL_LIBRARY_VERSION_TLS_1_0,
|
||||
SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
#ifndef NSS_DISABLE_TLS_1_3
|
||||
SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
#endif
|
||||
SSL_LIBRARY_VERSION_MAX_SUPPORTED + 1
|
||||
/* clang-format on */
|
||||
};
|
||||
static ::testing::internal::ParamGenerator<uint16_t> kExpandedVersions =
|
||||
::testing::ValuesIn(kExpandedVersionsArr);
|
||||
|
||||
static const SSLProtocolVariant kVariantsArr[] = {ssl_variant_stream,
|
||||
ssl_variant_datagram};
|
||||
static ::testing::internal::ParamGenerator<SSLProtocolVariant> kVariants =
|
||||
::testing::ValuesIn(kVariantsArr);
|
||||
|
||||
TEST_P(TestPolicyVersionRange, TestAllTLSVersionsAndPolicyCombinations) {
|
||||
ASSERT_TRUE(variant_ == ssl_variant_stream ||
|
||||
variant_ == ssl_variant_datagram)
|
||||
<< "testing unsupported ssl variant";
|
||||
|
||||
std::cerr << "testing: " << variant_ << policy_ << input_ << library_
|
||||
<< std::endl;
|
||||
|
||||
SSLVersionRange supported_range;
|
||||
SECStatus rv = SSL_VersionRangeGetSupported(variant_, &supported_range);
|
||||
VersionRangeWithLabel supported("SSL_VersionRangeGetSupported",
|
||||
supported_range);
|
||||
|
||||
std::cerr << supported << std::endl;
|
||||
|
||||
std::shared_ptr<DummyPrSocket> dummy_socket;
|
||||
ScopedPRFileDesc ssl_fd;
|
||||
CreateDummySocket(&dummy_socket, &ssl_fd);
|
||||
|
||||
SECStatus rv_socket;
|
||||
SSLVersionRange overlap_policy_and_lib;
|
||||
if (!GetOverlap(policy_.range(), library_.range(), &overlap_policy_and_lib)) {
|
||||
EXPECT_EQ(SECFailure, rv)
|
||||
<< "expected SSL_VersionRangeGetSupported to fail with invalid policy";
|
||||
|
||||
SSLVersionRange enabled_range;
|
||||
rv = SSL_VersionRangeGetDefault(variant_, &enabled_range);
|
||||
EXPECT_EQ(SECFailure, rv)
|
||||
<< "expected SSL_VersionRangeGetDefault to fail with invalid policy";
|
||||
|
||||
SSLVersionRange enabled_range_on_socket;
|
||||
rv_socket = SSL_VersionRangeGet(ssl_fd.get(), &enabled_range_on_socket);
|
||||
EXPECT_EQ(SECFailure, rv_socket)
|
||||
<< "expected SSL_VersionRangeGet to fail with invalid policy";
|
||||
|
||||
ConnectExpectFail();
|
||||
return;
|
||||
}
|
||||
|
||||
EXPECT_EQ(SECSuccess, rv)
|
||||
<< "expected SSL_VersionRangeGetSupported to succeed with valid policy";
|
||||
|
||||
EXPECT_TRUE(supported_range.min != SSL_LIBRARY_VERSION_NONE &&
|
||||
supported_range.max != SSL_LIBRARY_VERSION_NONE)
|
||||
<< "expected SSL_VersionRangeGetSupported to return real values with "
|
||||
"valid policy";
|
||||
|
||||
RemoveConflictingVersions(variant_, &overlap_policy_and_lib);
|
||||
VersionRangeWithLabel overlap_info("overlap", overlap_policy_and_lib);
|
||||
|
||||
EXPECT_TRUE(supported_range == overlap_policy_and_lib)
|
||||
<< "expected range from GetSupported to be identical with calculated "
|
||||
"overlap "
|
||||
<< overlap_info;
|
||||
|
||||
// We don't know which versions are "enabled by default" by the library,
|
||||
// therefore we don't know if there's overlap between the default
|
||||
// and the policy, and therefore, we don't if TLS connections should
|
||||
// be successful or fail in this combination.
|
||||
// Therefore we don't test if we can connect, without having configured a
|
||||
// version range explicitly.
|
||||
|
||||
// Now start testing with supplied input.
|
||||
|
||||
SSLVersionRange expected_effective_range;
|
||||
bool is_valid_input =
|
||||
IsValidInputForVersionRangeSet(&expected_effective_range);
|
||||
|
||||
SSLVersionRange temp_input = input_.range();
|
||||
rv = SSL_VersionRangeSetDefault(variant_, &temp_input);
|
||||
rv_socket = SSL_VersionRangeSet(ssl_fd.get(), &temp_input);
|
||||
|
||||
if (!is_valid_input) {
|
||||
EXPECT_EQ(SECFailure, rv)
|
||||
<< "expected failure return from SSL_VersionRangeSetDefault";
|
||||
|
||||
EXPECT_EQ(SECFailure, rv_socket)
|
||||
<< "expected failure return from SSL_VersionRangeSet";
|
||||
return;
|
||||
}
|
||||
|
||||
EXPECT_EQ(SECSuccess, rv)
|
||||
<< "expected successful return from SSL_VersionRangeSetDefault";
|
||||
|
||||
EXPECT_EQ(SECSuccess, rv_socket)
|
||||
<< "expected successful return from SSL_VersionRangeSet";
|
||||
|
||||
SSLVersionRange effective;
|
||||
SSLVersionRange effective_socket;
|
||||
|
||||
rv = SSL_VersionRangeGetDefault(variant_, &effective);
|
||||
EXPECT_EQ(SECSuccess, rv)
|
||||
<< "expected successful return from SSL_VersionRangeGetDefault";
|
||||
|
||||
rv_socket = SSL_VersionRangeGet(ssl_fd.get(), &effective_socket);
|
||||
EXPECT_EQ(SECSuccess, rv_socket)
|
||||
<< "expected successful return from SSL_VersionRangeGet";
|
||||
|
||||
VersionRangeWithLabel expected_info("expectation", expected_effective_range);
|
||||
VersionRangeWithLabel effective_info("effectively-enabled", effective);
|
||||
|
||||
EXPECT_TRUE(expected_effective_range == effective)
|
||||
<< "range returned by SSL_VersionRangeGetDefault doesn't match "
|
||||
"expectation: "
|
||||
<< expected_info << effective_info;
|
||||
|
||||
EXPECT_TRUE(expected_effective_range == effective_socket)
|
||||
<< "range returned by SSL_VersionRangeGet doesn't match "
|
||||
"expectation: "
|
||||
<< expected_info << effective_info;
|
||||
|
||||
// Because we found overlap between policy and supported versions,
|
||||
// and because we have used SetDefault to enable at least one version,
|
||||
// it should be possible to execute an SSL/TLS connection.
|
||||
Connect();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(TLSVersionRanges, TestPolicyVersionRange,
|
||||
::testing::Combine(kVariants, kExpandedVersions,
|
||||
kExpandedVersions, kExpandedVersions,
|
||||
kExpandedVersions));
|
||||
} // namespace nss_test
|
@ -72,7 +72,8 @@ TlsAgent::TlsAgent(const std::string& name, Role role, Mode mode)
|
||||
handshake_callback_(),
|
||||
auth_certificate_callback_(),
|
||||
sni_callback_(),
|
||||
expect_short_headers_(false) {
|
||||
expect_short_headers_(false),
|
||||
skip_version_checks_(false) {
|
||||
memset(&info_, 0, sizeof(info_));
|
||||
memset(&csinfo_, 0, sizeof(csinfo_));
|
||||
SECStatus rv = SSL_VersionRangeGetDefault(
|
||||
@ -165,9 +166,12 @@ bool TlsAgent::EnsureTlsSetup(PRFileDesc* modelSocket) {
|
||||
}
|
||||
dummy_fd.release(); // Now subsumed by ssl_fd_.
|
||||
|
||||
SECStatus rv = SSL_VersionRangeSet(ssl_fd(), &vrange_);
|
||||
EXPECT_EQ(SECSuccess, rv);
|
||||
if (rv != SECSuccess) return false;
|
||||
SECStatus rv;
|
||||
if (!skip_version_checks_) {
|
||||
rv = SSL_VersionRangeSet(ssl_fd(), &vrange_);
|
||||
EXPECT_EQ(SECSuccess, rv);
|
||||
if (rv != SECSuccess) return false;
|
||||
}
|
||||
|
||||
if (role_ == SERVER) {
|
||||
EXPECT_TRUE(ConfigServerCert(name_, true));
|
||||
@ -435,6 +439,8 @@ void TlsAgent::ExpectReadWriteError() { expect_readwrite_error_ = true; }
|
||||
|
||||
void TlsAgent::ExpectShortHeaders() { expect_short_headers_ = true; }
|
||||
|
||||
void TlsAgent::SkipVersionChecks() { skip_version_checks_ = true; }
|
||||
|
||||
void TlsAgent::SetSignatureSchemes(const SSLSignatureScheme* schemes,
|
||||
size_t count) {
|
||||
EXPECT_TRUE(EnsureTlsSetup());
|
||||
|
@ -137,6 +137,7 @@ class TlsAgent : public PollTarget {
|
||||
void EnableFalseStart();
|
||||
void ExpectResumption();
|
||||
void ExpectShortHeaders();
|
||||
void SkipVersionChecks();
|
||||
void SetSignatureSchemes(const SSLSignatureScheme* schemes, size_t count);
|
||||
void EnableAlpn(const uint8_t* val, size_t len);
|
||||
void CheckAlpn(SSLNextProtoState expected_state,
|
||||
@ -388,6 +389,7 @@ class TlsAgent : public PollTarget {
|
||||
AuthCertificateCallbackFunction auth_certificate_callback_;
|
||||
SniCallbackFunction sni_callback_;
|
||||
bool expect_short_headers_;
|
||||
bool skip_version_checks_;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& stream,
|
||||
@ -485,6 +487,10 @@ class TlsAgentDgramTestClient : public TlsAgentTestBase {
|
||||
TlsAgentDgramTestClient() : TlsAgentTestBase(TlsAgent::CLIENT, DGRAM) {}
|
||||
};
|
||||
|
||||
inline bool operator==(const SSLVersionRange& vr1, const SSLVersionRange& vr2) {
|
||||
return vr1.min == vr2.min && vr1.max == vr2.max;
|
||||
}
|
||||
|
||||
} // namespace nss_test
|
||||
|
||||
#endif
|
||||
|
@ -110,7 +110,8 @@ TlsConnectTestBase::TlsConnectTestBase(Mode mode, uint16_t version)
|
||||
expected_resumption_mode_(RESUME_NONE),
|
||||
session_ids_(),
|
||||
expect_extended_master_secret_(false),
|
||||
expect_early_data_accepted_(false) {
|
||||
expect_early_data_accepted_(false),
|
||||
skip_version_checks_(false) {
|
||||
std::string v;
|
||||
if (mode_ == DGRAM && version_ == SSL_LIBRARY_VERSION_TLS_1_1) {
|
||||
v = "1.0";
|
||||
@ -209,6 +210,10 @@ void TlsConnectTestBase::Reset(const std::string& server_name,
|
||||
const std::string& client_name) {
|
||||
client_.reset(new TlsAgent(client_name, TlsAgent::CLIENT, mode_));
|
||||
server_.reset(new TlsAgent(server_name, TlsAgent::SERVER, mode_));
|
||||
if (skip_version_checks_) {
|
||||
client_->SkipVersionChecks();
|
||||
server_->SkipVersionChecks();
|
||||
}
|
||||
|
||||
Init();
|
||||
}
|
||||
@ -268,10 +273,12 @@ void TlsConnectTestBase::ConnectWithCipherSuite(uint16_t cipher_suite) {
|
||||
}
|
||||
|
||||
void TlsConnectTestBase::CheckConnected() {
|
||||
// Check the version is as expected
|
||||
EXPECT_EQ(client_->version(), server_->version());
|
||||
EXPECT_EQ(std::min(client_->max_version(), server_->max_version()),
|
||||
client_->version());
|
||||
if (!skip_version_checks_) {
|
||||
// Check the version is as expected
|
||||
EXPECT_EQ(std::min(client_->max_version(), server_->max_version()),
|
||||
client_->version());
|
||||
}
|
||||
|
||||
EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
|
||||
EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
|
||||
@ -510,6 +517,10 @@ void TlsConnectTestBase::EnsureModelSockets() {
|
||||
new TlsAgent(TlsAgent::kClient, TlsAgent::CLIENT, mode_));
|
||||
server_model_.reset(
|
||||
new TlsAgent(TlsAgent::kServerRsa, TlsAgent::SERVER, mode_));
|
||||
if (skip_version_checks_) {
|
||||
client_model_->SkipVersionChecks();
|
||||
server_model_->SkipVersionChecks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -635,6 +646,12 @@ void TlsConnectTestBase::DisableECDHEServerKeyReuse() {
|
||||
server_->DisableECDHEServerKeyReuse();
|
||||
}
|
||||
|
||||
void TlsConnectTestBase::SkipVersionChecks() {
|
||||
skip_version_checks_ = true;
|
||||
client_->SkipVersionChecks();
|
||||
server_->SkipVersionChecks();
|
||||
}
|
||||
|
||||
TlsConnectGeneric::TlsConnectGeneric()
|
||||
: TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())) {}
|
||||
|
||||
|
@ -111,6 +111,7 @@ class TlsConnectTestBase : public ::testing::Test {
|
||||
void ExpectExtendedMasterSecret(bool expected);
|
||||
void ExpectEarlyDataAccepted(bool expected);
|
||||
void DisableECDHEServerKeyReuse();
|
||||
void SkipVersionChecks();
|
||||
|
||||
protected:
|
||||
Mode mode_;
|
||||
@ -139,6 +140,7 @@ class TlsConnectTestBase : public ::testing::Test {
|
||||
|
||||
bool expect_extended_master_secret_;
|
||||
bool expect_early_data_accepted_;
|
||||
bool skip_version_checks_;
|
||||
|
||||
// Track groups and make sure that there are no duplicates.
|
||||
class DuplicateGroupChecker {
|
||||
|
@ -68,11 +68,13 @@ TEST_F(B64EncodeDecodeTest, FakeEncDecTest) {
|
||||
}
|
||||
|
||||
// These takes a while ...
|
||||
TEST_F(B64EncodeDecodeTest, LongFakeDecTest1) {
|
||||
TEST_F(B64EncodeDecodeTest, DISABLED_LongFakeDecTest1) {
|
||||
EXPECT_TRUE(TestFakeDecode(0x66666666));
|
||||
}
|
||||
TEST_F(B64EncodeDecodeTest, LongFakeEncDecTest1) { TestFakeEncode(0x3fffffff); }
|
||||
TEST_F(B64EncodeDecodeTest, LongFakeEncDecTest2) {
|
||||
TEST_F(B64EncodeDecodeTest, DISABLED_LongFakeEncDecTest1) {
|
||||
TestFakeEncode(0x3fffffff);
|
||||
}
|
||||
TEST_F(B64EncodeDecodeTest, DISABLED_LongFakeEncDecTest2) {
|
||||
EXPECT_FALSE(TestFakeEncode(0x40000000));
|
||||
}
|
||||
|
||||
|
@ -58,4 +58,11 @@ SEC_END_PROTOS
|
||||
|
||||
#undef HAVE_NO_SANITIZE_ATTR
|
||||
|
||||
SECStatus RSA_Init();
|
||||
|
||||
/* Freebl state. */
|
||||
PRBool aesni_support();
|
||||
PRBool clmul_support();
|
||||
PRBool avx_support();
|
||||
|
||||
#endif /* _BLAPII_H_ */
|
||||
|
119
security/nss/lib/freebl/blinit.c
Normal file
119
security/nss/lib/freebl/blinit.c
Normal file
@ -0,0 +1,119 @@
|
||||
/* 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/. */
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
#include "stubs.h"
|
||||
#endif
|
||||
|
||||
#include "blapii.h"
|
||||
#include "mpi.h"
|
||||
#include "secerr.h"
|
||||
#include "prtypes.h"
|
||||
#include "prinit.h"
|
||||
#include "prenv.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_M_IX86)
|
||||
#include <intrin.h> /* for _xgetbv() */
|
||||
#endif
|
||||
|
||||
static PRCallOnceType coFreeblInit;
|
||||
|
||||
/* State variables. */
|
||||
static PRBool aesni_support_ = PR_FALSE;
|
||||
static PRBool clmul_support_ = PR_FALSE;
|
||||
static PRBool avx_support_ = PR_FALSE;
|
||||
|
||||
#ifdef NSS_X86_OR_X64
|
||||
/*
|
||||
* Adapted from the example code in "How to detect New Instruction support in
|
||||
* the 4th generation Intel Core processor family" by Max Locktyukhin.
|
||||
*
|
||||
* XGETBV:
|
||||
* Reads an extended control register (XCR) specified by ECX into EDX:EAX.
|
||||
*/
|
||||
static PRBool
|
||||
check_xcr0_ymm()
|
||||
{
|
||||
PRUint32 xcr0;
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_M_IX86)
|
||||
__asm {
|
||||
mov ecx, 0
|
||||
xgetbv
|
||||
mov xcr0, eax
|
||||
}
|
||||
#else
|
||||
xcr0 = (PRUint32)_xgetbv(0); /* Requires VS2010 SP1 or later. */
|
||||
#endif /* _M_IX86 */
|
||||
#else /* _MSC_VER */
|
||||
/* Old OSX compilers don't support xgetbv. Use byte form. */
|
||||
__asm__(".byte 0x0F, 0x01, 0xd0"
|
||||
: "=a"(xcr0)
|
||||
: "c"(0)
|
||||
: "%edx");
|
||||
#endif /* _MSC_VER */
|
||||
/* Check if xmm and ymm state are enabled in XCR0. */
|
||||
return (xcr0 & 6) == 6;
|
||||
}
|
||||
|
||||
#define ECX_AESNI (1 << 25)
|
||||
#define ECX_CLMUL (1 << 1)
|
||||
#define ECX_XSAVE (1 << 26)
|
||||
#define ECX_OSXSAVE (1 << 27)
|
||||
#define ECX_AVX (1 << 28)
|
||||
#define AVX_BITS (ECX_XSAVE | ECX_OSXSAVE | ECX_AVX)
|
||||
|
||||
void
|
||||
CheckX86CPUSupport()
|
||||
{
|
||||
unsigned long eax, ebx, ecx, edx;
|
||||
char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES");
|
||||
char *disable_pclmul = PR_GetEnvSecure("NSS_DISABLE_PCLMUL");
|
||||
char *disable_avx = PR_GetEnvSecure("NSS_DISABLE_AVX");
|
||||
freebl_cpuid(1, &eax, &ebx, &ecx, &edx);
|
||||
aesni_support_ = (PRBool)((ecx & ECX_AESNI) != 0 && disable_hw_aes == NULL);
|
||||
clmul_support_ = (PRBool)((ecx & ECX_CLMUL) != 0 && disable_pclmul == NULL);
|
||||
/* For AVX we check AVX, OSXSAVE, and XSAVE
|
||||
* as well as XMM and YMM state. */
|
||||
avx_support_ = (PRBool)((ecx & AVX_BITS) == AVX_BITS) && check_xcr0_ymm() &&
|
||||
disable_avx == NULL;
|
||||
}
|
||||
#endif /* NSS_X86_OR_X64 */
|
||||
|
||||
PRBool
|
||||
aesni_support()
|
||||
{
|
||||
return aesni_support_;
|
||||
}
|
||||
PRBool
|
||||
clmul_support()
|
||||
{
|
||||
return clmul_support_;
|
||||
}
|
||||
PRBool
|
||||
avx_support()
|
||||
{
|
||||
return avx_support_;
|
||||
}
|
||||
|
||||
static PRStatus
|
||||
FreeblInit(void)
|
||||
{
|
||||
#ifdef NSS_X86_OR_X64
|
||||
CheckX86CPUSupport();
|
||||
#endif
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
BL_Init()
|
||||
{
|
||||
if (PR_CallOnce(&coFreeblInit, FreeblInit) != PR_SUCCESS) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
RSA_Init();
|
||||
|
||||
return SECSuccess;
|
||||
}
|
@ -158,8 +158,6 @@
|
||||
'VCCLCompilerTool': {
|
||||
#TODO: -Ox optimize flags
|
||||
'PreprocessorDefinitions': [
|
||||
'NSS_X86_OR_X64',
|
||||
'NSS_X86',
|
||||
'MP_ASSEMBLY_MULTIPLY',
|
||||
'MP_ASSEMBLY_SQUARE',
|
||||
'MP_ASSEMBLY_DIV_2DX1D',
|
||||
@ -176,9 +174,6 @@
|
||||
'VCCLCompilerTool': {
|
||||
#TODO: -Ox optimize flags
|
||||
'PreprocessorDefinitions': [
|
||||
'NSS_USE_64',
|
||||
'NSS_X86_OR_X64',
|
||||
'NSS_X64',
|
||||
'MP_IS_LITTLE_ENDIAN',
|
||||
'NSS_BEVAND_ARCFOUR',
|
||||
'MPI_AMD64',
|
||||
@ -192,11 +187,8 @@
|
||||
}],
|
||||
[ 'OS!="win"', {
|
||||
'conditions': [
|
||||
[ 'target_arch=="x64"', {
|
||||
[ 'target_arch=="x64" or target_arch=="arm64" or target_arch=="aarch64"', {
|
||||
'defines': [
|
||||
'NSS_USE_64',
|
||||
'NSS_X86_OR_X64',
|
||||
'NSS_X64',
|
||||
# The Makefile does version-tests on GCC, but we're not doing that here.
|
||||
'HAVE_INT128_SUPPORT',
|
||||
],
|
||||
@ -205,12 +197,6 @@
|
||||
'ecl/uint128.c',
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="ia32"', {
|
||||
'defines': [
|
||||
'NSS_X86_OR_X64',
|
||||
'NSS_X86',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
[ 'OS=="linux"', {
|
||||
@ -251,11 +237,7 @@
|
||||
'MP_ASSEMBLY_SQUARE',
|
||||
'MP_USE_UINT_DIGIT',
|
||||
'SHA_NO_LONG_LONG',
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="arm64" or target_arch=="aarch64"', {
|
||||
'defines': [
|
||||
'NSS_USE_64',
|
||||
'ARMHF',
|
||||
],
|
||||
}],
|
||||
],
|
||||
|
@ -33,6 +33,7 @@
|
||||
'ecl/ecp_jm.c',
|
||||
'ecl/ecp_mont.c',
|
||||
'fipsfreebl.c',
|
||||
'blinit.c',
|
||||
'freeblver.c',
|
||||
'gcm.c',
|
||||
'hmacct.c',
|
||||
|
@ -132,6 +132,7 @@ CSRCS = \
|
||||
chacha20poly1305.c \
|
||||
cts.c \
|
||||
ctr.c \
|
||||
blinit.c \
|
||||
fipsfreebl.c \
|
||||
gcm.c \
|
||||
hmacct.c \
|
||||
|
@ -26,17 +26,11 @@
|
||||
#include "mpi.h"
|
||||
|
||||
#ifdef USE_HW_AES
|
||||
static int has_intel_aes = 0;
|
||||
static PRBool use_hw_aes = PR_FALSE;
|
||||
|
||||
#ifdef INTEL_GCM
|
||||
#include "intel-gcm.h"
|
||||
static int has_intel_avx = 0;
|
||||
static int has_intel_clmul = 0;
|
||||
static PRBool use_hw_gcm = PR_FALSE;
|
||||
#if defined(_MSC_VER) && !defined(_M_IX86)
|
||||
#include <intrin.h> /* for _xgetbv() */
|
||||
#endif
|
||||
#endif
|
||||
#endif /* USE_HW_AES */
|
||||
|
||||
@ -999,39 +993,6 @@ AES_AllocateContext(void)
|
||||
return PORT_ZNew(AESContext);
|
||||
}
|
||||
|
||||
#ifdef INTEL_GCM
|
||||
/*
|
||||
* Adapted from the example code in "How to detect New Instruction support in
|
||||
* the 4th generation Intel Core processor family" by Max Locktyukhin.
|
||||
*
|
||||
* XGETBV:
|
||||
* Reads an extended control register (XCR) specified by ECX into EDX:EAX.
|
||||
*/
|
||||
static PRBool
|
||||
check_xcr0_ymm()
|
||||
{
|
||||
PRUint32 xcr0;
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_M_IX86)
|
||||
__asm {
|
||||
mov ecx, 0
|
||||
xgetbv
|
||||
mov xcr0, eax
|
||||
}
|
||||
#else
|
||||
xcr0 = (PRUint32)_xgetbv(0); /* Requires VS2010 SP1 or later. */
|
||||
#endif
|
||||
#else
|
||||
__asm__("xgetbv"
|
||||
: "=a"(xcr0)
|
||||
: "c"(0)
|
||||
: "%edx");
|
||||
#endif
|
||||
/* Check if xmm and ymm state are enabled in XCR0. */
|
||||
return (xcr0 & 6) == 6;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Initialize a new AES context suitable for AES encryption/decryption in
|
||||
** the ECB or CBC mode.
|
||||
@ -1070,33 +1031,9 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
|
||||
return SECFailure;
|
||||
}
|
||||
#ifdef USE_HW_AES
|
||||
if (has_intel_aes == 0) {
|
||||
unsigned long eax, ebx, ecx, edx;
|
||||
char *disable_hw_aes = PR_GetEnvSecure("NSS_DISABLE_HW_AES");
|
||||
|
||||
if (disable_hw_aes == NULL) {
|
||||
freebl_cpuid(1, &eax, &ebx, &ecx, &edx);
|
||||
has_intel_aes = (ecx & (1 << 25)) != 0 ? 1 : -1;
|
||||
use_hw_aes = aesni_support() && (keysize % 8) == 0 && blocksize == 16;
|
||||
#ifdef INTEL_GCM
|
||||
has_intel_clmul = (ecx & (1 << 1)) != 0 ? 1 : -1;
|
||||
if ((ecx & (1 << 27)) != 0 && (ecx & (1 << 28)) != 0 &&
|
||||
check_xcr0_ymm()) {
|
||||
has_intel_avx = 1;
|
||||
} else {
|
||||
has_intel_avx = -1;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
has_intel_aes = -1;
|
||||
#ifdef INTEL_GCM
|
||||
has_intel_avx = -1;
|
||||
has_intel_clmul = -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
use_hw_aes = (PRBool)(has_intel_aes > 0 && (keysize % 8) == 0 && blocksize == 16);
|
||||
#ifdef INTEL_GCM
|
||||
use_hw_gcm = (PRBool)(use_hw_aes && has_intel_avx > 0 && has_intel_clmul > 0);
|
||||
use_hw_gcm = use_hw_aes && avx_support() && clmul_support();
|
||||
#endif
|
||||
#endif /* USE_HW_AES */
|
||||
/* Nb = (block size in bits) / 32 */
|
||||
|
@ -1551,7 +1551,7 @@ cleanup:
|
||||
return rv;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
SECStatus
|
||||
RSA_Init(void)
|
||||
{
|
||||
if (PR_CallOnce(&coBPInit, init_blinding_params_list) != PR_SUCCESS) {
|
||||
@ -1561,12 +1561,6 @@ RSA_Init(void)
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
BL_Init(void)
|
||||
{
|
||||
return RSA_Init();
|
||||
}
|
||||
|
||||
/* cleanup at shutdown */
|
||||
void
|
||||
RSA_Cleanup(void)
|
||||
|
@ -1211,6 +1211,7 @@ RSA_SignPSS(RSAPrivateKey *key,
|
||||
if (rv != SECSuccess)
|
||||
goto done;
|
||||
|
||||
// This sets error codes upon failure.
|
||||
rv = RSA_PrivateKeyOpDoubleChecked(key, output, pssEncoded);
|
||||
*outputLen = modulusLen;
|
||||
|
||||
@ -1270,7 +1271,6 @@ RSA_CheckSignPSS(RSAPublicKey *key,
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* XXX Doesn't set error code */
|
||||
SECStatus
|
||||
RSA_Sign(RSAPrivateKey *key,
|
||||
unsigned char *output,
|
||||
@ -1279,34 +1279,34 @@ RSA_Sign(RSAPrivateKey *key,
|
||||
const unsigned char *input,
|
||||
unsigned int inputLen)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
SECStatus rv = SECFailure;
|
||||
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
|
||||
SECItem formatted;
|
||||
SECItem unformatted;
|
||||
SECItem formatted = { siBuffer, NULL, 0 };
|
||||
SECItem unformatted = { siBuffer, (unsigned char *)input, inputLen };
|
||||
|
||||
if (maxOutputLen < modulusLen)
|
||||
return SECFailure;
|
||||
if (maxOutputLen < modulusLen) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
goto done;
|
||||
}
|
||||
|
||||
unformatted.len = inputLen;
|
||||
unformatted.data = (unsigned char *)input;
|
||||
formatted.data = NULL;
|
||||
rv = rsa_FormatBlock(&formatted, modulusLen, RSA_BlockPrivate,
|
||||
&unformatted);
|
||||
if (rv != SECSuccess)
|
||||
if (rv != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
// This sets error codes upon failure.
|
||||
rv = RSA_PrivateKeyOpDoubleChecked(key, output, formatted.data);
|
||||
*outputLen = modulusLen;
|
||||
|
||||
goto done;
|
||||
|
||||
done:
|
||||
if (formatted.data != NULL)
|
||||
if (formatted.data != NULL) {
|
||||
PORT_ZFree(formatted.data, modulusLen);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* XXX Doesn't set error code */
|
||||
SECStatus
|
||||
RSA_CheckSign(RSAPublicKey *key,
|
||||
const unsigned char *sig,
|
||||
@ -1314,60 +1314,71 @@ RSA_CheckSign(RSAPublicKey *key,
|
||||
const unsigned char *data,
|
||||
unsigned int dataLen)
|
||||
{
|
||||
SECStatus rv;
|
||||
SECStatus rv = SECFailure;
|
||||
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
|
||||
unsigned int i;
|
||||
unsigned char *buffer;
|
||||
unsigned char *buffer = NULL;
|
||||
|
||||
if (sigLen != modulusLen) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (sigLen != modulusLen)
|
||||
goto failure;
|
||||
/*
|
||||
* 0x00 || BT || Pad || 0x00 || ActualData
|
||||
*
|
||||
* The "3" below is the first octet + the second octet + the 0x00
|
||||
* octet that always comes just before the ActualData.
|
||||
*/
|
||||
if (dataLen > modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN))
|
||||
goto failure;
|
||||
if (dataLen > modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
goto done;
|
||||
}
|
||||
|
||||
buffer = (unsigned char *)PORT_Alloc(modulusLen + 1);
|
||||
if (!buffer)
|
||||
goto failure;
|
||||
if (!buffer) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
rv = RSA_PublicKeyOp(key, buffer, sig);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
if (RSA_PublicKeyOp(key, buffer, sig) != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* check the padding that was used
|
||||
*/
|
||||
if (buffer[0] != RSA_BLOCK_FIRST_OCTET ||
|
||||
buffer[1] != (unsigned char)RSA_BlockPrivate) {
|
||||
goto loser;
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
for (i = 2; i < modulusLen - dataLen - 1; i++) {
|
||||
if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET)
|
||||
goto loser;
|
||||
if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (buffer[i] != RSA_BLOCK_AFTER_PAD_OCTET) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
if (buffer[i] != RSA_BLOCK_AFTER_PAD_OCTET)
|
||||
goto loser;
|
||||
|
||||
/*
|
||||
* make sure we get the same results
|
||||
*/
|
||||
if (PORT_Memcmp(buffer + modulusLen - dataLen, data, dataLen) != 0)
|
||||
goto loser;
|
||||
if (PORT_Memcmp(buffer + modulusLen - dataLen, data, dataLen) == 0) {
|
||||
rv = SECSuccess;
|
||||
}
|
||||
|
||||
PORT_Free(buffer);
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
PORT_Free(buffer);
|
||||
failure:
|
||||
return SECFailure;
|
||||
done:
|
||||
if (buffer) {
|
||||
PORT_Free(buffer);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* XXX Doesn't set error code */
|
||||
SECStatus
|
||||
RSA_CheckSignRecover(RSAPublicKey *key,
|
||||
unsigned char *output,
|
||||
@ -1376,21 +1387,27 @@ RSA_CheckSignRecover(RSAPublicKey *key,
|
||||
const unsigned char *sig,
|
||||
unsigned int sigLen)
|
||||
{
|
||||
SECStatus rv;
|
||||
SECStatus rv = SECFailure;
|
||||
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
|
||||
unsigned int i;
|
||||
unsigned char *buffer;
|
||||
unsigned char *buffer = NULL;
|
||||
|
||||
if (sigLen != modulusLen)
|
||||
goto failure;
|
||||
if (sigLen != modulusLen) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
buffer = (unsigned char *)PORT_Alloc(modulusLen + 1);
|
||||
if (!buffer)
|
||||
goto failure;
|
||||
if (!buffer) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (RSA_PublicKeyOp(key, buffer, sig) != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
|
||||
rv = RSA_PublicKeyOp(key, buffer, sig);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
*outputLen = 0;
|
||||
|
||||
/*
|
||||
@ -1398,28 +1415,34 @@ RSA_CheckSignRecover(RSAPublicKey *key,
|
||||
*/
|
||||
if (buffer[0] != RSA_BLOCK_FIRST_OCTET ||
|
||||
buffer[1] != (unsigned char)RSA_BlockPrivate) {
|
||||
goto loser;
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
for (i = 2; i < modulusLen; i++) {
|
||||
if (buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET) {
|
||||
*outputLen = modulusLen - i - 1;
|
||||
break;
|
||||
}
|
||||
if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET)
|
||||
goto loser;
|
||||
if (buffer[i] != RSA_BLOCK_PRIVATE_PAD_OCTET) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (*outputLen == 0) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
goto done;
|
||||
}
|
||||
if (*outputLen > maxOutputLen) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
goto done;
|
||||
}
|
||||
if (*outputLen == 0)
|
||||
goto loser;
|
||||
if (*outputLen > maxOutputLen)
|
||||
goto loser;
|
||||
|
||||
PORT_Memcpy(output, buffer + modulusLen - *outputLen, *outputLen);
|
||||
rv = SECSuccess;
|
||||
|
||||
PORT_Free(buffer);
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
PORT_Free(buffer);
|
||||
failure:
|
||||
return SECFailure;
|
||||
done:
|
||||
if (buffer) {
|
||||
PORT_Free(buffer);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -26,49 +26,6 @@
|
||||
'defines': [
|
||||
'MOZILLA_CLIENT=1',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'OS=="win"', {
|
||||
'configurations': {
|
||||
'x86_Base': {
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'PreprocessorDefinitions': [
|
||||
'NSS_X86_OR_X64',
|
||||
'NSS_X86',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
'x64_Base': {
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'PreprocessorDefinitions': [
|
||||
'NSS_USE_64',
|
||||
'NSS_X86_OR_X64',
|
||||
'NSS_X64',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
'conditions': [
|
||||
[ 'target_arch=="x64"', {
|
||||
'defines': [
|
||||
'NSS_USE_64',
|
||||
'NSS_X86_OR_X64',
|
||||
'NSS_X64',
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="ia32"', {
|
||||
'defines': [
|
||||
'NSS_X86_OR_X64',
|
||||
'NSS_X86',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
'variables': {
|
||||
'module': 'nss'
|
||||
|
@ -1496,6 +1496,14 @@ extern PRInt32 ssl3_SendRecord(sslSocket *ss, ssl3CipherSpec *cwSpec,
|
||||
*/
|
||||
#define SSL_LIBRARY_VERSION_NONE 0
|
||||
|
||||
/* SSL_LIBRARY_VERSION_MIN_SUPPORTED is the minimum version that this version
|
||||
* of libssl supports. Applications should use SSL_VersionRangeGetSupported at
|
||||
* runtime to determine which versions are supported by the version of libssl
|
||||
* in use.
|
||||
*/
|
||||
#define SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM SSL_LIBRARY_VERSION_TLS_1_1
|
||||
#define SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM SSL_LIBRARY_VERSION_3_0
|
||||
|
||||
/* SSL_LIBRARY_VERSION_MAX_SUPPORTED is the maximum version that this version
|
||||
* of libssl supports. Applications should use SSL_VersionRangeGetSupported at
|
||||
* runtime to determine which versions are supported by the version of libssl
|
||||
|
@ -2152,11 +2152,11 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
|
||||
ss->sniSocketConfig = sm->sniSocketConfig;
|
||||
if (sm->sniSocketConfigArg)
|
||||
ss->sniSocketConfigArg = sm->sniSocketConfigArg;
|
||||
if (ss->alertReceivedCallback) {
|
||||
if (sm->alertReceivedCallback) {
|
||||
ss->alertReceivedCallback = sm->alertReceivedCallback;
|
||||
ss->alertReceivedCallbackArg = sm->alertReceivedCallbackArg;
|
||||
}
|
||||
if (ss->alertSentCallback) {
|
||||
if (sm->alertSentCallback) {
|
||||
ss->alertSentCallback = sm->alertSentCallback;
|
||||
ss->alertSentCallbackArg = sm->alertSentCallbackArg;
|
||||
}
|
||||
@ -2173,61 +2173,82 @@ SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
|
||||
return fd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the user supplied range
|
||||
*/
|
||||
static SECStatus
|
||||
ssl3_GetRangePolicy(SSLProtocolVariant protocolVariant, SSLVersionRange *prange)
|
||||
SECStatus
|
||||
ssl3_GetEffectiveVersionPolicy(SSLProtocolVariant variant,
|
||||
SSLVersionRange *effectivePolicy)
|
||||
{
|
||||
SECStatus rv;
|
||||
PRUint32 policy;
|
||||
PRInt32 option;
|
||||
PRUint32 policyFlag;
|
||||
PRInt32 minPolicy, maxPolicy;
|
||||
|
||||
/* only use policy constraints if we've set the apply ssl policy bit */
|
||||
rv = NSS_GetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, &policy);
|
||||
if ((rv != SECSuccess) || !(policy & NSS_USE_POLICY_IN_SSL)) {
|
||||
if (variant == ssl_variant_stream) {
|
||||
effectivePolicy->min = SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM;
|
||||
effectivePolicy->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
|
||||
} else {
|
||||
effectivePolicy->min = SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM;
|
||||
effectivePolicy->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
|
||||
}
|
||||
|
||||
rv = NSS_GetAlgorithmPolicy(SEC_OID_APPLY_SSL_POLICY, &policyFlag);
|
||||
if ((rv != SECSuccess) || !(policyFlag & NSS_USE_POLICY_IN_SSL)) {
|
||||
/* Policy is not active, report library extents. */
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
rv = NSS_OptionGet(VERSIONS_POLICY_MIN(variant), &minPolicy);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
rv = NSS_OptionGet(VERSIONS_POLICY_MIN(protocolVariant), &option);
|
||||
rv = NSS_OptionGet(VERSIONS_POLICY_MAX(variant), &maxPolicy);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
return SECFailure;
|
||||
}
|
||||
prange->min = (PRUint16)option;
|
||||
rv = NSS_OptionGet(VERSIONS_POLICY_MAX(protocolVariant), &option);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
prange->max = (PRUint16)option;
|
||||
if (prange->max < prange->min) {
|
||||
return SECFailure; /* don't accept an invalid policy */
|
||||
|
||||
if (minPolicy > effectivePolicy->max ||
|
||||
maxPolicy < effectivePolicy->min ||
|
||||
minPolicy > maxPolicy) {
|
||||
return SECFailure;
|
||||
}
|
||||
effectivePolicy->min = PR_MAX(effectivePolicy->min, minPolicy);
|
||||
effectivePolicy->max = PR_MIN(effectivePolicy->max, maxPolicy);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* Constrain a single protocol variant's range based on the user policy
|
||||
/*
|
||||
* Assumes that rangeParam values are within the supported boundaries,
|
||||
* but should contain all potentially allowed versions, even if they contain
|
||||
* conflicting versions.
|
||||
* Will return the overlap, or a NONE range if system policy is invalid.
|
||||
*/
|
||||
static SECStatus
|
||||
ssl3_ConstrainVariantRangeByPolicy(SSLProtocolVariant protocolVariant)
|
||||
ssl3_CreateOverlapWithPolicy(SSLProtocolVariant protocolVariant,
|
||||
SSLVersionRange *input,
|
||||
SSLVersionRange *overlap)
|
||||
{
|
||||
SSLVersionRange vrange;
|
||||
SSLVersionRange pvrange;
|
||||
SECStatus rv;
|
||||
SSLVersionRange effectivePolicyBoundary;
|
||||
SSLVersionRange vrange;
|
||||
|
||||
vrange = *VERSIONS_DEFAULTS(protocolVariant);
|
||||
rv = ssl3_GetRangePolicy(protocolVariant, &pvrange);
|
||||
if (rv != SECSuccess) {
|
||||
return SECSuccess; /* we don't have any policy */
|
||||
PORT_Assert(input != NULL);
|
||||
|
||||
rv = ssl3_GetEffectiveVersionPolicy(protocolVariant,
|
||||
&effectivePolicyBoundary);
|
||||
if (rv == SECFailure) {
|
||||
/* SECFailure means internal failure or invalid configuration. */
|
||||
overlap->min = overlap->max = SSL_LIBRARY_VERSION_NONE;
|
||||
return SECFailure;
|
||||
}
|
||||
vrange.min = PR_MAX(vrange.min, pvrange.min);
|
||||
vrange.max = PR_MIN(vrange.max, pvrange.max);
|
||||
if (vrange.max >= vrange.min) {
|
||||
*VERSIONS_DEFAULTS(protocolVariant) = vrange;
|
||||
} else {
|
||||
|
||||
vrange.min = PR_MAX(input->min, effectivePolicyBoundary.min);
|
||||
vrange.max = PR_MIN(input->max, effectivePolicyBoundary.max);
|
||||
|
||||
if (vrange.max < vrange.min) {
|
||||
/* there was no overlap, turn off range altogether */
|
||||
pvrange.min = pvrange.max = SSL_LIBRARY_VERSION_NONE;
|
||||
*VERSIONS_DEFAULTS(protocolVariant) = pvrange;
|
||||
overlap->min = overlap->max = SSL_LIBRARY_VERSION_NONE;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
*overlap = vrange;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
@ -2235,16 +2256,17 @@ static PRBool
|
||||
ssl_VersionIsSupportedByPolicy(SSLProtocolVariant protocolVariant,
|
||||
SSL3ProtocolVersion version)
|
||||
{
|
||||
SSLVersionRange pvrange;
|
||||
SECStatus rv;
|
||||
SSLVersionRange effectivePolicyBoundary;
|
||||
|
||||
rv = ssl3_GetRangePolicy(protocolVariant, &pvrange);
|
||||
if (rv == SECSuccess) {
|
||||
if ((version > pvrange.max) || (version < pvrange.min)) {
|
||||
return PR_FALSE; /* disallowed by policy */
|
||||
}
|
||||
rv = ssl3_GetEffectiveVersionPolicy(protocolVariant,
|
||||
&effectivePolicyBoundary);
|
||||
if (rv == SECFailure) {
|
||||
/* SECFailure means internal failure or invalid configuration. */
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
return version >= effectivePolicyBoundary.min &&
|
||||
version <= effectivePolicyBoundary.max;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2254,18 +2276,36 @@ ssl_VersionIsSupportedByPolicy(SSLProtocolVariant protocolVariant,
|
||||
SECStatus
|
||||
ssl3_ConstrainRangeByPolicy(void)
|
||||
{
|
||||
SECStatus rv;
|
||||
rv = ssl3_ConstrainVariantRangeByPolicy(ssl_variant_stream);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
rv = ssl3_ConstrainVariantRangeByPolicy(ssl_variant_datagram);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
/* We ignore failures in ssl3_CreateOverlapWithPolicy. Although an empty
|
||||
* overlap disables all connectivity, it's an allowed state.
|
||||
*/
|
||||
ssl3_CreateOverlapWithPolicy(ssl_variant_stream,
|
||||
VERSIONS_DEFAULTS(ssl_variant_stream),
|
||||
VERSIONS_DEFAULTS(ssl_variant_stream));
|
||||
ssl3_CreateOverlapWithPolicy(ssl_variant_datagram,
|
||||
VERSIONS_DEFAULTS(ssl_variant_datagram),
|
||||
VERSIONS_DEFAULTS(ssl_variant_datagram));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ssl3_VersionIsSupportedByCode(SSLProtocolVariant protocolVariant,
|
||||
SSL3ProtocolVersion version)
|
||||
{
|
||||
switch (protocolVariant) {
|
||||
case ssl_variant_stream:
|
||||
return (version >= SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM &&
|
||||
version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
|
||||
case ssl_variant_datagram:
|
||||
return (version >= SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM &&
|
||||
version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
|
||||
}
|
||||
|
||||
/* Can't get here */
|
||||
PORT_Assert(PR_FALSE);
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
|
||||
SSL3ProtocolVersion version)
|
||||
@ -2273,33 +2313,7 @@ ssl3_VersionIsSupported(SSLProtocolVariant protocolVariant,
|
||||
if (!ssl_VersionIsSupportedByPolicy(protocolVariant, version)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
switch (protocolVariant) {
|
||||
case ssl_variant_stream:
|
||||
return (version >= SSL_LIBRARY_VERSION_3_0 &&
|
||||
version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
|
||||
case ssl_variant_datagram:
|
||||
return (version >= SSL_LIBRARY_VERSION_TLS_1_1 &&
|
||||
version <= SSL_LIBRARY_VERSION_MAX_SUPPORTED);
|
||||
default:
|
||||
/* Can't get here */
|
||||
PORT_Assert(PR_FALSE);
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns PR_TRUE if the given version range is valid and
|
||||
** fully supported; otherwise, returns PR_FALSE.
|
||||
*/
|
||||
static PRBool
|
||||
ssl3_VersionRangeIsValid(SSLProtocolVariant protocolVariant,
|
||||
const SSLVersionRange *vrange)
|
||||
{
|
||||
return vrange &&
|
||||
vrange->min <= vrange->max &&
|
||||
ssl3_VersionIsSupported(protocolVariant, vrange->min) &&
|
||||
ssl3_VersionIsSupported(protocolVariant, vrange->max) &&
|
||||
(vrange->min > SSL_LIBRARY_VERSION_3_0 ||
|
||||
vrange->max < SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
return ssl3_VersionIsSupportedByCode(protocolVariant, version);
|
||||
}
|
||||
|
||||
const SECItem *
|
||||
@ -2325,6 +2339,8 @@ SECStatus
|
||||
SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
|
||||
SSLVersionRange *vrange)
|
||||
{
|
||||
SECStatus rv;
|
||||
|
||||
if (!vrange) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
@ -2332,15 +2348,15 @@ SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
|
||||
|
||||
switch (protocolVariant) {
|
||||
case ssl_variant_stream:
|
||||
vrange->min = SSL_LIBRARY_VERSION_3_0;
|
||||
vrange->min = SSL_LIBRARY_VERSION_MIN_SUPPORTED_STREAM;
|
||||
vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
|
||||
// We don't allow SSLv3 and TLSv1.3 together.
|
||||
if (vrange->max == SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
vrange->min = SSL_LIBRARY_VERSION_TLS_1_0;
|
||||
}
|
||||
/* We don't allow SSLv3 and TLSv1.3 together.
|
||||
* However, don't check yet, apply the policy first.
|
||||
* Because if the effective supported range doesn't use TLS 1.3,
|
||||
* then we don't need to increase the minimum. */
|
||||
break;
|
||||
case ssl_variant_datagram:
|
||||
vrange->min = SSL_LIBRARY_VERSION_TLS_1_1;
|
||||
vrange->min = SSL_LIBRARY_VERSION_MIN_SUPPORTED_DATAGRAM;
|
||||
vrange->max = SSL_LIBRARY_VERSION_MAX_SUPPORTED;
|
||||
break;
|
||||
default:
|
||||
@ -2348,6 +2364,17 @@ SSL_VersionRangeGetSupported(SSLProtocolVariant protocolVariant,
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
rv = ssl3_CreateOverlapWithPolicy(protocolVariant, vrange, vrange);
|
||||
if (rv != SECSuccess) {
|
||||
/* Library default and policy don't overlap. */
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* We don't allow SSLv3 and TLSv1.3 together */
|
||||
if (vrange->max >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
vrange->min = PR_MAX(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0);
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
@ -2363,6 +2390,43 @@ SSL_VersionRangeGetDefault(SSLProtocolVariant protocolVariant,
|
||||
}
|
||||
|
||||
*vrange = *VERSIONS_DEFAULTS(protocolVariant);
|
||||
return ssl3_CreateOverlapWithPolicy(protocolVariant, vrange, vrange);
|
||||
}
|
||||
|
||||
static PRBool
|
||||
ssl3_HasConflictingSSLVersions(const SSLVersionRange *vrange)
|
||||
{
|
||||
return (vrange->min <= SSL_LIBRARY_VERSION_3_0 &&
|
||||
vrange->max >= SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ssl3_CheckRangeValidAndConstrainByPolicy(SSLProtocolVariant protocolVariant,
|
||||
SSLVersionRange *vrange)
|
||||
{
|
||||
SECStatus rv;
|
||||
|
||||
if (vrange->min > vrange->max ||
|
||||
!ssl3_VersionIsSupportedByCode(protocolVariant, vrange->min) ||
|
||||
!ssl3_VersionIsSupportedByCode(protocolVariant, vrange->max) ||
|
||||
ssl3_HasConflictingSSLVersions(vrange)) {
|
||||
PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Try to adjust the received range using our policy.
|
||||
* If there's overlap, we'll use the (possibly reduced) range.
|
||||
* If there isn't overlap, it's failure. */
|
||||
|
||||
rv = ssl3_CreateOverlapWithPolicy(protocolVariant, vrange, vrange);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* We don't allow SSLv3 and TLSv1.3 together */
|
||||
if (vrange->max >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
vrange->min = PR_MAX(vrange->min, SSL_LIBRARY_VERSION_TLS_1_0);
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
@ -2371,13 +2435,21 @@ SECStatus
|
||||
SSL_VersionRangeSetDefault(SSLProtocolVariant protocolVariant,
|
||||
const SSLVersionRange *vrange)
|
||||
{
|
||||
if (!ssl3_VersionRangeIsValid(protocolVariant, vrange)) {
|
||||
PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
|
||||
SSLVersionRange constrainedRange;
|
||||
SECStatus rv;
|
||||
|
||||
if (!vrange) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
*VERSIONS_DEFAULTS(protocolVariant) = *vrange;
|
||||
constrainedRange = *vrange;
|
||||
rv = ssl3_CheckRangeValidAndConstrainByPolicy(protocolVariant,
|
||||
&constrainedRange);
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
||||
*VERSIONS_DEFAULTS(protocolVariant) = constrainedRange;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
@ -2405,24 +2477,33 @@ SSL_VersionRangeGet(PRFileDesc *fd, SSLVersionRange *vrange)
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
ssl_Release1stHandshakeLock(ss);
|
||||
|
||||
return SECSuccess;
|
||||
return ssl3_CreateOverlapWithPolicy(ss->protocolVariant, vrange, vrange);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange)
|
||||
{
|
||||
sslSocket *ss = ssl_FindSocket(fd);
|
||||
SSLVersionRange constrainedRange;
|
||||
sslSocket *ss;
|
||||
SECStatus rv;
|
||||
|
||||
if (!vrange) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_VersionRangeSet",
|
||||
SSL_GETPID(), fd));
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (!ssl3_VersionRangeIsValid(ss->protocolVariant, vrange)) {
|
||||
PORT_SetError(SSL_ERROR_INVALID_VERSION_RANGE);
|
||||
return SECFailure;
|
||||
}
|
||||
constrainedRange = *vrange;
|
||||
rv = ssl3_CheckRangeValidAndConstrainByPolicy(ss->protocolVariant,
|
||||
&constrainedRange);
|
||||
if (rv != SECSuccess)
|
||||
return rv;
|
||||
|
||||
ssl_Get1stHandshakeLock(ss);
|
||||
ssl_GetSSL3HandshakeLock(ss);
|
||||
@ -2435,7 +2516,7 @@ SSL_VersionRangeSet(PRFileDesc *fd, const SSLVersionRange *vrange)
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
ss->vrange = *vrange;
|
||||
ss->vrange = constrainedRange;
|
||||
|
||||
ssl_ReleaseSSL3HandshakeLock(ss);
|
||||
ssl_Release1stHandshakeLock(ss);
|
||||
@ -3684,7 +3765,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProtocolVariant protocolVariant)
|
||||
ss->opt.noLocks = !makeLocks;
|
||||
ss->vrange = *VERSIONS_DEFAULTS(protocolVariant);
|
||||
ss->protocolVariant = protocolVariant;
|
||||
|
||||
/* Ignore overlap failures, because returning NULL would trigger assertion
|
||||
* failures elsewhere. We don't want this scenario to be fatal, it's just
|
||||
* a state where no SSL connectivity is possible. */
|
||||
ssl3_CreateOverlapWithPolicy(ss->protocolVariant, &ss->vrange, &ss->vrange);
|
||||
ss->peerID = NULL;
|
||||
ss->rTimeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
ss->wTimeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
|
@ -231,20 +231,20 @@ bool EncTool::DoCipher(std::string file_name, std::string out_file,
|
||||
bool encrypt, key_func_t get_params) {
|
||||
SECStatus rv;
|
||||
unsigned int outLen = 0, chunkSize = 1024;
|
||||
char buffer[chunkSize + 16];
|
||||
char buffer[1040];
|
||||
const unsigned char* bufferStart =
|
||||
reinterpret_cast<const unsigned char*>(buffer);
|
||||
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
if (!slot) {
|
||||
PrintError("Unable to find security device", PR_GetError(), __LINE__);
|
||||
return SECFailure;
|
||||
return false;
|
||||
}
|
||||
|
||||
ScopedSECItem key, params;
|
||||
if (!(this->*get_params)(std::vector<uint8_t>(), key, params)) {
|
||||
PrintError("Geting keys and params failed.", __LINE__);
|
||||
return SECFailure;
|
||||
return false;
|
||||
}
|
||||
|
||||
ScopedPK11SymKey symKey(
|
||||
@ -252,7 +252,7 @@ bool EncTool::DoCipher(std::string file_name, std::string out_file,
|
||||
CKA_DECRYPT | CKA_ENCRYPT, key.get(), nullptr));
|
||||
if (!symKey) {
|
||||
PrintError("Failure to import key into NSS", PR_GetError(), __LINE__);
|
||||
return SECFailure;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::streambuf* buf;
|
||||
@ -270,21 +270,21 @@ bool EncTool::DoCipher(std::string file_name, std::string out_file,
|
||||
// Read from stdin.
|
||||
if (file_name.empty()) {
|
||||
std::vector<uint8_t> data = ReadInputData("");
|
||||
uint8_t out[data.size() + 16];
|
||||
std::vector<uint8_t> out(data.size() + 16);
|
||||
SECStatus rv;
|
||||
if (encrypt) {
|
||||
rv = PK11_Encrypt(symKey.get(), cipher_mech_, params.get(), out, &outLen,
|
||||
data.size() + 16, data.data(), data.size());
|
||||
rv = PK11_Encrypt(symKey.get(), cipher_mech_, params.get(), out.data(),
|
||||
&outLen, data.size() + 16, data.data(), data.size());
|
||||
} else {
|
||||
rv = PK11_Decrypt(symKey.get(), cipher_mech_, params.get(), out, &outLen,
|
||||
data.size() + 16, data.data(), data.size());
|
||||
rv = PK11_Decrypt(symKey.get(), cipher_mech_, params.get(), out.data(),
|
||||
&outLen, data.size() + 16, data.data(), data.size());
|
||||
}
|
||||
if (rv != SECSuccess) {
|
||||
PrintError(encrypt ? "Error encrypting" : "Error decrypting",
|
||||
PR_GetError(), __LINE__);
|
||||
return false;
|
||||
};
|
||||
output.write(reinterpret_cast<char*>(out), outLen);
|
||||
output.write(reinterpret_cast<char*>(out.data()), outLen);
|
||||
output.flush();
|
||||
if (output_file.good()) {
|
||||
output_file.close();
|
||||
@ -302,7 +302,7 @@ bool EncTool::DoCipher(std::string file_name, std::string out_file,
|
||||
if (!input.good()) {
|
||||
return false;
|
||||
}
|
||||
uint8_t out[chunkSize + 16];
|
||||
uint8_t out[1040];
|
||||
while (input) {
|
||||
if (encrypt) {
|
||||
input.read(buffer, chunkSize);
|
||||
|
@ -27,6 +27,9 @@ if [ -z "${CLEANUP}" -o "${CLEANUP}" = "${SCRIPTNAME}" ]; then
|
||||
echo "NSS_AIA_OCSP=${NSS_AIA_OCSP}"
|
||||
echo "IOPR_HOSTADDR_LIST=${IOPR_HOSTADDR_LIST}"
|
||||
echo "PKITS_DATA=${PKITS_DATA}"
|
||||
echo "NSS_DISABLE_HW_AES=${NSS_DISABLE_HW_AES}"
|
||||
echo "NSS_DISABLE_PCLMUL=${NSS_DISABLE_PCLMUL}"
|
||||
echo "NSS_DISABLE_AVX=${NSS_DISABLE_AVX}"
|
||||
echo
|
||||
echo "Tests summary:"
|
||||
echo "--------------"
|
||||
|
Loading…
Reference in New Issue
Block a user