Bug 1488622 - Update NSS to 704d253fa016, UPGRADE_NSS_RELEASE, r=me
authorMartin Thomson <martin.thomson@gmail.com>
Tue, 16 Oct 2018 15:00:24 +1100
changeset 500050 d327a2dc9cba31f1c446bc2b99627057040fbfc1
parent 500049 52a35a1526e787da657af59fb35bb5c53594744a
child 500051 0522e105ea10e64fcd421dd082e0ba1cd02dfae1
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs1488622
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1488622 - Update NSS to 704d253fa016, UPGRADE_NSS_RELEASE, r=me MozReview-Commit-ID: JVXe36Pq0We
security/nss/TAG-INFO
security/nss/automation/taskcluster/graph/src/extend.js
security/nss/automation/taskcluster/windows/build.sh
security/nss/automation/taskcluster/windows/build_gyp.sh
security/nss/automation/taskcluster/windows/setup.sh
security/nss/automation/taskcluster/windows/setup32.sh
security/nss/automation/taskcluster/windows/setup64.sh
security/nss/build.sh
security/nss/coreconf/coreconf.dep
security/nss/coreconf/fuzz.sh
security/nss/coreconf/msvc.sh
security/nss/coreconf/nspr.sh
security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc
security/nss/gtests/ssl_gtest/tls_esni_unittest.cc
security/nss/help.txt
security/nss/lib/nss/nss.h
security/nss/lib/softoken/softkver.h
security/nss/lib/ssl/ssl3con.c
security/nss/lib/ssl/sslnonce.c
security/nss/lib/ssl/tls13con.c
security/nss/lib/util/nssutil.h
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-dc4500650617
+704d253fa016
--- a/security/nss/automation/taskcluster/graph/src/extend.js
+++ b/security/nss/automation/taskcluster/graph/src/extend.js
@@ -147,23 +147,23 @@ queue.map(task => {
 });
 
 /*****************************************************************************/
 
 export default async function main() {
   await scheduleLinux("Linux 32 (opt)", {
     platform: "linux32",
     image: LINUX_IMAGE
-  }, "-m32 --opt");
+  }, "-t ia32 --opt");
 
   await scheduleLinux("Linux 32 (debug)", {
     platform: "linux32",
     collection: "debug",
     image: LINUX_IMAGE
-  }, "-m32");
+  }, "-t ia32");
 
   await scheduleLinux("Linux 64 (opt)", {
     platform: "linux64",
     image: LINUX_IMAGE
   }, "--opt");
 
   await scheduleLinux("Linux 64 (debug)", {
     platform: "linux64",
@@ -243,22 +243,22 @@ export default async function main() {
 
   await scheduleWindows("Windows 2012 64 (debug)", {
     platform: "windows2012-64",
     collection: "debug"
   }, "build_gyp.sh");
 
   await scheduleWindows("Windows 2012 32 (opt)", {
     platform: "windows2012-32",
-  }, "build_gyp.sh --opt -m32");
+  }, "build_gyp.sh --opt -t ia32");
 
   await scheduleWindows("Windows 2012 32 (debug)", {
     platform: "windows2012-32",
     collection: "debug"
-  }, "build_gyp.sh -m32");
+  }, "build_gyp.sh -t ia32");
 
   await scheduleFuzzing();
   await scheduleFuzzing32();
 
   await scheduleTools();
 
   let aarch64_base = {
     image: "franziskus/nss-aarch64-ci",
@@ -674,17 +674,17 @@ async function scheduleFuzzing32() {
   };
 
   // Build base definition.
   let build_base = merge(base, {
     command: [
       "/bin/bash",
       "-c",
       "bin/checkout.sh && " +
-      "nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz -m32"
+      "nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz -t ia32"
     ],
     artifacts: {
       public: {
         expires: 24 * 7,
         type: "directory",
         path: "/home/worker/artifacts"
       }
     },
@@ -701,17 +701,17 @@ async function scheduleFuzzing32() {
   let task_build_tls = queue.scheduleTask(merge(build_base, {
     name: "Linux 32 (debug, TLS fuzz)",
     symbol: "B",
     group: "TLS",
     command: [
       "/bin/bash",
       "-c",
       "bin/checkout.sh && " +
-      "nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz=tls -m32"
+      "nss/automation/taskcluster/scripts/build_gyp.sh -g -v --fuzz=tls -t ia32"
     ],
   }));
 
   // Schedule tests.
   queue.scheduleTask(merge(base, {
     parent: task_build_tls,
     name: "Gtests",
     command: [
@@ -1100,17 +1100,17 @@ async function scheduleTools() {
         expires: 24 * 7,
         type: "directory",
         path: "/home/worker/artifacts"
       }
     },
     command: [
       "/bin/bash",
       "-c",
-      "bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh --disable-tests --emit-llvm -m32"
+      "bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh --disable-tests --emit-llvm -t ia32"
     ]
   }));
 
   queue.scheduleTask(merge(base, {
     parent: task_saw,
     symbol: "bmul",
     group: "SAW",
     name: "bmul.saw",
--- a/security/nss/automation/taskcluster/windows/build.sh
+++ b/security/nss/automation/taskcluster/windows/build.sh
@@ -1,18 +1,18 @@
 #!/usr/bin/env bash
 
 set -v -e -x
 
-# Set up the toolchain.
-if [ "$USE_64" = 1 ]; then
-  source $(dirname $0)/setup64.sh
+if [[ "$USE_64" == 1 ]]; then
+    m=x64
 else
-  source $(dirname $0)/setup32.sh
+    m=x86
 fi
+source "$(dirname "$0")/setup.sh"
 
 # Clone NSPR.
 hg_clone https://hg.mozilla.org/projects/nspr nspr default
 
 # Build.
 make -C nss nss_build_all
 
 # Package.
--- a/security/nss/automation/taskcluster/windows/build_gyp.sh
+++ b/security/nss/automation/taskcluster/windows/build_gyp.sh
@@ -1,34 +1,38 @@
 #!/usr/bin/env bash
 
 set -v -e -x
 
-# Set up the toolchain.
-if [[ "$@" == *"-m32"* ]]; then
-  source $(dirname $0)/setup32.sh
-else
-  source $(dirname $0)/setup64.sh
-fi
+# Parse for the -t option.
+m=x64
+for i in "$@"; do
+    case "$i" in
+        -t|--target) m= ;;
+        --target=*) m="${i#*=}" ;;
+        *) [[ -z "$m" ]] && m="$i" ;;
+    esac
+done
+[[ "$m" == "ia32" ]] && m=x86
+source "$(dirname "$0")/setup.sh"
 
 # Install GYP.
-cd gyp
+pushd gyp
 python -m virtualenv test-env
 test-env/Scripts/python setup.py install
 test-env/Scripts/python -m pip install --upgrade pip
 test-env/Scripts/pip install --upgrade setuptools
-cd ..
-
-export GYP_MSVS_OVERRIDE_PATH="${VSPATH}"
-export GYP_MSVS_VERSION="2015"
-export GYP="${PWD}/gyp/test-env/Scripts/gyp"
-
 # Fool GYP.
 touch "${VSPATH}/VC/vcvarsall.bat"
+export GYP_MSVS_OVERRIDE_PATH="${VSPATH}"
+export GYP_MSVS_VERSION=2015
+popd
+
+export PATH="${PATH}:${PWD}/ninja/bin:${PWD}/gyp/test-env/Scripts"
 
 # Clone NSPR.
 hg_clone https://hg.mozilla.org/projects/nspr nspr default
 
 # Build with gyp.
-GYP=${GYP} ./nss/build.sh -g -v "$@"
+./nss/build.sh -g -v "$@"
 
 # Package.
 7z a public/build/dist.7z dist
--- a/security/nss/automation/taskcluster/windows/setup.sh
+++ b/security/nss/automation/taskcluster/windows/setup.sh
@@ -1,26 +1,56 @@
 #!/usr/bin/env bash
 
 set -v -e -x
 
-export VSPATH="$(pwd)/vs2017_15.4.2"
-export NINJA_PATH="$(pwd)/ninja/bin"
-
-export WINDOWSSDKDIR="${VSPATH}/SDK"
-export VS90COMNTOOLS="${VSPATH}/VC"
-export INCLUDE="${VSPATH}/VC/include:${VSPATH}/SDK/Include/10.0.15063.0/ucrt:${VSPATH}/SDK/Include/10.0.15063.0/shared:${VSPATH}/SDK/Include/10.0.15063.0/um"
-
 # Usage: hg_clone repo dir [revision=@]
 hg_clone() {
     repo=$1
     dir=$2
     rev=${3:-@}
     for i in 0 2 5; do
         sleep $i
         hg clone -r "$rev" "$repo" "$dir" && return
         rm -rf "$dir"
     done
     exit 1
 }
 
-hg_clone https://hg.mozilla.org/build/tools tools default
-tools/scripts/tooltool/tooltool_wrapper.sh $(dirname $0)/releng.manifest https://tooltool.mozilla-releng.net/ non-existant-file.sh /c/mozilla-build/python/python.exe /c/builds/tooltool.py --authentication-file /c/builds/relengapi.tok -c /c/builds/tooltool_cache
+hg_clone https://hg.mozilla.org/build/tools tools b8d7c263dfc3
+tools/scripts/tooltool/tooltool_wrapper.sh \
+    $(dirname $0)/releng.manifest https://tooltool.mozilla-releng.net/ \
+    non-existant-file.sh /c/mozilla-build/python/python.exe \
+    /c/builds/tooltool.py --authentication-file /c/builds/relengapi.tok \
+    -c /c/builds/tooltool_cache
+
+# This needs $m to be set.
+[[ -n "$m" ]]
+
+# Setup MSVC paths.
+export VSPATH="${PWD}/vs2017_15.4.2"
+UCRTVersion="10.0.15063.0"
+
+export WINDOWSSDKDIR="${VSPATH}/SDK"
+export VS90COMNTOOLS="${VSPATH}/VC"
+export WIN32_REDIST_DIR="${VSPATH}/VC/redist/${m}/Microsoft.VC141.CRT"
+export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/${m}"
+
+if [ "$m" == "x86" ]; then
+    PATH="${PATH}:${VSPATH}/VC/bin/Hostx64/x86"
+    PATH="${PATH}:${VSPATH}/VC/bin/Hostx64/x64"
+fi
+PATH="${PATH}:${VSPATH}/VC/bin/Host${m}/${m}"
+PATH="${PATH}:${WIN32_REDIST_DIR}"
+PATH="${PATH}:${WIN_UCRT_REDIST_DIR}"
+PATH="${PATH}:${VSPATH}/SDK/bin/${UCRTVersion}/x64"
+export PATH
+
+LIB="${LIB}:${VSPATH}/VC/lib/${m}"
+LIB="${LIB}:${VSPATH}/SDK/lib/${UCRTVersion}/ucrt/${m}"
+LIB="${LIB}:${VSPATH}/SDK/lib/${UCRTVersion}/um/${m}"
+export LIB
+
+INCLUDE="${INCLUDE}:${VSPATH}/VC/include"
+INCLUDE="${INCLUDE}:${VSPATH}/SDK/Include/${UCRTVersion}/ucrt"
+INCLUDE="${INCLUDE}:${VSPATH}/SDK/Include/${UCRTVersion}/shared"
+INCLUDE="${INCLUDE}:${VSPATH}/SDK/Include/${UCRTVersion}/um"
+export INCLUDE
deleted file mode 100644
--- a/security/nss/automation/taskcluster/windows/setup32.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-set -v -e -x
-
-source $(dirname $0)/setup.sh
-
-export WIN32_REDIST_DIR="${VSPATH}/VC/redist/x86/Microsoft.VC141.CRT"
-export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x86"
-export PATH="${NINJA_PATH}:${VSPATH}/VC/bin/Hostx64/x86:${VSPATH}/VC/bin/Hostx64/x64:${VSPATH}/VC/Hostx86/x86:${VSPATH}/SDK/bin/10.0.15063.0/x64:${VSPATH}/VC/redist/x86/Microsoft.VC141.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x86:${PATH}"
-export LIB="${VSPATH}/VC/lib/x86:${VSPATH}/SDK/lib/10.0.15063.0/ucrt/x86:${VSPATH}/SDK/lib/10.0.15063.0/um/x86"
deleted file mode 100644
--- a/security/nss/automation/taskcluster/windows/setup64.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-set -v -e -x
-
-source $(dirname $0)/setup.sh
-
-export WIN32_REDIST_DIR="${VSPATH}/VC/redist/x64/Microsoft.VC141.CRT"
-export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x64"
-export PATH="${NINJA_PATH}:${VSPATH}/VC/bin/Hostx64/x64:${VSPATH}/VC/bin/Hostx86/x86:${VSPATH}/SDK/bin/10.0.15063.0/x64:${VSPATH}/VC/redist/x64/Microsoft.VC141.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${PATH}"
-export LIB="${VSPATH}/VC/lib/x64:${VSPATH}/SDK/lib/10.0.15063.0/ucrt/x64:${VSPATH}/SDK/lib/10.0.15063.0/um/x64"
--- a/security/nss/build.sh
+++ b/security/nss/build.sh
@@ -45,86 +45,96 @@ clean=0
 rebuild_gyp=0
 rebuild_nspr=0
 target=Debug
 verbose=0
 fuzz=0
 fuzz_tls=0
 fuzz_oss=0
 no_local_nspr=0
-armhf=0
 
 gyp_params=(--depth="$cwd" --generator-output=".")
-nspr_params=()
 ninja_params=()
 
-# try to guess sensible defaults
-arch=$(python "$cwd"/coreconf/detect_host_arch.py)
-if [ "$arch" = "x64" -o "$arch" = "aarch64" ]; then
-    build_64=1
-elif [ "$arch" = "arm" ]; then
-    armhf=1
+# Assume that the target architecture is the same as the host by default.
+host_arch=$(python "$cwd"/coreconf/detect_host_arch.py)
+target_arch=$host_arch
+
+# Assume that MSVC is wanted if this is running on windows.
+platform=$(uname -s)
+if [ "${platform%-*}" = "MINGW32_NT" -o "${platform%-*}" = "MINGW64_NT" ]; then
+    msvc=1
 fi
 
-# parse command line arguments
+# Parse command line arguments.
 while [ $# -gt 0 ]; do
-    case $1 in
+    case "$1" in
         -c) clean=1 ;;
         -cc) clean_only=1 ;;
-        --gyp|-g) rebuild_gyp=1 ;;
-        --nspr) nspr_clean; rebuild_nspr=1 ;;
+        -v) ninja_params+=(-v); verbose=1 ;;
         -j) ninja_params+=(-j "$2"); shift ;;
