зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1334127 - land NSS dbbf303cf467, r=me
--HG-- extra : rebase_source : 0275628dd4cb24c87ce4a59c8d5e60e07a2ada20
This commit is contained in:
Родитель
2971191875
Коммит
4551817b24
|
@ -1 +1 @@
|
|||
ee21c9892907
|
||||
dbbf303cf467
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#!/bin/bash -eu
|
||||
#
|
||||
# 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/.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
# List of targets disabled for oss-fuzz.
|
||||
declare -A disabled=([pkcs8]=1)
|
||||
|
||||
# Build the library.
|
||||
CXX="$CXX -stdlib=libc++" LDFLAGS="$CFLAGS" \
|
||||
./build.sh -c -v --fuzz=oss --fuzz=tls --disable-tests
|
||||
|
||||
# Find fuzzing targets.
|
||||
for fuzzer in $(find ../dist/Debug/bin -name "nssfuzz-*" -printf "%f\n"); do
|
||||
name=${fuzzer:8}
|
||||
[ -n "${disabled[$name]:-}" ] && continue;
|
||||
|
||||
# Copy the binary.
|
||||
cp ../dist/Debug/bin/$fuzzer $OUT/$name
|
||||
|
||||
# Zip and copy the corpus, if any.
|
||||
if [ -d "$SRC/nss-corpus/$name" ]; then
|
||||
zip $OUT/${name}_seed_corpus.zip $SRC/nss-corpus/$name/*
|
||||
else
|
||||
zip $OUT/${name}_seed_corpus.zip $SRC/nss-corpus/*/*
|
||||
fi
|
||||
done
|
|
@ -15,6 +15,7 @@ apt_packages+=('ca-certificates')
|
|||
apt_packages+=('curl')
|
||||
apt_packages+=('git')
|
||||
apt_packages+=('gyp')
|
||||
apt_packages+=('libssl-dev')
|
||||
apt_packages+=('ninja-build')
|
||||
apt_packages+=('pkg-config')
|
||||
apt_packages+=('zlib1g-dev')
|
||||
|
|
|
@ -125,7 +125,6 @@ export default async function main() {
|
|||
"bin/checkout.sh && nss/automation/taskcluster/scripts/build_gyp.sh -g -v --ubsan --asan"
|
||||
],
|
||||
env: {
|
||||
ASAN_OPTIONS: "detect_odr_violation=0", // bug 1316276
|
||||
UBSAN_OPTIONS: "print_stacktrace=1",
|
||||
NSS_DISABLE_ARENA_FREE_LIST: "1",
|
||||
NSS_DISABLE_UNLOAD: "1",
|
||||
|
@ -258,6 +257,12 @@ async function scheduleLinux(name, base) {
|
|||
symbol: "noLibpkix"
|
||||
}));
|
||||
|
||||
queue.scheduleTask(merge(extra_base, {
|
||||
name: `${name} w/ modular builds`,
|
||||
env: {NSS_BUILD_MODULAR: "1"},
|
||||
symbol: "modular"
|
||||
}));
|
||||
|
||||
return queue.submit();
|
||||
}
|
||||
|
||||
|
@ -266,8 +271,7 @@ async function scheduleLinux(name, base) {
|
|||
async function scheduleFuzzing() {
|
||||
let base = {
|
||||
env: {
|
||||
// bug 1316276
|
||||
ASAN_OPTIONS: "allocator_may_return_null=1:detect_odr_violation=0",
|
||||
ASAN_OPTIONS: "allocator_may_return_null=1",
|
||||
UBSAN_OPTIONS: "print_stacktrace=1",
|
||||
NSS_DISABLE_ARENA_FREE_LIST: "1",
|
||||
NSS_DISABLE_UNLOAD: "1",
|
||||
|
@ -319,6 +323,23 @@ async function scheduleFuzzing() {
|
|||
kind: "test"
|
||||
}));
|
||||
|
||||
queue.scheduleTask(merge(base, {
|
||||
parent: task_build,
|
||||
name: "Hash",
|
||||
command: [
|
||||
"/bin/bash",
|
||||
"-c",
|
||||
"bin/checkout.sh && nss/automation/taskcluster/scripts/fuzz.sh " +
|
||||
"hash nss/fuzz/corpus/hash -max_total_time=300 -max_len=4096"
|
||||
],
|
||||
// Need a privileged docker container to remove detect_leaks=0.
|
||||
env: {
|
||||
ASAN_OPTIONS: "allocator_may_return_null=1:detect_leaks=0",
|
||||
},
|
||||
symbol: "Hash",
|
||||
kind: "test"
|
||||
}));
|
||||
|
||||
queue.scheduleTask(merge(base, {
|
||||
parent: task_build,
|
||||
name: "QuickDER",
|
||||
|
@ -326,14 +347,50 @@ async function scheduleFuzzing() {
|
|||
"/bin/bash",
|
||||
"-c",
|
||||
"bin/checkout.sh && nss/automation/taskcluster/scripts/fuzz.sh " +
|
||||
"quickder nss/fuzz/corpus/quickder -max_total_time=300"
|
||||
"quickder nss/fuzz/corpus/quickder -max_total_time=300 -max_len=10000"
|
||||
],
|
||||
// Need a privileged docker container to remove this.
|
||||
env: {ASAN_OPTIONS: "detect_leaks=0"},
|
||||
// Need a privileged docker container to remove detect_leaks=0.
|
||||
env: {
|
||||
ASAN_OPTIONS: "allocator_may_return_null=1:detect_leaks=0",
|
||||
},
|
||||
symbol: "QuickDER",
|
||||
kind: "test"
|
||||
}));
|
||||
|
||||
queue.scheduleTask(merge(base, {
|
||||
parent: task_build,
|
||||
name: "MPI",
|
||||
command: [
|
||||
"/bin/bash",
|
||||
"-c",
|
||||
"bin/checkout.sh && nss/automation/taskcluster/scripts/fuzz.sh " +
|
||||
"mpi nss/fuzz/corpus/mpi -max_total_time=300 -max_len=2048"
|
||||
],
|
||||
// Need a privileged docker container to remove detect_leaks=0.
|
||||
env: {
|
||||
ASAN_OPTIONS: "allocator_may_return_null=1:detect_leaks=0",
|
||||
},
|
||||
symbol: "MPI",
|
||||
kind: "test"
|
||||
}));
|
||||
|
||||
queue.scheduleTask(merge(base, {
|
||||
parent: task_build,
|
||||
name: "CertDN",
|
||||
command: [
|
||||
"/bin/bash",
|
||||
"-c",
|
||||
"bin/checkout.sh && nss/automation/taskcluster/scripts/fuzz.sh " +
|
||||
"certDN nss/fuzz/corpus/quickder -max_total_time=300 -max_len=4096"
|
||||
],
|
||||
// Need a privileged docker container to remove detect_leaks=0.
|
||||
env: {
|
||||
ASAN_OPTIONS: "allocator_may_return_null=1:detect_leaks=0",
|
||||
},
|
||||
symbol: "CertDN",
|
||||
kind: "test"
|
||||
}));
|
||||
|
||||
return queue.submit();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,14 @@
|
|||
|
||||
source $(dirname "$0")/tools.sh
|
||||
|
||||
if [ -n "$NSS_BUILD_MODULAR" ]; then
|
||||
$(dirname "$0")/build_nspr.sh || exit $?
|
||||
$(dirname "$0")/build_util.sh || exit $?
|
||||
$(dirname "$0")/build_softoken.sh || exit $?
|
||||
$(dirname "$0")/build_nss.sh || exit $?
|
||||
exit
|
||||
fi
|
||||
|
||||
# Clone NSPR if needed.
|
||||
hg_clone https://hg.mozilla.org/projects/nspr ./nspr default
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -v -e -x
|
||||
|
||||
source $(dirname $0)/tools.sh
|
||||
|
||||
# Clone NSPR if needed.
|
||||
hg_clone https://hg.mozilla.org/projects/nspr nspr default
|
||||
|
||||
# Build.
|
||||
rm -rf dist
|
||||
make -C nss build_nspr
|
||||
|
||||
# Package.
|
||||
test -d artifacts || mkdir artifacts
|
||||
rm -rf dist-nspr
|
||||
mv dist dist-nspr
|
||||
tar cvfjh artifacts/dist-nspr.tar.bz2 dist-nspr
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -v -e -x
|
||||
|
||||
source $(dirname $0)/tools.sh
|
||||
source $(dirname $0)/split.sh
|
||||
|
||||
test -d dist-softoken || { echo "run build_softoken.sh first" 1>&2; exit 1; }
|
||||
|
||||
rm -rf nss-nss
|
||||
split_nss nss nss-nss
|
||||
|
||||
# Build.
|
||||
export NSS_BUILD_WITHOUT_SOFTOKEN=1
|
||||
export NSS_USE_SYSTEM_FREEBL=1
|
||||
|
||||
platform=`make -s -C nss platform`
|
||||
|
||||
export NSPR_LIB_DIR="$PWD/dist-nspr/$platform/lib"
|
||||
export NSSUTIL_LIB_DIR="$PWD/dist-util/$platform/lib"
|
||||
export FREEBL_LIB_DIR="$PWD/dist-softoken/$platform/lib"
|
||||
export SOFTOKEN_LIB_DIR="$PWD/dist-softoken/$platform/lib"
|
||||
export FREEBL_LIBS=-lfreebl
|
||||
|
||||
export NSS_NO_PKCS11_BYPASS=1
|
||||
export FREEBL_NO_DEPEND=1
|
||||
|
||||
export LIBRARY_PATH="$PWD/dist-nspr/$platform/lib:$PWD/dist-util/$platform/lib:$PWD/dist-softoken/$platform/lib"
|
||||
export LD_LIBRARY_PATH="$LIBRARY_PATH:$LD_LIBRARY_PATH"
|
||||
export INCLUDES="-I$PWD/dist-nspr/$platform/include -I$PWD/dist-util/public/nss -I$PWD/dist-softoken/public/nss"
|
||||
|
||||
rm -rf dist
|
||||
make -C nss-nss nss_build_all
|
||||
|
||||
# Package.
|
||||
test -d artifacts || mkdir artifacts
|
||||
rm -rf dist-nss
|
||||
mv dist dist-nss
|
||||
tar cvfjh artifacts/dist-nss.tar.bz2 dist-nss
|
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -v -e -x
|
||||
|
||||
source $(dirname $0)/tools.sh
|
||||
source $(dirname $0)/split.sh
|
||||
|
||||
test -d dist-util || { echo "run build_util.sh first" 1>&2; exit 1; }
|
||||
|
||||
rm -rf nss-softoken
|
||||
split_softoken nss nss-softoken
|
||||
|
||||
# Build.
|
||||
platform=`make -s -C nss platform`
|
||||
export LIBRARY_PATH="$PWD/dist-nspr/$platform/lib:$PWD/dist-util/$platform/lib"
|
||||
export LD_LIBRARY_PATH="$LIBRARY_PATH:$LD_LIBRARY_PATH"
|
||||
export INCLUDES="-I$PWD/dist-nspr/$platform/include -I$PWD/dist-util/public/nss"
|
||||
export NSS_BUILD_SOFTOKEN_ONLY=1
|
||||
|
||||
rm -rf dist
|
||||
make -C nss-softoken nss_build_all
|
||||
|
||||
mv dist/private/nss/blapi.h dist/public/nss
|
||||
mv dist/private/nss/alghmac.h dist/public/nss
|
||||
|
||||
# Package.
|
||||
test -d artifacts || mkdir artifacts
|
||||
rm -rf dist-softoken
|
||||
mv dist dist-softoken
|
||||
tar cvfjh artifacts/dist-softoken.tar.bz2 dist-softoken
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -v -e -x
|
||||
|
||||
source $(dirname $0)/tools.sh
|
||||
source $(dirname $0)/split.sh
|
||||
|
||||
rm -rf nss-util
|
||||
split_util nss nss-util
|
||||
|
||||
# Build.
|
||||
platform=`make -s -C nss platform`
|
||||
export LIBRARY_PATH="$PWD/dist-nspr/$platform/lib"
|
||||
export LD_LIBRARY_PATH="$LIBRARY_PATH:$LD_LIBRARY_PATH"
|
||||
export INCLUDES="-I$PWD/dist-nspr/$platform/include"
|
||||
export NSS_BUILD_UTIL_ONLY=1
|
||||
|
||||
rm -rf dist
|
||||
make -C nss-util nss_build_all
|
||||
|
||||
# Package.
|
||||
test -d artifacts || mkdir artifacts
|
||||
rm -rf dist-util
|
||||
mv dist dist-util
|
||||
tar cvfjh artifacts/dist-util.tar.bz2 dist-util
|
|
@ -11,8 +11,15 @@ fetch_dist
|
|||
# Clone corpus.
|
||||
./nss/fuzz/clone_corpus.sh
|
||||
|
||||
# Ensure we have a directory.
|
||||
mkdir -p nss/fuzz/corpus/$type
|
||||
# Ensure we have a corpus.
|
||||
if [ ! -d "nss/fuzz/corpus/$type" ]; then
|
||||
mkdir -p nss/fuzz/corpus/$type
|
||||
|
||||
# Create a corpus out of what we have.
|
||||
for f in $(find nss/fuzz/corpus -type f); do
|
||||
cp $f "nss/fuzz/corpus/$type"
|
||||
done
|
||||
fi
|
||||
|
||||
# Fetch objdir name.
|
||||
objdir=$(cat dist/latest)
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
copy_top()
|
||||
{
|
||||
srcdir_="$1"
|
||||
dstdir_="$2"
|
||||
files=`find "$srcdir_" -maxdepth 1 -mindepth 1 -type f`
|
||||
for f in $files; do
|
||||
cp -p "$f" "$dstdir_"
|
||||
done
|
||||
}
|
||||
|
||||
split_util() {
|
||||
nssdir="$1"
|
||||
dstdir="$2"
|
||||
|
||||
# Prepare a source tree only containing files to build nss-util:
|
||||
#
|
||||
# nss/dbm full directory
|
||||
# nss/coreconf full directory
|
||||
# nss top files only
|
||||
# nss/lib top files only
|
||||
# nss/lib/util full directory
|
||||
|
||||
# Copy everything.
|
||||
cp -R $nssdir $dstdir
|
||||
|
||||
# Skip gtests when building.
|
||||
sed '/^DIRS = /s/ gtests$//' $nssdir/manifest.mn > $dstdir/manifest.mn-t && mv $dstdir/manifest.mn-t $dstdir/manifest.mn
|
||||
|
||||
# Remove subdirectories that we don't want.
|
||||
rm -rf $dstdir/cmd
|
||||
rm -rf $dstdir/tests
|
||||
rm -rf $dstdir/lib
|
||||
rm -rf $dstdir/automation
|
||||
rm -rf $dstdir/gtests
|
||||
rm -rf $dstdir/doc
|
||||
|
||||
# Start with an empty cmd lib directories to be filled selectively.
|
||||
mkdir $dstdir/cmd
|
||||
cp $nssdir/cmd/Makefile $dstdir/cmd
|
||||
cp $nssdir/cmd/manifest.mn $dstdir/cmd
|
||||
cp $nssdir/cmd/platlibs.mk $dstdir/cmd
|
||||
cp $nssdir/cmd/platrules.mk $dstdir/cmd
|
||||
|
||||
# Copy some files at the top and the util subdirectory recursively.
|
||||
mkdir $dstdir/lib
|
||||
cp $nssdir/lib/Makefile $dstdir/lib
|
||||
cp $nssdir/lib/manifest.mn $dstdir/lib
|
||||
cp -R $nssdir/lib/util $dstdir/lib/util
|
||||
}
|
||||
|
||||
split_softoken() {
|
||||
nssdir="$1"
|
||||
dstdir="$2"
|
||||
|
||||
# Prepare a source tree only containing files to build nss-softoken:
|
||||
#
|
||||
# nss/dbm full directory
|
||||
# nss/coreconf full directory
|
||||
# nss top files only
|
||||
# nss/lib top files only
|
||||
# nss/lib/freebl full directory
|
||||
# nss/lib/softoken full directory
|
||||
# nss/lib/softoken/dbm full directory
|
||||
|
||||
# Copy everything.
|
||||
cp -R $nssdir $dstdir
|
||||
|
||||
# Skip gtests when building.
|
||||
sed '/^DIRS = /s/ gtests$//' $nssdir/manifest.mn > $dstdir/manifest.mn-t && mv $dstdir/manifest.mn-t $dstdir/manifest.mn
|
||||
|
||||
# Remove subdirectories that we don't want.
|
||||
rm -rf $dstdir/cmd
|
||||
rm -rf $dstdir/tests
|
||||
rm -rf $dstdir/lib
|
||||
rm -rf $dstdir/pkg
|
||||
rm -rf $dstdir/automation
|
||||
rm -rf $dstdir/gtests
|
||||
rm -rf $dstdir/doc
|
||||
|
||||
# Start with an empty lib directory and copy only what we need.
|
||||
mkdir $dstdir/lib
|
||||
copy_top $nssdir/lib $dstdir/lib
|
||||
cp -R $nssdir/lib/dbm $dstdir/lib/dbm
|
||||
cp -R $nssdir/lib/freebl $dstdir/lib/freebl
|
||||
cp -R $nssdir/lib/softoken $dstdir/lib/softoken
|
||||
cp -R $nssdir/lib/sqlite $dstdir/lib/sqlite
|
||||
|
||||
mkdir $dstdir/cmd
|
||||
copy_top $nssdir/cmd $dstdir/cmd
|
||||
cp -R $nssdir/cmd/bltest $dstdir/cmd/bltest
|
||||
cp -R $nssdir/cmd/ecperf $dstdir/cmd/ecperf
|
||||
cp -R $nssdir/cmd/fbectest $dstdir/cmd/fbectest
|
||||
cp -R $nssdir/cmd/fipstest $dstdir/cmd/fipstest
|
||||
cp -R $nssdir/cmd/lib $dstdir/cmd/lib
|
||||
cp -R $nssdir/cmd/lowhashtest $dstdir/cmd/lowhashtest
|
||||
cp -R $nssdir/cmd/shlibsign $dstdir/cmd/shlibsign
|
||||
|
||||
mkdir $dstdir/tests
|
||||
copy_top $nssdir/tests $dstdir/tests
|
||||
|
||||
cp -R $nssdir/tests/cipher $dstdir/tests/cipher
|
||||
cp -R $nssdir/tests/common $dstdir/tests/common
|
||||
cp -R $nssdir/tests/ec $dstdir/tests/ec
|
||||
cp -R $nssdir/tests/lowhash $dstdir/tests/lowhash
|
||||
|
||||
cp $nssdir/lib/util/verref.h $dstdir/lib/freebl
|
||||
cp $nssdir/lib/util/verref.h $dstdir/lib/softoken
|
||||
cp $nssdir/lib/util/verref.h $dstdir/lib/softoken/legacydb
|
||||
}
|
||||
|
||||
split_nss() {
|
||||
nssdir="$1"
|
||||
dstdir="$2"
|
||||
|
||||
# Prepare a source tree only containing files to build nss:
|
||||
#
|
||||
# nss/dbm full directory
|
||||
# nss/coreconf full directory
|
||||
# nss top files only
|
||||
# nss/lib top files only
|
||||
# nss/lib/freebl full directory
|
||||
# nss/lib/softoken full directory
|
||||
# nss/lib/softoken/dbm full directory
|
||||
|
||||
# Copy everything.
|
||||
cp -R $nssdir $dstdir
|
||||
|
||||
# Remove subdirectories that we don't want.
|
||||
rm -rf $dstdir/lib/freebl
|
||||
rm -rf $dstdir/lib/softoken
|
||||
rm -rf $dstdir/lib/util
|
||||
rm -rf $dstdir/cmd/bltest
|
||||
rm -rf $dstdir/cmd/fipstest
|
||||
rm -rf $dstdir/cmd/rsaperf_low
|
||||
|
||||
# Copy these headers until the upstream bug is accepted
|
||||
# Upstream https://bugzilla.mozilla.org/show_bug.cgi?id=820207
|
||||
cp $nssdir/lib/softoken/lowkeyi.h $dstdir/cmd/rsaperf
|
||||
cp $nssdir/lib/softoken/lowkeyti.h $dstdir/cmd/rsaperf
|
||||
|
||||
# Copy verref.h which will be needed later during the build phase.
|
||||
cp $nssdir/lib/util/verref.h $dstdir/lib/ckfw/builtins/verref.h
|
||||
cp $nssdir/lib/util/verref.h $dstdir/lib/nss/verref.h
|
||||
cp $nssdir/lib/util/verref.h $dstdir/lib/smime/verref.h
|
||||
cp $nssdir/lib/util/verref.h $dstdir/lib/ssl/verref.h
|
||||
cp $nssdir/lib/util/templates.c $dstdir/lib/nss/templates.c
|
||||
|
||||
# FIXME: Skip util_gtest because it links with libnssutil.a. Note
|
||||
# that we can't use libnssutil3.so instead, because util_gtest
|
||||
# depends on internal symbols not exported from the shared library.
|
||||
sed '/ util_gtest \\/d' $dstdir/gtests/manifest.mn > $dstdir/gtests/manifest.mn-t && mv $dstdir/gtests/manifest.mn-t $dstdir/gtests/manifest.mn
|
||||
}
|
|
@ -1,4 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# 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/.
|
||||
################################################################################
|
||||
#
|
||||
# This script builds NSS with gyp and ninja.
|
||||
#
|
||||
# This build system is still under development. It does not yet support all
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "basicutil.h"
|
||||
#include "pkcs11.h"
|
||||
#include "nspr.h"
|
||||
#include "secutil.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define __PASTE(x, y) x##y
|
||||
|
@ -106,6 +105,8 @@ typedef struct ThreadDataStr {
|
|||
int isSign;
|
||||
} ThreadData;
|
||||
|
||||
typedef SECItem SECKEYECParams;
|
||||
|
||||
void
|
||||
PKCS11Thread(void *data)
|
||||
{
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "basicutil.h"
|
||||
#include "secder.h"
|
||||
#include "secitem.h"
|
||||
#include "secutil.h"
|
||||
#include "nspr.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#endif
|
||||
|
||||
#include "secoid.h"
|
||||
#include "sslt.h"
|
||||
|
||||
extern long DER_GetInteger(const SECItem *src);
|
||||
|
||||
|
@ -733,97 +732,45 @@ SECU_SECItemHexStringToBinary(SECItem *srcdest)
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
SSLNamedGroup
|
||||
groupNameToNamedGroup(char *name)
|
||||
SECItem *
|
||||
SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str)
|
||||
{
|
||||
if (PL_strlen(name) == 4) {
|
||||
if (!strncmp(name, "P256", 4)) {
|
||||
return ssl_grp_ec_secp256r1;
|
||||
}
|
||||
if (!strncmp(name, "P384", 4)) {
|
||||
return ssl_grp_ec_secp384r1;
|
||||
}
|
||||
if (!strncmp(name, "P521", 4)) {
|
||||
return ssl_grp_ec_secp521r1;
|
||||
}
|
||||
}
|
||||
if (PL_strlen(name) == 6) {
|
||||
if (!strncmp(name, "x25519", 6)) {
|
||||
return ssl_grp_ec_curve25519;
|
||||
}
|
||||
if (!strncmp(name, "FF2048", 6)) {
|
||||
return ssl_grp_ffdhe_2048;
|
||||
}
|
||||
if (!strncmp(name, "FF3072", 6)) {
|
||||
return ssl_grp_ffdhe_3072;
|
||||
}
|
||||
if (!strncmp(name, "FF4096", 6)) {
|
||||
return ssl_grp_ffdhe_4096;
|
||||
}
|
||||
if (!strncmp(name, "FF6144", 6)) {
|
||||
return ssl_grp_ffdhe_6144;
|
||||
}
|
||||
if (!strncmp(name, "FF8192", 6)) {
|
||||
return ssl_grp_ffdhe_8192;
|
||||
}
|
||||
int i = 0;
|
||||
int byteval = 0;
|
||||
int tmp = PORT_Strlen(str);
|
||||
|
||||
PORT_Assert(arena);
|
||||
PORT_Assert(item);
|
||||
|
||||
if ((tmp % 2) != 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ssl_grp_none;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
parseGroupList(const char *arg, SSLNamedGroup **enabledGroups,
|
||||
unsigned int *enabledGroupsCount)
|
||||
{
|
||||
SSLNamedGroup *groups;
|
||||
char *str;
|
||||
char *p;
|
||||
unsigned int numValues = 0;
|
||||
unsigned int count = 0;
|
||||
|
||||
/* Count the number of groups. */
|
||||
str = PORT_Strdup(arg);
|
||||
if (!str) {
|
||||
return SECFailure;
|
||||
}
|
||||
p = strtok(str, ",");
|
||||
while (p) {
|
||||
++numValues;
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
PORT_Free(str);
|
||||
str = NULL;
|
||||
groups = PORT_ZNewArray(SSLNamedGroup, numValues);
|
||||
if (!groups) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Get group names. */
|
||||
str = PORT_Strdup(arg);
|
||||
if (!str) {
|
||||
goto done;
|
||||
}
|
||||
p = strtok(str, ",");
|
||||
while (p) {
|
||||
SSLNamedGroup group = groupNameToNamedGroup(p);
|
||||
if (group == ssl_grp_none) {
|
||||
count = 0;
|
||||
goto done;
|
||||
}
|
||||
groups[count++] = group;
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
done:
|
||||
if (str) {
|
||||
PORT_Free(str);
|
||||
}
|
||||
if (!count) {
|
||||
PORT_Free(groups);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
*enabledGroupsCount = count;
|
||||
*enabledGroups = groups;
|
||||
return SECSuccess;
|
||||
item = SECITEM_AllocItem(arena, item, tmp / 2);
|
||||
if (item == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (str[i]) {
|
||||
if ((str[i] >= '0') && (str[i] <= '9')) {
|
||||
tmp = str[i] - '0';
|
||||
} else if ((str[i] >= 'a') && (str[i] <= 'f')) {
|
||||
tmp = str[i] - 'a' + 10;
|
||||
} else if ((str[i] >= 'A') && (str[i] <= 'F')) {
|
||||
tmp = str[i] - 'A' + 10;
|
||||
} else {
|
||||
/* item is in arena and gets freed by the caller */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
byteval = byteval * 16 + tmp;
|
||||
if ((i % 2) != 0) {
|
||||
item->data[i / 2] = byteval;
|
||||
byteval = 0;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "base64.h"
|
||||
#include "secasn1.h"
|
||||
#include "secder.h"
|
||||
#include "sslt.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef SECUTIL_NEW
|
||||
|
@ -81,6 +80,12 @@ SECU_SECItemToHex(const SECItem *item, char *dst);
|
|||
SECStatus
|
||||
SECU_SECItemHexStringToBinary(SECItem *srcdest);
|
||||
|
||||
/*
|
||||
** Read a hex string into a SecItem.
|
||||
*/
|
||||
extern SECItem *SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item,
|
||||
const char *str);
|
||||
|
||||
/*
|
||||
*
|
||||
* Utilities for parsing security tools command lines
|
||||
|
@ -113,10 +118,6 @@ SECU_ParseCommandLine(int argc, char **argv, char *progName,
|
|||
char *
|
||||
SECU_GetOptionArg(const secuCommand *cmd, int optionNum);
|
||||
|
||||
SECStatus parseGroupList(const char *arg, SSLNamedGroup **enabledGroups,
|
||||
unsigned int *enabledGroupsCount);
|
||||
SSLNamedGroup groupNameToNamedGroup(char *name);
|
||||
|
||||
/*
|
||||
*
|
||||
* Error messaging
|
||||
|
|
|
@ -3833,45 +3833,97 @@ SECU_ParseSSLVersionRangeString(const char *input,
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECItem *
|
||||
SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str)
|
||||
SSLNamedGroup
|
||||
groupNameToNamedGroup(char *name)
|
||||
{
|
||||
int i = 0;
|
||||
int byteval = 0;
|
||||
int tmp = PORT_Strlen(str);
|
||||
|
||||
PORT_Assert(arena);
|
||||
PORT_Assert(item);
|
||||
|
||||
if ((tmp % 2) != 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
item = SECITEM_AllocItem(arena, item, tmp / 2);
|
||||
if (item == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (str[i]) {
|
||||
if ((str[i] >= '0') && (str[i] <= '9')) {
|
||||
tmp = str[i] - '0';
|
||||
} else if ((str[i] >= 'a') && (str[i] <= 'f')) {
|
||||
tmp = str[i] - 'a' + 10;
|
||||
} else if ((str[i] >= 'A') && (str[i] <= 'F')) {
|
||||
tmp = str[i] - 'A' + 10;
|
||||
} else {
|
||||
/* item is in arena and gets freed by the caller */
|
||||
return NULL;
|
||||
if (PL_strlen(name) == 4) {
|
||||
if (!strncmp(name, "P256", 4)) {
|
||||
return ssl_grp_ec_secp256r1;
|
||||
}
|
||||
|
||||
byteval = byteval * 16 + tmp;
|
||||
if ((i % 2) != 0) {
|
||||
item->data[i / 2] = byteval;
|
||||
byteval = 0;
|
||||
if (!strncmp(name, "P384", 4)) {
|
||||
return ssl_grp_ec_secp384r1;
|
||||
}
|
||||
if (!strncmp(name, "P521", 4)) {
|
||||
return ssl_grp_ec_secp521r1;
|
||||
}
|
||||
}
|
||||
if (PL_strlen(name) == 6) {
|
||||
if (!strncmp(name, "x25519", 6)) {
|
||||
return ssl_grp_ec_curve25519;
|
||||
}
|
||||
if (!strncmp(name, "FF2048", 6)) {
|
||||
return ssl_grp_ffdhe_2048;
|
||||
}
|
||||
if (!strncmp(name, "FF3072", 6)) {
|
||||
return ssl_grp_ffdhe_3072;
|
||||
}
|
||||
if (!strncmp(name, "FF4096", 6)) {
|
||||
return ssl_grp_ffdhe_4096;
|
||||
}
|
||||
if (!strncmp(name, "FF6144", 6)) {
|
||||
return ssl_grp_ffdhe_6144;
|
||||
}
|
||||
if (!strncmp(name, "FF8192", 6)) {
|
||||
return ssl_grp_ffdhe_8192;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return item;
|
||||
return ssl_grp_none;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
parseGroupList(const char *arg, SSLNamedGroup **enabledGroups,
|
||||
unsigned int *enabledGroupsCount)
|
||||
{
|
||||
SSLNamedGroup *groups;
|
||||
char *str;
|
||||
char *p;
|
||||
unsigned int numValues = 0;
|
||||
unsigned int count = 0;
|
||||
|
||||
/* Count the number of groups. */
|
||||
str = PORT_Strdup(arg);
|
||||
if (!str) {
|
||||
return SECFailure;
|
||||
}
|
||||
p = strtok(str, ",");
|
||||
while (p) {
|
||||
++numValues;
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
PORT_Free(str);
|
||||
str = NULL;
|
||||
groups = PORT_ZNewArray(SSLNamedGroup, numValues);
|
||||
if (!groups) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Get group names. */
|
||||
str = PORT_Strdup(arg);
|
||||
if (!str) {
|
||||
goto done;
|
||||
}
|
||||
p = strtok(str, ",");
|
||||
while (p) {
|
||||
SSLNamedGroup group = groupNameToNamedGroup(p);
|
||||
if (group == ssl_grp_none) {
|
||||
count = 0;
|
||||
goto done;
|
||||
}
|
||||
groups[count++] = group;
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
done:
|
||||
if (str) {
|
||||
PORT_Free(str);
|
||||
}
|
||||
if (!count) {
|
||||
PORT_Free(groups);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
*enabledGroupsCount = count;
|
||||
*enabledGroups = groups;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
|
|
@ -408,6 +408,10 @@ SECU_ParseSSLVersionRangeString(const char *input,
|
|||
extern SECItem *SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item,
|
||||
const char *str);
|
||||
|
||||
SECStatus parseGroupList(const char *arg, SSLNamedGroup **enabledGroups,
|
||||
unsigned int *enabledGroupsCount);
|
||||
SSLNamedGroup groupNameToNamedGroup(char *name);
|
||||
|
||||
/*
|
||||
*
|
||||
* Error messaging
|
||||
|
|
|
@ -22,3 +22,4 @@ CSRCS = \
|
|||
lowhashtest.c \
|
||||
$(NULL)
|
||||
|
||||
USE_STATIC_LIBS = 1
|
||||
|
|
|
@ -14,7 +14,16 @@
|
|||
'mpi-test.c',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/lib/freebl/freebl.gyp:<(freebl_name)',
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'<(DEPTH)/lib/util/util.gyp:nssutil3',
|
||||
'<(DEPTH)/lib/nss/nss.gyp:nss_static',
|
||||
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
|
||||
'<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
|
||||
'<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
|
||||
'<(DEPTH)/lib/certdb/certdb.gyp:certdb',
|
||||
'<(DEPTH)/lib/base/base.gyp:nssb',
|
||||
'<(DEPTH)/lib/dev/dev.gyp:nssdev',
|
||||
'<(DEPTH)/lib/pki/pki.gyp:nsspki',
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
|
@ -231,9 +231,6 @@ endif
|
|||
# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
|
||||
EXTRA_SHARED_LIBS += \
|
||||
-L$(DIST)/lib \
|
||||
-lssl3 \
|
||||
-lsmime3 \
|
||||
-lnss3 \
|
||||
-L$(NSSUTIL_LIB_DIR) \
|
||||
-lnssutil3 \
|
||||
-L$(NSPR_LIB_DIR) \
|
||||
|
@ -241,6 +238,12 @@ EXTRA_SHARED_LIBS += \
|
|||
-lplds4 \
|
||||
-lnspr4 \
|
||||
$(NULL)
|
||||
ifndef NSS_BUILD_SOFTOKEN_ONLY
|
||||
EXTRA_SHARED_LIBS += \
|
||||
-lssl3 \
|
||||
-lsmime3 \
|
||||
-lnss3
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef SOFTOKEN_LIB_DIR
|
||||
|
|
|
@ -102,6 +102,7 @@
|
|||
'no_zdefs%': 0,
|
||||
'fuzz%': 0,
|
||||
'fuzz_tls%': 0,
|
||||
'fuzz_oss%': 0,
|
||||
'sign_libs%': 1,
|
||||
'use_pprof%': 0,
|
||||
'ct_verif%': 0,
|
||||
|
@ -152,7 +153,7 @@
|
|||
'product_dir': '<(nss_dist_obj_dir)/lib'
|
||||
}],
|
||||
# mapfile handling
|
||||
[ 'test_build==0 and mapfile!=""', {
|
||||
[ 'mapfile!=""', {
|
||||
# Work around a gyp bug. Fixed upstream but not in Ubuntu packages:
|
||||
# https://chromium.googlesource.com/external/gyp/+/b85ad3e578da830377dbc1843aa4fbc5af17a192%5E%21/
|
||||
'sources': [
|
||||
|
@ -350,11 +351,21 @@
|
|||
'cflags': [
|
||||
'<!@(<(python) <(DEPTH)/coreconf/werror.py)',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'OTHER_CFLAGS': [
|
||||
'<!@(<(python) <(DEPTH)/coreconf/werror.py)',
|
||||
],
|
||||
},
|
||||
}],
|
||||
[ 'fuzz_tls==1', {
|
||||
'cflags': [
|
||||
'-Wno-unused-function',
|
||||
],
|
||||
'xcode_settings': {
|
||||
'OTHER_CFLAGS': [
|
||||
'-Wno-unused-function',
|
||||
],
|
||||
},
|
||||
}],
|
||||
[ 'sanitizer_flags!=0', {
|
||||
'cflags': ['<@(sanitizer_flags)'],
|
||||
|
|
|
@ -10,4 +10,3 @@
|
|||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
|
|
@ -15,13 +15,13 @@ if [ -z "$CC" ]; then
|
|||
export CXX=clang++
|
||||
fi
|
||||
|
||||
gyp_params+=(-Dtest_build=1 -Dfuzz=1)
|
||||
gyp_params+=(-Dtest_build=1 -Dfuzz=1 -Dsign_libs=0)
|
||||
|
||||
# Add debug symbols even for opt builds.
|
||||
nspr_params+=(--enable-debug-symbols)
|
||||
|
||||
if [ "$fuzz_oss" = 1 ]; then
|
||||
gyp_params+=(-Dno_zdefs=1)
|
||||
gyp_params+=(-Dno_zdefs=1 -Dfuzz_oss=1)
|
||||
else
|
||||
enable_sanitizer asan
|
||||
enable_ubsan
|
||||
|
|
|
@ -21,8 +21,8 @@ enable_sanitizer()
|
|||
|
||||
enable_sancov()
|
||||
{
|
||||
local clang_version=$($CC --version | grep -oE 'clang version (3\.9\.|4\.)')
|
||||
if [ -z "$clang_version" ]; then
|
||||
local clang_version=$($CC --version | grep -oE '([0-9]{1,}\.)+[0-9]{1,}')
|
||||
if [[ ${clang_version:0:1} -lt 4 && ${clang_version:0:1} -eq 3 && ${clang_version:2:1} -lt 9 ]]; then
|
||||
echo "Need at least clang-3.9 (better 4.0) for sancov." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
@ -30,7 +30,7 @@ enable_sancov()
|
|||
local sancov
|
||||
if [ -n "$1" ]; then
|
||||
sancov="$1"
|
||||
elif [ "$clang_version" = "clang version 3.9." ]; then
|
||||
elif [ "${clang_version:0:3}" = "3.9" ]; then
|
||||
sancov=edge,indirect-calls,8bit-counters
|
||||
else
|
||||
sancov=trace-pc-guard,trace-cmp
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <random>
|
||||
#include <tuple>
|
||||
|
||||
#include "FuzzerRandom.h"
|
||||
#include "asn1_mutators.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -94,9 +94,11 @@ static vector<uint8_t *> ParseItems(uint8_t *Data, size_t Size) {
|
|||
|
||||
size_t ASN1MutatorFlipConstructed(uint8_t *Data, size_t Size, size_t MaxSize,
|
||||
unsigned int Seed) {
|
||||
fuzzer::Random R(Seed);
|
||||
auto items = ParseItems(Data, Size);
|
||||
uint8_t *item = items.at(R(items.size()));
|
||||
|
||||
std::mt19937 rng(Seed);
|
||||
std::uniform_int_distribution<size_t> dist(0, items.size() - 1);
|
||||
uint8_t *item = items.at(dist(rng));
|
||||
|
||||
// Flip "constructed" type bit.
|
||||
item[0] ^= 0x20;
|
||||
|
@ -106,12 +108,15 @@ size_t ASN1MutatorFlipConstructed(uint8_t *Data, size_t Size, size_t MaxSize,
|
|||
|
||||
size_t ASN1MutatorChangeType(uint8_t *Data, size_t Size, size_t MaxSize,
|
||||
unsigned int Seed) {
|
||||
fuzzer::Random R(Seed);
|
||||
auto items = ParseItems(Data, Size);
|
||||
uint8_t *item = items.at(R(items.size()));
|
||||
|
||||
// Change type to a random int [0, 31).
|
||||
item[0] = R(31);
|
||||
std::mt19937 rng(Seed);
|
||||
std::uniform_int_distribution<size_t> dist(0, items.size() - 1);
|
||||
uint8_t *item = items.at(dist(rng));
|
||||
|
||||
// Change type to a random int [0, 30].
|
||||
static std::uniform_int_distribution<size_t> tdist(0, 30);
|
||||
item[0] = tdist(rng);
|
||||
|
||||
return Size;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/* 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 <string>
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
#define TEST_FUNCTION(f) \
|
||||
out = f(certName); \
|
||||
free(out);
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
std::string name(data, data + size);
|
||||
|
||||
assert(SECOID_Init() == SECSuccess);
|
||||
|
||||
CERTName* certName = CERT_AsciiToName(name.c_str());
|
||||
if (certName) {
|
||||
char* out;
|
||||
TEST_FUNCTION(CERT_NameToAscii)
|
||||
TEST_FUNCTION(CERT_GetCertEmailAddress)
|
||||
|
||||
// These functions call CERT_GetNameElement with different OIDs.
|
||||
// Unfotunately CERT_GetNameElement is not accesible from here.
|
||||
TEST_FUNCTION(CERT_GetCertUid)
|
||||
TEST_FUNCTION(CERT_GetCommonName)
|
||||
TEST_FUNCTION(CERT_GetCountryName)
|
||||
TEST_FUNCTION(CERT_GetDomainComponentName)
|
||||
TEST_FUNCTION(CERT_GetLocalityName)
|
||||
TEST_FUNCTION(CERT_GetOrgName)
|
||||
TEST_FUNCTION(CERT_GetOrgUnitName)
|
||||
TEST_FUNCTION(CERT_GetStateName)
|
||||
|
||||
out = CERT_NameToAsciiInvertible(certName, CERT_N2A_READABLE);
|
||||
free(out);
|
||||
out = CERT_NameToAsciiInvertible(certName, CERT_N2A_STRICT);
|
||||
free(out);
|
||||
out = CERT_NameToAsciiInvertible(certName, CERT_N2A_INVERTIBLE);
|
||||
free(out);
|
||||
}
|
||||
CERT_DestroyName(certName);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
/* 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 "FuzzerInternal.h"
|
||||
#include "asn1_mutators.h"
|
||||
#include "shared.h"
|
||||
|
||||
extern const uint16_t DEFAULT_MAX_LENGTH = 3072U;
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
CERTCertificate cert;
|
||||
QuickDERDecode(&cert, SEC_SignedCertificateTemplate, Data, Size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ADD_CUSTOM_MUTATORS({&ASN1MutatorFlipConstructed, &ASN1MutatorChangeType})
|
|
@ -5,9 +5,6 @@
|
|||
'includes': [
|
||||
'../coreconf/config.gypi',
|
||||
],
|
||||
'variables': {
|
||||
'use_fuzzing_engine': '<!(test -f /usr/lib/libFuzzingEngine.a && echo 1 || echo 0)',
|
||||
},
|
||||
'target_defaults': {
|
||||
'variables': {
|
||||
'debug_optimization_level': '2',
|
||||
|
@ -37,11 +34,12 @@
|
|||
'<(DEPTH)/lib/pki/pki.gyp:nsspki',
|
||||
'<(DEPTH)/lib/util/util.gyp:nssutil',
|
||||
'<(DEPTH)/lib/nss/nss.gyp:nss_static',
|
||||
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap',
|
||||
'<(DEPTH)/lib/pkcs7/pkcs7.gyp:pkcs7',
|
||||
# This is a static build of pk11wrap, softoken, and freebl.
|
||||
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
|
||||
],
|
||||
'conditions': [
|
||||
['use_fuzzing_engine==0', {
|
||||
['fuzz_oss==0', {
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'libFuzzer/FuzzerCrossOver.cpp',
|
||||
|
@ -91,7 +89,6 @@
|
|||
'type': 'executable',
|
||||
'sources': [
|
||||
'asn1_mutators.cc',
|
||||
'initialize.cc',
|
||||
'pkcs8_target.cc',
|
||||
],
|
||||
'dependencies': [
|
||||
|
@ -104,7 +101,6 @@
|
|||
'type': 'executable',
|
||||
'sources': [
|
||||
'asn1_mutators.cc',
|
||||
'initialize.cc',
|
||||
'quickder_target.cc',
|
||||
],
|
||||
'dependencies': [
|
||||
|
@ -117,7 +113,42 @@
|
|||
'type': 'executable',
|
||||
'sources': [
|
||||
'hash_target.cc',
|
||||
'initialize.cc',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'fuzz_base',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'nssfuzz-mpi',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'mpi_target.cc',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'fuzz_base',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'fuzz_oss==1', {
|
||||
'libraries': [
|
||||
'/usr/lib/x86_64-linux-gnu/libcrypto.a',
|
||||
],
|
||||
}, {
|
||||
'libraries': [
|
||||
'-lcrypto',
|
||||
],
|
||||
}],
|
||||
],
|
||||
'include_dirs': [
|
||||
'<(DEPTH)/lib/freebl/mpi',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'nssfuzz-certDN',
|
||||
'type': 'executable',
|
||||
'sources': [
|
||||
'certDN_target.cc',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
|
@ -128,7 +159,9 @@
|
|||
'target_name': 'nssfuzz',
|
||||
'type': 'none',
|
||||
'dependencies': [
|
||||
'nssfuzz-certDN',
|
||||
'nssfuzz-hash',
|
||||
'nssfuzz-mpi',
|
||||
'nssfuzz-pkcs8',
|
||||
'nssfuzz-quickder',
|
||||
],
|
||||
|
|
|
@ -5,14 +5,11 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "FuzzerInternal.h"
|
||||
#include "hasht.h"
|
||||
#include "pk11pub.h"
|
||||
#include "secoidt.h"
|
||||
#include "shared.h"
|
||||
|
||||
extern const uint16_t DEFAULT_MAX_LENGTH = 4096U;
|
||||
|
||||
const std::vector<SECOidTag> algos = {SEC_OID_MD5, SEC_OID_SHA1, SEC_OID_SHA256,
|
||||
SEC_OID_SHA384, SEC_OID_SHA512};
|
||||
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
/* 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 <string.h>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "assert.h"
|
||||
|
||||
extern const uint16_t DEFAULT_MAX_LENGTH;
|
||||
|
||||
const uint16_t MERGE_MAX_LENGTH = 50000U;
|
||||
|
||||
extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
|
||||
std::vector<std::string> args(*argv, *argv + *argc);
|
||||
|
||||
auto hasMaxLenArg = [](std::string &a) { return a.find("-max_len=") == 0; };
|
||||
|
||||
// Nothing to do if a max_len argument is given.
|
||||
if (any_of(args.begin(), args.end(), hasMaxLenArg)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto hasMergeArg = [](std::string &a) { return a.find("-merge=1") == 0; };
|
||||
|
||||
uint16_t max_length = DEFAULT_MAX_LENGTH;
|
||||
|
||||
// Set specific max_len when merging.
|
||||
if (any_of(args.begin(), args.end(), hasMergeArg)) {
|
||||
max_length = MERGE_MAX_LENGTH;
|
||||
}
|
||||
|
||||
std::cerr << "INFO: MaxLen: " << max_length << std::endl;
|
||||
std::string param = "-max_len=" + std::to_string(max_length);
|
||||
|
||||
// Copy original arguments.
|
||||
char **new_args = new char *[*argc + 1];
|
||||
for (int i = 0; i < *argc; i++) {
|
||||
new_args[i] = (*argv)[i];
|
||||
}
|
||||
|
||||
// Append corpus max length.
|
||||
size_t param_len = param.size() + 1;
|
||||
new_args[*argc] = new char[param_len];
|
||||
memcpy(new_args[*argc], param.c_str(), param_len);
|
||||
|
||||
// Update arguments.
|
||||
(*argc)++;
|
||||
*argv = new_args;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
/* 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/. */
|
||||
|
||||
/*
|
||||
* This target fuzzes NSS mpi against openssl bignum.
|
||||
* It therefore requires openssl to be installed.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "hasht.h"
|
||||
#include "mpi.h"
|
||||
#include "shared.h"
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#define CLEAR_NUMS \
|
||||
mp_zero(&c); \
|
||||
BN_zero(C); \
|
||||
mp_zero(&r); \
|
||||
BN_zero(R);
|
||||
|
||||
// Check that the two numbers are equal.
|
||||
void check_equal(BIGNUM *b, mp_int *m, size_t max_size) {
|
||||
char *bnBc = BN_bn2hex(b);
|
||||
char mpiMc[max_size];
|
||||
mp_tohex(m, mpiMc);
|
||||
std::string bnA(bnBc);
|
||||
std::string mpiA(mpiMc);
|
||||
OPENSSL_free(bnBc);
|
||||
// We have to strip leading zeros from bignums, ignoring the sign.
|
||||
if (bnA.at(0) != '-') {
|
||||
bnA.erase(0, std::min(bnA.find_first_not_of('0'), bnA.size() - 1));
|
||||
} else if (bnA.at(1) == '0') {
|
||||
bnA.erase(1, std::min(bnA.find_first_not_of('0', 1) - 1, bnA.size() - 1));
|
||||
}
|
||||
|
||||
if (mpiA != bnA) {
|
||||
std::cout << "openssl: " << std::hex << bnA << std::endl;
|
||||
std::cout << "nss: " << std::hex << mpiA << std::endl;
|
||||
}
|
||||
|
||||
assert(mpiA == bnA);
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
// We require at least size 3 to get two integers from Data.
|
||||
if (size <= 3) {
|
||||
return 0;
|
||||
}
|
||||
size_t max_size = 2 * size + 1;
|
||||
|
||||
mp_int a, b, c, r;
|
||||
BN_CTX *ctx = BN_CTX_new();
|
||||
BN_CTX_start(ctx);
|
||||
BIGNUM *A = BN_CTX_get(ctx);
|
||||
BIGNUM *B = BN_CTX_get(ctx);
|
||||
BIGNUM *C = BN_CTX_get(ctx);
|
||||
BIGNUM *R = BN_CTX_get(ctx);
|
||||
assert(mp_init(&a) == MP_OKAY);
|
||||
assert(mp_init(&b) == MP_OKAY);
|
||||
assert(mp_init(&c) == MP_OKAY);
|
||||
assert(mp_init(&r) == MP_OKAY);
|
||||
|
||||
// Note that b might overlap a.
|
||||
size_t len = (size_t)size / 2;
|
||||
assert(mp_read_raw(
|
||||
&a, reinterpret_cast<char *>(const_cast<unsigned char *>(data)),
|
||||
len) == MP_OKAY);
|
||||
assert(mp_read_raw(
|
||||
&b,
|
||||
reinterpret_cast<char *>(const_cast<unsigned char *>(data)) + len,
|
||||
len) == MP_OKAY);
|
||||
// Force a positive sign.
|
||||
// TODO: add tests for negatives.
|
||||
MP_SIGN(&a) = MP_ZPOS;
|
||||
MP_SIGN(&b) = MP_ZPOS;
|
||||
|
||||
// Skip the first byte as it's interpreted as sign by NSS.
|
||||
assert(BN_bin2bn(data + 1, len - 1, A) != nullptr);
|
||||
assert(BN_bin2bn(data + len + 1, len - 1, B) != nullptr);
|
||||
|
||||
check_equal(A, &a, max_size);
|
||||
check_equal(B, &b, max_size);
|
||||
|
||||
// Addition
|
||||
assert(mp_add(&a, &b, &c) == MP_OKAY);
|
||||
(void)BN_add(C, A, B);
|
||||
check_equal(C, &c, max_size);
|
||||
|
||||
// Subtraction
|
||||
CLEAR_NUMS
|
||||
assert(mp_sub(&a, &b, &c) == MP_OKAY);
|
||||
(void)BN_sub(C, A, B);
|
||||
check_equal(C, &c, max_size);
|
||||
|
||||
// Sqr
|
||||
CLEAR_NUMS
|
||||
assert(mp_sqr(&a, &c) == MP_OKAY);
|
||||
(void)BN_sqr(C, A, ctx);
|
||||
check_equal(C, &c, max_size);
|
||||
|
||||
// We can't divide by 0.
|
||||
if (mp_cmp_z(&b) != 0) {
|
||||
CLEAR_NUMS
|
||||
assert(mp_div(&a, &b, &c, &r) == MP_OKAY);
|
||||
BN_div(C, R, A, B, ctx);
|
||||
check_equal(C, &c, max_size);
|
||||
check_equal(R, &r, max_size);
|
||||
|
||||
// Modulo
|
||||
CLEAR_NUMS
|
||||
assert(mp_mod(&a, &b, &c) == MP_OKAY);
|
||||
(void)BN_mod(C, A, B, ctx);
|
||||
check_equal(C, &c, max_size);
|
||||
|
||||
// Mod sqr
|
||||
CLEAR_NUMS
|
||||
assert(mp_sqrmod(&a, &b, &c) == MP_OKAY);
|
||||
(void)BN_mod_sqr(C, A, B, ctx);
|
||||
check_equal(C, &c, max_size);
|
||||
}
|
||||
|
||||
// Mod add
|
||||
CLEAR_NUMS
|
||||
mp_add(&a, &b, &r);
|
||||
(void)BN_add(R, A, B);
|
||||
assert(mp_addmod(&a, &b, &r, &c) == MP_OKAY);
|
||||
(void)BN_mod_add(C, A, B, R, ctx);
|
||||
check_equal(C, &c, max_size);
|
||||
|
||||
// Mod sub
|
||||
CLEAR_NUMS
|
||||
mp_add(&a, &b, &r);
|
||||
(void)BN_add(R, A, B);
|
||||
assert(mp_submod(&a, &b, &r, &c) == MP_OKAY);
|
||||
(void)BN_mod_sub(C, A, B, R, ctx);
|
||||
check_equal(C, &c, max_size);
|
||||
|
||||
// Mod mul
|
||||
CLEAR_NUMS
|
||||
mp_add(&a, &b, &r);
|
||||
(void)BN_add(R, A, B);
|
||||
assert(mp_mulmod(&a, &b, &r, &c) == MP_OKAY);
|
||||
(void)BN_mod_mul(C, A, B, R, ctx);
|
||||
check_equal(C, &c, max_size);
|
||||
|
||||
// Mod exp
|
||||
// NOTE: This must be the last test as we change b!
|
||||
CLEAR_NUMS
|
||||
mp_add(&a, &b, &r);
|
||||
mp_add_d(&r, 1, &r); // NSS doesn't allow 0 as modulus here.
|
||||
size_t num = MP_USED(&b) * MP_DIGIT_BIT;
|
||||
mp_div_2d(&b, num, &b, nullptr); // make the exponent smaller, larger
|
||||
// exponents need too much memory
|
||||
MP_USED(&b) = 1;
|
||||
(void)BN_add(R, A, B);
|
||||
BN_add_word(R, 1);
|
||||
BN_rshift(B, B, num);
|
||||
check_equal(B, &b, max_size);
|
||||
assert(mp_exptmod(&a, &b, &r, &c) == MP_OKAY);
|
||||
(void)BN_mod_exp(C, A, B, R, ctx);
|
||||
check_equal(C, &c, max_size);
|
||||
|
||||
mp_clear(&a);
|
||||
mp_clear(&b);
|
||||
mp_clear(&c);
|
||||
mp_clear(&r);
|
||||
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -8,13 +8,9 @@
|
|||
#include "keyhi.h"
|
||||
#include "pk11pub.h"
|
||||
|
||||
#include "FuzzerInternal.h"
|
||||
#include "asn1_mutators.h"
|
||||
#include "assert.h"
|
||||
#include "shared.h"
|
||||
|
||||
extern const uint16_t DEFAULT_MAX_LENGTH = 2048U;
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
SECItem data = {siBuffer, (unsigned char *)Data, (unsigned int)Size};
|
||||
|
||||
|
@ -35,4 +31,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
ADD_CUSTOM_MUTATORS({&ASN1MutatorFlipConstructed, &ASN1MutatorChangeType})
|
||||
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
|
||||
size_t MaxSize, unsigned int Seed) {
|
||||
static Mutators mutators = {&ASN1MutatorFlipConstructed,
|
||||
&ASN1MutatorChangeType};
|
||||
return CustomMutate(mutators, Data, Size, MaxSize, Seed);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* 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 "FuzzerInternal.h"
|
||||
#include "asn1_mutators.h"
|
||||
#include "shared.h"
|
||||
|
||||
|
@ -62,8 +61,6 @@ const std::vector<const SEC_ASN1Template *> templates = {
|
|||
SECKEY_RSAPublicKeyTemplate,
|
||||
SECOID_AlgorithmIDTemplate};
|
||||
|
||||
extern const uint16_t DEFAULT_MAX_LENGTH = 10000U;
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
char *dest[2048];
|
||||
|
||||
|
@ -80,4 +77,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
ADD_CUSTOM_MUTATORS({&ASN1MutatorFlipConstructed, &ASN1MutatorChangeType})
|
||||
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
|
||||
size_t MaxSize, unsigned int Seed) {
|
||||
static Mutators mutators = {&ASN1MutatorFlipConstructed,
|
||||
&ASN1MutatorChangeType};
|
||||
return CustomMutate(mutators, Data, Size, MaxSize, Seed);
|
||||
}
|
||||
|
|
|
@ -7,33 +7,34 @@
|
|||
#ifndef shared_h__
|
||||
#define shared_h__
|
||||
|
||||
#include "FuzzerRandom.h"
|
||||
#include <assert.h>
|
||||
#include <random>
|
||||
#include "cert.h"
|
||||
#include "nss.h"
|
||||
|
||||
extern "C" size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
|
||||
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
|
||||
size_t MaxSize, unsigned int Seed);
|
||||
|
||||
class NSSDatabase {
|
||||
public:
|
||||
NSSDatabase() { NSS_NoDB_Init(nullptr); }
|
||||
~NSSDatabase() { NSS_Shutdown(); }
|
||||
NSSDatabase() { assert(NSS_NoDB_Init(nullptr) == SECSuccess); }
|
||||
~NSSDatabase() { assert(NSS_Shutdown() == SECSuccess); }
|
||||
};
|
||||
|
||||
size_t CustomMutate(std::vector<decltype(LLVMFuzzerCustomMutator) *> mutators,
|
||||
uint8_t *Data, size_t Size, size_t MaxSize,
|
||||
unsigned int Seed) {
|
||||
fuzzer::Random R(Seed);
|
||||
typedef std::vector<decltype(LLVMFuzzerCustomMutator) *> Mutators;
|
||||
|
||||
if (R.RandBool()) {
|
||||
auto idx = R(mutators.size());
|
||||
return mutators.at(idx)(Data, Size, MaxSize, Seed);
|
||||
size_t CustomMutate(Mutators &mutators, uint8_t *Data, size_t Size,
|
||||
size_t MaxSize, unsigned int Seed) {
|
||||
std::mt19937 rng(Seed);
|
||||
static std::bernoulli_distribution bdist;
|
||||
|
||||
if (bdist(rng)) {
|
||||
std::uniform_int_distribution<size_t> idist(0, mutators.size() - 1);
|
||||
return mutators.at(idist(rng))(Data, Size, MaxSize, Seed);
|
||||
}
|
||||
|
||||
return LLVMFuzzerMutate(Data, Size, MaxSize);
|
||||
}
|
||||
|
||||
#define ADD_CUSTOM_MUTATORS(...) \
|
||||
extern "C" size_t LLVMFuzzerCustomMutator( \
|
||||
uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed) { \
|
||||
return CustomMutate(__VA_ARGS__, Data, Size, MaxSize, Seed); \
|
||||
}
|
||||
|
||||
#endif // shared_h__
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
/* 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 "FuzzerInternal.h"
|
||||
#include "asn1_mutators.h"
|
||||
#include "shared.h"
|
||||
|
||||
extern const uint16_t DEFAULT_MAX_LENGTH = 1024U;
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
CERTSubjectPublicKeyInfo spki;
|
||||
QuickDERDecode(&spki, CERT_SubjectPublicKeyInfoTemplate, Data, Size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ADD_CUSTOM_MUTATORS({&ASN1MutatorFlipConstructed, &ASN1MutatorChangeType})
|
|
@ -18,6 +18,9 @@
|
|||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'<(DEPTH)/gtests/google_test/google_test.gyp:gtest',
|
||||
'<(DEPTH)/lib/util/util.gyp:nssutil3',
|
||||
'<(DEPTH)/lib/ssl/ssl.gyp:ssl3',
|
||||
'<(DEPTH)/lib/nss/nss.gyp:nss3',
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
|
@ -16,8 +16,17 @@
|
|||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'<(DEPTH)/lib/freebl/freebl.gyp:<(freebl_name)',
|
||||
'<(DEPTH)/lib/util/util.gyp:nssutil3',
|
||||
'<(DEPTH)/gtests/google_test/google_test.gyp:gtest',
|
||||
'<(DEPTH)/lib/nss/nss.gyp:nss_static',
|
||||
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
|
||||
'<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
|
||||
'<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
|
||||
'<(DEPTH)/lib/certdb/certdb.gyp:certdb',
|
||||
'<(DEPTH)/lib/base/base.gyp:nssb',
|
||||
'<(DEPTH)/lib/dev/dev.gyp:nssdev',
|
||||
'<(DEPTH)/lib/pki/pki.gyp:nsspki',
|
||||
'<(DEPTH)/lib/ssl/ssl.gyp:ssl',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'ct_verif==1', {
|
||||
|
|
|
@ -13,39 +13,7 @@
|
|||
'sources': [
|
||||
'gtest/src/gtest-all.cc'
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/lib/nss/nss.gyp:nss3',
|
||||
'<(DEPTH)/lib/util/util.gyp:nssutil3',
|
||||
'<(DEPTH)/lib/smime/smime.gyp:smime3',
|
||||
'<(DEPTH)/lib/ssl/ssl.gyp:ssl3',
|
||||
'<(DEPTH)/cmd/lib/lib.gyp:sectool'
|
||||
]
|
||||
},
|
||||
{
|
||||
'target_name': 'gtest1',
|
||||
'type': 'shared_library',
|
||||
'dependencies': [
|
||||
'gtest'
|
||||
],
|
||||
# Work around a gyp bug. Fixed upstream in gyp:
|
||||
# https://chromium.googlesource.com/external/gyp/+/93cc6e2c23e4d5ebd179f388e67aa907d0dfd43d
|
||||
'conditions': [
|
||||
['OS!="win"', {
|
||||
'libraries': [
|
||||
'-lstdc++',
|
||||
],
|
||||
}],
|
||||
],
|
||||
# For some reason when just linking static libraries into
|
||||
# a DLL the link fails without this.
|
||||
'msvs_settings': {
|
||||
'VCLinkerTool': {
|
||||
'AdditionalDependencies': [
|
||||
'/DEFAULTLIB:MSVCRT',
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
],
|
||||
'target_defaults': {
|
||||
'include_dirs': [
|
||||
|
|
|
@ -21,9 +21,29 @@
|
|||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'<(DEPTH)/lib/freebl/freebl.gyp:<(freebl_name)',
|
||||
'<(DEPTH)/lib/util/util.gyp:nssutil3',
|
||||
'<(DEPTH)/gtests/google_test/google_test.gyp:gtest',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'test_build==1', {
|
||||
'dependencies': [
|
||||
'<(DEPTH)/lib/nss/nss.gyp:nss_static',
|
||||
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
|
||||
'<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
|
||||
'<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
|
||||
'<(DEPTH)/lib/certdb/certdb.gyp:certdb',
|
||||
'<(DEPTH)/lib/base/base.gyp:nssb',
|
||||
'<(DEPTH)/lib/dev/dev.gyp:nssdev',
|
||||
'<(DEPTH)/lib/pki/pki.gyp:nsspki',
|
||||
'<(DEPTH)/lib/ssl/ssl.gyp:ssl',
|
||||
],
|
||||
}, {
|
||||
'dependencies': [
|
||||
'<(DEPTH)/lib/nss/nss.gyp:nss3',
|
||||
'<(DEPTH)/lib/ssl/ssl.gyp:ssl3',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}
|
||||
],
|
||||
'target_defaults': {
|
||||
|
|
|
@ -62,10 +62,7 @@ PRBool SSLInt_ExtensionNegotiated(PRFileDesc *fd, PRUint16 ext) {
|
|||
return (PRBool)(ss && ssl3_ExtensionNegotiated(ss, ext));
|
||||
}
|
||||
|
||||
void SSLInt_ClearSessionTicketKey() {
|
||||
ssl3_SessionTicketShutdown(NULL, NULL);
|
||||
NSS_UnregisterShutdown(ssl3_SessionTicketShutdown, NULL);
|
||||
}
|
||||
void SSLInt_ClearSessionTicketKey() { ssl_ResetSessionTicketKeys(); }
|
||||
|
||||
SECStatus SSLInt_SetMTU(PRFileDesc *fd, PRUint16 mtu) {
|
||||
sslSocket *ss = ssl_FindSocket(fd);
|
||||
|
@ -209,7 +206,7 @@ PRBool SSLInt_HasCertWithAuthType(PRFileDesc *fd, SSLAuthType authType) {
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return (PRBool)(!!ssl_FindServerCertByAuthType(ss, authType));
|
||||
return (PRBool)(!!ssl_FindServerCert(ss, authType, NULL));
|
||||
}
|
||||
|
||||
PRBool SSLInt_SendAlert(PRFileDesc *fd, uint8_t level, uint8_t type) {
|
||||
|
|
|
@ -51,7 +51,6 @@ INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
|
|||
REQUIRES = nspr nss libdbm gtest
|
||||
|
||||
PROGRAM = ssl_gtest
|
||||
EXTRA_LIBS = $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)softokn.$(LIB_SUFFIX)
|
||||
EXTRA_LIBS = $(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX)
|
||||
|
||||
USE_STATIC_LIBS = 1
|
||||
|
|
|
@ -62,10 +62,22 @@ static const uint8_t kSctValue[] = {0x01, 0x23, 0x45, 0x67, 0x89};
|
|||
static const SECItem kSctItem = {siBuffer, const_cast<uint8_t*>(kSctValue),
|
||||
sizeof(kSctValue)};
|
||||
static const DataBuffer kSctBuffer(kSctValue, sizeof(kSctValue));
|
||||
static const SSLExtraServerCertData kExtraSctData = {ssl_auth_null, nullptr,
|
||||
nullptr, &kSctItem};
|
||||
|
||||
// Test timestamps extraction during a successful handshake.
|
||||
TEST_P(TlsConnectGeneric, SignedCertificateTimestampsHandshake) {
|
||||
TEST_P(TlsConnectGenericPre13, SignedCertificateTimestampsLegacy) {
|
||||
EnsureTlsSetup();
|
||||
|
||||
// We have to use the legacy API consistently here for configuring certs.
|
||||
// Also, this doesn't work in TLS 1.3 because this only configures the SCT for
|
||||
// RSA decrypt and PKCS#1 signing, not PSS.
|
||||
ScopedCERTCertificate cert;
|
||||
ScopedSECKEYPrivateKey priv;
|
||||
ASSERT_TRUE(TlsAgent::LoadCertificate(TlsAgent::kServerRsa, &cert, &priv));
|
||||
EXPECT_EQ(SECSuccess, SSL_ConfigSecureServerWithCertChain(
|
||||
server_->ssl_fd(), cert.get(), nullptr, priv.get(),
|
||||
ssl_kea_rsa));
|
||||
EXPECT_EQ(SECSuccess, SSL_SetSignedCertTimestamps(server_->ssl_fd(),
|
||||
&kSctItem, ssl_kea_rsa));
|
||||
EXPECT_EQ(SECSuccess,
|
||||
|
@ -78,13 +90,10 @@ TEST_P(TlsConnectGeneric, SignedCertificateTimestampsHandshake) {
|
|||
timestamps_extractor.assertTimestamps(kSctBuffer);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, SignedCertificateTimestampsConfig) {
|
||||
static const SSLExtraServerCertData kExtraData = {ssl_auth_rsa_sign, nullptr,
|
||||
nullptr, &kSctItem};
|
||||
|
||||
TEST_P(TlsConnectGeneric, SignedCertificateTimestampsSuccess) {
|
||||
EnsureTlsSetup();
|
||||
EXPECT_TRUE(
|
||||
server_->ConfigServerCert(TlsAgent::kServerRsa, true, &kExtraData));
|
||||
server_->ConfigServerCert(TlsAgent::kServerRsa, true, &kExtraSctData));
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_OptionSet(client_->ssl_fd(), SSL_ENABLE_SIGNED_CERT_TIMESTAMPS,
|
||||
PR_TRUE));
|
||||
|
@ -99,8 +108,8 @@ TEST_P(TlsConnectGeneric, SignedCertificateTimestampsConfig) {
|
|||
// when the client / the server / both have not enabled the feature.
|
||||
TEST_P(TlsConnectGeneric, SignedCertificateTimestampsInactiveClient) {
|
||||
EnsureTlsSetup();
|
||||
EXPECT_EQ(SECSuccess, SSL_SetSignedCertTimestamps(server_->ssl_fd(),
|
||||
&kSctItem, ssl_kea_rsa));
|
||||
EXPECT_TRUE(
|
||||
server_->ConfigServerCert(TlsAgent::kServerRsa, true, &kExtraSctData));
|
||||
SignedCertificateTimestampsExtractor timestamps_extractor(client_);
|
||||
|
||||
Connect();
|
||||
|
@ -141,8 +150,8 @@ static const SECItem kOcspItems[] = {
|
|||
{siBuffer, const_cast<uint8_t*>(kOcspValue2), sizeof(kOcspValue2)}};
|
||||
static const SECItemArray kOcspResponses = {const_cast<SECItem*>(kOcspItems),
|
||||
PR_ARRAY_SIZE(kOcspItems)};
|
||||
const static SSLExtraServerCertData kOcspExtraData = {
|
||||
ssl_auth_rsa_sign, nullptr, &kOcspResponses, nullptr};
|
||||
const static SSLExtraServerCertData kOcspExtraData = {ssl_auth_null, nullptr,
|
||||
&kOcspResponses, nullptr};
|
||||
|
||||
TEST_P(TlsConnectGeneric, NoOcsp) {
|
||||
EnsureTlsSetup();
|
||||
|
|
|
@ -128,16 +128,22 @@ class TlsCipherSuiteTestBase : public TlsConnectTestBase {
|
|||
Connect();
|
||||
SendReceive();
|
||||
|
||||
// Check that we used the right cipher suite.
|
||||
// Check that we used the right cipher suite, auth type and kea type.
|
||||
uint16_t actual;
|
||||
EXPECT_TRUE(client_->cipher_suite(&actual) && actual == cipher_suite_);
|
||||
EXPECT_TRUE(server_->cipher_suite(&actual) && actual == cipher_suite_);
|
||||
EXPECT_TRUE(client_->cipher_suite(&actual));
|
||||
EXPECT_EQ(cipher_suite_, actual);
|
||||
EXPECT_TRUE(server_->cipher_suite(&actual));
|
||||
EXPECT_EQ(cipher_suite_, actual);
|
||||
SSLAuthType auth;
|
||||
EXPECT_TRUE(client_->auth_type(&auth) && auth == auth_type_);
|
||||
EXPECT_TRUE(server_->auth_type(&auth) && auth == auth_type_);
|
||||
EXPECT_TRUE(client_->auth_type(&auth));
|
||||
EXPECT_EQ(auth_type_, auth);
|
||||
EXPECT_TRUE(server_->auth_type(&auth));
|
||||
EXPECT_EQ(auth_type_, auth);
|
||||
SSLKEAType kea;
|
||||
EXPECT_TRUE(client_->kea_type(&kea) && kea == kea_type_);
|
||||
EXPECT_TRUE(server_->kea_type(&kea) && kea == kea_type_);
|
||||
EXPECT_TRUE(client_->kea_type(&kea));
|
||||
EXPECT_EQ(kea_type_, kea);
|
||||
EXPECT_TRUE(server_->kea_type(&kea));
|
||||
EXPECT_EQ(kea_type_, kea);
|
||||
}
|
||||
|
||||
// Get the expected limit on the number of records that can be sent for the
|
||||
|
|
|
@ -47,27 +47,33 @@
|
|||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'<(DEPTH)/lib/util/util.gyp:nssutil3',
|
||||
'<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3',
|
||||
'<(DEPTH)/gtests/google_test/google_test.gyp:gtest',
|
||||
'<(DEPTH)/lib/softoken/softoken.gyp:softokn',
|
||||
'<(DEPTH)/lib/smime/smime.gyp:smime',
|
||||
'<(DEPTH)/lib/ssl/ssl.gyp:ssl',
|
||||
'<(DEPTH)/lib/nss/nss.gyp:nss_static',
|
||||
'<(DEPTH)/cmd/lib/lib.gyp:sectool',
|
||||
'<(DEPTH)/lib/pkcs12/pkcs12.gyp:pkcs12',
|
||||
'<(DEPTH)/lib/pkcs7/pkcs7.gyp:pkcs7',
|
||||
'<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
|
||||
'<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
|
||||
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap',
|
||||
'<(DEPTH)/lib/softoken/softoken.gyp:softokn',
|
||||
'<(DEPTH)/lib/certdb/certdb.gyp:certdb',
|
||||
'<(DEPTH)/lib/pki/pki.gyp:nsspki',
|
||||
'<(DEPTH)/lib/dev/dev.gyp:nssdev',
|
||||
'<(DEPTH)/lib/base/base.gyp:nssb',
|
||||
'<(DEPTH)/lib/freebl/freebl.gyp:<(freebl_name)',
|
||||
'<(DEPTH)/lib/zlib/zlib.gyp:nss_zlib'
|
||||
],
|
||||
'conditions': [
|
||||
[ 'test_build==1', {
|
||||
'dependencies': [
|
||||
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
|
||||
],
|
||||
}, {
|
||||
'dependencies': [
|
||||
'<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3',
|
||||
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap',
|
||||
'<(DEPTH)/lib/softoken/softoken.gyp:softokn',
|
||||
'<(DEPTH)/lib/freebl/freebl.gyp:freebl',
|
||||
],
|
||||
}],
|
||||
[ 'disable_dbm==0', {
|
||||
'dependencies': [
|
||||
'<(DEPTH)/lib/dbm/src/src.gyp:dbm',
|
||||
|
@ -103,6 +109,5 @@
|
|||
},
|
||||
'variables': {
|
||||
'module': 'nss',
|
||||
'use_static_libs': 1,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,22 +102,34 @@ void TlsAgent::SetState(State state) {
|
|||
state_ = state;
|
||||
}
|
||||
|
||||
/*static*/ bool TlsAgent::LoadCertificate(const std::string& name,
|
||||
ScopedCERTCertificate* cert,
|
||||
ScopedSECKEYPrivateKey* priv) {
|
||||
cert->reset(PK11_FindCertFromNickname(name.c_str(), nullptr));
|
||||
EXPECT_NE(nullptr, cert->get());
|
||||
if (!cert->get()) return false;
|
||||
|
||||
priv->reset(PK11_FindKeyByAnyCert(cert->get(), nullptr));
|
||||
EXPECT_NE(nullptr, priv->get());
|
||||
if (!priv->get()) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TlsAgent::ConfigServerCert(const std::string& name, bool updateKeyBits,
|
||||
const SSLExtraServerCertData* serverCertData) {
|
||||
ScopedCERTCertificate cert(PK11_FindCertFromNickname(name.c_str(), nullptr));
|
||||
EXPECT_NE(nullptr, cert.get());
|
||||
if (!cert.get()) return false;
|
||||
|
||||
ScopedSECKEYPublicKey pub(CERT_ExtractPublicKey(cert.get()));
|
||||
EXPECT_NE(nullptr, pub.get());
|
||||
if (!pub.get()) return false;
|
||||
if (updateKeyBits) {
|
||||
server_key_bits_ = SECKEY_PublicKeyStrengthInBits(pub.get());
|
||||
ScopedCERTCertificate cert;
|
||||
ScopedSECKEYPrivateKey priv;
|
||||
if (!TlsAgent::LoadCertificate(name, &cert, &priv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ScopedSECKEYPrivateKey priv(PK11_FindKeyByAnyCert(cert.get(), nullptr));
|
||||
EXPECT_NE(nullptr, priv.get());
|
||||
if (!priv.get()) return false;
|
||||
if (updateKeyBits) {
|
||||
ScopedSECKEYPublicKey pub(CERT_ExtractPublicKey(cert.get()));
|
||||
EXPECT_NE(nullptr, pub.get());
|
||||
if (!pub.get()) return false;
|
||||
server_key_bits_ = SECKEY_PublicKeyStrengthInBits(pub.get());
|
||||
}
|
||||
|
||||
SECStatus rv =
|
||||
SSL_ConfigSecureServer(ssl_fd_, nullptr, nullptr, ssl_kea_null);
|
||||
|
@ -181,30 +193,23 @@ void TlsAgent::SetupClientAuth() {
|
|||
reinterpret_cast<void*>(this)));
|
||||
}
|
||||
|
||||
bool TlsAgent::GetClientAuthCredentials(CERTCertificate** cert,
|
||||
SECKEYPrivateKey** priv) const {
|
||||
*cert = PK11_FindCertFromNickname(name_.c_str(), nullptr);
|
||||
EXPECT_NE(nullptr, *cert);
|
||||
if (!*cert) return false;
|
||||
|
||||
*priv = PK11_FindKeyByAnyCert(*cert, nullptr);
|
||||
EXPECT_NE(nullptr, *priv);
|
||||
if (!*priv) return false; // Leak cert.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SECStatus TlsAgent::GetClientAuthDataHook(void* self, PRFileDesc* fd,
|
||||
CERTDistNames* caNames,
|
||||
CERTCertificate** cert,
|
||||
SECKEYPrivateKey** privKey) {
|
||||
CERTCertificate** clientCert,
|
||||
SECKEYPrivateKey** clientKey) {
|
||||
TlsAgent* agent = reinterpret_cast<TlsAgent*>(self);
|
||||
ScopedCERTCertificate peerCert(SSL_PeerCertificate(agent->ssl_fd()));
|
||||
EXPECT_TRUE(peerCert) << "Client should be able to see the server cert";
|
||||
if (agent->GetClientAuthCredentials(cert, privKey)) {
|
||||
return SECSuccess;
|
||||
|
||||
ScopedCERTCertificate cert;
|
||||
ScopedSECKEYPrivateKey priv;
|
||||
if (!TlsAgent::LoadCertificate(agent->name(), &cert, &priv)) {
|
||||
return SECFailure;
|
||||
}
|
||||
return SECFailure;
|
||||
|
||||
*clientCert = cert.release();
|
||||
*clientKey = priv.release();
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
bool TlsAgent::GetPeerChainLength(size_t* count) {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#define GTEST_HAS_RTTI 0
|
||||
#include "gtest/gtest.h"
|
||||
#include "scoped_ptrs.h"
|
||||
|
||||
extern bool g_ssl_gtest_verbose;
|
||||
|
||||
|
@ -115,6 +116,9 @@ class TlsAgent : public PollTarget {
|
|||
void PrepareForRenegotiate();
|
||||
// Prepares for renegotiation, then actually triggers it.
|
||||
void StartRenegotiate();
|
||||
static bool LoadCertificate(const std::string& name,
|
||||
ScopedCERTCertificate* cert,
|
||||
ScopedSECKEYPrivateKey* priv);
|
||||
bool ConfigServerCert(const std::string& name, bool updateKeyBits = false,
|
||||
const SSLExtraServerCertData* serverCertData = nullptr);
|
||||
bool ConfigServerCertWithChain(const std::string& name);
|
||||
|
@ -122,8 +126,6 @@ class TlsAgent : public PollTarget {
|
|||
|
||||
void SetupClientAuth();
|
||||
void RequestClientAuth(bool requireAuth);
|
||||
bool GetClientAuthCredentials(CERTCertificate** cert,
|
||||
SECKEYPrivateKey** priv) const;
|
||||
|
||||
void ConfigureSessionCache(SessionResumptionMode mode);
|
||||
void SetSessionTicketsEnabled(bool en);
|
||||
|
|
|
@ -13,6 +13,7 @@ extern "C" {
|
|||
|
||||
#include "databuffer.h"
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "sslproto.h"
|
||||
|
||||
extern std::string g_working_dir_path;
|
||||
|
@ -345,6 +346,13 @@ void TlsConnectTestBase::CheckKeys(SSLKEAType kea_type,
|
|||
scheme = ssl_sig_none;
|
||||
break;
|
||||
case ssl_auth_rsa_sign:
|
||||
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_2) {
|
||||
scheme = ssl_sig_rsa_pss_sha256;
|
||||
} else {
|
||||
scheme = ssl_sig_rsa_pkcs1_sha256;
|
||||
}
|
||||
break;
|
||||
case ssl_auth_rsa_pss:
|
||||
scheme = ssl_sig_rsa_pss_sha256;
|
||||
break;
|
||||
case ssl_auth_ecdsa:
|
||||
|
@ -390,6 +398,7 @@ void TlsConnectTestBase::ConnectExpectFailOneSide(TlsAgent::Role failing_side) {
|
|||
}
|
||||
|
||||
void TlsConnectTestBase::ConfigureVersion(uint16_t version) {
|
||||
version_ = version;
|
||||
client_->SetVersionRange(version, version);
|
||||
server_->SetVersionRange(version, version);
|
||||
}
|
||||
|
@ -440,10 +449,16 @@ void TlsConnectTestBase::ConfigureSessionCache(SessionResumptionMode client,
|
|||
client_->ConfigureSessionCache(client);
|
||||
server_->ConfigureSessionCache(server);
|
||||
if ((server & RESUME_TICKET) != 0) {
|
||||
// This is an abomination. NSS encrypts session tickets with the server's
|
||||
// RSA public key. That means we need the server to have an RSA certificate
|
||||
// even if it won't be used for the connection.
|
||||
server_->ConfigServerCert(TlsAgent::kServerRsaDecrypt);
|
||||
ScopedCERTCertificate cert;
|
||||
ScopedSECKEYPrivateKey privKey;
|
||||
ASSERT_TRUE(TlsAgent::LoadCertificate(TlsAgent::kServerRsaDecrypt, &cert,
|
||||
&privKey));
|
||||
|
||||
ScopedSECKEYPublicKey pubKey(CERT_ExtractPublicKey(cert.get()));
|
||||
ASSERT_TRUE(pubKey);
|
||||
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_SetSessionTicketKeyPair(pubKey.get(), privKey.get()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,15 @@
|
|||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'<(DEPTH)/gtests/google_test/google_test.gyp:gtest',
|
||||
'<(DEPTH)/lib/util/util.gyp:nssutil',
|
||||
'<(DEPTH)/lib/nss/nss.gyp:nss_static',
|
||||
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
|
||||
'<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
|
||||
'<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
|
||||
'<(DEPTH)/lib/certdb/certdb.gyp:certdb',
|
||||
'<(DEPTH)/lib/base/base.gyp:nssb',
|
||||
'<(DEPTH)/lib/dev/dev.gyp:nssdev',
|
||||
'<(DEPTH)/lib/pki/pki.gyp:nsspki',
|
||||
'<(DEPTH)/lib/ssl/ssl.gyp:ssl',
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
|
@ -341,13 +341,16 @@ hexToBin(PLArenaPool* pool, SECItem* destItem, const char* src, int len)
|
|||
goto loser;
|
||||
}
|
||||
len >>= 1;
|
||||
if (!SECITEM_AllocItem(pool, destItem, len))
|
||||
if (!SECITEM_AllocItem(pool, destItem, len)) {
|
||||
goto loser;
|
||||
}
|
||||
dest = destItem->data;
|
||||
for (; len > 0; len--, src += 2) {
|
||||
PRInt16 bin = (x2b[(PRUint8)src[0]] << 4) | x2b[(PRUint8)src[1]];
|
||||
if (bin < 0)
|
||||
PRUint16 bin = ((PRUint16)x2b[(PRUint8)src[0]] << 4);
|
||||
bin |= (PRUint16)x2b[(PRUint8)src[1]];
|
||||
if (bin >> 15) { /* is negative */
|
||||
goto loser;
|
||||
}
|
||||
*dest++ = (PRUint8)bin;
|
||||
}
|
||||
return SECSuccess;
|
||||
|
|
|
@ -32,125 +32,55 @@
|
|||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
]
|
||||
},
|
||||
# For test builds, build a static freebl library so we can statically
|
||||
# link it into the test build binary. This way we don't have to
|
||||
# dlopen() the shared lib but can directly call freebl functions.
|
||||
{
|
||||
'target_name': '<(freebl_name)',
|
||||
'type': 'shared_library',
|
||||
'sources': [
|
||||
'aeskeywrap.c',
|
||||
'alg2268.c',
|
||||
'alghmac.c',
|
||||
'arcfive.c',
|
||||
'arcfour.c',
|
||||
'camellia.c',
|
||||
'chacha20poly1305.c',
|
||||
'ctr.c',
|
||||
'cts.c',
|
||||
'des.c',
|
||||
'desblapi.c',
|
||||
'dh.c',
|
||||
'drbg.c',
|
||||
'dsa.c',
|
||||
'ec.c',
|
||||
'ecdecode.c',
|
||||
'ecl/ec_naf.c',
|
||||
'ecl/ecl.c',
|
||||
'ecl/ecl_curve.c',
|
||||
'ecl/ecl_gf.c',
|
||||
'ecl/ecl_mult.c',
|
||||
'ecl/ecp_25519.c',
|
||||
'ecl/ecp_256.c',
|
||||
'ecl/ecp_256_32.c',
|
||||
'ecl/ecp_384.c',
|
||||
'ecl/ecp_521.c',
|
||||
'ecl/ecp_aff.c',
|
||||
'ecl/ecp_jac.c',
|
||||
'ecl/ecp_jm.c',
|
||||
'ecl/ecp_mont.c',
|
||||
'fipsfreebl.c',
|
||||
'freeblver.c',
|
||||
'gcm.c',
|
||||
'hmacct.c',
|
||||
'jpake.c',
|
||||
'ldvector.c',
|
||||
'md2.c',
|
||||
'md5.c',
|
||||
'mpi/mp_gf2m.c',
|
||||
'mpi/mpcpucache.c',
|
||||
'mpi/mpi.c',
|
||||
'mpi/mplogic.c',
|
||||
'mpi/mpmontg.c',
|
||||
'mpi/mpprime.c',
|
||||
'pqg.c',
|
||||
'rawhash.c',
|
||||
'rijndael.c',
|
||||
'rsa.c',
|
||||
'rsapkcs.c',
|
||||
'seed.c',
|
||||
'sha512.c',
|
||||
'sha_fast.c',
|
||||
'shvfy.c',
|
||||
'sysrand.c',
|
||||
'tlsprfalg.c'
|
||||
'target_name': 'freebl_static',
|
||||
'type': 'static_library',
|
||||
'includes': [
|
||||
'freebl_base.gypi',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'OS=="linux"', {
|
||||
'sources': [
|
||||
'nsslowhash.c',
|
||||
'stubs.c',
|
||||
'defines!': [
|
||||
'FREEBL_NO_DEPEND',
|
||||
'FREEBL_LOWHASH',
|
||||
'USE_HW_AES',
|
||||
'INTEL_GCM',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'test_build==1', {
|
||||
'dependencies': [
|
||||
'<(DEPTH)/lib/util/util.gyp:nssutil3',
|
||||
],
|
||||
}],
|
||||
]
|
||||
}],
|
||||
[ 'OS=="linux" or OS=="android"', {
|
||||
'conditions': [
|
||||
[ 'target_arch=="x64"', {
|
||||
'sources': [
|
||||
'arcfour-amd64-gas.s',
|
||||
# The AES assembler code doesn't work in static test builds.
|
||||
# The linker complains about non-relocatable code, and I
|
||||
# currently don't know how to fix this properly.
|
||||
'sources!': [
|
||||
'intel-aes.s',
|
||||
'intel-gcm.s',
|
||||
'mpi/mpi_amd64.c',
|
||||
'mpi/mpi_amd64_gas.s',
|
||||
'mpi/mp_comba.c',
|
||||
],
|
||||
'dependencies': [
|
||||
'intel-gcm-wrap_c_lib',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'cc_is_clang==1', {
|
||||
'cflags': [
|
||||
'-no-integrated-as',
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-no-integrated-as',
|
||||
],
|
||||
'asflags_mozilla': [
|
||||
'-no-integrated-as',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="ia32"', {
|
||||
'sources': [
|
||||
'mpi/mpi_x86.s',
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="arm"', {
|
||||
'sources': [
|
||||
'mpi/mpi_arm.c',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}, {
|
||||
# not Linux or Android
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': '<(freebl_name)',
|
||||
'type': 'shared_library',
|
||||
'includes': [
|
||||
'freebl_base.gypi',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'OS!="linux" and OS!="android"', {
|
||||
'conditions': [
|
||||
[ 'moz_fold_libs==0', {
|
||||
'dependencies': [
|
||||
'../util/util.gyp:nssutil3',
|
||||
'<(DEPTH)/lib/util/util.gyp:nssutil3',
|
||||
],
|
||||
}, {
|
||||
'libraries': [
|
||||
|
@ -158,104 +88,22 @@
|
|||
],
|
||||
}],
|
||||
],
|
||||
}, 'target_arch=="x64"', {
|
||||
'dependencies': [
|
||||
'intel-gcm-wrap_c_lib',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="win"', {
|
||||
[ 'OS=="win" and cc_is_clang==1', {
|
||||
'dependencies': [
|
||||
'intel-gcm-wrap_c_lib',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="linux"', {
|
||||
'sources': [
|
||||
#TODO: building with mingw should not need this.
|
||||
'ecl/uint128.c',
|
||||
],
|
||||
'libraries': [
|
||||
'advapi32.lib',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'target_arch=="x64"', {
|
||||
'sources': [
|
||||
'arcfour-amd64-masm.asm',
|
||||
'mpi/mpi_amd64.c',
|
||||
'mpi/mpi_amd64_masm.asm',
|
||||
'mpi/mp_comba_amd64_masm.asm',
|
||||
'intel-aes-x64-masm.asm',
|
||||
'intel-gcm-x64-masm.asm',
|
||||
],
|
||||
}, {
|
||||
# not x64
|
||||
'sources': [
|
||||
'mpi/mpi_x86_asm.c',
|
||||
'intel-aes-x86-masm.asm',
|
||||
'intel-gcm-x86-masm.asm',
|
||||
],
|
||||
}],
|
||||
[ 'cc_is_clang==1', {
|
||||
'dependencies': [
|
||||
'intel-gcm-wrap_c_lib',
|
||||
],
|
||||
}, {
|
||||
# MSVC
|
||||
'sources': [
|
||||
'intel-gcm-wrap.c',
|
||||
],
|
||||
}],
|
||||
'nsslowhash.c',
|
||||
'stubs.c',
|
||||
],
|
||||
}],
|
||||
['target_arch=="ia32" or target_arch=="x64"', {
|
||||
'sources': [
|
||||
# All intel architectures get the 64 bit version
|
||||
'ecl/curve25519_64.c',
|
||||
],
|
||||
}, {
|
||||
'sources': [
|
||||
# All non intel architectures get the generic 32 bit implementation (slow!)
|
||||
'ecl/curve25519_32.c',
|
||||
],
|
||||
}],
|
||||
#TODO uint128.c
|
||||
[ 'disable_chachapoly==0', {
|
||||
'conditions': [
|
||||
[ 'OS!="win" and target_arch=="x64"', {
|
||||
'sources': [
|
||||
'chacha20_vec.c',
|
||||
'poly1305-donna-x64-sse2-incremental-source.c',
|
||||
],
|
||||
}, {
|
||||
# not x64
|
||||
'sources': [
|
||||
'chacha20.c',
|
||||
'poly1305.c',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
[ 'fuzz_tls==1', {
|
||||
'sources': [
|
||||
'det_rng.c',
|
||||
],
|
||||
'defines': [
|
||||
'UNSAFE_FUZZER_MODE',
|
||||
],
|
||||
}],
|
||||
[ 'ct_verif==1', {
|
||||
'defines': [
|
||||
'CT_VERIF',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="mac"', {
|
||||
'conditions': [
|
||||
[ 'target_arch=="ia32"', {
|
||||
'sources': [
|
||||
'mpi/mpi_sse2.s',
|
||||
],
|
||||
'defines': [
|
||||
'MP_USE_UINT_DIGIT',
|
||||
'MP_ASSEMBLY_MULTIPLY',
|
||||
'MP_ASSEMBLY_SQUARE',
|
||||
'MP_ASSEMBLY_DIV_2DX1D',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
],
|
||||
'variables': {
|
||||
'conditions': [
|
||||
|
@ -266,9 +114,6 @@
|
|||
}],
|
||||
]
|
||||
},
|
||||
'ldflags': [
|
||||
'-Wl,-Bsymbolic'
|
||||
]
|
||||
},
|
||||
],
|
||||
'conditions': [
|
||||
|
@ -371,13 +216,7 @@
|
|||
[ 'OS=="linux"', {
|
||||
'defines': [
|
||||
'FREEBL_LOWHASH',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'test_build==0', {
|
||||
'defines': [
|
||||
'FREEBL_NO_DEPEND',
|
||||
],
|
||||
}],
|
||||
'FREEBL_NO_DEPEND',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="linux" or OS=="android"', {
|
||||
|
|
|
@ -0,0 +1,194 @@
|
|||
# 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/.
|
||||
{
|
||||
'sources': [
|
||||
'aeskeywrap.c',
|
||||
'alg2268.c',
|
||||
'alghmac.c',
|
||||
'arcfive.c',
|
||||
'arcfour.c',
|
||||
'camellia.c',
|
||||
'chacha20poly1305.c',
|
||||
'ctr.c',
|
||||
'cts.c',
|
||||
'des.c',
|
||||
'desblapi.c',
|
||||
'dh.c',
|
||||
'drbg.c',
|
||||
'dsa.c',
|
||||
'ec.c',
|
||||
'ecdecode.c',
|
||||
'ecl/ec_naf.c',
|
||||
'ecl/ecl.c',
|
||||
'ecl/ecl_curve.c',
|
||||
'ecl/ecl_gf.c',
|
||||
'ecl/ecl_mult.c',
|
||||
'ecl/ecp_25519.c',
|
||||
'ecl/ecp_256.c',
|
||||
'ecl/ecp_256_32.c',
|
||||
'ecl/ecp_384.c',
|
||||
'ecl/ecp_521.c',
|
||||
'ecl/ecp_aff.c',
|
||||
'ecl/ecp_jac.c',
|
||||
'ecl/ecp_jm.c',
|
||||
'ecl/ecp_mont.c',
|
||||
'fipsfreebl.c',
|
||||
'freeblver.c',
|
||||
'gcm.c',
|
||||
'hmacct.c',
|
||||
'jpake.c',
|
||||
'ldvector.c',
|
||||
'md2.c',
|
||||
'md5.c',
|
||||
'mpi/mp_gf2m.c',
|
||||
'mpi/mpcpucache.c',
|
||||
'mpi/mpi.c',
|
||||
'mpi/mplogic.c',
|
||||
'mpi/mpmontg.c',
|
||||
'mpi/mpprime.c',
|
||||
'pqg.c',
|
||||
'rawhash.c',
|
||||
'rijndael.c',
|
||||
'rsa.c',
|
||||
'rsapkcs.c',
|
||||
'seed.c',
|
||||
'sha512.c',
|
||||
'sha_fast.c',
|
||||
'shvfy.c',
|
||||
'sysrand.c',
|
||||
'tlsprfalg.c'
|
||||
],
|
||||
'conditions': [
|
||||
[ 'OS=="linux" or OS=="android"', {
|
||||
'conditions': [
|
||||
[ 'target_arch=="x64"', {
|
||||
'sources': [
|
||||
'arcfour-amd64-gas.s',
|
||||
'intel-aes.s',
|
||||
'intel-gcm.s',
|
||||
'mpi/mpi_amd64.c',
|
||||
'mpi/mpi_amd64_gas.s',
|
||||
'mpi/mp_comba.c',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'cc_is_clang==1', {
|
||||
'cflags': [
|
||||
'-no-integrated-as',
|
||||
],
|
||||
'cflags_mozilla': [
|
||||
'-no-integrated-as',
|
||||
],
|
||||
'asflags_mozilla': [
|
||||
'-no-integrated-as',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="ia32"', {
|
||||
'sources': [
|
||||
'mpi/mpi_x86.s',
|
||||
],
|
||||
}],
|
||||
[ 'target_arch=="arm"', {
|
||||
'sources': [
|
||||
'mpi/mpi_arm.c',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
[ 'OS=="win"', {
|
||||
'sources': [
|
||||
#TODO: building with mingw should not need this.
|
||||
'ecl/uint128.c',
|
||||
],
|
||||
'libraries': [
|
||||
'advapi32.lib',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'target_arch=="x64"', {
|
||||
'sources': [
|
||||
'arcfour-amd64-masm.asm',
|
||||
'mpi/mpi_amd64.c',
|
||||
'mpi/mpi_amd64_masm.asm',
|
||||
'mpi/mp_comba_amd64_masm.asm',
|
||||
'intel-aes-x64-masm.asm',
|
||||
'intel-gcm-x64-masm.asm',
|
||||
],
|
||||
}, {
|
||||
# not x64
|
||||
'sources': [
|
||||
'mpi/mpi_x86_asm.c',
|
||||
'intel-aes-x86-masm.asm',
|
||||
'intel-gcm-x86-masm.asm',
|
||||
],
|
||||
}],
|
||||
[ 'cc_is_clang!=1', {
|
||||
# MSVC
|
||||
'sources': [
|
||||
'intel-gcm-wrap.c',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
['target_arch=="ia32" or target_arch=="x64"', {
|
||||
'sources': [
|
||||
# All intel architectures get the 64 bit version
|
||||
'ecl/curve25519_64.c',
|
||||
],
|
||||
}, {
|
||||
'sources': [
|
||||
# All non intel architectures get the generic 32 bit implementation (slow!)
|
||||
'ecl/curve25519_32.c',
|
||||
],
|
||||
}],
|
||||
#TODO uint128.c
|
||||
[ 'disable_chachapoly==0', {
|
||||
'conditions': [
|
||||
[ 'OS!="win" and target_arch=="x64"', {
|
||||
'sources': [
|
||||
'chacha20_vec.c',
|
||||
'poly1305-donna-x64-sse2-incremental-source.c',
|
||||
],
|
||||
}, {
|
||||
# not x64
|
||||
'sources': [
|
||||
'chacha20.c',
|
||||
'poly1305.c',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
[ 'fuzz_tls==1', {
|
||||
'sources': [
|
||||
'det_rng.c',
|
||||
],
|
||||
'defines': [
|
||||
'UNSAFE_FUZZER_MODE',
|
||||
],
|
||||
}],
|
||||
[ 'ct_verif==1', {
|
||||
'defines': [
|
||||
'CT_VERIF',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="mac"', {
|
||||
'conditions': [
|
||||
[ 'target_arch=="ia32"', {
|
||||
'sources': [
|
||||
'mpi/mpi_sse2.s',
|
||||
],
|
||||
'defines': [
|
||||
'MP_USE_UINT_DIGIT',
|
||||
'MP_ASSEMBLY_MULTIPLY',
|
||||
'MP_ASSEMBLY_SQUARE',
|
||||
'MP_ASSEMBLY_DIV_2DX1D',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}],
|
||||
],
|
||||
'ldflags': [
|
||||
'-Wl,-Bsymbolic'
|
||||
],
|
||||
}
|
|
@ -22,9 +22,9 @@
|
|||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
|
||||
*/
|
||||
#define NSS_VERSION "3.29" _NSS_CUSTOMIZED " Beta"
|
||||
#define NSS_VERSION "3.30" _NSS_CUSTOMIZED " Beta"
|
||||
#define NSS_VMAJOR 3
|
||||
#define NSS_VMINOR 29
|
||||
#define NSS_VMINOR 30
|
||||
#define NSS_VPATCH 0
|
||||
#define NSS_VBUILD 0
|
||||
#define NSS_BETA PR_TRUE
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
#include "secerr.h"
|
||||
#include "prenv.h"
|
||||
#include "utilparst.h"
|
||||
#include "prio.h"
|
||||
#include "prprf.h"
|
||||
#include <stdio.h>
|
||||
#include "prsystem.h"
|
||||
|
||||
#define DEBUG_MODULE 1
|
||||
|
||||
|
@ -350,6 +354,7 @@ SECMOD_SetRootCerts(PK11SlotInfo *slot, SECMODModule *mod)
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef NSS_TEST_BUILD
|
||||
static const char *my_shlib_name =
|
||||
SHLIB_PREFIX "nss" SHLIB_VERSION "." SHLIB_SUFFIX;
|
||||
static const char *softoken_shlib_name =
|
||||
|
@ -359,11 +364,6 @@ static PRCallOnceType loadSoftokenOnce;
|
|||
static PRLibrary *softokenLib;
|
||||
static PRInt32 softokenLoadCount;
|
||||
|
||||
#include "prio.h"
|
||||
#include "prprf.h"
|
||||
#include <stdio.h>
|
||||
#include "prsystem.h"
|
||||
|
||||
/* This function must be run only once. */
|
||||
/* determine if hybrid platform, then actually load the DSO. */
|
||||
static PRStatus
|
||||
|
@ -380,6 +380,10 @@ softoken_LoadDSO(void)
|
|||
}
|
||||
return PR_FAILURE;
|
||||
}
|
||||
#else
|
||||
CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList);
|
||||
char **NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* load a new module into our address space and initialize it.
|
||||
|
@ -398,8 +402,11 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
|
|||
if (mod->loaded)
|
||||
return SECSuccess;
|
||||
|
||||
/* intenal modules get loaded from their internal list */
|
||||
/* internal modules get loaded from their internal list */
|
||||
if (mod->internal && (mod->dllName == NULL)) {
|
||||
#ifdef NSS_TEST_BUILD
|
||||
entry = (CK_C_GetFunctionList)NSC_GetFunctionList;
|
||||
#else
|
||||
/*
|
||||
* Loads softoken as a dynamic library,
|
||||
* even though the rest of NSS assumes this as the "internal" module.
|
||||
|
@ -420,10 +427,15 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
|
|||
|
||||
if (!entry)
|
||||
return SECFailure;
|
||||
#endif
|
||||
|
||||
if (mod->isModuleDB) {
|
||||
mod->moduleDBFunc = (CK_C_GetFunctionList)
|
||||
#ifdef NSS_TEST_BUILD
|
||||
NSC_ModuleDBFunc;
|
||||
#else
|
||||
PR_FindSymbol(softokenLib, "NSC_ModuleDBFunc");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mod->moduleDBOnly) {
|
||||
|
@ -601,6 +613,7 @@ SECMOD_UnloadModule(SECMODModule *mod)
|
|||
* if not, we should change this to SECFailure and move it above the
|
||||
* mod->loaded = PR_FALSE; */
|
||||
if (mod->internal && (mod->dllName == NULL)) {
|
||||
#ifndef NSS_TEST_BUILD
|
||||
if (0 == PR_ATOMIC_DECREMENT(&softokenLoadCount)) {
|
||||
if (softokenLib) {
|
||||
disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
|
||||
|
@ -616,6 +629,7 @@ SECMOD_UnloadModule(SECMODModule *mod)
|
|||
}
|
||||
loadSoftokenOnce = pristineCallOnce;
|
||||
}
|
||||
#endif
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,35 +7,54 @@
|
|||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'pk11wrap',
|
||||
'target_name': 'pk11wrap_static',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'dev3hack.c',
|
||||
'pk11akey.c',
|
||||
'pk11auth.c',
|
||||
'pk11cert.c',
|
||||
'pk11cxt.c',
|
||||
'pk11err.c',
|
||||
'pk11kea.c',
|
||||
'pk11list.c',
|
||||
'pk11load.c',
|
||||
'pk11mech.c',
|
||||
'pk11merge.c',
|
||||
'pk11nobj.c',
|
||||
'pk11obj.c',
|
||||
'pk11pars.c',
|
||||
'pk11pbe.c',
|
||||
'pk11pk12.c',
|
||||
'pk11pqg.c',
|
||||
'pk11sdr.c',
|
||||
'pk11skey.c',
|
||||
'pk11slot.c',
|
||||
'pk11util.c'
|
||||
'defines': [
|
||||
'NSS_TEST_BUILD',
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
]
|
||||
}
|
||||
'pk11wrap_base',
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'<(DEPTH)/lib/softoken/softoken.gyp:softokn_static',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'pk11wrap',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'pk11wrap_base',
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'pk11wrap_base',
|
||||
'type': 'none',
|
||||
'direct_dependent_settings': {
|
||||
'sources': [
|
||||
'dev3hack.c',
|
||||
'pk11akey.c',
|
||||
'pk11auth.c',
|
||||
'pk11cert.c',
|
||||
'pk11cxt.c',
|
||||
'pk11err.c',
|
||||
'pk11kea.c',
|
||||
'pk11list.c',
|
||||
'pk11load.c',
|
||||
'pk11mech.c',
|
||||
'pk11merge.c',
|
||||
'pk11nobj.c',
|
||||
'pk11obj.c',
|
||||
'pk11pars.c',
|
||||
'pk11pbe.c',
|
||||
'pk11pk12.c',
|
||||
'pk11pqg.c',
|
||||
'pk11sdr.c',
|
||||
'pk11skey.c',
|
||||
'pk11slot.c',
|
||||
'pk11util.c'
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
'target_defaults': {
|
||||
'defines': [
|
||||
|
@ -48,4 +67,4 @@
|
|||
'variables': {
|
||||
'module': 'nss'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,9 +47,6 @@ struct DBSStr {
|
|||
char *blobdir;
|
||||
int mode;
|
||||
PRBool readOnly;
|
||||
PRFileMap *dbs_mapfile;
|
||||
unsigned char *dbs_addr;
|
||||
PRUint32 dbs_len;
|
||||
char staticBlobArea[BLOB_BUF_LEN];
|
||||
};
|
||||
|
||||
|
@ -243,43 +240,6 @@ loser:
|
|||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* we need to keep a address map in memory between calls to DBM.
|
||||
* remember what we have mapped can close it when we get another dbm
|
||||
* call.
|
||||
*
|
||||
* NOTE: Not all platforms support mapped files. This code is designed to
|
||||
* detect this at runtime. If map files aren't supported the OS will indicate
|
||||
* this by failing the PR_Memmap call. In this case we emulate mapped files
|
||||
* by just reading in the file into regular memory. We signal this state by
|
||||
* making dbs_mapfile NULL and dbs_addr non-NULL.
|
||||
*/
|
||||
|
||||
static void
|
||||
dbs_freemap(DBS *dbsp)
|
||||
{
|
||||
if (dbsp->dbs_mapfile) {
|
||||
PR_MemUnmap(dbsp->dbs_addr, dbsp->dbs_len);
|
||||
PR_CloseFileMap(dbsp->dbs_mapfile);
|
||||
dbsp->dbs_mapfile = NULL;
|
||||
dbsp->dbs_addr = NULL;
|
||||
dbsp->dbs_len = 0;
|
||||
} else if (dbsp->dbs_addr) {
|
||||
PORT_Free(dbsp->dbs_addr);
|
||||
dbsp->dbs_addr = NULL;
|
||||
dbsp->dbs_len = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
dbs_setmap(DBS *dbsp, PRFileMap *mapfile, unsigned char *addr, PRUint32 len)
|
||||
{
|
||||
dbsp->dbs_mapfile = mapfile;
|
||||
dbsp->dbs_addr = addr;
|
||||
dbsp->dbs_len = len;
|
||||
}
|
||||
|
||||
/*
|
||||
* platforms that cannot map the file need to read it into a temp buffer.
|
||||
*/
|
||||
|
@ -317,7 +277,6 @@ dbs_readBlob(DBS *dbsp, DBT *data)
|
|||
{
|
||||
char *file = NULL;
|
||||
PRFileDesc *filed = NULL;
|
||||
PRFileMap *mapfile = NULL;
|
||||
unsigned char *addr = NULL;
|
||||
int error;
|
||||
int len = -1;
|
||||
|
@ -344,7 +303,6 @@ dbs_readBlob(DBS *dbsp, DBT *data)
|
|||
goto loser;
|
||||
}
|
||||
PR_Close(filed);
|
||||
dbs_setmap(dbsp, mapfile, addr, len);
|
||||
|
||||
data->data = addr;
|
||||
data->size = len;
|
||||
|
@ -353,9 +311,6 @@ dbs_readBlob(DBS *dbsp, DBT *data)
|
|||
loser:
|
||||
/* preserve the error code */
|
||||
error = PR_GetError();
|
||||
if (mapfile) {
|
||||
PR_CloseFileMap(mapfile);
|
||||
}
|
||||
if (filed) {
|
||||
PR_Close(filed);
|
||||
}
|
||||
|
@ -373,8 +328,6 @@ dbs_get(const DB *dbs, const DBT *key, DBT *data, unsigned int flags)
|
|||
DBS *dbsp = (DBS *)dbs;
|
||||
DB *db = (DB *)dbs->internal;
|
||||
|
||||
dbs_freemap(dbsp);
|
||||
|
||||
ret = (*db->get)(db, key, data, flags);
|
||||
if ((ret == 0) && dbs_IsBlob(data)) {
|
||||
ret = dbs_readBlob(dbsp, data);
|
||||
|
@ -391,8 +344,6 @@ dbs_put(const DB *dbs, DBT *key, const DBT *data, unsigned int flags)
|
|||
DBS *dbsp = (DBS *)dbs;
|
||||
DB *db = (DB *)dbs->internal;
|
||||
|
||||
dbs_freemap(dbsp);
|
||||
|
||||
/* If the db is readonly, just pass the data down to rdb and let it fail */
|
||||
if (!dbsp->readOnly) {
|
||||
DBT oldData;
|
||||
|
@ -425,10 +376,6 @@ static int
|
|||
dbs_sync(const DB *dbs, unsigned int flags)
|
||||
{
|
||||
DB *db = (DB *)dbs->internal;
|
||||
DBS *dbsp = (DBS *)dbs;
|
||||
|
||||
dbs_freemap(dbsp);
|
||||
|
||||
return (*db->sync)(db, flags);
|
||||
}
|
||||
|
||||
|
@ -439,8 +386,6 @@ dbs_del(const DB *dbs, const DBT *key, unsigned int flags)
|
|||
DBS *dbsp = (DBS *)dbs;
|
||||
DB *db = (DB *)dbs->internal;
|
||||
|
||||
dbs_freemap(dbsp);
|
||||
|
||||
if (!dbsp->readOnly) {
|
||||
DBT oldData;
|
||||
ret = (*db->get)(db, key, &oldData, 0);
|
||||
|
@ -459,8 +404,6 @@ dbs_seq(const DB *dbs, DBT *key, DBT *data, unsigned int flags)
|
|||
DBS *dbsp = (DBS *)dbs;
|
||||
DB *db = (DB *)dbs->internal;
|
||||
|
||||
dbs_freemap(dbsp);
|
||||
|
||||
ret = (*db->seq)(db, key, data, flags);
|
||||
if ((ret == 0) && dbs_IsBlob(data)) {
|
||||
/* don't return a blob read as an error so traversals keep going */
|
||||
|
@ -477,7 +420,6 @@ dbs_close(DB *dbs)
|
|||
DB *db = (DB *)dbs->internal;
|
||||
int ret;
|
||||
|
||||
dbs_freemap(dbsp);
|
||||
ret = (*db->close)(db);
|
||||
PORT_Free(dbsp->blobdir);
|
||||
PORT_Free(dbsp);
|
||||
|
@ -568,9 +510,6 @@ dbsopen(const char *dbname, int flags, int mode, DBTYPE type,
|
|||
}
|
||||
dbsp->mode = mode;
|
||||
dbsp->readOnly = (PRBool)(flags == NO_RDONLY);
|
||||
dbsp->dbs_mapfile = NULL;
|
||||
dbsp->dbs_addr = NULL;
|
||||
dbsp->dbs_len = 0;
|
||||
|
||||
/* the real dbm call */
|
||||
db = dbopen(dbname, flags, mode, type, &dbs_hashInfo);
|
||||
|
|
|
@ -3149,9 +3149,11 @@ nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS)
|
|||
* this call doesn't force freebl to be reloaded. */
|
||||
BL_SetForkState(PR_FALSE);
|
||||
|
||||
#ifndef NSS_TEST_BUILD
|
||||
/* unload freeBL shared library from memory. This may only decrement the
|
||||
* OS refcount if it's been loaded multiple times, eg. by libssl */
|
||||
BL_Unload();
|
||||
#endif
|
||||
|
||||
/* clean up the default OID table */
|
||||
SECOID_Shutdown();
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
|
||||
*/
|
||||
#define SOFTOKEN_VERSION "3.29" SOFTOKEN_ECC_STRING " Beta"
|
||||
#define SOFTOKEN_VERSION "3.30" SOFTOKEN_ECC_STRING " Beta"
|
||||
#define SOFTOKEN_VMAJOR 3
|
||||
#define SOFTOKEN_VMINOR 29
|
||||
#define SOFTOKEN_VMINOR 30
|
||||
#define SOFTOKEN_VPATCH 0
|
||||
#define SOFTOKEN_VBUILD 0
|
||||
#define SOFTOKEN_BETA PR_TRUE
|
||||
|
|
|
@ -7,34 +7,64 @@
|
|||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'softokn',
|
||||
'target_name': 'softokn_static',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'fipsaudt.c',
|
||||
'fipstest.c',
|
||||
'fipstokn.c',
|
||||
'jpakesftk.c',
|
||||
'lgglue.c',
|
||||
'lowkey.c',
|
||||
'lowpbe.c',
|
||||
'padbuf.c',
|
||||
'pkcs11.c',
|
||||
'pkcs11c.c',
|
||||
'pkcs11u.c',
|
||||
'sdb.c',
|
||||
'sftkdb.c',
|
||||
'sftkhmac.c',
|
||||
'sftkpars.c',
|
||||
'sftkpwd.c',
|
||||
'softkver.c',
|
||||
'tlsprf.c'
|
||||
'defines': [
|
||||
'NSS_TEST_BUILD',
|
||||
],
|
||||
'dependencies': [
|
||||
'softokn_base',
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'<(DEPTH)/lib/freebl/freebl.gyp:freebl_static',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'use_system_sqlite==1', {
|
||||
'dependencies': [
|
||||
'<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3',
|
||||
],
|
||||
}, {
|
||||
'dependencies': [
|
||||
'<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'softokn',
|
||||
'type': 'static_library',
|
||||
'dependencies': [
|
||||
'softokn_base',
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'<(DEPTH)/lib/sqlite/sqlite.gyp:sqlite3',
|
||||
'<(DEPTH)/lib/freebl/freebl.gyp:freebl',
|
||||
]
|
||||
},
|
||||
{
|
||||
'target_name': 'softokn_base',
|
||||
'type': 'none',
|
||||
'direct_dependent_settings': {
|
||||
'sources': [
|
||||
'fipsaudt.c',
|
||||
'fipstest.c',
|
||||
'fipstokn.c',
|
||||
'jpakesftk.c',
|
||||
'lgglue.c',
|
||||
'lowkey.c',
|
||||
'lowpbe.c',
|
||||
'padbuf.c',
|
||||
'pkcs11.c',
|
||||
'pkcs11c.c',
|
||||
'pkcs11u.c',
|
||||
'sdb.c',
|
||||
'sftkdb.c',
|
||||
'sftkhmac.c',
|
||||
'sftkpars.c',
|
||||
'sftkpwd.c',
|
||||
'softkver.c',
|
||||
'tlsprf.c'
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
'target_name': 'softokn3',
|
||||
'type': 'shared_library',
|
||||
|
|
|
@ -221,3 +221,9 @@ SSL_SignatureSchemePrefGet;
|
|||
;+ local:
|
||||
;+*;
|
||||
;+};
|
||||
;+NSS_3.30 { # NSS 3.30 release
|
||||
;+ global:
|
||||
SSL_SetSessionTicketKeyPair;
|
||||
;+ local:
|
||||
;+*;
|
||||
;+};
|
||||
|
|
|
@ -76,7 +76,6 @@
|
|||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports',
|
||||
'<(DEPTH)/lib/freebl/freebl.gyp:freebl',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -86,6 +85,7 @@
|
|||
'ssl',
|
||||
'<(DEPTH)/lib/nss/nss.gyp:nss3',
|
||||
'<(DEPTH)/lib/util/util.gyp:nssutil3',
|
||||
'<(DEPTH)/lib/freebl/freebl.gyp:freebl',
|
||||
],
|
||||
'variables': {
|
||||
'mapfile': 'ssl.def'
|
||||
|
|
|
@ -913,6 +913,19 @@ SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert,
|
|||
const CERTCertificateList *certChainOpt,
|
||||
SECKEYPrivateKey *key, SSLKEAType kea);
|
||||
|
||||
/*
|
||||
** SSL_SetSessionTicketKeyPair configures an asymmetric key pair for use in
|
||||
** wrapping session ticket keys, used by the server. This function currently
|
||||
** only accepts an RSA public/private key pair.
|
||||
**
|
||||
** Prior to the existence of this function, NSS used an RSA private key
|
||||
** associated with a configured certificate to perform session ticket
|
||||
** encryption. If this function isn't used, the keys provided with a configured
|
||||
** RSA certificate are used for wrapping session ticket keys.
|
||||
*/
|
||||
SSL_IMPORT SECStatus
|
||||
SSL_SetSessionTicketKeyPair(SECKEYPublicKey *pubKey, SECKEYPrivateKey *privKey);
|
||||
|
||||
/*
|
||||
** Configure a secure server's session-id cache. Define the maximum number
|
||||
** of entries in the cache, the longevity of the entires, and the directory
|
||||
|
|
|
@ -273,10 +273,6 @@ static const /*SSL3ClientCertificateType */ PRUint8 certificate_types[] = {
|
|||
ct_DSS_sign,
|
||||
};
|
||||
|
||||
/* This global item is used only in servers. It is is initialized by
|
||||
** SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest().
|
||||
*/
|
||||
CERTDistNames *ssl3_server_ca_list = NULL;
|
||||
static SSL3Statistics ssl3stats;
|
||||
|
||||
/* Record protection algorithms, indexed by SSL3BulkCipher.
|
||||
|
@ -863,12 +859,10 @@ ssl_HasCert(const sslSocket *ss, SSLAuthType authType)
|
|||
cursor != &ss->serverCerts;
|
||||
cursor = PR_NEXT_LINK(cursor)) {
|
||||
sslServerCert *cert = (sslServerCert *)cursor;
|
||||
if (cert->certType.authType != authType) {
|
||||
continue;
|
||||
}
|
||||
if (!cert->serverKeyPair ||
|
||||
!cert->serverKeyPair->privKey ||
|
||||
!cert->serverCertChain) {
|
||||
!cert->serverCertChain ||
|
||||
!SSL_CERT_IS(cert, authType)) {
|
||||
continue;
|
||||
}
|
||||
/* When called from ssl3_config_match_init(), all the EC curves will be
|
||||
|
@ -879,7 +873,7 @@ ssl_HasCert(const sslSocket *ss, SSLAuthType authType)
|
|||
if ((authType == ssl_auth_ecdsa ||
|
||||
authType == ssl_auth_ecdh_ecdsa ||
|
||||
authType == ssl_auth_ecdh_rsa) &&
|
||||
!ssl_NamedGroupEnabled(ss, cert->certType.namedCurve)) {
|
||||
!ssl_NamedGroupEnabled(ss, cert->namedCurve)) {
|
||||
continue;
|
||||
}
|
||||
return PR_TRUE;
|
||||
|
@ -5583,8 +5577,6 @@ ssl3_HandleHelloRequest(sslSocket *ss)
|
|||
return rv;
|
||||
}
|
||||
|
||||
#define UNKNOWN_WRAP_MECHANISM 0x7fffffff
|
||||
|
||||
static const CK_MECHANISM_TYPE wrapMechanismList[SSL_NUM_WRAP_MECHS] = {
|
||||
CKM_DES3_ECB,
|
||||
CKM_CAST5_ECB,
|
||||
|
@ -5600,27 +5592,58 @@ static const CK_MECHANISM_TYPE wrapMechanismList[SSL_NUM_WRAP_MECHS] = {
|
|||
CKM_SKIPJACK_CBC64,
|
||||
CKM_AES_ECB,
|
||||
CKM_CAMELLIA_ECB,
|
||||
CKM_SEED_ECB,
|
||||
UNKNOWN_WRAP_MECHANISM
|
||||
CKM_SEED_ECB
|
||||
};
|
||||
|
||||
static int
|
||||
ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech)
|
||||
static SECStatus
|
||||
ssl_FindIndexByWrapMechanism(CK_MECHANISM_TYPE mech, unsigned int *wrapMechIndex)
|
||||
{
|
||||
const CK_MECHANISM_TYPE *pMech = wrapMechanismList;
|
||||
|
||||
while (mech != *pMech && *pMech != UNKNOWN_WRAP_MECHANISM) {
|
||||
++pMech;
|
||||
unsigned int i;
|
||||
for (i = 0; i < SSL_NUM_WRAP_MECHS; ++i) {
|
||||
if (wrapMechanismList[i] == mech) {
|
||||
*wrapMechIndex = i;
|
||||
return SECSuccess;
|
||||
}
|
||||
}
|
||||
return (*pMech == UNKNOWN_WRAP_MECHANISM) ? -1
|
||||
: (pMech - wrapMechanismList);
|
||||
PORT_Assert(0);
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Each process sharing the server session ID cache has its own array of SymKey
|
||||
* pointers for the symmetric wrapping keys that are used to wrap the master
|
||||
* secrets. There is one key for each authentication type. These Symkeys
|
||||
* correspond to the wrapped SymKeys kept in the server session cache.
|
||||
*/
|
||||
const SSLAuthType ssl_wrap_key_auth_type[SSL_NUM_WRAP_KEYS] = {
|
||||
ssl_auth_rsa_decrypt,
|
||||
ssl_auth_rsa_sign,
|
||||
ssl_auth_rsa_pss,
|
||||
ssl_auth_ecdsa,
|
||||
ssl_auth_ecdh_rsa,
|
||||
ssl_auth_ecdh_ecdsa
|
||||
};
|
||||
|
||||
static SECStatus
|
||||
ssl_FindIndexByWrapKey(const sslServerCert *serverCert, unsigned int *wrapKeyIndex)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < SSL_NUM_WRAP_KEYS; ++i) {
|
||||
if (SSL_CERT_IS(serverCert, ssl_wrap_key_auth_type[i])) {
|
||||
*wrapKeyIndex = i;
|
||||
return SECSuccess;
|
||||
}
|
||||
}
|
||||
/* Can't assert here because we still get people using DSA certificates. */
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
static PK11SymKey *
|
||||
ssl_UnwrapSymWrappingKey(
|
||||
SSLWrappedSymWrappingKey *pWswk,
|
||||
SECKEYPrivateKey *svrPrivKey,
|
||||
SSLAuthType authType,
|
||||
unsigned int wrapKeyIndex,
|
||||
CK_MECHANISM_TYPE masterWrapMech,
|
||||
void *pwArg)
|
||||
{
|
||||
|
@ -5632,9 +5655,9 @@ ssl_UnwrapSymWrappingKey(
|
|||
|
||||
/* found the wrapping key on disk. */
|
||||
PORT_Assert(pWswk->symWrapMechanism == masterWrapMech);
|
||||
PORT_Assert(pWswk->authType == authType);
|
||||
PORT_Assert(pWswk->wrapKeyIndex == wrapKeyIndex);
|
||||
if (pWswk->symWrapMechanism != masterWrapMech ||
|
||||
pWswk->authType != authType) {
|
||||
pWswk->wrapKeyIndex != wrapKeyIndex) {
|
||||
goto loser;
|
||||
}
|
||||
wrappedKey.type = siBuffer;
|
||||
|
@ -5642,7 +5665,7 @@ ssl_UnwrapSymWrappingKey(
|
|||
wrappedKey.len = pWswk->wrappedSymKeyLen;
|
||||
PORT_Assert(wrappedKey.len <= sizeof pWswk->wrappedSymmetricWrappingkey);
|
||||
|
||||
switch (authType) {
|
||||
switch (ssl_wrap_key_auth_type[wrapKeyIndex]) {
|
||||
|
||||
case ssl_auth_rsa_decrypt:
|
||||
case ssl_auth_rsa_sign: /* bad: see Bug 1248320 */
|
||||
|
@ -5715,14 +5738,8 @@ loser:
|
|||
return unwrappedWrappingKey;
|
||||
}
|
||||
|
||||
/* Each process sharing the server session ID cache has its own array of SymKey
|
||||
* pointers for the symmetric wrapping keys that are used to wrap the master
|
||||
* secrets. There is one key for each authentication type. These Symkeys
|
||||
* correspond to the wrapped SymKeys kept in the server session cache.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
PK11SymKey *symWrapKey[ssl_auth_size];
|
||||
PK11SymKey *symWrapKey[SSL_NUM_WRAP_KEYS];
|
||||
} ssl3SymWrapKey;
|
||||
|
||||
static PZLock *symWrapKeysLock = NULL;
|
||||
|
@ -5750,7 +5767,7 @@ SSL3_ShutdownServerCache(void)
|
|||
PZ_Lock(symWrapKeysLock);
|
||||
/* get rid of all symWrapKeys */
|
||||
for (i = 0; i < SSL_NUM_WRAP_MECHS; ++i) {
|
||||
for (j = 0; j < ssl_auth_size; ++j) {
|
||||
for (j = 0; j < SSL_NUM_WRAP_KEYS; ++j) {
|
||||
PK11SymKey **pSymWrapKey;
|
||||
pSymWrapKey = &symWrapKeys[i].symWrapKey[j];
|
||||
if (*pSymWrapKey) {
|
||||
|
@ -5784,7 +5801,6 @@ ssl_InitSymWrapKeysLock(void)
|
|||
PK11SymKey *
|
||||
ssl3_GetWrappingKey(sslSocket *ss,
|
||||
PK11SlotInfo *masterSecretSlot,
|
||||
const sslServerCert *serverCert,
|
||||
CK_MECHANISM_TYPE masterWrapMech,
|
||||
void *pwArg)
|
||||
{
|
||||
|
@ -5795,7 +5811,8 @@ ssl3_GetWrappingKey(sslSocket *ss,
|
|||
PK11SymKey **pSymWrapKey;
|
||||
CK_MECHANISM_TYPE asymWrapMechanism = CKM_INVALID_MECHANISM;
|
||||
int length;
|
||||
int symWrapMechIndex;
|
||||
unsigned int wrapMechIndex;
|
||||
unsigned int wrapKeyIndex;
|
||||
SECStatus rv;
|
||||
SECItem wrappedKey;
|
||||
SSLWrappedSymWrappingKey wswk;
|
||||
|
@ -5803,6 +5820,7 @@ ssl3_GetWrappingKey(sslSocket *ss,
|
|||
SECKEYPublicKey *pubWrapKey = NULL;
|
||||
SECKEYPrivateKey *privWrapKey = NULL;
|
||||
ECCWrappedKeyInfo *ecWrapped;
|
||||
const sslServerCert *serverCert = ss->sec.serverCert;
|
||||
|
||||
PORT_Assert(serverCert);
|
||||
PORT_Assert(serverCert->serverKeyPair);
|
||||
|
@ -5814,15 +5832,18 @@ ssl3_GetWrappingKey(sslSocket *ss,
|
|||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return NULL; /* hmm */
|
||||
}
|
||||
authType = serverCert->certType.authType;
|
||||
svrPrivKey = serverCert->serverKeyPair->privKey;
|
||||
|
||||
symWrapMechIndex = ssl_FindIndexByWrapMechanism(masterWrapMech);
|
||||
PORT_Assert(symWrapMechIndex >= 0);
|
||||
if (symWrapMechIndex < 0)
|
||||
rv = ssl_FindIndexByWrapKey(serverCert, &wrapKeyIndex);
|
||||
if (rv != SECSuccess)
|
||||
return NULL; /* unusable wrapping key. */
|
||||
|
||||
rv = ssl_FindIndexByWrapMechanism(masterWrapMech, &wrapMechIndex);
|
||||
if (rv != SECSuccess)
|
||||
return NULL; /* invalid masterWrapMech. */
|
||||
|
||||
pSymWrapKey = &symWrapKeys[symWrapMechIndex].symWrapKey[authType];
|
||||
authType = ssl_wrap_key_auth_type[wrapKeyIndex];
|
||||
svrPrivKey = serverCert->serverKeyPair->privKey;
|
||||
pSymWrapKey = &symWrapKeys[wrapMechIndex].symWrapKey[wrapKeyIndex];
|
||||
|
||||
ssl_InitSessionCacheLocks(PR_TRUE);
|
||||
|
||||
|
@ -5841,10 +5862,11 @@ ssl3_GetWrappingKey(sslSocket *ss,
|
|||
|
||||
/* Try to get wrapped SymWrapping key out of the (disk) cache. */
|
||||
/* Following call fills in wswk on success. */
|
||||
if (ssl_GetWrappingKey(symWrapMechIndex, authType, &wswk)) {
|
||||
rv = ssl_GetWrappingKey(wrapMechIndex, wrapKeyIndex, &wswk);
|
||||
if (rv == SECSuccess) {
|
||||
/* found the wrapped sym wrapping key on disk. */
|
||||
unwrappedWrappingKey =
|
||||
ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, authType,
|
||||
ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, wrapKeyIndex,
|
||||
masterWrapMech, pwArg);
|
||||
if (unwrappedWrappingKey) {
|
||||
goto install;
|
||||
|
@ -5993,9 +6015,9 @@ ssl3_GetWrappingKey(sslSocket *ss,
|
|||
PORT_Assert(asymWrapMechanism != CKM_INVALID_MECHANISM);
|
||||
|
||||
wswk.symWrapMechanism = masterWrapMech;
|
||||
wswk.symWrapMechIndex = symWrapMechIndex;
|
||||
wswk.asymWrapMechanism = asymWrapMechanism;
|
||||
wswk.authType = authType;
|
||||
wswk.wrapMechIndex = wrapMechIndex;
|
||||
wswk.wrapKeyIndex = wrapKeyIndex;
|
||||
wswk.wrappedSymKeyLen = wrappedKey.len;
|
||||
|
||||
/* put it on disk. */
|
||||
|
@ -6003,7 +6025,8 @@ ssl3_GetWrappingKey(sslSocket *ss,
|
|||
* then abandon the value we just computed and
|
||||
* use the one we got from the disk.
|
||||
*/
|
||||
if (ssl_SetWrappingKey(&wswk)) {
|
||||
rv = ssl_SetWrappingKey(&wswk);
|
||||
if (rv == SECSuccess) {
|
||||
/* somebody beat us to it. The original contents of our wswk
|
||||
* has been replaced with the content on disk. Now, discard
|
||||
* the key we just created and unwrap this new one.
|
||||
|
@ -6011,7 +6034,7 @@ ssl3_GetWrappingKey(sslSocket *ss,
|
|||
PK11_FreeSymKey(unwrappedWrappingKey);
|
||||
|
||||
unwrappedWrappingKey =
|
||||
ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, authType,
|
||||
ssl_UnwrapSymWrappingKey(&wswk, svrPrivKey, wrapKeyIndex,
|
||||
masterWrapMech, pwArg);
|
||||
}
|
||||
|
||||
|
@ -8255,19 +8278,17 @@ ssl3_SelectServerCert(sslSocket *ss)
|
|||
cursor != &ss->serverCerts;
|
||||
cursor = PR_NEXT_LINK(cursor)) {
|
||||
sslServerCert *cert = (sslServerCert *)cursor;
|
||||
if (cert->certType.authType != kea_def->authKeyType) {
|
||||
if (!SSL_CERT_IS(cert, kea_def->authKeyType)) {
|
||||
continue;
|
||||
}
|
||||
if ((cert->certType.authType == ssl_auth_ecdsa ||
|
||||
cert->certType.authType == ssl_auth_ecdh_rsa ||
|
||||
cert->certType.authType == ssl_auth_ecdh_ecdsa) &&
|
||||
!ssl_NamedGroupEnabled(ss, cert->certType.namedCurve)) {
|
||||
if (SSL_CERT_IS_EC(cert) &&
|
||||
!ssl_NamedGroupEnabled(ss, cert->namedCurve)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Found one. */
|
||||
ss->sec.serverCert = cert;
|
||||
ss->sec.authType = cert->certType.authType;
|
||||
ss->sec.authType = kea_def->authKeyType;
|
||||
ss->sec.authKeyBits = cert->serverKeyBits;
|
||||
|
||||
/* Don't pick a signature scheme if we aren't going to use it. */
|
||||
|
@ -8791,7 +8812,6 @@ compression_found:
|
|||
do {
|
||||
ssl3CipherSpec *pwSpec;
|
||||
SECItem wrappedMS; /* wrapped key */
|
||||
const sslServerCert *serverCert;
|
||||
|
||||
if (sid->version != ss->version ||
|
||||
sid->u.ssl3.cipherSuite != ss->ssl3.hs.cipher_suite ||
|
||||
|
@ -8799,8 +8819,13 @@ compression_found:
|
|||
break; /* not an error */
|
||||
}
|
||||
|
||||
serverCert = ssl_FindServerCert(ss, &sid->certType);
|
||||
if (!serverCert || !serverCert->serverCert) {
|
||||
/* server sids don't remember the server cert we previously sent,
|
||||
** but they do remember the slot we originally used, so we
|
||||
** can locate it again, provided that the current ssl socket
|
||||
** has had its server certs configured the same as the previous one.
|
||||
*/
|
||||
ss->sec.serverCert = ssl_FindServerCert(ss, sid->authType, sid->namedCurve);
|
||||
if (!ss->sec.serverCert || !ss->sec.serverCert->serverCert) {
|
||||
/* A compatible certificate must not have been configured. It
|
||||
* might not be the same certificate, but we only find that out
|
||||
* when the ticket fails to decrypt. */
|
||||
|
@ -8848,7 +8873,7 @@ compression_found:
|
|||
PK11SymKey *wrapKey; /* wrapping key */
|
||||
CK_FLAGS keyFlags = 0;
|
||||
|
||||
wrapKey = ssl3_GetWrappingKey(ss, NULL, serverCert,
|
||||
wrapKey = ssl3_GetWrappingKey(ss, NULL,
|
||||
sid->u.ssl3.masterWrapMech,
|
||||
ss->pkcs11PinArg);
|
||||
if (!wrapKey) {
|
||||
|
@ -8907,13 +8932,8 @@ compression_found:
|
|||
ss->sec.keaType = sid->keaType;
|
||||
ss->sec.keaKeyBits = sid->keaKeyBits;
|
||||
|
||||
/* server sids don't remember the server cert we previously sent,
|
||||
** but they do remember the slot we originally used, so we
|
||||
** can locate it again, provided that the current ssl socket
|
||||
** has had its server certs configured the same as the previous one.
|
||||
*/
|
||||
ss->sec.serverCert = serverCert;
|
||||
ss->sec.localCert = CERT_DupCertificate(serverCert->serverCert);
|
||||
ss->sec.localCert =
|
||||
CERT_DupCertificate(ss->sec.serverCert->serverCert);
|
||||
|
||||
/* Copy cached name in to pending spec */
|
||||
if (sid != NULL &&
|
||||
|
@ -9631,34 +9651,6 @@ ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf, unsigned maxLen, PRUint32
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
ssl3_GetCertificateRequestCAs(sslSocket *ss, int *calen, SECItem **names,
|
||||
int *nnames)
|
||||
{
|
||||
SECItem *name;
|
||||
CERTDistNames *ca_list;
|
||||
int i;
|
||||
|
||||
*calen = 0;
|
||||
*names = NULL;
|
||||
*nnames = 0;
|
||||
|
||||
/* ssl3.ca_list is initialized to NULL, and never changed. */
|
||||
ca_list = ss->ssl3.ca_list;
|
||||
if (!ca_list) {
|
||||
ca_list = ssl3_server_ca_list;
|
||||
}
|
||||
|
||||
if (ca_list != NULL) {
|
||||
*names = ca_list->names;
|
||||
*nnames = ca_list->nnames;
|
||||
}
|
||||
|
||||
for (i = 0, name = *names; i < *nnames; i++, name++) {
|
||||
*calen += 2 + name->len;
|
||||
}
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ssl3_SendCertificateRequest(sslSocket *ss)
|
||||
{
|
||||
|
@ -9667,8 +9659,8 @@ ssl3_SendCertificateRequest(sslSocket *ss)
|
|||
SECStatus rv;
|
||||
int length;
|
||||
SECItem *names;
|
||||
int calen;
|
||||
int nnames;
|
||||
unsigned int calen;
|
||||
unsigned int nnames;
|
||||
SECItem *name;
|
||||
int i;
|
||||
int certTypesLength;
|
||||
|
@ -9683,7 +9675,10 @@ ssl3_SendCertificateRequest(sslSocket *ss)
|
|||
|
||||
isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
|
||||
ssl3_GetCertificateRequestCAs(ss, &calen, &names, &nnames);
|
||||
rv = ssl_GetCertificateRequestCAs(ss, &calen, &names, &nnames);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
certTypes = certificate_types;
|
||||
certTypesLength = sizeof certificate_types;
|
||||
|
||||
|
@ -11331,7 +11326,7 @@ fail:
|
|||
*/
|
||||
SECStatus
|
||||
ssl3_CacheWrappedMasterSecret(sslSocket *ss, sslSessionID *sid,
|
||||
ssl3CipherSpec *spec, SSLAuthType authType)
|
||||
ssl3CipherSpec *spec)
|
||||
{
|
||||
PK11SymKey *wrappingKey = NULL;
|
||||
PK11SlotInfo *symKeySlot;
|
||||
|
@ -11385,8 +11380,7 @@ ssl3_CacheWrappedMasterSecret(sslSocket *ss, sslSessionID *sid,
|
|||
mechanism = PK11_GetBestWrapMechanism(symKeySlot);
|
||||
if (mechanism != CKM_INVALID_MECHANISM) {
|
||||
wrappingKey =
|
||||
ssl3_GetWrappingKey(ss, symKeySlot, ss->sec.serverCert,
|
||||
mechanism, pwArg);
|
||||
ssl3_GetWrappingKey(ss, symKeySlot, mechanism, pwArg);
|
||||
if (wrappingKey) {
|
||||
mechanism = PK11_GetMechanism(wrappingKey); /* can't fail. */
|
||||
}
|
||||
|
@ -11593,9 +11587,7 @@ ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid)
|
|||
sid->expirationTime = sid->creationTime + ssl3_sid_timeout;
|
||||
sid->localCert = CERT_DupCertificate(ss->sec.localCert);
|
||||
if (ss->sec.isServer) {
|
||||
memcpy(&sid->certType, &ss->sec.serverCert->certType, sizeof(sid->certType));
|
||||
} else {
|
||||
sid->certType.authType = ssl_auth_null;
|
||||
sid->namedCurve = ss->sec.serverCert->namedCurve;
|
||||
}
|
||||
|
||||
if (ss->xtnData.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
|
||||
|
@ -11619,8 +11611,7 @@ ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid)
|
|||
rv = SECSuccess;
|
||||
} else {
|
||||
rv = ssl3_CacheWrappedMasterSecret(ss, ss->sec.ci.sid,
|
||||
ss->ssl3.crSpec,
|
||||
ss->ssl3.hs.kea_def->authKeyType);
|
||||
ss->ssl3.crSpec);
|
||||
sid->u.ssl3.keys.msIsWrapped = PR_TRUE;
|
||||
}
|
||||
ssl_ReleaseSpecReadLock(ss); /*************************************/
|
||||
|
|
|
@ -440,23 +440,19 @@ ssl_GetECGroupForServerSocket(sslSocket *ss)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (cert->certType.authType == ssl_auth_rsa_sign) {
|
||||
if (SSL_CERT_IS(cert, ssl_auth_rsa_sign) ||
|
||||
SSL_CERT_IS(cert, ssl_auth_rsa_pss)) {
|
||||
certKeySize = SECKEY_PublicKeyStrengthInBits(cert->serverKeyPair->pubKey);
|
||||
certKeySize =
|
||||
SSL_RSASTRENGTH_TO_ECSTRENGTH(certKeySize);
|
||||
} else if (cert->certType.authType == ssl_auth_ecdsa ||
|
||||
cert->certType.authType == ssl_auth_ecdh_rsa ||
|
||||
cert->certType.authType == ssl_auth_ecdh_ecdsa) {
|
||||
const sslNamedGroupDef *groupDef = cert->certType.namedCurve;
|
||||
|
||||
certKeySize = SSL_RSASTRENGTH_TO_ECSTRENGTH(certKeySize);
|
||||
} else if (SSL_CERT_IS_EC(cert)) {
|
||||
/* We won't select a certificate unless the named curve has been
|
||||
* negotiated (or supported_curves was absent), double check that. */
|
||||
PORT_Assert(groupDef->keaType == ssl_kea_ecdh);
|
||||
PORT_Assert(ssl_NamedGroupEnabled(ss, groupDef));
|
||||
if (!ssl_NamedGroupEnabled(ss, groupDef)) {
|
||||
PORT_Assert(cert->namedCurve->keaType == ssl_kea_ecdh);
|
||||
PORT_Assert(ssl_NamedGroupEnabled(ss, cert->namedCurve));
|
||||
if (!ssl_NamedGroupEnabled(ss, cert->namedCurve)) {
|
||||
return NULL;
|
||||
}
|
||||
certKeySize = groupDef->bits;
|
||||
certKeySize = cert->namedCurve->bits;
|
||||
} else {
|
||||
PORT_Assert(0);
|
||||
return NULL;
|
||||
|
|
|
@ -16,12 +16,6 @@
|
|||
#include "ssl3exthandle.h"
|
||||
#include "tls13exthandle.h" /* For tls13_ServerSendStatusRequestXtn. */
|
||||
|
||||
static unsigned char key_name[SESS_TICKET_KEY_NAME_LEN];
|
||||
static PK11SymKey *session_ticket_enc_key = NULL;
|
||||
static PK11SymKey *session_ticket_mac_key = NULL;
|
||||
|
||||
static PRCallOnceType generate_session_keys_once;
|
||||
|
||||
static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss,
|
||||
SECItem *data, EncryptedSessionTicket *enc_session_ticket);
|
||||
static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf,
|
||||
|
@ -29,8 +23,6 @@ static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf,
|
|||
static SECStatus ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes);
|
||||
static SECStatus ssl3_AppendNumberToItem(SECItem *item, PRUint32 num,
|
||||
PRInt32 lenSize);
|
||||
static SECStatus ssl3_GetSessionTicketKeys(sslSocket *ss,
|
||||
PK11SymKey **aes_key, PK11SymKey **mac_key);
|
||||
static SECStatus ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes);
|
||||
|
||||
/*
|
||||
|
@ -76,83 +68,6 @@ ssl3_AppendNumberToItem(SECItem *item, PRUint32 num, PRInt32 lenSize)
|
|||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ssl3_SessionTicketShutdown(void *appData, void *nssData)
|
||||
{
|
||||
if (session_ticket_enc_key) {
|
||||
PK11_FreeSymKey(session_ticket_enc_key);
|
||||
session_ticket_enc_key = NULL;
|
||||
}
|
||||
if (session_ticket_mac_key) {
|
||||
PK11_FreeSymKey(session_ticket_mac_key);
|
||||
session_ticket_mac_key = NULL;
|
||||
}
|
||||
PORT_Memset(&generate_session_keys_once, 0,
|
||||
sizeof(generate_session_keys_once));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static PRStatus
|
||||
ssl3_GenerateSessionTicketKeys(void *data)
|
||||
{
|
||||
SECStatus rv;
|
||||
sslSocket *ss = (sslSocket *)data;
|
||||
sslServerCertType certType = { ssl_auth_rsa_decrypt, NULL };
|
||||
const sslServerCert *sc;
|
||||
SECKEYPrivateKey *svrPrivKey;
|
||||
SECKEYPublicKey *svrPubKey;
|
||||
|
||||
sc = ssl_FindServerCert(ss, &certType);
|
||||
if (!sc || !sc->serverKeyPair) {
|
||||
SSL_DBG(("%d: SSL[%d]: No ssl_auth_rsa_decrypt cert and key pair",
|
||||
SSL_GETPID(), ss->fd));
|
||||
goto loser;
|
||||
}
|
||||
svrPrivKey = sc->serverKeyPair->privKey;
|
||||
svrPubKey = sc->serverKeyPair->pubKey;
|
||||
if (svrPrivKey == NULL || svrPubKey == NULL) {
|
||||
SSL_DBG(("%d: SSL[%d]: Pub or priv key(s) is NULL.",
|
||||
SSL_GETPID(), ss->fd));
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get a copy of the session keys from shared memory. */
|
||||
PORT_Memcpy(key_name, SESS_TICKET_KEY_NAME_PREFIX,
|
||||
sizeof(SESS_TICKET_KEY_NAME_PREFIX));
|
||||
if (!ssl_GetSessionTicketKeys(svrPrivKey, svrPubKey, ss->pkcs11PinArg,
|
||||
&key_name[SESS_TICKET_KEY_NAME_PREFIX_LEN],
|
||||
&session_ticket_enc_key, &session_ticket_mac_key))
|
||||
return PR_FAILURE;
|
||||
|
||||
rv = NSS_RegisterShutdown(ssl3_SessionTicketShutdown, NULL);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
return PR_SUCCESS;
|
||||
|
||||
loser:
|
||||
ssl3_SessionTicketShutdown(NULL, NULL);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ssl3_GetSessionTicketKeys(sslSocket *ss, PK11SymKey **aes_key,
|
||||
PK11SymKey **mac_key)
|
||||
{
|
||||
if (PR_CallOnceWithArg(&generate_session_keys_once,
|
||||
ssl3_GenerateSessionTicketKeys, ss) !=
|
||||
PR_SUCCESS)
|
||||
return SECFailure;
|
||||
|
||||
if (session_ticket_enc_key == NULL ||
|
||||
session_ticket_mac_key == NULL)
|
||||
return SECFailure;
|
||||
|
||||
*aes_key = session_ticket_enc_key;
|
||||
*mac_key = session_ticket_mac_key;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* Format an SNI extension, using the name from the socket's URL,
|
||||
* unless that name is a dotted decimal string.
|
||||
* Used by client and server.
|
||||
|
@ -960,6 +875,7 @@ ssl3_EncodeSessionTicket(sslSocket *ss,
|
|||
PRUint32 cert_length = 0;
|
||||
PRUint8 length_buf[4];
|
||||
PRUint32 now;
|
||||
unsigned char key_name[SESS_TICKET_KEY_NAME_LEN];
|
||||
PK11SymKey *aes_key = NULL;
|
||||
PK11SymKey *mac_key = NULL;
|
||||
CK_MECHANISM_TYPE cipherMech = CKM_AES_CBC;
|
||||
|
@ -975,7 +891,6 @@ ssl3_EncodeSessionTicket(sslSocket *ss,
|
|||
CK_MECHANISM_TYPE msWrapMech = 0; /* dummy default value,
|
||||
* must be >= 0 */
|
||||
ssl3CipherSpec *spec;
|
||||
const sslServerCertType *certType;
|
||||
SECItem alpnSelection = { siBuffer, NULL, 0 };
|
||||
|
||||
SSL_TRC(3, ("%d: SSL3[%d]: send session_ticket handshake",
|
||||
|
@ -995,7 +910,7 @@ ssl3_EncodeSessionTicket(sslSocket *ss,
|
|||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
rv = ssl3_GetSessionTicketKeys(ss, &aes_key, &mac_key);
|
||||
rv = ssl_GetSessionTicketKeys(ss, key_name, &aes_key, &mac_key);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
|
@ -1014,8 +929,7 @@ ssl3_EncodeSessionTicket(sslSocket *ss,
|
|||
sslSessionID sid;
|
||||
PORT_Memset(&sid, 0, sizeof(sslSessionID));
|
||||
|
||||
rv = ssl3_CacheWrappedMasterSecret(ss, &sid, spec,
|
||||
ss->ssl3.hs.kea_def->authKeyType);
|
||||
rv = ssl3_CacheWrappedMasterSecret(ss, &sid, spec);
|
||||
if (rv == SECSuccess) {
|
||||
if (sid.u.ssl3.keys.wrapped_master_secret_len > sizeof(wrapped_ms))
|
||||
goto loser;
|
||||
|
@ -1108,22 +1022,15 @@ ssl3_EncodeSessionTicket(sslSocket *ss,
|
|||
goto loser;
|
||||
|
||||
/* certificate type */
|
||||
certType = &ss->sec.serverCert->certType;
|
||||
PORT_Assert(certType->authType == ss->sec.authType);
|
||||
switch (ss->sec.authType) {
|
||||
case ssl_auth_ecdsa:
|
||||
case ssl_auth_ecdh_rsa:
|
||||
case ssl_auth_ecdh_ecdsa:
|
||||
PORT_Assert(certType->namedCurve);
|
||||
PORT_Assert(certType->namedCurve->keaType == ssl_kea_ecdh);
|
||||
/* EC curves only use the second of the two bytes. */
|
||||
PORT_Assert(certType->namedCurve->name < 256);
|
||||
rv = ssl3_AppendNumberToItem(&plaintext,
|
||||
certType->namedCurve->name, 1);
|
||||
break;
|
||||
default:
|
||||
rv = ssl3_AppendNumberToItem(&plaintext, 0, 1);
|
||||
break;
|
||||
PORT_Assert(SSL_CERT_IS(ss->sec.serverCert, ss->sec.authType));
|
||||
if (SSL_CERT_IS_EC(ss->sec.serverCert)) {
|
||||
const sslServerCert *cert = ss->sec.serverCert;
|
||||
PORT_Assert(cert->namedCurve);
|
||||
/* EC curves only use the second of the two bytes. */
|
||||
PORT_Assert(cert->namedCurve->name < 256);
|
||||
rv = ssl3_AppendNumberToItem(&plaintext, cert->namedCurve->name, 1);
|
||||
} else {
|
||||
rv = ssl3_AppendNumberToItem(&plaintext, 0, 1);
|
||||
}
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
|
@ -1350,6 +1257,7 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data)
|
|||
EncryptedSessionTicket enc_session_ticket;
|
||||
unsigned char computed_mac[TLS_EX_SESS_TICKET_MAC_LENGTH];
|
||||
unsigned int computed_mac_length;
|
||||
unsigned char key_name[SESS_TICKET_KEY_NAME_LEN];
|
||||
PK11SymKey *aes_key = NULL;
|
||||
PK11SymKey *mac_key = NULL;
|
||||
PK11Context *hmac_ctx;
|
||||
|
@ -1387,7 +1295,7 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data)
|
|||
}
|
||||
|
||||
/* Get session ticket keys. */
|
||||
rv = ssl3_GetSessionTicketKeys(ss, &aes_key, &mac_key);
|
||||
rv = ssl_GetSessionTicketKeys(ss, key_name, &aes_key, &mac_key);
|
||||
if (rv != SECSuccess) {
|
||||
SSL_DBG(("%d: SSL[%d]: Unable to get/generate session ticket keys.",
|
||||
SSL_GETPID(), ss->fd));
|
||||
|
@ -1538,24 +1446,19 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data)
|
|||
goto no_ticket;
|
||||
parsed_session_ticket->keaKeyBits = temp;
|
||||
|
||||
/* Read certificate slot */
|
||||
parsed_session_ticket->certType.authType = parsed_session_ticket->authType;
|
||||
/* Read the optional named curve. */
|
||||
rv = ssl3_ExtConsumeHandshakeNumber(ss, &temp, 1, &buffer, &buffer_len);
|
||||
if (rv != SECSuccess)
|
||||
goto no_ticket;
|
||||
switch (parsed_session_ticket->authType) {
|
||||
case ssl_auth_ecdsa:
|
||||
case ssl_auth_ecdh_rsa:
|
||||
case ssl_auth_ecdh_ecdsa: {
|
||||
const sslNamedGroupDef *group =
|
||||
ssl_LookupNamedGroup((SSLNamedGroup)temp);
|
||||
if (!group || group->keaType != ssl_kea_ecdh) {
|
||||
goto no_ticket;
|
||||
}
|
||||
parsed_session_ticket->certType.namedCurve = group;
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
if (parsed_session_ticket->authType == ssl_auth_ecdsa ||
|
||||
parsed_session_ticket->authType == ssl_auth_ecdh_rsa ||
|
||||
parsed_session_ticket->authType == ssl_auth_ecdh_ecdsa) {
|
||||
const sslNamedGroupDef *group =
|
||||
ssl_LookupNamedGroup((SSLNamedGroup)temp);
|
||||
if (!group || group->keaType != ssl_kea_ecdh) {
|
||||
goto no_ticket;
|
||||
}
|
||||
parsed_session_ticket->namedCurve = group;
|
||||
}
|
||||
|
||||
/* Read wrapped master_secret. */
|
||||
|
@ -1682,8 +1585,7 @@ ssl3_ProcessSessionTicketCommon(sslSocket *ss, SECItem *data)
|
|||
sid->authKeyBits = parsed_session_ticket->authKeyBits;
|
||||
sid->keaType = parsed_session_ticket->keaType;
|
||||
sid->keaKeyBits = parsed_session_ticket->keaKeyBits;
|
||||
memcpy(&sid->certType, &parsed_session_ticket->certType,
|
||||
sizeof(sslServerCertType));
|
||||
sid->namedCurve = parsed_session_ticket->namedCurve;
|
||||
|
||||
if (SECITEM_CopyItem(NULL, &sid->u.ssl3.locked.sessionTicket.ticket,
|
||||
&extension_data) != SECSuccess)
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -13,26 +13,21 @@
|
|||
#include "secitem.h"
|
||||
#include "keyhi.h"
|
||||
|
||||
/* The following struct identifies a single slot into which a certificate can be
|
||||
** loaded. The authType field determines the basic slot, then additional
|
||||
** parameters further narrow the slot.
|
||||
**
|
||||
** An EC key (ssl_auth_ecdsa or ssl_auth_ecdh_*) is assigned to a slot based on
|
||||
** the named curve of the key.
|
||||
*/
|
||||
typedef struct sslServerCertTypeStr {
|
||||
SSLAuthType authType;
|
||||
/* This type is a bitvector that is indexed by SSLAuthType values. Note that
|
||||
* the bit for ssl_auth_null(0) - the least significant bit - isn't used. */
|
||||
typedef PRUint16 sslAuthTypeMask;
|
||||
PR_STATIC_ASSERT(sizeof(sslAuthTypeMask) * 8 >= ssl_auth_size);
|
||||
|
||||
typedef struct sslServerCertStr {
|
||||
PRCList link; /* The linked list link */
|
||||
|
||||
/* The auth types that this certificate provides. */
|
||||
sslAuthTypeMask authTypes;
|
||||
/* For ssl_auth_ecdsa and ssl_auth_ecdh_*. This is only the named curve
|
||||
* of the end-entity certificate key. The keys in other certificates in
|
||||
* the chain aren't directly relevant to the operation of TLS (though it
|
||||
* might make certificate validation difficult, libssl doesn't care). */
|
||||
const sslNamedGroupDef *namedCurve;
|
||||
} sslServerCertType;
|
||||
|
||||
typedef struct sslServerCertStr {
|
||||
PRCList link; /* The linked list link */
|
||||
|
||||
sslServerCertType certType; /* The certificate slot this occupies */
|
||||
|
||||
/* Configuration state for server sockets */
|
||||
CERTCertificate *serverCert;
|
||||
|
@ -48,12 +43,18 @@ typedef struct sslServerCertStr {
|
|||
SECItem signedCertTimestamps;
|
||||
} sslServerCert;
|
||||
|
||||
extern sslServerCert *ssl_NewServerCert(const sslServerCertType *slot);
|
||||
#define SSL_CERT_IS(c, t) ((c)->authTypes & (1 << (t)))
|
||||
#define SSL_CERT_IS_ONLY(c, t) ((c)->authTypes == (1 << (t)))
|
||||
#define SSL_CERT_IS_EC(c) \
|
||||
((c)->authTypes & ((1 << ssl_auth_ecdsa) | \
|
||||
(1 << ssl_auth_ecdh_rsa) | \
|
||||
(1 << ssl_auth_ecdh_ecdsa)))
|
||||
|
||||
extern sslServerCert *ssl_NewServerCert();
|
||||
extern sslServerCert *ssl_CopyServerCert(const sslServerCert *oc);
|
||||
extern sslServerCert *ssl_FindServerCert(const sslSocket *ss,
|
||||
const sslServerCertType *slot);
|
||||
extern sslServerCert *ssl_FindServerCertByAuthType(const sslSocket *ss,
|
||||
SSLAuthType authType);
|
||||
extern const sslServerCert *ssl_FindServerCert(
|
||||
const sslSocket *ss, SSLAuthType authType,
|
||||
const sslNamedGroupDef *namedCurve);
|
||||
extern void ssl_FreeServerCert(sslServerCert *sc);
|
||||
|
||||
#endif /* __sslcert_h_ */
|
||||
|
|
|
@ -125,7 +125,8 @@ typedef enum { SSLAppOpRead = 0,
|
|||
#define SSL3_MASTER_SECRET_LENGTH 48
|
||||
|
||||
/* number of wrap mechanisms potentially used to wrap master secrets. */
|
||||
#define SSL_NUM_WRAP_MECHS 16
|
||||
#define SSL_NUM_WRAP_MECHS 15
|
||||
#define SSL_NUM_WRAP_KEYS 6
|
||||
|
||||
/* This makes the cert cache entry exactly 4k. */
|
||||
#define SSL_MAX_CACHED_CERT_LEN 4060
|
||||
|
@ -530,10 +531,10 @@ struct sslSessionIDStr {
|
|||
*/
|
||||
|
||||
CERTCertificate *peerCert;
|
||||
SECItemArray peerCertStatus; /* client only */
|
||||
const char *peerID; /* client only */
|
||||
const char *urlSvrName; /* client only */
|
||||
sslServerCertType certType;
|
||||
SECItemArray peerCertStatus; /* client only */
|
||||
const char *peerID; /* client only */
|
||||
const char *urlSvrName; /* client only */
|
||||
const sslNamedGroupDef *namedCurve; /* (server) for certificate lookup */
|
||||
CERTCertificate *localCert;
|
||||
|
||||
PRIPv6Addr addr;
|
||||
|
@ -983,8 +984,8 @@ typedef struct SSLWrappedSymWrappingKeyStr {
|
|||
CK_MECHANISM_TYPE asymWrapMechanism;
|
||||
/* mechanism used to wrap the SymmetricWrappingKey using
|
||||
* server's public and/or private keys. */
|
||||
SSLAuthType authType; /* type of keys used to wrap SymWrapKey*/
|
||||
PRInt32 symWrapMechIndex;
|
||||
PRInt16 wrapMechIndex;
|
||||
PRUint16 wrapKeyIndex;
|
||||
PRUint16 wrappedSymKeyLen;
|
||||
} SSLWrappedSymWrappingKey;
|
||||
|
||||
|
@ -997,7 +998,8 @@ typedef struct SessionTicketStr {
|
|||
PRUint32 authKeyBits;
|
||||
SSLKEAType keaType;
|
||||
PRUint32 keaKeyBits;
|
||||
sslServerCertType certType;
|
||||
const sslNamedGroupDef *namedCurve; /* For certificate lookup. */
|
||||
|
||||
/*
|
||||
* msWrapMech contains a meaningful value only if ms_is_wrapped is true.
|
||||
*/
|
||||
|
@ -1228,7 +1230,6 @@ extern char ssl_debug;
|
|||
extern char ssl_trace;
|
||||
extern FILE *ssl_trace_iob;
|
||||
extern FILE *ssl_keylog_iob;
|
||||
extern CERTDistNames *ssl3_server_ca_list;
|
||||
extern PRUint32 ssl_sid_timeout;
|
||||
extern PRUint32 ssl3_sid_timeout;
|
||||
|
||||
|
@ -1684,8 +1685,7 @@ extern SECStatus ssl3_SignHashes(sslSocket *ss, SSL3Hashes *hash,
|
|||
extern SECStatus ssl3_VerifySignedHashes(sslSocket *ss, SSLSignatureScheme scheme,
|
||||
SSL3Hashes *hash, SECItem *buf);
|
||||
extern SECStatus ssl3_CacheWrappedMasterSecret(
|
||||
sslSocket *ss, sslSessionID *sid,
|
||||
ssl3CipherSpec *spec, SSLAuthType authType);
|
||||
sslSocket *ss, sslSessionID *sid, ssl3CipherSpec *spec);
|
||||
extern void ssl3_FreeSniNameArray(TLSExtensionData *xtnData);
|
||||
|
||||
/* Hello Extension related routines. */
|
||||
|
@ -1694,11 +1694,10 @@ extern void ssl3_SetSIDSessionTicket(sslSessionID *sid,
|
|||
SECStatus ssl3_EncodeSessionTicket(sslSocket *ss,
|
||||
const NewSessionTicket *ticket_input,
|
||||
SECItem *ticket_data);
|
||||
extern PRBool ssl_GetSessionTicketKeys(SECKEYPrivateKey *svrPrivKey,
|
||||
SECKEYPublicKey *svrPubKey, void *pwArg,
|
||||
unsigned char *keyName, PK11SymKey **aesKey,
|
||||
PK11SymKey **macKey);
|
||||
extern SECStatus ssl3_SessionTicketShutdown(void *appData, void *nssData);
|
||||
SECStatus ssl_MaybeSetSessionTicketKeyPair(const sslKeyPair *keyPair);
|
||||
SECStatus ssl_GetSessionTicketKeys(sslSocket *ss, unsigned char *keyName,
|
||||
PK11SymKey **encKey, PK11SymKey **macKey);
|
||||
void ssl_ResetSessionTicketKeys();
|
||||
|
||||
/* Tell clients to consider tickets valid for this long. */
|
||||
#define TLS_EX_SESS_TICKET_LIFETIME_HINT (2 * 24 * 60 * 60) /* 2 days */
|
||||
|
@ -1716,8 +1715,8 @@ extern void ssl_FreePRSocket(PRFileDesc *fd);
|
|||
extern int ssl3_config_match_init(sslSocket *);
|
||||
|
||||
/* calls for accessing wrapping keys across processes. */
|
||||
extern PRBool
|
||||
ssl_GetWrappingKey(PRInt32 symWrapMechIndex, SSLAuthType authType,
|
||||
extern SECStatus
|
||||
ssl_GetWrappingKey(unsigned int symWrapMechIndex, unsigned int wrapKeyIndex,
|
||||
SSLWrappedSymWrappingKey *wswk);
|
||||
|
||||
/* The caller passes in the new value it wants
|
||||
|
@ -1729,7 +1728,7 @@ ssl_GetWrappingKey(PRInt32 symWrapMechIndex, SSLAuthType authType,
|
|||
* This is all done while holding the locks/semaphores necessary to make
|
||||
* the operation atomic.
|
||||
*/
|
||||
extern PRBool
|
||||
extern SECStatus
|
||||
ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk);
|
||||
|
||||
/* get rid of the symmetric wrapping key references. */
|
||||
|
@ -1794,8 +1793,8 @@ SECStatus ssl_ReadCertificateStatus(sslSocket *ss, SSL3Opaque *b,
|
|||
PRUint32 length);
|
||||
SECStatus ssl3_EncodeSigAlgs(const sslSocket *ss, PRUint8 *buf,
|
||||
unsigned maxLen, PRUint32 *len);
|
||||
void ssl3_GetCertificateRequestCAs(sslSocket *ss, int *calenp, SECItem **namesp,
|
||||
int *nnamesp);
|
||||
SECStatus ssl_GetCertificateRequestCAs(sslSocket *ss, unsigned int *calenp,
|
||||
SECItem **namesp, unsigned int *nnamesp);
|
||||
SECStatus ssl3_ParseCertificateRequestCAs(sslSocket *ss, SSL3Opaque **b,
|
||||
PRUint32 *length, PLArenaPool *arena,
|
||||
CERTDistNames *ca_list);
|
||||
|
@ -1815,7 +1814,6 @@ SECStatus ssl_CreateStaticECDHEKey(sslSocket *ss,
|
|||
SECStatus ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags);
|
||||
PK11SymKey *ssl3_GetWrappingKey(sslSocket *ss,
|
||||
PK11SlotInfo *masterSecretSlot,
|
||||
const sslServerCert *serverCert,
|
||||
CK_MECHANISM_TYPE masterWrapMech,
|
||||
void *pwArg);
|
||||
SECStatus ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This file implements the SERVER Session ID cache.
|
||||
* NOTE: The contents of this file are NOT used by the client.
|
||||
*
|
||||
|
@ -33,7 +34,7 @@
|
|||
* sidCacheSet sidCacheSets[ numSIDCacheSets ];
|
||||
* sidCacheEntry sidCacheData[ numSIDCacheEntries];
|
||||
* certCacheEntry certCacheData[numCertCacheEntries];
|
||||
* SSLWrappedSymWrappingKey keyCacheData[ssl_auth_size][SSL_NUM_WRAP_MECHS];
|
||||
* SSLWrappedSymWrappingKey keyCacheData[SSL_NUM_WRAP_KEYS][SSL_NUM_WRAP_MECHS];
|
||||
* PRUint8 keyNameSuffix[SESS_TICKET_KEY_VAR_NAME_LEN]
|
||||
* encKeyCacheEntry ticketEncKey; // Wrapped
|
||||
* encKeyCacheEntry ticketMacKey; // Wrapped
|
||||
|
@ -54,6 +55,7 @@
|
|||
#include "base64.h"
|
||||
#include "keyhi.h"
|
||||
#include "blapit.h"
|
||||
#include "nss.h" /* for NSS_RegisterShutdown */
|
||||
#include "sechash.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -109,7 +111,7 @@ struct sidCacheEntryStr {
|
|||
/* 4 */ PRInt32 certIndex;
|
||||
/* 4 */ PRInt32 srvNameIndex;
|
||||
/* 32 */ PRUint8 srvNameHash[SHA256_LENGTH]; /* SHA256 name hash */
|
||||
/* 2 */ PRUint16 certTypeArgs;
|
||||
/* 2 */ PRUint16 namedCurve;
|
||||
/*104 */} ssl3;
|
||||
|
||||
/* force sizeof(sidCacheEntry) to be a multiple of cache line size */
|
||||
|
@ -440,17 +442,12 @@ ConvertFromSID(sidCacheEntry *to, sslSessionID *from)
|
|||
to->u.ssl3.srvNameIndex = -1;
|
||||
PORT_Memcpy(to->sessionID, from->u.ssl3.sessionID,
|
||||
to->sessionIDLength);
|
||||
to->u.ssl3.certTypeArgs = 0U;
|
||||
switch (from->authType) {
|
||||
case ssl_auth_ecdsa:
|
||||
case ssl_auth_ecdh_rsa:
|
||||
case ssl_auth_ecdh_ecdsa:
|
||||
PORT_Assert(from->certType.namedCurve);
|
||||
to->u.ssl3.certTypeArgs =
|
||||
(PRUint16)from->certType.namedCurve->name;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
to->u.ssl3.namedCurve = 0U;
|
||||
if (from->authType == ssl_auth_ecdsa ||
|
||||
from->authType == ssl_auth_ecdh_rsa ||
|
||||
from->authType == ssl_auth_ecdh_ecdsa) {
|
||||
PORT_Assert(from->namedCurve);
|
||||
to->u.ssl3.namedCurve = (PRUint16)from->namedCurve->name;
|
||||
}
|
||||
|
||||
SSL_TRC(8, ("%d: SSL3: ConvertSID: time=%d addr=0x%08x%08x%08x%08x "
|
||||
|
@ -526,16 +523,11 @@ ConvertToSID(sidCacheEntry *from,
|
|||
if (to->peerCert == NULL)
|
||||
goto loser;
|
||||
}
|
||||
to->certType.authType = from->authType;
|
||||
switch (from->authType) {
|
||||
case ssl_auth_ecdsa:
|
||||
case ssl_auth_ecdh_rsa:
|
||||
case ssl_auth_ecdh_ecdsa:
|
||||
to->certType.namedCurve =
|
||||
ssl_LookupNamedGroup((SSLNamedGroup)from->u.ssl3.certTypeArgs);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (from->authType == ssl_auth_ecdsa ||
|
||||
from->authType == ssl_auth_ecdh_rsa ||
|
||||
from->authType == ssl_auth_ecdh_ecdsa) {
|
||||
to->namedCurve =
|
||||
ssl_LookupNamedGroup((SSLNamedGroup)from->u.ssl3.namedCurve);
|
||||
}
|
||||
|
||||
to->version = from->version;
|
||||
|
@ -983,7 +975,7 @@ InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries,
|
|||
cache->certCacheSize =
|
||||
(char *)cache->keyCacheData - (char *)cache->certCacheData;
|
||||
|
||||
cache->numKeyCacheEntries = ssl_auth_size * SSL_NUM_WRAP_MECHS;
|
||||
cache->numKeyCacheEntries = SSL_NUM_WRAP_KEYS * SSL_NUM_WRAP_MECHS;
|
||||
ptr = (ptrdiff_t)(cache->keyCacheData + cache->numKeyCacheEntries);
|
||||
ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);
|
||||
|
||||
|
@ -1608,36 +1600,254 @@ StopLockPoller(cacheDesc *cache)
|
|||
* Code dealing with shared wrapped symmetric wrapping keys below *
|
||||
************************************************************************/
|
||||
|
||||
/* If now is zero, it implies that the lock is not held, and must be
|
||||
** aquired here.
|
||||
*/
|
||||
/* The asymmetric key we use for wrapping the symmetric ticket keys. This is a
|
||||
* global structure that can be initialized without a socket. Access is
|
||||
* synchronized on the reader-writer lock. This is setup either by calling
|
||||
* SSL_SetSessionTicketKeyPair() or by configuring a certificate of the
|
||||
* ssl_auth_rsa_decrypt type. */
|
||||
static struct {
|
||||
PRCallOnceType setup;
|
||||
PRRWLock *lock;
|
||||
SECKEYPublicKey *pubKey;
|
||||
SECKEYPrivateKey *privKey;
|
||||
PRBool configured;
|
||||
} ssl_session_ticket_key_pair;
|
||||
|
||||
/* The symmetric ticket keys. This requires a socket to construct and requires
|
||||
* that the global structure be initialized before use. */
|
||||
static struct {
|
||||
PRCallOnceType setup;
|
||||
unsigned char keyName[SESS_TICKET_KEY_NAME_LEN];
|
||||
PK11SymKey *encKey;
|
||||
PK11SymKey *macKey;
|
||||
} ssl_session_ticket_keys;
|
||||
|
||||
static void
|
||||
ssl_CleanupSessionTicketKeyPair()
|
||||
{
|
||||
if (ssl_session_ticket_key_pair.pubKey) {
|
||||
PORT_Assert(ssl_session_ticket_key_pair.privKey);
|
||||
SECKEY_DestroyPublicKey(ssl_session_ticket_key_pair.pubKey);
|
||||
SECKEY_DestroyPrivateKey(ssl_session_ticket_key_pair.privKey);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ssl_ResetSessionTicketKeys()
|
||||
{
|
||||
if (ssl_session_ticket_keys.encKey) {
|
||||
PORT_Assert(ssl_session_ticket_keys.macKey);
|
||||
PK11_FreeSymKey(ssl_session_ticket_keys.encKey);
|
||||
PK11_FreeSymKey(ssl_session_ticket_keys.macKey);
|
||||
}
|
||||
PORT_Memset(&ssl_session_ticket_keys, 0,
|
||||
sizeof(ssl_session_ticket_keys));
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ssl_SessionTicketShutdown(void *appData, void *nssData)
|
||||
{
|
||||
ssl_CleanupSessionTicketKeyPair();
|
||||
PR_DestroyRWLock(ssl_session_ticket_key_pair.lock);
|
||||
PORT_Memset(&ssl_session_ticket_key_pair, 0,
|
||||
sizeof(ssl_session_ticket_key_pair));
|
||||
|
||||
ssl_ResetSessionTicketKeys();
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static PRStatus
|
||||
ssl_SessionTicketSetup(void)
|
||||
{
|
||||
SECStatus rv = NSS_RegisterShutdown(ssl_SessionTicketShutdown, NULL);
|
||||
if (rv != SECSuccess) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
ssl_session_ticket_key_pair.lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, NULL);
|
||||
if (!ssl_session_ticket_key_pair.lock) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
/* Configure a session ticket key pair. |explicitConfig| is set to true for
|
||||
* calls to SSL_SetSessionTicketKeyPair(), false for implicit configuration.
|
||||
* This assumes that the setup has been run. */
|
||||
static SECStatus
|
||||
ssl_SetSessionTicketKeyPair(SECKEYPublicKey *pubKey,
|
||||
SECKEYPrivateKey *privKey,
|
||||
PRBool explicitConfig)
|
||||
{
|
||||
SECKEYPublicKey *pubKeyCopy;
|
||||
SECKEYPrivateKey *privKeyCopy;
|
||||
|
||||
PORT_Assert(ssl_session_ticket_key_pair.lock);
|
||||
|
||||
pubKeyCopy = SECKEY_CopyPublicKey(pubKey);
|
||||
if (!pubKeyCopy) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
privKeyCopy = SECKEY_CopyPrivateKey(privKey);
|
||||
if (!privKeyCopy) {
|
||||
SECKEY_DestroyPublicKey(pubKeyCopy);
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PR_RWLock_Wlock(ssl_session_ticket_key_pair.lock);
|
||||
ssl_CleanupSessionTicketKeyPair();
|
||||
ssl_session_ticket_key_pair.pubKey = pubKeyCopy;
|
||||
ssl_session_ticket_key_pair.privKey = privKeyCopy;
|
||||
ssl_session_ticket_key_pair.configured = explicitConfig;
|
||||
PR_RWLock_Unlock(ssl_session_ticket_key_pair.lock);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SSL_SetSessionTicketKeyPair(SECKEYPublicKey *pubKey,
|
||||
SECKEYPrivateKey *privKey)
|
||||
{
|
||||
if (SECKEY_GetPublicKeyType(pubKey) != rsaKey ||
|
||||
SECKEY_GetPrivateKeyType(privKey) != rsaKey) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (PR_SUCCESS != PR_CallOnce(&ssl_session_ticket_key_pair.setup,
|
||||
&ssl_SessionTicketSetup)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return ssl_SetSessionTicketKeyPair(pubKey, privKey, PR_TRUE);
|
||||
}
|
||||
|
||||
/* When configuring a server cert, we should save the RSA key in case it is
|
||||
* needed for ticket encryption. This saves the latest copy, unless there has
|
||||
* been an explicit call to SSL_SetSessionTicketKeyPair(). */
|
||||
SECStatus
|
||||
ssl_MaybeSetSessionTicketKeyPair(const sslKeyPair *keyPair)
|
||||
{
|
||||
PRBool configured;
|
||||
|
||||
if (PR_SUCCESS != PR_CallOnce(&ssl_session_ticket_key_pair.setup,
|
||||
&ssl_SessionTicketSetup)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PR_RWLock_Rlock(ssl_session_ticket_key_pair.lock);
|
||||
configured = ssl_session_ticket_key_pair.configured;
|
||||
PR_RWLock_Unlock(ssl_session_ticket_key_pair.lock);
|
||||
if (configured) {
|
||||
return SECSuccess;
|
||||
}
|
||||
return ssl_SetSessionTicketKeyPair(keyPair->pubKey,
|
||||
keyPair->privKey, PR_FALSE);
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
ssl_GetSessionTicketKeyPair(SECKEYPublicKey **pubKey,
|
||||
SECKEYPrivateKey **privKey)
|
||||
{
|
||||
if (PR_SUCCESS != PR_CallOnce(&ssl_session_ticket_key_pair.setup,
|
||||
&ssl_SessionTicketSetup)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PR_RWLock_Rlock(ssl_session_ticket_key_pair.lock);
|
||||
*pubKey = ssl_session_ticket_key_pair.pubKey;
|
||||
*privKey = ssl_session_ticket_key_pair.privKey;
|
||||
PR_RWLock_Unlock(ssl_session_ticket_key_pair.lock);
|
||||
if (!*pubKey) {
|
||||
PORT_Assert(!*privKey);
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_Assert(*privKey);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
getSvrWrappingKey(PRInt32 symWrapMechIndex,
|
||||
SSLAuthType authType,
|
||||
ssl_GenerateSessionTicketKeys(void *pwArg, unsigned char *keyName,
|
||||
PK11SymKey **aesKey, PK11SymKey **macKey);
|
||||
|
||||
static PRStatus
|
||||
ssl_GenerateSessionTicketKeysOnce(void *arg)
|
||||
{
|
||||
SECStatus rv;
|
||||
|
||||
/* Get a copy of the session keys from shared memory. */
|
||||
PORT_Memcpy(ssl_session_ticket_keys.keyName,
|
||||
SESS_TICKET_KEY_NAME_PREFIX,
|
||||
sizeof(SESS_TICKET_KEY_NAME_PREFIX));
|
||||
/* This function calls ssl_GetSessionTicketKeyPair(), which initializes the
|
||||
* key pair stuff. That allows this to use the same shutdown function. */
|
||||
rv = ssl_GenerateSessionTicketKeys(arg, ssl_session_ticket_keys.keyName,
|
||||
&ssl_session_ticket_keys.encKey,
|
||||
&ssl_session_ticket_keys.macKey);
|
||||
if (rv != SECSuccess) {
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
ssl_GetSessionTicketKeys(sslSocket *ss, unsigned char *keyName,
|
||||
PK11SymKey **encKey, PK11SymKey **macKey)
|
||||
{
|
||||
if (PR_SUCCESS != PR_CallOnceWithArg(&ssl_session_ticket_keys.setup,
|
||||
&ssl_GenerateSessionTicketKeysOnce,
|
||||
ss->pkcs11PinArg)) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (!ssl_session_ticket_keys.encKey || !ssl_session_ticket_keys.macKey) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PORT_Memcpy(keyName, ssl_session_ticket_keys.keyName,
|
||||
sizeof(ssl_session_ticket_keys.keyName));
|
||||
*encKey = ssl_session_ticket_keys.encKey;
|
||||
*macKey = ssl_session_ticket_keys.macKey;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* If lockTime is zero, it implies that the lock is not held, and must be
|
||||
* aquired here.
|
||||
*/
|
||||
static SECStatus
|
||||
getSvrWrappingKey(unsigned int symWrapMechIndex,
|
||||
unsigned int wrapKeyIndex,
|
||||
SSLWrappedSymWrappingKey *wswk,
|
||||
cacheDesc *cache,
|
||||
PRUint32 lockTime)
|
||||
{
|
||||
PRUint32 ndx = (authType * SSL_NUM_WRAP_MECHS) + symWrapMechIndex;
|
||||
PRUint32 ndx = (wrapKeyIndex * SSL_NUM_WRAP_MECHS) + symWrapMechIndex;
|
||||
SSLWrappedSymWrappingKey *pwswk = cache->keyCacheData + ndx;
|
||||
PRUint32 now = 0;
|
||||
PRBool rv = PR_FALSE;
|
||||
PRBool rv = SECFailure;
|
||||
|
||||
if (!cache->cacheMem) { /* cache is uninitialized */
|
||||
PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED);
|
||||
return rv;
|
||||
return SECFailure;
|
||||
}
|
||||
if (!lockTime) {
|
||||
lockTime = now = LockSidCacheLock(cache->keyCacheLock, now);
|
||||
if (!lockTime) {
|
||||
return rv;
|
||||
now = LockSidCacheLock(cache->keyCacheLock, 0);
|
||||
if (!now) {
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
if (pwswk->authType == authType &&
|
||||
pwswk->symWrapMechIndex == symWrapMechIndex &&
|
||||
if (pwswk->wrapKeyIndex == wrapKeyIndex &&
|
||||
pwswk->wrapMechIndex == symWrapMechIndex &&
|
||||
pwswk->wrappedSymKeyLen != 0) {
|
||||
*wswk = *pwswk;
|
||||
rv = PR_TRUE;
|
||||
rv = SECSuccess;
|
||||
}
|
||||
if (now) {
|
||||
UnlockSidCacheLock(cache->keyCacheLock);
|
||||
|
@ -1645,28 +1855,25 @@ getSvrWrappingKey(PRInt32 symWrapMechIndex,
|
|||
return rv;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ssl_GetWrappingKey(PRInt32 symWrapMechIndex,
|
||||
SSLAuthType authType,
|
||||
SECStatus
|
||||
ssl_GetWrappingKey(unsigned int wrapMechIndex,
|
||||
unsigned int wrapKeyIndex,
|
||||
SSLWrappedSymWrappingKey *wswk)
|
||||
{
|
||||
PRBool rv;
|
||||
|
||||
PORT_Assert((unsigned)authType < ssl_auth_size);
|
||||
PORT_Assert((unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS);
|
||||
if ((unsigned)authType < ssl_auth_size &&
|
||||
(unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS) {
|
||||
rv = getSvrWrappingKey(symWrapMechIndex, authType, wswk,
|
||||
&globalCache, 0);
|
||||
} else {
|
||||
rv = PR_FALSE;
|
||||
PORT_Assert(wrapMechIndex < SSL_NUM_WRAP_MECHS);
|
||||
PORT_Assert(wrapKeyIndex < SSL_NUM_WRAP_KEYS);
|
||||
if (wrapMechIndex >= SSL_NUM_WRAP_MECHS ||
|
||||
wrapKeyIndex >= SSL_NUM_WRAP_KEYS) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return rv;
|
||||
return getSvrWrappingKey(wrapMechIndex, wrapKeyIndex, wswk,
|
||||
&globalCache, 0);
|
||||
}
|
||||
|
||||
/* Wrap and cache a session ticket key. */
|
||||
static PRBool
|
||||
static SECStatus
|
||||
WrapTicketKey(SECKEYPublicKey *svrPubKey, PK11SymKey *symKey,
|
||||
const char *keyName, encKeyCacheEntry *cacheEntry)
|
||||
{
|
||||
|
@ -1682,13 +1889,13 @@ WrapTicketKey(SECKEYPublicKey *svrPubKey, PK11SymKey *symKey,
|
|||
SECSuccess) {
|
||||
SSL_DBG(("%d: SSL[%s]: Unable to wrap session ticket %s.",
|
||||
SSL_GETPID(), "unknown", keyName));
|
||||
return PR_FALSE;
|
||||
return SECFailure;
|
||||
}
|
||||
cacheEntry->length = wrappedKey.len;
|
||||
return PR_TRUE;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
static SECStatus
|
||||
GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey,
|
||||
PK11SymKey **macKey)
|
||||
{
|
||||
|
@ -1712,7 +1919,7 @@ GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey,
|
|||
SECSuccess) {
|
||||
SSL_DBG(("%d: SSL[%s]: Unable to generate random key name bytes.",
|
||||
SSL_GETPID(), "unknown"));
|
||||
goto loser;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
mechanismArray[0] = CKM_AES_CBC;
|
||||
|
@ -1735,17 +1942,17 @@ GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey,
|
|||
PORT_Memcpy(keyName, ticketKeyNameSuffix, SESS_TICKET_KEY_VAR_NAME_LEN);
|
||||
*aesKey = aesKeyTmp;
|
||||
*macKey = macKeyTmp;
|
||||
return PR_TRUE;
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
if (aesKeyTmp)
|
||||
PK11_FreeSymKey(aesKeyTmp);
|
||||
if (macKeyTmp)
|
||||
PK11_FreeSymKey(macKeyTmp);
|
||||
return PR_FALSE;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
static SECStatus
|
||||
GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg,
|
||||
unsigned char *keyName, PK11SymKey **aesKey,
|
||||
PK11SymKey **macKey)
|
||||
|
@ -1753,31 +1960,35 @@ GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg,
|
|||
PK11SymKey *aesKeyTmp = NULL;
|
||||
PK11SymKey *macKeyTmp = NULL;
|
||||
cacheDesc *cache = &globalCache;
|
||||
SECStatus rv;
|
||||
|
||||
if (!GenerateTicketKeys(pwArg, keyName, &aesKeyTmp, &macKeyTmp)) {
|
||||
goto loser;
|
||||
rv = GenerateTicketKeys(pwArg, keyName, &aesKeyTmp, &macKeyTmp);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (cache->cacheMem) {
|
||||
/* Export the keys to the shared cache in wrapped form. */
|
||||
if (!WrapTicketKey(svrPubKey, aesKeyTmp, "enc key", cache->ticketEncKey))
|
||||
rv = WrapTicketKey(svrPubKey, aesKeyTmp, "enc key", cache->ticketEncKey);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
if (!WrapTicketKey(svrPubKey, macKeyTmp, "mac key", cache->ticketMacKey))
|
||||
}
|
||||
rv = WrapTicketKey(svrPubKey, macKeyTmp, "mac key", cache->ticketMacKey);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
*aesKey = aesKeyTmp;
|
||||
*macKey = macKeyTmp;
|
||||
return PR_TRUE;
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
if (aesKeyTmp)
|
||||
PK11_FreeSymKey(aesKeyTmp);
|
||||
if (macKeyTmp)
|
||||
PK11_FreeSymKey(macKeyTmp);
|
||||
return PR_FALSE;
|
||||
PK11_FreeSymKey(aesKeyTmp);
|
||||
PK11_FreeSymKey(macKeyTmp);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
static SECStatus
|
||||
UnwrapCachedTicketKeys(SECKEYPrivateKey *svrPrivKey, unsigned char *keyName,
|
||||
PK11SymKey **aesKey, PK11SymKey **macKey)
|
||||
{
|
||||
|
@ -1810,52 +2021,52 @@ UnwrapCachedTicketKeys(SECKEYPrivateKey *svrPrivKey, unsigned char *keyName,
|
|||
SESS_TICKET_KEY_VAR_NAME_LEN);
|
||||
*aesKey = aesKeyTmp;
|
||||
*macKey = macKeyTmp;
|
||||
return PR_TRUE;
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
if (aesKeyTmp)
|
||||
PK11_FreeSymKey(aesKeyTmp);
|
||||
if (macKeyTmp)
|
||||
PK11_FreeSymKey(macKeyTmp);
|
||||
return PR_FALSE;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ssl_GetSessionTicketKeys(SECKEYPrivateKey *svrPrivKey,
|
||||
SECKEYPublicKey *svrPubKey, void *pwArg,
|
||||
unsigned char *keyName, PK11SymKey **aesKey,
|
||||
PK11SymKey **macKey)
|
||||
static SECStatus
|
||||
ssl_GenerateSessionTicketKeys(void *pwArg, unsigned char *keyName,
|
||||
PK11SymKey **encKey, PK11SymKey **macKey)
|
||||
{
|
||||
PRUint32 now = 0;
|
||||
PRBool rv = PR_FALSE;
|
||||
PRBool keysGenerated = PR_FALSE;
|
||||
SECKEYPrivateKey *svrPrivKey;
|
||||
SECKEYPublicKey *svrPubKey;
|
||||
PRUint32 now;
|
||||
SECStatus rv;
|
||||
cacheDesc *cache = &globalCache;
|
||||
|
||||
if (!cache->cacheMem) {
|
||||
/* cache is uninitialized. Generate keys and return them
|
||||
* without caching. */
|
||||
return GenerateTicketKeys(pwArg, keyName, aesKey, macKey);
|
||||
return GenerateTicketKeys(pwArg, keyName, encKey, macKey);
|
||||
}
|
||||
|
||||
now = LockSidCacheLock(cache->keyCacheLock, now);
|
||||
rv = ssl_GetSessionTicketKeyPair(&svrPubKey, &svrPrivKey);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
now = LockSidCacheLock(cache->keyCacheLock, 0);
|
||||
if (!now)
|
||||
return rv;
|
||||
return SECFailure;
|
||||
|
||||
if (!*(cache->ticketKeysValid)) {
|
||||
if (*(cache->ticketKeysValid)) {
|
||||
rv = UnwrapCachedTicketKeys(svrPrivKey, keyName, encKey, macKey);
|
||||
} else {
|
||||
/* Keys do not exist, create them. */
|
||||
if (!GenerateAndWrapTicketKeys(svrPubKey, pwArg, keyName,
|
||||
aesKey, macKey))
|
||||
goto loser;
|
||||
keysGenerated = PR_TRUE;
|
||||
*(cache->ticketKeysValid) = 1;
|
||||
rv = GenerateAndWrapTicketKeys(svrPubKey, pwArg, keyName,
|
||||
encKey, macKey);
|
||||
if (rv == SECSuccess) {
|
||||
*(cache->ticketKeysValid) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
rv = PR_TRUE;
|
||||
|
||||
loser:
|
||||
UnlockSidCacheLock(cache->keyCacheLock);
|
||||
if (rv && !keysGenerated)
|
||||
rv = UnwrapCachedTicketKeys(svrPrivKey, keyName, aesKey, macKey);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1868,47 +2079,45 @@ loser:
|
|||
* This is all done while holding the locks/mutexes necessary to make
|
||||
* the operation atomic.
|
||||
*/
|
||||
PRBool
|
||||
SECStatus
|
||||
ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk)
|
||||
{
|
||||
cacheDesc *cache = &globalCache;
|
||||
PRBool rv = PR_FALSE;
|
||||
SSLAuthType authType = wswk->authType;
|
||||
/* type of keys used to wrap SymWrapKey*/
|
||||
PRInt32 symWrapMechIndex = wswk->symWrapMechIndex;
|
||||
PRBool rv = SECFailure;
|
||||
PRUint32 ndx;
|
||||
PRUint32 now = 0;
|
||||
PRUint32 now;
|
||||
SSLWrappedSymWrappingKey myWswk;
|
||||
|
||||
if (!cache->cacheMem) { /* cache is uninitialized */
|
||||
PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED);
|
||||
return 0;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PORT_Assert((unsigned)authType < ssl_auth_size);
|
||||
if ((unsigned)authType >= ssl_auth_size)
|
||||
return 0;
|
||||
PORT_Assert(wswk->wrapMechIndex < SSL_NUM_WRAP_MECHS);
|
||||
PORT_Assert(wswk->wrapKeyIndex < SSL_NUM_WRAP_KEYS);
|
||||
if (wswk->wrapMechIndex >= SSL_NUM_WRAP_MECHS ||
|
||||
wswk->wrapKeyIndex >= SSL_NUM_WRAP_KEYS) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PORT_Assert((unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS);
|
||||
if ((unsigned)symWrapMechIndex >= SSL_NUM_WRAP_MECHS)
|
||||
return 0;
|
||||
|
||||
ndx = (authType * SSL_NUM_WRAP_MECHS) + symWrapMechIndex;
|
||||
ndx = (wswk->wrapKeyIndex * SSL_NUM_WRAP_MECHS) + wswk->wrapMechIndex;
|
||||
PORT_Memset(&myWswk, 0, sizeof myWswk); /* eliminate UMRs. */
|
||||
|
||||
now = LockSidCacheLock(cache->keyCacheLock, now);
|
||||
if (now) {
|
||||
rv = getSvrWrappingKey(wswk->symWrapMechIndex, wswk->authType,
|
||||
&myWswk, cache, now);
|
||||
if (rv) {
|
||||
/* we found it on disk, copy it out to the caller. */
|
||||
PORT_Memcpy(wswk, &myWswk, sizeof *wswk);
|
||||
} else {
|
||||
/* Wasn't on disk, and we're still holding the lock, so write it. */
|
||||
cache->keyCacheData[ndx] = *wswk;
|
||||
}
|
||||
UnlockSidCacheLock(cache->keyCacheLock);
|
||||
now = LockSidCacheLock(cache->keyCacheLock, 0);
|
||||
if (!now) {
|
||||
return SECFailure;
|
||||
}
|
||||
rv = getSvrWrappingKey(wswk->wrapMechIndex, wswk->wrapKeyIndex,
|
||||
&myWswk, cache, now);
|
||||
if (rv == SECSuccess) {
|
||||
/* we found it on disk, copy it out to the caller. */
|
||||
PORT_Memcpy(wswk, &myWswk, sizeof *wswk);
|
||||
} else {
|
||||
/* Wasn't on disk, and we're still holding the lock, so write it. */
|
||||
cache->keyCacheData[ndx] = *wswk;
|
||||
}
|
||||
UnlockSidCacheLock(cache->keyCacheLock);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1946,14 +2155,13 @@ SSL_InheritMPServerSIDCache(const char *envString)
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ssl_GetWrappingKey(PRInt32 symWrapMechIndex,
|
||||
SSLAuthType authType,
|
||||
SECStatus
|
||||
ssl_GetWrappingKey(unsigned int wrapMechIndex,
|
||||
unsigned int wrapKeyIndex,
|
||||
SSLWrappedSymWrappingKey *wswk)
|
||||
{
|
||||
PRBool rv = PR_FALSE;
|
||||
PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_GetWrappingKey)");
|
||||
return rv;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* This is a kind of test-and-set. The caller passes in the new value it wants
|
||||
|
@ -1965,12 +2173,11 @@ ssl_GetWrappingKey(PRInt32 symWrapMechIndex,
|
|||
* This is all done while holding the locks/mutexes necessary to make
|
||||
* the operation atomic.
|
||||
*/
|
||||
PRBool
|
||||
SECStatus
|
||||
ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk)
|
||||
{
|
||||
PRBool rv = PR_FALSE;
|
||||
PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_SetWrappingKey)");
|
||||
return rv;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
|
|
|
@ -628,13 +628,9 @@ tls13_RecoverWrappedSharedSecret(sslSocket *ss, sslSessionID *sid)
|
|||
hashType = tls13_GetHashForCipherSuite(sid->u.ssl3.cipherSuite);
|
||||
|
||||
/* If we are the server, we compute the wrapping key, but if we
|
||||
* are the client, it's coordinates are stored with the ticket. */
|
||||
* are the client, its coordinates are stored with the ticket. */
|
||||
if (ss->sec.isServer) {
|
||||
const sslServerCert *serverCert;
|
||||
|
||||
serverCert = ssl_FindServerCert(ss, &sid->certType);
|
||||
PORT_Assert(serverCert);
|
||||
wrapKey = ssl3_GetWrappingKey(ss, NULL, serverCert,
|
||||
wrapKey = ssl3_GetWrappingKey(ss, NULL,
|
||||
sid->u.ssl3.masterWrapMech,
|
||||
ss->pkcs11PinArg);
|
||||
} else {
|
||||
|
@ -937,7 +933,7 @@ tls13_CanResume(sslSocket *ss, const sslSessionID *sid)
|
|||
* do remember the type of certificate we originally used, so we can locate
|
||||
* it again, provided that the current ssl socket has had its server certs
|
||||
* configured the same as the previous one. */
|
||||
sc = ssl_FindServerCert(ss, &sid->certType);
|
||||
sc = ssl_FindServerCert(ss, sid->authType, sid->namedCurve);
|
||||
if (!sc || !sc->serverCert) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -1161,6 +1157,30 @@ tls13_NegotiateKeyExchange(sslSocket *ss, TLS13KeyShareEntry **clientShare)
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
SSLAuthType
|
||||
ssl_SignatureSchemeToAuthType(SSLSignatureScheme scheme)
|
||||
{
|
||||
switch (scheme) {
|
||||
case ssl_sig_rsa_pkcs1_sha1:
|
||||
case ssl_sig_rsa_pkcs1_sha256:
|
||||
case ssl_sig_rsa_pkcs1_sha384:
|
||||
case ssl_sig_rsa_pkcs1_sha512:
|
||||
/* We report PSS signatures as being just RSA signatures. */
|
||||
case ssl_sig_rsa_pss_sha256:
|
||||
case ssl_sig_rsa_pss_sha384:
|
||||
case ssl_sig_rsa_pss_sha512:
|
||||
return ssl_auth_rsa_sign;
|
||||
case ssl_sig_ecdsa_secp256r1_sha256:
|
||||
case ssl_sig_ecdsa_secp384r1_sha384:
|
||||
case ssl_sig_ecdsa_secp521r1_sha512:
|
||||
case ssl_sig_ecdsa_sha1:
|
||||
return ssl_auth_ecdsa;
|
||||
default:
|
||||
PORT_Assert(0);
|
||||
}
|
||||
return ssl_auth_null;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
tls13_SelectServerCert(sslSocket *ss)
|
||||
{
|
||||
|
@ -1184,8 +1204,7 @@ tls13_SelectServerCert(sslSocket *ss)
|
|||
cursor = PR_NEXT_LINK(cursor)) {
|
||||
sslServerCert *cert = (sslServerCert *)cursor;
|
||||
|
||||
if (cert->certType.authType == ssl_auth_rsa_pss ||
|
||||
cert->certType.authType == ssl_auth_rsa_decrypt) {
|
||||
if (SSL_CERT_IS_ONLY(cert, ssl_auth_rsa_decrypt)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1198,8 +1217,8 @@ tls13_SelectServerCert(sslSocket *ss)
|
|||
if (rv == SECSuccess) {
|
||||
/* Found one. */
|
||||
ss->sec.serverCert = cert;
|
||||
ss->sec.authType = cert->certType.authType;
|
||||
ss->ssl3.hs.kea_def_mutable.authKeyType = cert->certType.authType;
|
||||
ss->sec.authType = ss->ssl3.hs.kea_def_mutable.authKeyType =
|
||||
ssl_SignatureSchemeToAuthType(ss->ssl3.hs.signatureScheme);
|
||||
ss->sec.authKeyBits = cert->serverKeyBits;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
@ -1230,8 +1249,6 @@ tls13_NegotiateAuthentication(sslSocket *ss)
|
|||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
ss->ssl3.hs.kea_def_mutable.authKeyType =
|
||||
ss->sec.serverCert->certType.authType;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
@ -1343,6 +1360,10 @@ tls13_HandleClientHelloPart2(sslSocket *ss,
|
|||
goto loser;
|
||||
}
|
||||
|
||||
ss->sec.serverCert = ssl_FindServerCert(ss, sid->authType,
|
||||
sid->namedCurve);
|
||||
PORT_Assert(ss->sec.serverCert);
|
||||
|
||||
rv = tls13_RecoverWrappedSharedSecret(ss, sid);
|
||||
if (rv != SECSuccess) {
|
||||
SSL_AtomicIncrementLong(&ssl3stats->hch_sid_cache_not_ok);
|
||||
|
@ -1351,12 +1372,11 @@ tls13_HandleClientHelloPart2(sslSocket *ss,
|
|||
}
|
||||
tls13_RestoreCipherInfo(ss, sid);
|
||||
|
||||
ss->sec.serverCert = ssl_FindServerCert(ss, &sid->certType);
|
||||
PORT_Assert(ss->sec.serverCert);
|
||||
ss->sec.localCert = CERT_DupCertificate(ss->sec.serverCert->serverCert);
|
||||
if (sid->peerCert != NULL) {
|
||||
ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
|
||||
}
|
||||
|
||||
ssl3_RegisterExtensionSender(
|
||||
ss, &ss->xtnData,
|
||||
ssl_tls13_pre_shared_key_xtn, tls13_ServerSendPreSharedKeyXtn);
|
||||
|
@ -1617,9 +1637,9 @@ static SECStatus
|
|||
tls13_SendCertificateRequest(sslSocket *ss)
|
||||
{
|
||||
SECStatus rv;
|
||||
int calen;
|
||||
unsigned int calen;
|
||||
SECItem *names;
|
||||
int nnames;
|
||||
unsigned int nnames;
|
||||
SECItem *name;
|
||||
int i;
|
||||
PRUint8 sigSchemes[MAX_SIGNATURE_SCHEMES * 2];
|
||||
|
@ -1635,7 +1655,10 @@ tls13_SendCertificateRequest(sslSocket *ss)
|
|||
return rv;
|
||||
}
|
||||
|
||||
ssl3_GetCertificateRequestCAs(ss, &calen, &names, &nnames);
|
||||
rv = ssl_GetCertificateRequestCAs(ss, &calen, &names, &nnames);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
length = 1 + 0 /* length byte for empty request context */ +
|
||||
2 + sigSchemesLength + 2 + calen + 2;
|
||||
|
||||
|
@ -3291,16 +3314,7 @@ tls13_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
|
|||
|
||||
/* Set the auth type. */
|
||||
if (!ss->sec.isServer) {
|
||||
switch (ssl_SignatureSchemeToKeyType(sigScheme)) {
|
||||
case rsaKey:
|
||||
ss->sec.authType = ssl_auth_rsa_sign;
|
||||
break;
|
||||
case ecKey:
|
||||
ss->sec.authType = ssl_auth_ecdsa;
|
||||
break;
|
||||
default:
|
||||
PORT_Assert(PR_FALSE);
|
||||
}
|
||||
ss->sec.authType = ssl_SignatureSchemeToAuthType(sigScheme);
|
||||
}
|
||||
|
||||
/* Request a client certificate now if one was requested. */
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
|
||||
*/
|
||||
#define NSSUTIL_VERSION "3.29 Beta"
|
||||
#define NSSUTIL_VERSION "3.30 Beta"
|
||||
#define NSSUTIL_VMAJOR 3
|
||||
#define NSSUTIL_VMINOR 29
|
||||
#define NSSUTIL_VMINOR 30
|
||||
#define NSSUTIL_VPATCH 0
|
||||
#define NSSUTIL_VBUILD 0
|
||||
#define NSSUTIL_BETA PR_TRUE
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
#include "argparse.h"
|
||||
#include "scoped_ptrs.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
|
||||
#include <cert.h>
|
||||
|
@ -50,7 +52,8 @@ static std::string PrintFlags(unsigned int flags) {
|
|||
}
|
||||
|
||||
void DBTool::Usage() {
|
||||
std::cerr << "Usage: nss db [--path <directory>] --list-certs" << std::endl;
|
||||
std::cerr << "Usage: nss db [--path <directory>] [--create] --list-certs"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
bool DBTool::Run(const std::vector<std::string> &arguments) {
|
||||
|
@ -61,18 +64,33 @@ bool DBTool::Run(const std::vector<std::string> &arguments) {
|
|||
initDir = parser.Get("--path");
|
||||
if (PR_Access(initDir.c_str(), PR_ACCESS_READ_OK) != PR_SUCCESS) {
|
||||
std::cerr << "Directory '" << initDir
|
||||
<< "' does not exists or you don't have permissions!"
|
||||
<< "' does not exist or you don't have permissions!"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!parser.Has("--list-certs")) {
|
||||
if (!parser.Has("--list-certs") && !parser.Has("--create")) {
|
||||
return false;
|
||||
}
|
||||
std::cout << "Using database directory: " << initDir << std::endl
|
||||
<< std::endl;
|
||||
|
||||
bool dbFilesExist = PathHasDBFiles(initDir);
|
||||
if (parser.Has("--create") && dbFilesExist) {
|
||||
std::cerr << "Trying to create database files in a directory where they "
|
||||
"already exists. Delete the db files before creating new ones."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
if (!parser.Has("--create") && !dbFilesExist) {
|
||||
std::cerr << "No db files found." << std::endl;
|
||||
std::cerr << "Create them using 'nss db --create [--path /foo/bar]' before "
|
||||
"continuing."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// init NSS
|
||||
const char *certPrefix = ""; // certutil -P option --- can leave this empty
|
||||
SECStatus rv =
|
||||
|
@ -82,7 +100,13 @@ bool DBTool::Run(const std::vector<std::string> &arguments) {
|
|||
return false;
|
||||
}
|
||||
|
||||
ListCertificates();
|
||||
if (parser.Has("--list-certs")) {
|
||||
ListCertificates();
|
||||
}
|
||||
|
||||
if (parser.Has("--create")) {
|
||||
std::cout << "DB files created successfully." << std::endl;
|
||||
}
|
||||
|
||||
// shutdown nss
|
||||
if (NSS_Shutdown() != SECSuccess) {
|
||||
|
@ -93,6 +117,31 @@ bool DBTool::Run(const std::vector<std::string> &arguments) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DBTool::PathHasDBFiles(std::string path) {
|
||||
std::regex certDBPattern("cert.*\\.db");
|
||||
std::regex keyDBPattern("key.*\\.db");
|
||||
|
||||
DIR *dir;
|
||||
if (!(dir = opendir(path.c_str()))) {
|
||||
std::cerr << "Directory " << path << " could not be accessed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct dirent *ent;
|
||||
bool dbFileExists = false;
|
||||
while ((ent = readdir(dir))) {
|
||||
if (std::regex_match(ent->d_name, certDBPattern) ||
|
||||
std::regex_match(ent->d_name, keyDBPattern) ||
|
||||
"secmod.db" == std::string(ent->d_name)) {
|
||||
dbFileExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
return dbFileExists;
|
||||
}
|
||||
|
||||
void DBTool::ListCertificates() {
|
||||
ScopedCERTCertList list(PK11_ListCerts(PK11CertListAll, nullptr));
|
||||
CERTCertListNode *node;
|
||||
|
|
|
@ -15,6 +15,7 @@ class DBTool {
|
|||
void Usage();
|
||||
|
||||
private:
|
||||
bool PathHasDBFiles(std::string path);
|
||||
void ListCertificates();
|
||||
};
|
||||
|
||||
|
|
|
@ -177,7 +177,6 @@
|
|||
'cmd/tstclnt/tstclnt.gyp:tstclnt',
|
||||
'cmd/vfychain/vfychain.gyp:vfychain',
|
||||
'cmd/vfyserv/vfyserv.gyp:vfyserv',
|
||||
'gtests/google_test/google_test.gyp:gtest1',
|
||||
'gtests/der_gtest/der_gtest.gyp:der_gtest',
|
||||
'gtests/pk11_gtest/pk11_gtest.gyp:pk11_gtest',
|
||||
'gtests/ssl_gtest/ssl_gtest.gyp:ssl_gtest',
|
||||
|
|
Загрузка…
Ссылка в новой задаче