Bug 1334127 - land NSS dbbf303cf467, r=me

--HG--
extra : rebase_source : 0275628dd4cb24c87ce4a59c8d5e60e07a2ada20
This commit is contained in:
Franziskus Kiefer 2017-01-26 19:49:57 +01:00
Родитель 2971191875
Коммит 4551817b24
75 изменённых файлов: 2371 добавлений и 1612 удалений

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

@ -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

0
security/nss/automation/release/nss-release-helper.py Normal file → Executable file
Просмотреть файл

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

@ -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',