-        -v) ninja_params+=(-v); verbose=1 ;;
-        --test) gyp_params+=(-Dtest_build=1) ;;
-        --clang) export CC=clang; export CCC=clang++; export CXX=clang++ ;;
-        --gcc) export CC=gcc; export CCC=g++; export CXX=g++ ;;
-        --fuzz) fuzz=1 ;;
-        --fuzz=oss) fuzz=1; fuzz_oss=1 ;;
-        --fuzz=tls) fuzz=1; fuzz_tls=1 ;;
+        --gyp|-g) rebuild_gyp=1 ;;
+        --opt|-o) opt_build=1 ;;
+        -m32|--m32) target_arch=ia32; echo 'Warning: use -t instead of -m32' 1>&2 ;;
+        -t|--target) target_arch="$2"; shift ;;
+        --target=*) target_arch="${1#*=}" ;;
+        --clang) export CC=clang; export CCC=clang++; export CXX=clang++; msvc=0 ;;
+        --gcc) export CC=gcc; export CCC=g++; export CXX=g++; msvc=0 ;;
+        --msvc) msvc=1 ;;
         --scan-build) enable_scanbuild  ;;
         --scan-build=?*) enable_scanbuild "${1#*=}" ;;
-        --opt|-o) opt_build=1 ;;
-        -m32|--m32) build_64=0 ;;
+        --disable-tests) gyp_params+=(-Ddisable_tests=1) ;;
+        --pprof) gyp_params+=(-Duse_pprof=1) ;;
         --asan) enable_sanitizer asan ;;
         --msan) enable_sanitizer msan ;;
         --ubsan) enable_ubsan ;;
         --ubsan=?*) enable_ubsan "${1#*=}" ;;
+        --fuzz) fuzz=1 ;;
+        --fuzz=oss) fuzz=1; fuzz_oss=1 ;;
+        --fuzz=tls) fuzz=1; fuzz_tls=1 ;;
         --sancov) enable_sancov ;;
         --sancov=?*) enable_sancov "${1#*=}" ;;
-        --pprof) gyp_params+=(-Duse_pprof=1) ;;
+        --emit-llvm) gyp_params+=(-Demit_llvm=1 -Dsign_libs=0) ;;
+        --no-zdefs) gyp_params+=(-Dno_zdefs=1) ;;
+        --test) gyp_params+=(-Dtest_build=1) ;;
         --ct-verif) gyp_params+=(-Dct_verif=1) ;;
-        --emit-llvm) gyp_params+=(-Demit_llvm=1 -Dsign_libs=0) ;;
-        --disable-tests) gyp_params+=(-Ddisable_tests=1) ;;
-        --no-zdefs) gyp_params+=(-Dno_zdefs=1) ;;
-        --system-sqlite) gyp_params+=(-Duse_system_sqlite=1) ;;
+        --nspr) nspr_clean; rebuild_nspr=1 ;;
         --with-nspr=?*) set_nspr_path "${1#*=}"; no_local_nspr=1 ;;
         --system-nspr) set_nspr_path "/usr/include/nspr/:"; no_local_nspr=1 ;;
+        --system-sqlite) gyp_params+=(-Duse_system_sqlite=1) ;;
+        --enable-fips) gyp_params+=(-Ddisable_fips=0) ;;
         --enable-libpkix) gyp_params+=(-Ddisable_libpkix=0) ;;
-        --enable-fips) gyp_params+=(-Ddisable_fips=0) ;;
         --mozpkix-only) gyp_params+=(-Dmozpkix_only=1 -Ddisable_tests=1 -Dsign_libs=0) ;;
         *) show_help; exit 2 ;;
     esac
     shift
 done
 
+# Set the target architecture and build type.
+gyp_params+=(-Dtarget_arch="$target_arch")
 if [ "$opt_build" = 1 ]; then
     target=Release
 else
     target=Debug
 fi
-if [ "$build_64" = 1 ]; then
-    nspr_params+=(--enable-64bit)
-elif [ ! "$armhf" = 1 ]; then
-    gyp_params+=(-Dtarget_arch=ia32)
-fi
+
+# Do special setup.
 if [ "$fuzz" = 1 ]; then
     source "$cwd"/coreconf/fuzz.sh
 fi
+nspr_set_flags $sanitizer_flags
+if [ ! -z "$sanitizer_flags" ]; then
+    gyp_params+=(-Dsanitizer_flags="$sanitizer_flags")
+fi
 
-# set paths
+if [ "$msvc" = 1 ]; then
+    source "$cwd"/coreconf/msvc.sh
+fi
+
+# Setup build paths.
 target_dir="$cwd"/out/$target
 mkdir -p "$target_dir"
 dist_dir="$cwd"/../dist
 dist_dir=$(mkdir -p "$dist_dir"; cd "$dist_dir"; pwd -P)
 gyp_params+=(-Dnss_dist_dir="$dist_dir")
 
 # -c = clean first
 if [ "$clean" = 1 -o "$clean_only" = 1 ]; then
@@ -145,61 +155,58 @@ fi
 check_config()
 {
     local newconf="$1".new oldconf="$1"
     shift
     mkdir -p $(dirname "$newconf")
     echo CC="$CC" >"$newconf"
     echo CCC="$CCC" >>"$newconf"
     echo CXX="$CXX" >>"$newconf"
+    echo target_arch="$target_arch" >>"$newconf"
     for i in "$@"; do echo $i; done | sort >>"$newconf"
 
     # Note: The following diff fails if $oldconf isn't there as well, which
     # happens if we don't have a previous successful build.
     ! diff -q "$newconf" "$oldconf" >/dev/null 2>&1
 }
 
 gyp_config="$cwd"/out/gyp_config
 nspr_config="$cwd"/out/$target/nspr_config
 
+# Now check what needs to be rebuilt.
 # If we don't have a build directory make sure that we rebuild.
 if [ ! -d "$target_dir" ]; then
     rebuild_nspr=1
     rebuild_gyp=1
 elif [ ! -d "$dist_dir"/$target ]; then
     rebuild_nspr=1
 fi
 
-# Update NSPR ${C,CXX,LD}FLAGS.
-nspr_set_flags $sanitizer_flags
-
-if check_config "$nspr_config" "${nspr_params[@]}" \
+if check_config "$nspr_config" \
                  nspr_cflags="$nspr_cflags" \
                  nspr_cxxflags="$nspr_cxxflags" \
                  nspr_ldflags="$nspr_ldflags"; then
     rebuild_nspr=1
 fi
 
-# Forward sanitizer flags.
-if [ ! -z "$sanitizer_flags" ]; then
-    gyp_params+=(-Dsanitizer_flags="$sanitizer_flags")
-fi
-
 if check_config "$gyp_config" "${gyp_params[@]}"; then
     rebuild_gyp=1
 fi
 
-# save the chosen target
+# Save the chosen target.
 mkdir -p "$dist_dir"
 echo $target > "$dist_dir"/latest
 
+# Build.
+# NSPR.
 if [[ "$rebuild_nspr" = 1 && "$no_local_nspr" = 0 ]]; then
-    nspr_build "${nspr_params[@]}"
+    nspr_build
     mv -f "$nspr_config".new "$nspr_config"
 fi
+# gyp.
 if [ "$rebuild_gyp" = 1 ]; then
     if ! hash ${GYP} 2> /dev/null; then
         echo "Please install gyp" 1>&2
         exit 1
     fi
     # These extra arguments aren't used in determining whether to rebuild.
     obj_dir="$dist_dir"/$target
     gyp_params+=(-Dnss_dist_obj_dir=$obj_dir)
@@ -207,18 +214,18 @@ if [ "$rebuild_gyp" = 1 ]; then
         set_nspr_path "$obj_dir/include/nspr:$obj_dir/lib"
     fi
 
     run_verbose run_scanbuild ${GYP} -f ninja "${gyp_params[@]}" "$cwd"/nss.gyp
 
     mv -f "$gyp_config".new "$gyp_config"
 fi
 
-# Run ninja.
-if hash ninja 2>/dev/null; then
+# ninja.
+if hash ninja-build 2>/dev/null; then
+    ninja=ninja-build
+elif hash ninja 2>/dev/null; then
     ninja=ninja
-elif hash ninja-build 2>/dev/null; then
-    ninja=ninja-build
 else
     echo "Please install ninja" 1>&2
     exit 1
 fi
 run_scanbuild $ninja -C "$target_dir" "${ninja_params[@]}"
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,8 +5,9 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
+
--- a/security/nss/coreconf/fuzz.sh
+++ b/security/nss/coreconf/fuzz.sh
@@ -1,17 +1,16 @@
 #!/usr/bin/env bash
 # This file is used by build.sh to setup fuzzing.
 
 set +e
 
 # Default to clang if CC is not set.
 if [ -z "$CC" ]; then
-    command -v clang &> /dev/null 2>&1
-    if [ $? != 0 ]; then
+    if ! command -v clang &> /dev/null 2>&1; then
         echo "Fuzzing requires clang!"
         exit 1
     fi
     export CC=clang
     export CCC=clang++
     export CXX=clang++
 fi
 
@@ -19,18 +18,18 @@ gyp_params+=(-Dtest_build=1 -Dfuzz=1 -Ds
 
 # Add debug symbols even for opt builds.
 nspr_params+=(--enable-debug-symbols)
 
 if [ "$fuzz_oss" = 1 ]; then
   gyp_params+=(-Dno_zdefs=1 -Dfuzz_oss=1)
 else
   enable_sanitizer asan
-  # Ubsan doesn't build on 32-bit at the moment. Disable it.
-  if [ "$build_64" = 1 ]; then
+  # Ubsan only builds on x64 for the moment.
+  if [ "$target_arch" = "x64" ]; then
     enable_ubsan
   fi
   enable_sancov
 fi
 
 if [ "$fuzz_tls" = 1 ]; then
   gyp_params+=(-Dfuzz_tls=1)
 fi
new file mode 100644
--- /dev/null
+++ b/security/nss/coreconf/msvc.sh
@@ -0,0 +1,106 @@
+#!/bin/bash
+# This configures the environment for running MSVC.  It uses vswhere, the
+# registry, and a little knowledge of how MSVC is laid out.
+
+if ! hash vswhere 2>/dev/null; then
+    echo "Can't find vswhere on the path, aborting" 1>&2
+    exit 1
+fi
+
+if ! hash reg 2>/dev/null; then
+    echo "Can't find reg on the path, aborting" 1>&2
+    exit 1
+fi
+
+# Turn a unix-y path into a windows one.
+fixpath() {
+    if hash cygpath 2>/dev/null; then
+        cygpath --unix "$1"
+    else # haxx
+        echo "$1" | sed -e 's,\\,/,g;s,^\(.\):,/\L\1,;s,/$,,'
+    fi
+}
+
+# Query the registry.  This takes $1 and tags that on the end of several
+# different paths, looking for a value called $2 at that location.
+# e.g.,
+#   regquery Microsoft\Microsoft SDKs\Windows\v10.0 ProductVersion
+# looks for a REG_SZ value called ProductVersion at
+#   HKLM\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0
+#   HKLU\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0
+#   etc...
+regquery() {
+    search=("HKLM\\SOFTWARE\\Wow6432Node" \
+            "HKCU\\SOFTWARE\\Wow6432Node" \
+            "HKLM\\SOFTWARE" \
+            "HKCU\\SOFTWARE")
+    for i in "${search[@]}"; do
+        r=$(reg query "${i}\\${1}" -v "$2" | sed -e 's/ *'"$2"' *REG_SZ *//;t;d')
+        if [ -n "$r" ]; then
+            echo "$r"
+            return 0
+        fi
+    done
+    return 1
+}
+
+VSCOMPONENT=Microsoft.VisualStudio.Component.VC.Tools.x86.x64
+vsinstall=$(vswhere -latest -requires "$VSCOMPONENT" -property installationPath)
+
+# Attempt to setup paths if vswhere returns something and VSPATH isn't set.
+# Otherwise, assume that the env is setup.
+if [[ -n "$vsinstall" && -z "$VSPATH" ]]; then
+
+    case "$target_arch" in
+        ia32) m=x86 ;;
+        x64) m="$target_arch" ;;
+        *)
+            echo "No support for target '$target_arch' with MSVC." 1>&2
+            exit 1
+    esac
+
+    export VSPATH=$(fixpath "$vsinstall")
+    export WINDOWSSDKDIR="${VSPATH}/SDK"
+    export VCINSTALLDIR="${VSPATH}/VC"
+
+    CRTREG="Microsoft\\Microsoft SDKs\\Windows\\v10.0"
+    UniversalCRTSdkDir=$(regquery "$CRTREG" InstallationFolder)
+    UniversalCRTSdkDir=$(fixpath "$UniversalCRTSdkDir")
+    UCRTVersion=$(regquery "$CRTREG" ProductVersion)
+    UCRTVersion=$(cd "${UniversalCRTSdkDir}/include"; ls -d "${UCRTVersion}"* | tail -1)
+
+    VCVER=$(cat "${VCINSTALLDIR}/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt")
+    REDISTVER=$(cat "${VCINSTALLDIR}/Auxiliary/Build/Microsoft.VCRedistVersion.default.txt")
+    export WIN32_REDIST_DIR="${VCINSTALLDIR}/Redist/MSVC/${REDISTVER}/${m}/Microsoft.VC141.CRT"
+    export WIN_UCRT_REDIST_DIR="${UniversalCRTSdkDir}/Redist/ucrt/DLLs/${m}"
+
+    if [ "$m" == "x86" ]; then
+        PATH="${PATH}:${VCINSTALLDIR}/Tools/MSVC/${VCVER}/bin/Hostx64/x64"
+        PATH="${PATH}:${VCINSTALLDIR}/Tools/MSVC/${VCVER}/bin/Hostx64/x86"
+    fi
+    PATH="${PATH}:${VCINSTALLDIR}/Tools/MSVC/${VCVER}/bin/Host${m}/${m}"
+    PATH="${PATH}:${UniversalCRTSdkDir}/bin/${UCRTVersion}/${m}"
+    PATH="${PATH}:${WIN32_REDIST_DIR}"
+    export PATH
+
+    INCLUDE="${VCINSTALLDIR}/Tools/MSVC/${VCVER}/ATLMFC/include"
+    INCLUDE="${INCLUDE}:${VCINSTALLDIR}/Tools/MSVC/${VCVER}/include"
+    INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/ucrt"
+    INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/shared"
+    INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/um"
+    INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/winrt"
+    INCLUDE="${INCLUDE}:${UniversalCRTSdkDir}/include/${UCRTVersion}/cppwinrt"
+    export INCLUDE
+
+    LIB="${VCINSTALLDIR}/lib/${m}"
+    LIB="${VCINSTALLDIR}/Tools/MSVC/${VCVER}/lib/${m}"
+    LIB="${LIB}:${UniversalCRTSdkDir}/lib/${UCRTVersion}/ucrt/${m}"
+    LIB="${LIB}:${UniversalCRTSdkDir}/lib/${UCRTVersion}/um/${m}"
+    export LIB
+
+    export GYP_MSVS_OVERRIDE_PATH="${VSPATH}"
+    export GYP_MSVS_VERSION=$(vswhere -latest -requires "$VSCOMPONENT" -property catalog_productLineVersion)
+else
+    echo Assuming env setup is already done.
+    echo VSPATH=$VSPATH
+fi
--- a/security/nss/coreconf/nspr.sh
+++ b/security/nss/coreconf/nspr.sh
@@ -27,16 +27,19 @@ nspr_build()
     mkdir -p "$nspr_dir"
 
     # These NSPR options are directory-specific, so they don't need to be
     # included in nspr_opt and changing them doesn't force a rebuild of NSPR.
     extra_params=(--prefix="$dist_dir"/$target)
     if [ "$opt_build" = 1 ]; then
         extra_params+=(--disable-debug --enable-optimize)
     fi
+    if [ "$target_arch" = "x64" ]; then
+        extra_params+=(--enable-64bit)
+    fi
 
     echo "NSPR [1/3] configure ..."
     pushd "$nspr_dir" >/dev/null
     CFLAGS="$nspr_cflags" CXXFLAGS="$nspr_cxxflags" \
           LDFLAGS="$nspr_ldflags" CC="$CC" CXX="$CCC" \
           run_verbose ../configure "${extra_params[@]}" "$@"
     popd >/dev/null
     echo "NSPR [2/3] make ..."
--- a/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc
@@ -941,16 +941,46 @@ TEST_F(TlsConnectDatagram13, SendSession
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
   Connect();
   EXPECT_EQ(SECFailure, SSL_SendSessionTicket(server_->ssl_fd(), NULL, 0))
       << "no extra tickets in DTLS until we have Ack support";
   EXPECT_EQ(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION, PORT_GetError());
 }
 
+TEST_F(TlsConnectStreamTls13, ExternalResumptionUseSecondTicket) {
+  ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
+  ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
+
+  struct ResumptionTicketState {
+    std::vector<uint8_t> ticket;
+    size_t invoked = 0;
+  } ticket_state;
+  auto cb = [](PRFileDesc* fd, const PRUint8* ticket, unsigned int ticket_len,
+               void* arg) -> SECStatus {
+    auto state = reinterpret_cast<ResumptionTicketState*>(arg);
+    state->ticket.assign(ticket, ticket + ticket_len);
+    state->invoked++;
+    return SECSuccess;
+  };
+  SSL_SetResumptionTokenCallback(client_->ssl_fd(), cb, &ticket_state);
+
+  Connect();
+  EXPECT_EQ(SECSuccess, SSL_SendSessionTicket(server_->ssl_fd(), nullptr, 0));
+  SendReceive();
+  EXPECT_EQ(2U, ticket_state.invoked);
+
+  Reset();
+  ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
+  client_->SetResumptionToken(ticket_state.ticket);
+  ExpectResumption(RESUME_TICKET);
+  Connect();
+  SendReceive();
+}
+
 TEST_F(TlsConnectTest, TestTls13ResumptionDowngrade) {
   ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
   ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
   Connect();
 
   SendReceive();  // Need to read so that we absorb the session tickets.
   CheckKeys();
 
--- a/security/nss/gtests/ssl_gtest/tls_esni_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/tls_esni_unittest.cc
@@ -445,9 +445,26 @@ TEST_P(TlsConnectTls13, ConnectBogusEsni
   const uint8_t bogusNonceBuf[16] = {0};
   DataBuffer bogusNonce(bogusNonceBuf, sizeof(bogusNonceBuf));
   auto filter = MakeTlsFilter<TlsExtensionReplacer>(
       server_, ssl_tls13_encrypted_sni_xtn, bogusNonce);
   filter->EnableDecryption();
   ConnectExpectAlert(client_, illegal_parameter);
   client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_ESNI_EXTENSION);
 }
+
+// ESNI is a commitment to doing TLS 1.3 or above.
+// The TLS 1.2 server ignores ESNI and processes the dummy SNI.
+// The client then aborts when it sees the server did TLS 1.2.
+TEST_P(TlsConnectTls13, EsniButTLS12Server) {
+  EnsureTlsSetup();
+  SetupEsni(client_, server_);
+  client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
+                           SSL_LIBRARY_VERSION_TLS_1_3);
+  server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
+                           SSL_LIBRARY_VERSION_TLS_1_2);
+  ConnectExpectAlert(client_, kTlsAlertProtocolVersion);
+  client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_VERSION);
+  server_->CheckErrorCode(SSL_ERROR_PROTOCOL_VERSION_ALERT);
+  ASSERT_FALSE(SSLInt_ExtensionNegotiated(server_->ssl_fd(),
+                                          ssl_tls13_encrypted_sni_xtn));
 }
+}
--- a/security/nss/help.txt
+++ b/security/nss/help.txt
@@ -1,52 +1,53 @@
-Usage: build.sh [-hcv] [-cc] [-j <n>] [--nspr] [--gyp|-g] [--opt|-o] [-m32]
-                [--test] [--pprof] [--scan-build[=output]] [--ct-verif]
-                [--asan] [--ubsan] [--msan] [--sancov[=edge|bb|func|...]]
-                [--disable-tests] [--fuzz[=tls|oss]] [--system-sqlite]
-                [--no-zdefs] [--with-nspr] [--system-nspr] [--enable-libpkix]
-                [--enable-fips] [--mozpkix-only]
+Usage: build.sh [-h] [-c|-cc] [-v] [-j <n>] [--gyp|-g] [--opt|-o]
+                [-t <x64|x86|...>|--target=<x64|x86|...>]
+                [--clang|--gcc|--msvc] [--scan-build[=dir]] [--disable-tests]
+                [--pprof] [--asan] [--msan] [--ubsan[=bool,shift,...]
+                [--fuzz[=tls|oss]] [--sancov[=edge|bb|func|...]]
+                [--emit-llvm] [--no-zdefs] [--test] [--ct-verif]
+                [--nspr|--with-nspr=<include>:<lib>|--system-nspr]
+                [--system-sqlite] [--enable-fips] [--enable-libpkix]
+                [--mozpkix-only]
 
 This script builds NSS with gyp and ninja.
 
-This build system is still under development.  It does not yet support all
-the features or platforms that NSS supports.
-
 NSS build tool options:
 
     -h               display this help and exit
     -c               clean before build
     -cc              clean without building
     -v               verbose build
     -j <n>           run at most <n> concurrent jobs
-    --nspr           force a rebuild of NSPR
     --gyp|-g         force a rerun of gyp
     --opt|-o         do an opt build
-    -m32             do a 32-bit build on a 64-bit system
+    --target|-t      specify target architecture (e.g., x86, x64, aarch64)
     --clang          build with clang and clang++
     --gcc            build with gcc and g++
-    --test           ignore map files and export everything we have
+    --msvc           build with MSVC
+    --scan-build     run the build with scan-build
+                     --scan-build=<dir> sets the output path for scan-build
+    --disable-tests  don't build tests and corresponding cmdline utils
+    --pprof          build with gperftool support
+    --asan           enable address sanitizer
+    --msan           enable memory sanitizer
+    --ubsan          enable undefined behavior sanitizer
+                     --ubsan=bool,shift,... sets specific UB sanitizers
     --fuzz           build fuzzing targets (this always enables test builds)
                      --fuzz=tls to enable TLS fuzzing mode
                      --fuzz=oss to build for OSS-Fuzz
-    --pprof          build with gperftool support
-    --ct-verif       build with valgrind for ct-verif
-    --scan-build     run the build with scan-build (scan-build has to be in the path)
-                     --scan-build=/out/path sets the output path for scan-build
-    --asan           do an asan build
-    --ubsan          do an ubsan build
-                     --ubsan=bool,shift,... sets specific UB sanitizers
-    --msan           do an msan build
     --sancov         do sanitize coverage builds
                      --sancov=func sets coverage to function level for example
     --emit-llvm      emit LLVM bitcode while building
                      (requires the gold linker, use clang-3.8 for SAW)
-    --disable-tests  don't build tests and corresponding cmdline utils
+    --no-zdefs       don't set -Wl,-z,defs
+    --test           ignore map files and export everything we have
+    --ct-verif       build with valgrind for ct-verif
+    --nspr           force a rebuild of NSPR
+    --with-nspr      use the NSPR build at the given locations
+                     --with-nspr=<include>:<lib> sets include and lib paths
+    --system-nspr    attempt to use system nspr
+                     shorthand for --with-nspr=/usr/include/nspr:
     --system-sqlite  use system sqlite
-    --no-zdefs       don't set -Wl,-z,defs
-    --with-nspr      don't build NSPR but use the one at the given location, e.g.
-                     --with-nspr=/path/to/nspr/include:/path/to/nspr/lib
-    --system-nspr    use system nspr. This requires an installation of NSPR and
-                     might not work on all systems.
-    --enable-libpkix make libpkix part of the build.
-    --enable-fips    don't disable FIPS checks.
-    --mozpkix-only   build only static mozpkix and mozpkix-test libraries.
-                     Note that support for this build option is limited.
+    --enable-fips    enable FIPS checks
+    --enable-libpkix make libpkix part of the build
+    --mozpkix-only   build only static mozpkix and mozpkix-test libraries
+                     support for this build option is limited
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -17,22 +17,22 @@
 
 /*
  * NSS's major version, minor version, patch level, build number, and whether
  * this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define NSS_VERSION "3.40" _NSS_CUSTOMIZED " Beta"
+#define NSS_VERSION "3.40" _NSS_CUSTOMIZED
 #define NSS_VMAJOR 3
 #define NSS_VMINOR 40
 #define NSS_VPATCH 0
 #define NSS_VBUILD 0
-#define NSS_BETA PR_TRUE
+#define NSS_BETA PR_FALSE
 
 #ifndef RC_INVOKED
 
 #include "seccomon.h"
 
 typedef struct NSSInitParametersStr NSSInitParameters;
 
 /*
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -12,16 +12,16 @@
 
 /*
  * Softoken's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define SOFTOKEN_VERSION "3.40" SOFTOKEN_ECC_STRING " Beta"
+#define SOFTOKEN_VERSION "3.40" SOFTOKEN_ECC_STRING
 #define SOFTOKEN_VMAJOR 3
 #define SOFTOKEN_VMINOR 40
 #define SOFTOKEN_VPATCH 0
 #define SOFTOKEN_VBUILD 0
-#define SOFTOKEN_BETA PR_TRUE
+#define SOFTOKEN_BETA PR_FALSE
 
 #endif /* _SOFTKVER_H_ */
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -6558,19 +6558,30 @@ ssl3_HandleServerHello(sslSocket *ss, PR
     if (isHelloRetry && ss->ssl3.hs.helloRetry) {
         SSL_TRC(3, ("%d: SSL3[%d]: received a second hello_retry_request",
                     SSL_GETPID(), ss->fd));
         desc = unexpected_message;
         errCode = SSL_ERROR_RX_UNEXPECTED_HELLO_RETRY_REQUEST;
         goto alert_loser;
     }
 
-    /* The server didn't pick 1.3 although we either received a
-     * HelloRetryRequest, or we prepared to send early app data. */
+    /* There are three situations in which the server must pick
+     * TLS 1.3.
+     *
+     * 1. We offered ESNI.
+     * 2. We received HRR
+     * 3. We sent early app data.
+     *
+     */
     if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
+        if (ss->xtnData.esniPrivateKey) {
+            desc = protocol_version;
+            errCode = SSL_ERROR_UNSUPPORTED_VERSION;
+            goto alert_loser;
+        }
         if (isHelloRetry || ss->ssl3.hs.helloRetry) {
             /* SSL3_SendAlert() will uncache the SID. */
             desc = illegal_parameter;
             errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
             goto alert_loser;
         }
         if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent) {
             /* SSL3_SendAlert() will uncache the SID. */
--- a/security/nss/lib/ssl/sslnonce.c
+++ b/security/nss/lib/ssl/sslnonce.c
@@ -1088,20 +1088,22 @@ ssl_CacheExternalToken(sslSocket *ss)
     if (ssl_EncodeResumptionToken(sid, &encodedToken) != SECSuccess) {
         SSL_TRC(3, ("SSL [%d]: encoding resumption token failed", ss->fd));
         return;
     }
     PORT_Assert(SSL_BUFFER_LEN(&encodedToken) > 0);
     PRINT_BUF(40, (ss, "SSL: encoded resumption token",
                    SSL_BUFFER_BASE(&encodedToken),
                    SSL_BUFFER_LEN(&encodedToken)));
-    ss->resumptionTokenCallback(ss->fd, SSL_BUFFER_BASE(&encodedToken),
-                                SSL_BUFFER_LEN(&encodedToken),
-                                ss->resumptionTokenContext);
-
+    SECStatus rv = ss->resumptionTokenCallback(
+        ss->fd, SSL_BUFFER_BASE(&encodedToken), SSL_BUFFER_LEN(&encodedToken),
+        ss->resumptionTokenContext);
+    if (rv == SECSuccess) {
+        sid->cached = in_external_cache;
+    }
     sslBuffer_Clear(&encodedToken);
 }
 
 void
 ssl_CacheSessionID(sslSocket *ss)
 {
     sslSecurityInfo *sec = &ss->sec;
     PORT_Assert(sec);
@@ -1195,27 +1197,33 @@ void
 ssl3_SetSIDSessionTicket(sslSessionID *sid,
                          /*in/out*/ NewSessionTicket *newSessionTicket)
 {
     PORT_Assert(sid);
     PORT_Assert(newSessionTicket);
     PORT_Assert(newSessionTicket->ticket.data);
     PORT_Assert(newSessionTicket->ticket.len != 0);
 
-    /* if sid->u.ssl3.lock, we are updating an existing entry that is already
-     * cached or was once cached, so we need to acquire and release the write
-     * lock. Otherwise, this is a new session that isn't shared with anything
-     * yet, so no locking is needed.
+    /* If this is in the client cache, we are updating an existing entry that is
+     * already cached or was once cached, so we need to acquire and release the
+     * write lock. Otherwise, this is a new session that isn't shared with
+     * anything yet, so no locking is needed.
      */
     if (sid->u.ssl3.lock) {
+        PORT_Assert(sid->cached == in_client_cache);
         PR_RWLock_Wlock(sid->u.ssl3.lock);
-        if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
-            SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
-                             PR_FALSE);
-        }
+    }
+    /* If this was in the client cache, then we might have to free the old
+     * ticket.  In TLS 1.3, we might get a replacement ticket if the server
+     * sends more than one ticket. */
+    if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
+        PORT_Assert(sid->cached == in_client_cache ||
+                    sid->version >= SSL_LIBRARY_VERSION_TLS_1_3);
+        SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
+                         PR_FALSE);
     }
 
     PORT_Assert(!sid->u.ssl3.locked.sessionTicket.ticket.data);
 
     /* Do a shallow copy, moving the ticket data. */
     sid->u.ssl3.locked.sessionTicket = *newSessionTicket;
     newSessionTicket->ticket.data = NULL;
     newSessionTicket->ticket.len = 0;
--- a/security/nss/lib/ssl/tls13con.c
+++ b/security/nss/lib/ssl/tls13con.c
@@ -4722,17 +4722,18 @@ tls13_HandleNewSessionTicket(sslSocket *
             return SECFailure;
         }
         PRINT_BUF(50, (ss, "Caching session ticket",
                        ticket.ticket.data,
                        ticket.ticket.len));
 
         /* Replace a previous session ticket when
          * we receive a second NewSessionTicket message. */
-        if (ss->sec.ci.sid->cached == in_client_cache) {
+        if (ss->sec.ci.sid->cached == in_client_cache ||
+            ss->sec.ci.sid->cached == in_external_cache) {
             /* Create a new session ID. */
             sslSessionID *sid = ssl3_NewSessionID(ss, PR_FALSE);
             if (!sid) {
                 return SECFailure;
             }
 
             /* Copy over the peerCert. */
             PORT_Assert(ss->sec.ci.sid->peerCert);
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -14,22 +14,22 @@
 
 /*
  * NSS utilities's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
  */
-#define NSSUTIL_VERSION "3.40 Beta"
+#define NSSUTIL_VERSION "3.40"
 #define NSSUTIL_VMAJOR 3
 #define NSSUTIL_VMINOR 40
 #define NSSUTIL_VPATCH 0
 #define NSSUTIL_VBUILD 0
-#define NSSUTIL_BETA PR_TRUE
+#define NSSUTIL_BETA PR_FALSE
 
 SEC_BEGIN_PROTOS
 
 /*
  * Returns a const string of the UTIL library version.
  */
 extern const char *NSSUTIL_GetVersion(void);