Bug 1934958 - land NSS NSS_3_108_BETA1 UPGRADE_NSS_RELEASE, r=nss-reviewers,jschanck

Differential Revision: https://phabricator.services.mozilla.com/D233104
This commit is contained in:
Dennis Jackson
2025-01-07 16:58:35 +00:00
parent ecfa655e10
commit a68667f89c
99 changed files with 1410 additions and 712 deletions

View File

@@ -13,7 +13,7 @@ system_lib_option(
imply_option("--with-system-nspr", True, when="--with-system-nss")
nss_pkg = pkg_check_modules(
"NSS", "nss >= 3.107", when="--with-system-nss", config=False
"NSS", "nss >= 3.108", when="--with-system-nss", config=False
)
set_config("MOZ_SYSTEM_NSS", True, when="--with-system-nss")

View File

@@ -1 +1 @@
NSS_3_107_RTM
NSS_3_108_BETA1

View File

@@ -0,0 +1,3 @@
1 Added function:
'function SECMODModule* SECMOD_LoadUserModuleWithFunction(const char*, CK_C_GetFunctionList)' {SECMOD_LoadUserModuleWithFunction@@NSS_3.107}

View File

@@ -0,0 +1,5 @@
1 Added function:
'function void PORT_SafeZero(void*, size_t)' {PORT_SafeZero@@NSSUTIL_3.108}

View File

@@ -1 +1 @@
NSS_3_106_BRANCH
NSS_3_107_BRANCH

View File

@@ -218,6 +218,7 @@ export default async function main() {
NSS_DISABLE_UNLOAD: "1",
CC: "clang",
CCC: "clang++",
CFLAGS: "-O2",
},
platform: "linux64",
collection: "asan",

View File

@@ -8,7 +8,7 @@ source $(dirname "$0")/tools.sh
export CRYPTOFUZZ_VERSION="687d3064c5cef2b0fe1f30824065a2f2c9c0bbd8"
export BOTAN_VERSION="3.6.1"
git clone -q https://github.com/guidovranken/cryptofuzz.git
git clone -q https://github.com/MozillaSecurity/cryptofuzz.git
git -C cryptofuzz checkout "$CRYPTOFUZZ_VERSION"
git clone -q https://github.com/randombit/botan.git

View File

@@ -27,7 +27,9 @@ popd
./cryptofuzz/generate_dict
# Run Cryptofuzz.
./cryptofuzz/cryptofuzz -dict="cryptofuzz-dict.txt" "nss/fuzz/corpus/cryptofuzz" "$@"
# Decrease the default ASAN quarantine size of 256 MB as we tend to run
# out of memory on 32-bit.
ASAN_OPTIONS="quarantine_size_mb=128" ./cryptofuzz/cryptofuzz -dict="cryptofuzz-dict.txt" --force-module=nss "nss/fuzz/corpus/cryptofuzz" "$@"
# Alert if version is older than half a year.
cryptofuzz_timestamp=$(git -C cryptofuzz show -s --format=%ct $CRYPTOFUZZ_VERSION)

View File

@@ -111,6 +111,7 @@ while [ $# -gt 0 ]; do
--fuzz) fuzz=1 ;;
--fuzz=oss) fuzz=1; fuzz_oss=1 ;;
--fuzz=tls) fuzz=1; fuzz_tls=1 ;;
--gtests-corpus) gyp_params+=(-Dgtests_corpus=1) ;;
--sancov) enable_sancov; gyp_params+=(-Dcoverage=1) ;;
--sancov=?*) enable_sancov "${1#*=}"; gyp_params+=(-Dcoverage=1) ;;
--emit-llvm) gyp_params+=(-Demit_llvm=1 -Dsign_libs=0) ;;

View File

@@ -32,12 +32,12 @@ static void
Usage()
{
#define FPS PR_fprintf(PR_STDERR,
FPS "Usage: %s -i importfile [-d certdir] [-P dbprefix] [-h tokenname]\n",
FPS "Usage: %s -i importfile [-I] [-d certdir] [-P dbprefix] [-h tokenname]\n",
progName);
FPS "\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
FPS "\t\t [-v]\n");
FPS "Usage: %s -l listfile [-d certdir] [-P dbprefix] [-h tokenname]\n",
FPS "Usage: %s -l listfile [-I] [-d certdir] [-P dbprefix] [-h tokenname]\n",
progName);
FPS "\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
FPS "\t\t [-v]\n");
@@ -351,7 +351,8 @@ P12U_InitSlot(PK11SlotInfo *slot, secuPWData *slotPw)
*/
SEC_PKCS12DecoderContext *
p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot,
secuPWData *slotPw, secuPWData *p12FilePw)
secuPWData *slotPw, secuPWData *p12FilePw,
PRBool ignoreIntegrity)
{
SEC_PKCS12DecoderContext *p12dcx = NULL;
p12uContext *p12cxt = NULL;
@@ -458,7 +459,10 @@ p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot,
/* rv has been set at this point */
done:
if (rv != SECSuccess) {
/* if we are ignoring Integrity and we failed because we couldn't
* verify the integrity code, go ahead and succeed */
if (rv != SECSuccess && !(ignoreIntegrity &&
(pk12uErrno == PK12UERR_DECODEVERIFY))) {
if (p12dcx != NULL) {
SEC_PKCS12DecoderFinish(p12dcx);
p12dcx = NULL;
@@ -490,7 +494,8 @@ done:
*/
PRIntn
P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot,
secuPWData *slotPw, secuPWData *p12FilePw)
secuPWData *slotPw, secuPWData *p12FilePw,
PRBool ignoreIntegrity)
{
SEC_PKCS12DecoderContext *p12dcx = NULL;
SECItem uniPwitem = { 0 };
@@ -509,7 +514,8 @@ P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot,
do {
trypw = PR_FALSE; /* normally we do this once */
rv = SECFailure;
p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, p12FilePw);
p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw,
p12FilePw, ignoreIntegrity);
if (p12dcx == NULL) {
goto loser;
@@ -777,14 +783,16 @@ loser:
PRIntn
P12U_ListPKCS12File(char *in_file, PK11SlotInfo *slot,
secuPWData *slotPw, secuPWData *p12FilePw)
secuPWData *slotPw, secuPWData *p12FilePw,
PRBool ignoreIntegrity)
{
SEC_PKCS12DecoderContext *p12dcx = NULL;
SECItem uniPwitem = { 0 };
SECStatus rv = SECFailure;
const SEC_PKCS12DecoderItem *dip;
p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, p12FilePw);
p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, p12FilePw,
ignoreIntegrity);
/* did the blob authenticate properly? */
if (p12dcx == NULL) {
SECU_PrintError(progName, "PKCS12 decode not verified");
@@ -997,7 +1005,8 @@ enum {
opt_CertCipher,
opt_KeyLength,
opt_CertKeyLength,
opt_Mac
opt_Mac,
opt_IgnoreIntegrity
};
static secuCommandFlag pk12util_options[] = {
@@ -1018,7 +1027,8 @@ static secuCommandFlag pk12util_options[] = {
{ /* opt_CertCipher */ 'C', PR_TRUE, 0, PR_FALSE },
{ /* opt_KeyLength */ 'm', PR_TRUE, 0, PR_FALSE, "key_len" },
{ /* opt_CertKeyLength */ 0, PR_TRUE, 0, PR_FALSE, "cert_key_len" },
{ /* opt_Mac */ 'M', PR_TRUE, 0, PR_FALSE, PR_FALSE }
{ /* opt_Mac */ 'M', PR_TRUE, 0, PR_FALSE },
{ /* opt_IgnoreIntegrity */ 'I', PR_FALSE, 0, PR_FALSE }
};
int
@@ -1039,6 +1049,7 @@ main(int argc, char **argv)
int certKeyLen = 0;
secuCommand pk12util;
PRInt32 forceUnicode;
PRBool ignoreIntegrity = PR_FALSE;
#ifdef _CRTDBG_MAP_ALLOC
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
@@ -1113,6 +1124,9 @@ main(int argc, char **argv)
if (pk12util.options[opt_Raw].activated) {
dumpRawFile = PR_TRUE;
}
if (pk12util.options[opt_IgnoreIntegrity].activated) {
ignoreIntegrity = PR_TRUE;
}
if (pk12util.options[opt_KeyLength].activated) {
keyLen = atoi(pk12util.options[opt_KeyLength].arg);
}
@@ -1183,7 +1197,8 @@ main(int argc, char **argv)
}
if (pk12util.options[opt_Import].activated) {
P12U_ImportPKCS12Object(import_file, slot, &slotPw, &p12FilePw);
P12U_ImportPKCS12Object(import_file, slot, &slotPw, &p12FilePw,
ignoreIntegrity);
} else if (pk12util.options[opt_Export].activated) {
P12U_ExportPKCS12Object(pk12util.options[opt_Nickname].arg,
@@ -1191,7 +1206,8 @@ main(int argc, char **argv)
hash, &slotPw, &p12FilePw);
} else if (pk12util.options[opt_List].activated) {
P12U_ListPKCS12File(import_file, slot, &slotPw, &p12FilePw);
P12U_ListPKCS12File(import_file, slot, &slotPw, &p12FilePw,
ignoreIntegrity);
} else {
Usage();

View File

@@ -16,7 +16,6 @@
'dependencies': [
'<(DEPTH)/exports.gyp:dbm_exports',
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/lib/ssl/ssl.gyp:ssl',
'<(DEPTH)/lib/zlib/zlib.gyp:nss_zlib'
],
'include_dirs': [

View File

@@ -125,6 +125,7 @@
'fuzz%': 0,
'fuzz_tls%': 0,
'fuzz_oss%': 0,
'gtests_corpus%': 0,
'sign_libs%': 1,
'use_pprof%': 0,
'ct_verif%': 0,

View File

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

View File

@@ -38,6 +38,7 @@
<arg>-P dbprefix</arg>
<arg>-r</arg>
<arg>-v</arg>
<arg>-I</arg>
<arg>--cert-key-len certKeyLength</arg>
<arg>-k slotPasswordFile|-K slotPassword</arg>
<arg>-w p12filePasswordFile|-W p12filePassword</arg>
@@ -146,6 +147,11 @@
<listitem><para>Enable debug logging when importing.</para></listitem>
</varlistentry>
<varlistentry>
<term>-I </term>
<listitem><para>Ignore integrity check results on importing and listing.</para></listitem>
</varlistentry>
<varlistentry>
<term>-w p12filePasswordFile</term>
<listitem><para>Specify the text file containing the pkcs #12 file password.</para></listitem>
@@ -317,7 +323,7 @@ Certificate Friendly Name: Thawte Freemail Member's Thawte Consulting (Pty) L
<refsection id="encryption">
<title>Password Encryption</title>
<para>PKCS #12 provides for not only the protection of the private keys but also the certificate and meta-data associated with the keys. Password-based encryption is used to protect private keys on export to a PKCS #12 file and, optionally, the associated certificates. If no algorithm is specified, the tool defaults to using PKCS #12 SHA-1 and 3-key triple DES for private key encryption. When not in FIPS mode, PKCS #12 SHA-1 and 40-bit RC4 is used for certificate encryption. When in FIPS mode, there is no certificate encryption. If certificate encryption is not wanted, specify <userinput>"NONE"</userinput> as the argument of the <option>-C</option> option.</para>
<para>PKCS #12 provides for not only the protection of the private keys but also the certificate and meta-data associated with the keys. Password-based encryption is used to protect private keys on export to a PKCS #12 file and, optionally, the associated certificates. If no algorithm is specified, the tool defaults to using AES-256-CBC for private key encryption and AES-128-CBC for certificate encryption. If certificate encryption is not wanted, specify <userinput>"NONE"</userinput> as the argument of the <option>-C</option> option.</para>
<para>The private key is always protected with strong encryption by default.</para>
<para>Several types of ciphers are supported.</para>
<variablelist>
@@ -327,6 +333,7 @@ Certificate Friendly Name: Thawte Freemail Member's Thawte Consulting (Pty) L
<listitem>
<itemizedlist>
<listitem><para>PBES2 with AES-CBC-Pad as underlying encryption scheme (<userinput>"AES-128-CBC"</userinput>, <userinput>"AES-192-CBC"</userinput>, and <userinput>"AES-256-CBC"</userinput>)</para></listitem>
<listitem><para>PBES2 with CAMELLIA-CBC-Pad as underlying encryption scheme (<userinput>"CAMELLIA-128-CBC"</userinput>, <userinput>"CAMELLIA-192-CBC"</userinput>, and <userinput>"CAMELLIA-256-CBC"</userinput>)</para></listitem>
</itemizedlist>
</listitem>
</varlistentry>

View File

@@ -1,228 +1,14 @@
# 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/.
{
'includes': [
'../coreconf/config.gypi',
],
'target_defaults': {
'variables': {
'debug_optimization_level': '3',
},
'cflags_cc': [
'-Wno-vla-extension',
],
'target_conditions': [
[ '_type=="executable"', {
'libraries!': [
'<@(nspr_libs)',
],
'libraries': [
'<(nss_dist_obj_dir)/lib/libplds4.a',
'<(nss_dist_obj_dir)/lib/libnspr4.a',
'<(nss_dist_obj_dir)/lib/libplc4.a',
],
}],
],
},
'targets': [
{
'target_name': 'fuzz_base',
'type': 'static_library',
'sources': [
'shared.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/lib/certdb/certdb.gyp:certdb',
'<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
'<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
'<(DEPTH)/lib/ssl/ssl.gyp:ssl',
'<(DEPTH)/lib/base/base.gyp:nssb',
'<(DEPTH)/lib/dev/dev.gyp:nssdev',
'<(DEPTH)/lib/pki/pki.gyp:nsspki',
'<(DEPTH)/lib/util/util.gyp:nssutil',
'<(DEPTH)/lib/nss/nss.gyp:nss_static',
'<(DEPTH)/lib/pkcs7/pkcs7.gyp:pkcs7',
'<(DEPTH)/lib/pkcs12/pkcs12.gyp:pkcs12',
# This is a static build of pk11wrap, softoken, and freebl.
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
'<(DEPTH)/lib/libpkix/libpkix.gyp:libpkix',
],
'cflags_cc': [
'-Wno-error=shadow',
],
'conditions': [
['fuzz_oss==0', {
'all_dependent_settings': {
'libraries': [
'-fsanitize=fuzzer',
],
}
}, {
'all_dependent_settings': {
'libraries': ['-lFuzzingEngine'],
}
}]
],
},
{
'target_name': 'nssfuzz-pkcs7',
'type': 'executable',
'sources': [
'asn1_mutators.cc',
'pkcs7_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'fuzz_base',
],
},
{
'target_name': 'nssfuzz-pkcs8',
'type': 'executable',
'sources': [
'asn1_mutators.cc',
'pkcs8_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'fuzz_base',
],
},
{
'target_name': 'nssfuzz-pkcs12',
'type': 'executable',
'sources': [
'asn1_mutators.cc',
'pkcs12_target.cc',
],
'dependencies': [
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'<(DEPTH)/exports.gyp:nss_exports',
'fuzz_base',
],
},
{
'target_name': 'nssfuzz-quickder',
'type': 'executable',
'sources': [
'asn1_mutators.cc',
'quickder_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'fuzz_base',
],
},
{
'target_name': 'nssfuzz-certDN',
'type': 'executable',
'sources': [
'certDN_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'fuzz_base',
],
},
{
'target_name': 'nssfuzz-tls-base',
'type': 'static_library',
'sources': [
'tls_common.cc',
'tls_mutators.cc',
'tls_socket.cc',
],
'dependencies': [
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'<(DEPTH)/exports.gyp:nss_exports',
'fuzz_base',
],
'include_dirs': [
'<(DEPTH)/lib/ssl',
],
'direct_dependent_settings': {
'include_dirs': [
'<(DEPTH)/lib/freebl',
'<(DEPTH)/lib/ssl',
],
},
},
{
'target_name': 'nssfuzz-tls-client',
'type': 'executable',
'sources': [
'tls_client_config.cc',
'tls_client_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'nssfuzz-tls-base',
],
},
{
'target_name': 'nssfuzz-tls-server',
'type': 'executable',
'sources': [
'tls_server_certs.cc',
'tls_server_config.cc',
'tls_server_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'nssfuzz-tls-base',
],
},
{
'target_name': 'nssfuzz-dtls-client',
'type': 'executable',
'sources': [
'tls_client_config.cc',
'tls_client_target.cc',
],
'defines': [
'IS_DTLS_FUZZ'
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'nssfuzz-tls-base',
],
},
{
'target_name': 'nssfuzz-dtls-server',
'type': 'executable',
'sources': [
'tls_server_certs.cc',
'tls_server_config.cc',
'tls_server_target.cc',
],
'defines': [
'IS_DTLS_FUZZ'
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'nssfuzz-tls-base',
],
},
{
'target_name': 'nssfuzz',
'target_name': 'fuzz',
'type': 'none',
'dependencies': [
'nssfuzz-certDN',
'nssfuzz-dtls-client',
'nssfuzz-dtls-server',
'nssfuzz-pkcs7',
'nssfuzz-pkcs8',
'nssfuzz-pkcs12',
'nssfuzz-quickder',
'nssfuzz-tls-client',
'nssfuzz-tls-server',
],
}
'<(DEPTH)/fuzz/targets/targets.gyp:nssfuzz',
],
},
]
}

View File

@@ -0,0 +1,17 @@
# 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/.
{
'includes': [
'../../../../coreconf/config.gypi',
],
'targets': [
{
'target_name': 'asn1',
'type': 'static_library',
'sources': [
'mutators.cc',
],
}
],
}

View File

@@ -2,57 +2,56 @@
* 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 "mutators.h"
#include <cassert>
#include <cstring>
#include <random>
#include <tuple>
#include "asn1_mutators.h"
using namespace std;
static tuple<uint8_t *, size_t> ParseItem(uint8_t *Data, size_t MaxLength) {
static std::tuple<uint8_t *, size_t> ParseItem(uint8_t *data,
size_t maxLength) {
// Short form. Bit 8 has value "0" and bits 7-1 give the length.
if ((Data[1] & 0x80) == 0) {
size_t length = min(static_cast<size_t>(Data[1]), MaxLength - 2);
return make_tuple(&Data[2], length);
if ((data[1] & 0x80) == 0) {
size_t length = std::min(static_cast<size_t>(data[1]), maxLength - 2);
return std::make_tuple(&data[2], length);
}
// Constructed, indefinite length. Read until {0x00, 0x00}.
if (Data[1] == 0x80) {
void *offset = memmem(&Data[2], MaxLength - 2, "\0", 2);
size_t length = offset ? (static_cast<uint8_t *>(offset) - &Data[2]) + 2
: MaxLength - 2;
return make_tuple(&Data[2], length);
if (data[1] == 0x80) {
void *offset = memmem(&data[2], maxLength - 2, "\0", 2);
size_t length = offset ? (static_cast<uint8_t *>(offset) - &data[2]) + 2
: maxLength - 2;
return std::make_tuple(&data[2], length);
}
// Long form. Two to 127 octets. Bit 8 of first octet has value "1"
// and bits 7-1 give the number of additional length octets.
size_t octets = min(static_cast<size_t>(Data[1] & 0x7f), MaxLength - 2);
size_t octets = std::min(static_cast<size_t>(data[1] & 0x7f), maxLength - 2);
// Handle lengths bigger than 32 bits.
if (octets > 4) {
// Ignore any further children, assign remaining length.
return make_tuple(&Data[2] + octets, MaxLength - 2 - octets);
return std::make_tuple(&data[2] + octets, maxLength - 2 - octets);
}
// Parse the length.
size_t length = 0;
for (size_t j = 0; j < octets; j++) {
length = (length << 8) | Data[2 + j];
length = (length << 8) | data[2 + j];
}
length = min(length, MaxLength - 2 - octets);
return make_tuple(&Data[2] + octets, length);
length = std::min(length, maxLength - 2 - octets);
return std::make_tuple(&data[2] + octets, length);
}
static vector<uint8_t *> ParseItems(uint8_t *Data, size_t Size) {
vector<uint8_t *> items;
vector<size_t> lengths;
static std::vector<uint8_t *> ParseItems(uint8_t *data, size_t size) {
std::vector<uint8_t *> items;
std::vector<size_t> lengths;
// The first item is always the whole corpus.
items.push_back(Data);
lengths.push_back(Size);
items.push_back(data);
lengths.push_back(size);
// Can't use iterators here because the `items` vector is modified inside the
// loop. That's safe as long as we always check `items.size()` before every
@@ -71,7 +70,7 @@ static vector<uint8_t *> ParseItems(uint8_t *Data, size_t Size) {
uint8_t *content;
size_t length;
tie(content, length) = ParseItem(item, remaining);
std::tie(content, length) = ParseItem(item, remaining);
if (length > 0) {
// Record the item.
@@ -94,25 +93,25 @@ static vector<uint8_t *> ParseItems(uint8_t *Data, size_t Size) {
namespace ASN1Mutators {
size_t FlipConstructed(uint8_t *Data, size_t Size, size_t MaxSize,
unsigned int Seed) {
auto items = ParseItems(Data, Size);
size_t FlipConstructed(uint8_t *data, size_t size, size_t maxSize,
unsigned int seed) {
auto items = ParseItems(data, size);
std::mt19937 rng(Seed);
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;
return Size;
return size;
}
size_t ChangeType(uint8_t *Data, size_t Size, size_t MaxSize,
unsigned int Seed) {
auto items = ParseItems(Data, Size);
size_t ChangeType(uint8_t *data, size_t size, size_t maxSize,
unsigned int seed) {
auto items = ParseItems(data, size);
std::mt19937 rng(Seed);
std::mt19937 rng(seed);
std::uniform_int_distribution<size_t> dist(0, items.size() - 1);
uint8_t *item = items.at(dist(rng));
@@ -120,7 +119,7 @@ size_t ChangeType(uint8_t *Data, size_t Size, size_t MaxSize,
static std::uniform_int_distribution<size_t> tdist(0, 30);
item[0] = tdist(rng);
return Size;
return size;
}
} // namespace ASN1Mutators

View File

@@ -0,0 +1,17 @@
# 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/.
{
'includes': [
'../../../../coreconf/config.gypi',
],
'targets': [
{
'target_name': 'base',
'type': 'static_library',
'sources': [
'mutate.cc',
],
}
],
}

View File

@@ -0,0 +1,19 @@
/* 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/. */
#ifndef BASE_DATABASE_H_
#define BASE_DATABASE_H_
#include <cassert>
#include "nss.h"
// TODO(mdauer): Add constructor for initializing with DB.
class NSSDatabase {
public:
NSSDatabase() { assert(NSS_NoDB_Init(nullptr) == SECSuccess); }
~NSSDatabase() { assert(NSS_Shutdown() == SECSuccess); }
};
#endif // BASE_DATABASE_H_

View File

@@ -2,21 +2,21 @@
* 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 "shared.h"
#include "mutate.h"
#include <cstddef>
#include <cstdint>
#include <random>
size_t CustomMutate(Mutators mutators, uint8_t* data, size_t size,
size_t max_size, unsigned int seed) {
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, max_size, seed);
return mutators.at(idist(rng))(data, size, maxSize, seed);
}
return LLVMFuzzerMutate(data, size, max_size);
return LLVMFuzzerMutate(data, size, maxSize);
}

View File

@@ -1,32 +1,21 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef SHARED_H_
#define SHARED_H_
#ifndef BASE_MUTATE_H_
#define BASE_MUTATE_H_
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <vector>
#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() { assert(NSS_NoDB_Init(nullptr) == SECSuccess); }
~NSSDatabase() { assert(NSS_Shutdown() == SECSuccess); }
};
typedef std::vector<decltype(LLVMFuzzerCustomMutator)*> Mutators;
size_t CustomMutate(Mutators mutators, uint8_t* data, size_t size,
size_t maxSize, unsigned int seed);
#endif // SHARED_H_
#endif // BASE_MUTATE_H_

View File

@@ -2,7 +2,7 @@
* 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 "tls_client_config.h"
#include "client_config.h"
#include <cassert>
#include <cstddef>
@@ -16,23 +16,24 @@
#include "ssl.h"
#include "sslexp.h"
#include "tls_common.h"
#include "common.h"
const SSLCertificateCompressionAlgorithm kCompressionAlg = {
0x1337, "fuzz", TlsCommon::DummyCompressionEncode,
TlsCommon::DummyCompressionDecode};
const PRUint8 kPskIdentity[] = "fuzz-psk-identity";
#ifndef IS_DTLS_FUZZ
const char kEchConfigs[] =
"AEX+"
"DQBBcQAgACDh4IuiuhhInUcKZx5uYcehlG9PQ1ZlzhvVZyjJl7dscQAEAAEAAQASY2xvdWRmbG"
"FyZS1lY2guY29tAAA=";
#endif // IS_DTLS_FUZZ
const SSLCertificateCompressionAlgorithm kCompressionAlg = {
0x1337, "fuzz", DummyCompressionEncode, DummyCompressionDecode};
const PRUint8 kPskIdentity[] = "fuzz-psk-identity";
static SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checksig,
PRBool isServer) {
assert(!isServer);
auto config = reinterpret_cast<ClientConfig*>(arg);
auto config = reinterpret_cast<TlsClient::Config*>(arg);
if (config->FailCertificateAuthentication()) return SECFailure;
return SECSuccess;
@@ -44,10 +45,12 @@ static SECStatus CanFalseStartCallback(PRFileDesc* fd, void* arg,
return SECSuccess;
}
namespace TlsClient {
// XOR 64-bit chunks of data to build a bitmap of config options derived from
// the fuzzing input. This seems the only way to fuzz various options while
// still maintaining compatibility with BoringSSL or OpenSSL fuzzers.
ClientConfig::ClientConfig(const uint8_t* data, size_t len) {
Config::Config(const uint8_t* data, size_t len) {
union {
uint64_t bitmap;
struct {
@@ -78,7 +81,7 @@ ClientConfig::ClientConfig(const uint8_t* data, size_t len) {
};
}
void ClientConfig::SetCallbacks(PRFileDesc* fd) {
void Config::SetCallbacks(PRFileDesc* fd) {
SECStatus rv = SSL_AuthCertificateHook(fd, AuthCertificateHook, this);
assert(rv == SECSuccess);
@@ -86,7 +89,7 @@ void ClientConfig::SetCallbacks(PRFileDesc* fd) {
assert(rv == SECSuccess);
}
void ClientConfig::SetSocketOptions(PRFileDesc* fd) {
void Config::SetSocketOptions(PRFileDesc* fd) {
SECStatus rv = SSL_OptionSet(fd, SSL_ENABLE_EXTENDED_MASTER_SECRET,
this->EnableExtendedMasterSecret());
assert(rv == SECSuccess);
@@ -168,6 +171,20 @@ void ClientConfig::SetSocketOptions(PRFileDesc* fd) {
rv = SSL_OptionSet(fd, SSL_NO_LOCKS, this->NoLocks());
assert(rv == SECSuccess);
rv = SSL_EnableTls13GreaseEch(fd, this->EnableTls13GreaseEch());
assert(rv == SECSuccess);
rv = SSL_SetDtls13VersionWorkaround(fd, this->SetDtls13VersionWorkaround());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_ENABLE_DELEGATED_CREDENTIALS,
this->EnableDelegatedCredentials());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_ENABLE_DTLS_SHORT_HEADER,
this->EnableDtlsShortHeader());
assert(rv == SECSuccess);
#ifndef IS_DTLS_FUZZ
rv =
SSL_OptionSet(fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED);
@@ -184,7 +201,7 @@ void ClientConfig::SetSocketOptions(PRFileDesc* fd) {
#endif // IS_DTLS_FUZZ
}
std::ostream& operator<<(std::ostream& out, ClientConfig& config) {
std::ostream& operator<<(std::ostream& out, Config& config) {
out << "============= ClientConfig ============="
<< "\n";
out << "SSL_NO_CACHE: " << config.NoCache() << "\n";
@@ -231,9 +248,15 @@ std::ostream& operator<<(std::ostream& out, ClientConfig& config) {
out << "SSL_ENABLE_TLS13_COMPAT_MODE: "
<< config.EnableTls13CompatMode() << "\n";
out << "SSL_NO_LOCKS: " << config.NoLocks() << "\n";
out << "SSL_EnableTls13GreaseEch: "
<< config.EnableTls13GreaseEch() << "\n";
out << "SSL_SetDtls13VersionWorkaround: "
<< config.SetDtls13VersionWorkaround() << "\n";
out << "SSL_SetClientEchConfigs: "
<< config.SetClientEchConfigs() << "\n";
out << "========================================";
return out;
}
} // namespace TlsClient

View File

@@ -19,9 +19,11 @@
#endif
#define SSL_VERSION_RANGE_MAX_VALID 0x0304
class ClientConfig {
namespace TlsClient {
class Config {
public:
ClientConfig(const uint8_t* data, size_t len);
Config(const uint8_t* data, size_t len);
void SetCallbacks(PRFileDesc* fd);
void SetSocketOptions(PRFileDesc* fd);
@@ -33,6 +35,8 @@ class ClientConfig {
};
SSLVersionRange SslVersionRange() { return ssl_version_range_; };
// NOTE: When adding more config options here, don't forget to print
// them in the "<<"-overloaded operator.
bool FailCertificateAuthentication() { return config_ & (1 << 0); };
bool EnableExtendedMasterSecret() { return config_ & (1 << 1); };
bool RequireDhNamedGroups() { return config_ & (1 << 2); };
@@ -55,12 +59,18 @@ class ClientConfig {
bool EnableSessionTickets() { return config_ & (1 << 19); };
bool EnableTls13CompatMode() { return config_ & (1 << 20); };
bool NoLocks() { return config_ & (1 << 21); };
bool EnableTls13GreaseEch() { return config_ & (1 << 22); };
bool SetDtls13VersionWorkaround() { return config_ & (1 << 23); };
bool EnableDelegatedCredentials() { return config_ & (1 << 24); };
bool EnableDtlsShortHeader() { return config_ & (1 << 25); };
private:
uint32_t config_;
SSLVersionRange ssl_version_range_;
};
std::ostream& operator<<(std::ostream& out, ClientConfig& config);
std::ostream& operator<<(std::ostream& out, Config& config);
} // namespace TlsClient
#endif // TLS_CLIENT_CONFIG_H_

View File

@@ -2,18 +2,21 @@
* 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 "tls_common.h"
#include "common.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include "prio.h"
#include "secport.h"
#include "ssl.h"
#include "sslexp.h"
static PRTime FixedTime(void*) { return 1234; }
namespace TlsCommon {
// Fix the time input, to avoid any time-based variation.
void FixTime(PRFileDesc* fd) {
SECStatus rv = SSL_SetTimeFunc(fd, FixedTime, nullptr);
@@ -68,7 +71,7 @@ void DoHandshake(PRFileDesc* fd, bool isServer) {
SECStatus DummyCompressionEncode(const SECItem* input, SECItem* output) {
if (!input || !input->data || input->len == 0 || !output) {
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@@ -80,12 +83,12 @@ SECStatus DummyCompressionEncode(const SECItem* input, SECItem* output) {
SECStatus DummyCompressionDecode(const SECItem* input, unsigned char* output,
size_t outputLen, size_t* usedLen) {
if (!input || !input->data || input->len == 0 || !output || outputLen == 0) {
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (input->len > outputLen) {
PR_SetError(SEC_ERROR_BAD_DATA, 0);
PORT_SetError(SEC_ERROR_BAD_DATA);
return SECFailure;
}
@@ -94,3 +97,5 @@ SECStatus DummyCompressionDecode(const SECItem* input, unsigned char* output,
return SECSuccess;
}
} // namespace TlsCommon

View File

@@ -10,6 +10,8 @@
#include "prio.h"
#include "seccomon.h"
namespace TlsCommon {
void FixTime(PRFileDesc* fd);
void EnableAllProtocolVersions();
void EnableAllCipherSuites(PRFileDesc* fd);
@@ -19,4 +21,6 @@ SECStatus DummyCompressionEncode(const SECItem* input, SECItem* output);
SECStatus DummyCompressionDecode(const SECItem* input, unsigned char* output,
size_t outputLen, size_t* usedLen);
} // namespace TlsCommon
#endif // TLS_COMMON_H_

View File

@@ -2,6 +2,8 @@
* 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 "mutators.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -11,12 +13,6 @@
#include "tls_parser.h"
using namespace nss_test;
// Number of additional bytes in the TLS header.
// Used to properly skip DTLS seqnums.
static size_t gExtraHeaderBytes = 0;
// Helper class to simplify TLS record manipulation.
class Record {
public:
@@ -40,9 +36,9 @@ class Record {
}
void truncate(size_t length) {
assert(length >= 5 + gExtraHeaderBytes);
assert(length >= 5 + EXTRA_HEADER_BYTES);
uint8_t *dest = const_cast<uint8_t *>(data_);
size_t l = length - (5 + gExtraHeaderBytes);
size_t l = length - (5 + EXTRA_HEADER_BYTES);
dest[3] = (l >> 8) & 0xff;
dest[4] = l & 0xff;
memmove(dest + length, data_ + size_, remaining_);
@@ -70,23 +66,23 @@ class Record {
std::vector<std::unique_ptr<Record>> ParseRecords(const uint8_t *data,
size_t size) {
std::vector<std::unique_ptr<Record>> records;
TlsParser parser(data, size);
nss_test::TlsParser parser(data, size);
while (parser.remaining()) {
size_t offset = parser.consumed();
// Skip type, version, and DTLS seqnums.
if (!parser.Skip(3 + gExtraHeaderBytes)) {
if (!parser.Skip(3 + EXTRA_HEADER_BYTES)) {
break;
}
DataBuffer fragment;
nss_test::DataBuffer fragment;
if (!parser.ReadVariable(&fragment, 2)) {
break;
}
records.push_back(Record::Create(data + offset,
fragment.len() + 5 + gExtraHeaderBytes,
fragment.len() + 5 + EXTRA_HEADER_BYTES,
parser.remaining()));
}
@@ -95,11 +91,8 @@ std::vector<std::unique_ptr<Record>> ParseRecords(const uint8_t *data,
namespace TlsMutators {
// Handle seqnums in DTLS transcripts.
void SetIsDTLS() { gExtraHeaderBytes = 8; }
// Mutator that drops whole TLS records.
size_t DropRecord(uint8_t *data, size_t size, size_t max_size,
size_t DropRecord(uint8_t *data, size_t size, size_t maxSize,
unsigned int seed) {
std::mt19937 rng(seed);
@@ -121,7 +114,7 @@ size_t DropRecord(uint8_t *data, size_t size, size_t max_size,
}
// Mutator that shuffles TLS records in a transcript.
size_t ShuffleRecords(uint8_t *data, size_t size, size_t max_size,
size_t ShuffleRecords(uint8_t *data, size_t size, size_t maxSize,
unsigned int seed) {
std::mt19937 rng(seed);
@@ -152,7 +145,7 @@ size_t ShuffleRecords(uint8_t *data, size_t size, size_t max_size,
}
// Mutator that duplicates a single TLS record and randomly inserts it.
size_t DuplicateRecord(uint8_t *data, size_t size, size_t max_size,
size_t DuplicateRecord(uint8_t *data, size_t size, size_t maxSize,
unsigned int seed) {
std::mt19937 rng(seed);
@@ -165,7 +158,7 @@ size_t DuplicateRecord(uint8_t *data, size_t size, size_t max_size,
// Pick a record to duplicate at random.
std::uniform_int_distribution<size_t> dist(0, records.size() - 1);
auto &rec = records.at(dist(rng));
if (size + rec->size() > max_size) {
if (size + rec->size() > maxSize) {
return 0;
}
@@ -177,7 +170,7 @@ size_t DuplicateRecord(uint8_t *data, size_t size, size_t max_size,
}
// Mutator that truncates a TLS record.
size_t TruncateRecord(uint8_t *data, size_t size, size_t max_size,
size_t TruncateRecord(uint8_t *data, size_t size, size_t maxSize,
unsigned int seed) {
std::mt19937 rng(seed);
@@ -192,12 +185,12 @@ size_t TruncateRecord(uint8_t *data, size_t size, size_t max_size,
auto &rec = records.at(dist(rng));
// Need a record with data.
if (rec->size() <= 5 + gExtraHeaderBytes) {
if (rec->size() <= 5 + EXTRA_HEADER_BYTES) {
return 0;
}
// Truncate.
std::uniform_int_distribution<size_t> dist2(5 + gExtraHeaderBytes,
std::uniform_int_distribution<size_t> dist2(5 + EXTRA_HEADER_BYTES,
rec->size() - 1);
size_t new_length = dist2(rng);
rec->truncate(new_length);
@@ -207,16 +200,16 @@ size_t TruncateRecord(uint8_t *data, size_t size, size_t max_size,
}
// Mutator that splits a TLS record in two.
size_t FragmentRecord(uint8_t *data, size_t size, size_t max_size,
size_t FragmentRecord(uint8_t *data, size_t size, size_t maxSize,
unsigned int seed) {
std::mt19937 rng(seed);
// We can't deal with DTLS yet.
if (gExtraHeaderBytes > 0) {
if (EXTRA_HEADER_BYTES > 0) {
return 0;
}
if (size + 5 > max_size) {
if (size + 5 > maxSize) {
return 0;
}
@@ -259,7 +252,7 @@ size_t FragmentRecord(uint8_t *data, size_t size, size_t max_size,
// Cross-over function that merges and shuffles two transcripts.
size_t CrossOver(const uint8_t *data1, size_t size1, const uint8_t *data2,
size_t size2, uint8_t *out, size_t max_out_size,
size_t size2, uint8_t *out, size_t maxOutSize,
unsigned int seed) {
std::mt19937 rng(seed);
@@ -283,7 +276,7 @@ size_t CrossOver(const uint8_t *data1, size_t size1, const uint8_t *data2,
size_t total = 0;
for (auto &rec : records1) {
size_t length = rec->size();
if (total + length > max_out_size) {
if (total + length > maxOutSize) {
break;
}

View File

@@ -8,23 +8,29 @@
#include <cstddef>
#include <cstdint>
// Number of additional bytes in the TLS header.
// Used to properly skip DTLS seqnums.
#ifdef IS_DTLS_FUZZ
#define EXTRA_HEADER_BYTES 8
#else
#define EXTRA_HEADER_BYTES 0
#endif
namespace TlsMutators {
void SetIsDTLS();
size_t DropRecord(uint8_t *data, size_t size, size_t max_size,
size_t DropRecord(uint8_t *data, size_t size, size_t maxSize,
unsigned int seed);
size_t ShuffleRecords(uint8_t *data, size_t size, size_t max_size,
size_t ShuffleRecords(uint8_t *data, size_t size, size_t maxSize,
unsigned int seed);
size_t DuplicateRecord(uint8_t *data, size_t size, size_t max_size,
size_t DuplicateRecord(uint8_t *data, size_t size, size_t maxSize,
unsigned int seed);
size_t TruncateRecord(uint8_t *data, size_t size, size_t max_size,
size_t TruncateRecord(uint8_t *data, size_t size, size_t maxSize,
unsigned int seed);
size_t FragmentRecord(uint8_t *data, size_t size, size_t max_size,
size_t FragmentRecord(uint8_t *data, size_t size, size_t maxSize,
unsigned int seed);
size_t CrossOver(const uint8_t *data1, size_t size1, const uint8_t *data2,
size_t size2, uint8_t *out, size_t max_out_size,
size_t size2, uint8_t *out, size_t maxOutSize,
unsigned int seed);
} // namespace TlsMutators

View File

@@ -2,14 +2,15 @@
* 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 <assert.h>
#include <stdint.h>
#include "server_certs.h"
#include "ssl.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include "cpputil.h"
#include "nss_scoped_ptrs.h"
#include "tls_server_certs.h"
#include "ssl.h"
const uint8_t kP256ServerCert[] = {
0x30, 0x82, 0x01, 0xcf, 0x30, 0x82, 0x01, 0x76, 0xa0, 0x03, 0x02, 0x01,
@@ -252,16 +253,16 @@ const uint8_t kRsaServerKey[] = {
0xfe, 0xbf, 0xda, 0x0e, 0xce, 0x28, 0xb9, 0xdb, 0x9b, 0xcf, 0x6e, 0xa8,
0xe4, 0x60, 0xca, 0x98};
void InstallServerCertificate(PRFileDesc* fd, const uint8_t* cert_data,
size_t cert_len, const uint8_t* key_data,
size_t key_len) {
static void InstallServerCertificate(PRFileDesc* fd, const uint8_t* certData,
size_t certLen, const uint8_t* keyData,
size_t keyLen) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
assert(slot);
SECItem certItem = {siBuffer, toUcharPtr(cert_data),
static_cast<unsigned int>(cert_len)};
SECItem pkcs8Item = {siBuffer, toUcharPtr(key_data),
static_cast<unsigned int>(key_len)};
SECItem certItem = {siBuffer, toUcharPtr(certData),
static_cast<unsigned int>(certLen)};
SECItem pkcs8Item = {siBuffer, toUcharPtr(keyData),
static_cast<unsigned int>(keyLen)};
// Import the certificate.
static CERTCertDBHandle* certDB = CERT_GetDefaultCertDB();
@@ -284,6 +285,8 @@ void InstallServerCertificate(PRFileDesc* fd, const uint8_t* cert_data,
assert(rv == SECSuccess);
}
namespace TlsServer {
void InstallServerCertificates(PRFileDesc* fd) {
// ECDSA P-256 certificate.
InstallServerCertificate(fd, kP256ServerCert, sizeof(kP256ServerCert),
@@ -292,4 +295,8 @@ void InstallServerCertificates(PRFileDesc* fd) {
// RSA-2048 certificate.
InstallServerCertificate(fd, kRsaServerCert, sizeof(kRsaServerCert),
kRsaServerKey, sizeof(kRsaServerKey));
// TODO(mdauer): Install more different cerificate types.
}
} // namespace TlsServer

View File

@@ -2,11 +2,15 @@
* 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/. */
#ifndef tls_server_certs_h__
#define tls_server_certs_h__
#ifndef TLS_SERVER_CERT_H_
#define TLS_SERVER_CERT_H_
#include "prio.h"
namespace TlsServer {
void InstallServerCertificates(PRFileDesc* fd);
#endif // tls_server_certs_h__
} // namespace TlsServer
#endif // TLS_SERVER_CERT_H_

View File

@@ -2,7 +2,7 @@
* 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 "tls_server_config.h"
#include "server_config.h"
#include <cassert>
#include <cstddef>
@@ -16,16 +16,17 @@
#include "sslexp.h"
#include "sslt.h"
#include "tls_common.h"
#include "common.h"
const SSLCertificateCompressionAlgorithm kCompressionAlg = {
0x1337, "fuzz", DummyCompressionEncode, DummyCompressionDecode};
0x1337, "fuzz", TlsCommon::DummyCompressionEncode,
TlsCommon::DummyCompressionDecode};
const PRUint8 kPskIdentity[] = "fuzz-psk-identity";
static SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checksig,
PRBool isServer) {
assert(isServer);
auto config = reinterpret_cast<ServerConfig*>(arg);
auto config = reinterpret_cast<TlsServer::Config*>(arg);
if (config->FailCertificateAuthentication()) return SECFailure;
return SECSuccess;
@@ -37,10 +38,12 @@ static SECStatus CanFalseStartCallback(PRFileDesc* fd, void* arg,
return SECSuccess;
}
namespace TlsServer {
// XOR 64-bit chunks of data to build a bitmap of config options derived from
// the fuzzing input. This seems the only way to fuzz various options while
// still maintaining compatibility with BoringSSL or OpenSSL fuzzers.
ServerConfig::ServerConfig(const uint8_t* data, size_t len) {
Config::Config(const uint8_t* data, size_t len) {
union {
uint64_t bitmap;
struct {
@@ -71,7 +74,7 @@ ServerConfig::ServerConfig(const uint8_t* data, size_t len) {
};
}
void ServerConfig::SetCallbacks(PRFileDesc* fd) {
void Config::SetCallbacks(PRFileDesc* fd) {
SECStatus rv = SSL_AuthCertificateHook(fd, AuthCertificateHook, this);
assert(rv == SECSuccess);
@@ -79,7 +82,7 @@ void ServerConfig::SetCallbacks(PRFileDesc* fd) {
assert(rv == SECSuccess);
}
void ServerConfig::SetSocketOptions(PRFileDesc* fd) {
void Config::SetSocketOptions(PRFileDesc* fd) {
SECStatus rv = SSL_OptionSet(fd, SSL_ENABLE_EXTENDED_MASTER_SECRET,
this->EnableExtendedMasterSecret());
assert(rv == SECSuccess);
@@ -145,6 +148,17 @@ void ServerConfig::SetSocketOptions(PRFileDesc* fd) {
rv = SSL_OptionSet(fd, SSL_NO_LOCKS, this->NoLocks());
assert(rv == SECSuccess);
rv = SSL_EnableTls13BackendEch(fd, this->EnableTls13BackendEch());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_ENABLE_DELEGATED_CREDENTIALS,
this->EnableDelegatedCredentials());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_ENABLE_DTLS_SHORT_HEADER,
this->EnableDtlsShortHeader());
assert(rv == SECSuccess);
#ifndef IS_DTLS_FUZZ
rv =
SSL_OptionSet(fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED);
@@ -152,7 +166,7 @@ void ServerConfig::SetSocketOptions(PRFileDesc* fd) {
#endif
}
std::ostream& operator<<(std::ostream& out, ServerConfig& config) {
std::ostream& operator<<(std::ostream& out, Config& config) {
out << "============= ServerConfig ============="
<< "\n";
out << "SSL_NO_CACHE: " << config.NoCache() << "\n";
@@ -195,3 +209,5 @@ std::ostream& operator<<(std::ostream& out, ServerConfig& config) {
return out;
}
} // namespace TlsServer

View File

@@ -19,9 +19,11 @@
#endif
#define SSL_VERSION_RANGE_MAX_VALID 0x0304
class ServerConfig {
namespace TlsServer {
class Config {
public:
ServerConfig(const uint8_t* data, size_t len);
Config(const uint8_t* data, size_t len);
void SetCallbacks(PRFileDesc* fd);
void SetSocketOptions(PRFileDesc* fd);
@@ -33,6 +35,8 @@ class ServerConfig {
};
SSLVersionRange SslVersionRange() { return ssl_version_range_; };
// NOTE: When adding more config options here, don't forget to print
// them in the "<<"-overloaded operator.
bool EnableExtendedMasterSecret() { return config_ & (1 << 0); };
bool RequestCertificate() { return config_ & (1 << 1); };
bool RequireCertificate() { return config_ & (1 << 2); };
@@ -50,12 +54,17 @@ class ServerConfig {
bool EnableSessionTickets() { return config_ & (1 << 14); };
bool NoLocks() { return config_ & (1 << 15); };
bool FailCertificateAuthentication() { return config_ & (1 << 16); }
bool EnableTls13BackendEch() { return config_ & (1 << 17); }
bool EnableDelegatedCredentials() { return config_ & (1 << 18); };
bool EnableDtlsShortHeader() { return config_ & (1 << 19); };
private:
uint32_t config_;
SSLVersionRange ssl_version_range_;
};
std::ostream& operator<<(std::ostream& out, ServerConfig& config);
std::ostream& operator<<(std::ostream& out, Config& config);
} // namespace TlsServer
#endif // TLS_SERVER_CONFIG_H_

View File

@@ -2,16 +2,19 @@
* 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 <assert.h>
#include <string.h>
#include <algorithm>
#include "socket.h"
#include "prerror.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
#include "prinrval.h"
#include "prio.h"
#include "tls_socket.h"
namespace TlsSocket {
int32_t DummyPrSocket::Read(PRFileDesc *f, void *data, int32_t len) {
int32_t DummyPrSocket::Read(PRFileDesc *fd, void *data, int32_t len) {
assert(data && len > 0);
int32_t amount = std::min(len, static_cast<int32_t>(len_));
@@ -23,12 +26,14 @@ int32_t DummyPrSocket::Read(PRFileDesc *f, void *data, int32_t len) {
return amount;
}
int32_t DummyPrSocket::Write(PRFileDesc *f, const void *buf, int32_t length) {
int32_t DummyPrSocket::Write(PRFileDesc *fd, const void *buf, int32_t length) {
return length;
}
int32_t DummyPrSocket::Recv(PRFileDesc *f, void *buf, int32_t buflen,
int32_t DummyPrSocket::Recv(PRFileDesc *fd, void *buf, int32_t buflen,
int32_t flags, PRIntervalTime to) {
assert(flags == 0);
return Read(f, buf, buflen);
return Read(fd, buf, buflen);
}
} // namespace TlsSocket

View File

@@ -2,19 +2,24 @@
* 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/. */
#ifndef tls_socket_h__
#define tls_socket_h__
#ifndef TLS_SOCKET_H_
#define TLS_SOCKET_H_
#include <cstdint>
#include "dummy_io.h"
#include "prinrval.h"
#include "prio.h"
namespace TlsSocket {
class DummyPrSocket : public DummyIOLayerMethods {
public:
DummyPrSocket(const uint8_t *buf, size_t len) : buf_(buf), len_(len) {}
virtual ~DummyPrSocket() {}
int32_t Read(PRFileDesc *f, void *data, int32_t len) override;
int32_t Write(PRFileDesc *f, const void *buf, int32_t length) override;
int32_t Recv(PRFileDesc *f, void *buf, int32_t buflen, int32_t flags,
int32_t Read(PRFileDesc *fd, void *data, int32_t len) override;
int32_t Write(PRFileDesc *fd, const void *buf, int32_t length) override;
int32_t Recv(PRFileDesc *fd, void *buf, int32_t buflen, int32_t flags,
PRIntervalTime to) override;
private:
@@ -22,4 +27,6 @@ class DummyPrSocket : public DummyIOLayerMethods {
size_t len_;
};
#endif // tls_socket_h__
} // namespace TlsSocket
#endif // TLS_SOCKET_H_

View File

@@ -0,0 +1,43 @@
# 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/.
{
'includes': [
'../../../../coreconf/config.gypi',
],
'targets': [
{
'target_name': 'tls_client',
'type': 'none',
'direct_dependent_settings': {
'sources': [
'client_config.cc',
'common.cc',
'mutators.cc',
'socket.cc'
],
'include_dirs': [
'<(DEPTH)/lib/freebl',
'<(DEPTH)/lib/ssl',
],
},
},
{
'target_name': 'tls_server',
'type': 'none',
'direct_dependent_settings': {
'sources': [
'common.cc',
'mutators.cc',
'server_certs.cc',
'server_config.cc',
'socket.cc'
],
'include_dirs': [
'<(DEPTH)/lib/freebl',
'<(DEPTH)/lib/ssl',
],
},
},
],
}

View File

@@ -5,15 +5,15 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <memory>
#include "nss_scoped_ptrs.h"
#include "p12.h"
#include "pk11pub.h"
#include "seccomon.h"
#include "asn1_mutators.h"
#include "shared.h"
#include "asn1/mutators.h"
#include "base/database.h"
#include "base/mutate.h"
static SECItem* nicknameCollision(SECItem* oldNick, PRBool* cancel,
void* wincx) {
@@ -22,7 +22,7 @@ static SECItem* nicknameCollision(SECItem* oldNick, PRBool* cancel,
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
static NSSDatabase db = NSSDatabase();
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
assert(slot);

View File

@@ -4,32 +4,18 @@
#include <cstddef>
#include <cstdint>
#include <memory>
#include "cert.h"
#include "seccomon.h"
#include "asn1_mutators.h"
#include "shared.h"
static SECStatus importFunc(void *arg, SECItem **certs, int numCerts) {
// This way we check that the callback gets called with the correct
// `numCerts`, as an invalid value potentially causes `certs` to go
// out-of-bounds. Testing `CERT_Hexify` is a nice bonus.
while (numCerts--) {
char *hex = CERT_Hexify(*certs, false);
free(hex);
certs++;
}
return SECSuccess;
}
#include "asn1/mutators.h"
#include "base/database.h"
#include "base/mutate.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
static NSSDatabase db = NSSDatabase();
CERT_DecodeCertPackage((char *)data, (int)size, importFunc, nullptr);
CERTCertificate *cert = CERT_DecodeCertFromPackage((char *)data, (int)size);
CERT_DestroyCertificate(cert);
return 0;
}

View File

@@ -2,32 +2,33 @@
* 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 <cassert>
#include <cstddef>
#include <cstdint>
#include <memory>
#include "keyhi.h"
#include "nss_scoped_ptrs.h"
#include "pk11pub.h"
#include "asn1_mutators.h"
#include "shared.h"
#include "asn1/mutators.h"
#include "base/database.h"
#include "base/mutate.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
PK11SlotInfo *slot = PK11_GetInternalSlot();
assert(slot);
static NSSDatabase db = NSSDatabase();
SECItem derPki = {siBuffer, (unsigned char *)data, (unsigned int)size};
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
assert(slot);
SECKEYPrivateKey *key = nullptr;
if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, &derPki, nullptr, nullptr,
false, false, KU_ALL, &key,
nullptr) == SECSuccess) {
if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot.get(), &derPki, nullptr,
nullptr, false, false, KU_ALL,
&key, nullptr) == SECSuccess) {
SECKEY_DestroyPrivateKey(key);
}
PK11_FreeSlot(slot);
return 0;
}

View File

@@ -6,11 +6,13 @@
#include <cstdint>
#include <vector>
#include "asn1_mutators.h"
#include "certt.h"
#include "keythi.h"
#include "secdert.h"
#include "shared.h"
#include "secport.h"
#include "asn1/mutators.h"
#include "base/mutate.h"
const std::vector<const SEC_ASN1Template *> templates = {
CERT_AttributeTemplate,
@@ -68,19 +70,19 @@ const std::vector<const SEC_ASN1Template *> templates = {
SECKEY_RSAPublicKeyTemplate,
SECOID_AlgorithmIDTemplate};
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
char *dest[2048];
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
static char *dest[2048];
PORTCheapArenaPool pool;
PORT_InitCheapArena(&pool, DER_DEFAULT_CHUNKSIZE);
for (auto tpl : templates) {
PORTCheapArenaPool pool;
SECItem buf = {siBuffer, const_cast<unsigned char *>(Data),
static_cast<unsigned int>(Size)};
PORT_InitCheapArena(&pool, DER_DEFAULT_CHUNKSIZE);
SECItem buf = {siBuffer, (unsigned char *)data, (unsigned int)size};
(void)SEC_QuickDERDecodeItem(&pool.arena, dest, tpl, &buf);
PORT_DestroyCheapArena(&pool);
}
PORT_DestroyCheapArena(&pool);
return 0;
}

View File

@@ -0,0 +1,202 @@
# 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/.
{
'includes': [
'../../coreconf/config.gypi',
],
'target_defaults': {
'variables': {
'debug_optimization_level': '3',
},
'target_conditions': [
[ '_type=="executable"', {
'libraries!': [
'<@(nspr_libs)',
],
'libraries': [
'<(nss_dist_obj_dir)/lib/libplds4.a',
'<(nss_dist_obj_dir)/lib/libnspr4.a',
'<(nss_dist_obj_dir)/lib/libplc4.a',
],
}],
],
},
'targets': [
{
'target_name': 'nssfuzz_base',
'type': 'none',
'dependencies': [
'<(DEPTH)/lib/certdb/certdb.gyp:certdb',
'<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
'<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
'<(DEPTH)/lib/ssl/ssl.gyp:ssl',
'<(DEPTH)/lib/base/base.gyp:nssb',
'<(DEPTH)/lib/dev/dev.gyp:nssdev',
'<(DEPTH)/lib/pki/pki.gyp:nsspki',
'<(DEPTH)/lib/util/util.gyp:nssutil',
'<(DEPTH)/lib/nss/nss.gyp:nss_static',
'<(DEPTH)/lib/pkcs7/pkcs7.gyp:pkcs7',
'<(DEPTH)/lib/pkcs12/pkcs12.gyp:pkcs12',
# This is a static build of pk11wrap, softoken, and freebl.
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
'<(DEPTH)/lib/libpkix/libpkix.gyp:libpkix',
],
'direct_dependent_settings': {
'include_dirs': [ '<(DEPTH)/fuzz/targets/lib' ],
},
'conditions': [
['fuzz_oss==0', {
'all_dependent_settings': {
'libraries': [
'-fsanitize=fuzzer',
],
}
}, {
'all_dependent_settings': {
'libraries': [ '-lFuzzingEngine' ],
}
}]
],
},
{
'target_name': 'nssfuzz-certDN',
'type': 'executable',
'sources': [
'certDN.cc',
],
'dependencies': [
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'<(DEPTH)/exports.gyp:nss_exports',
'nssfuzz_base',
],
},
{
'target_name': 'nssfuzz-dtls-client',
'type': 'executable',
'sources': [
'tls_client.cc',
],
'defines': [ 'IS_DTLS_FUZZ' ],
'dependencies': [
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/fuzz/targets/lib/base/base.gyp:base',
'<(DEPTH)/fuzz/targets/lib/tls/tls.gyp:tls_client',
'nssfuzz_base',
],
},
{
'target_name': 'nssfuzz-dtls-server',
'type': 'executable',
'sources': [
'tls_server.cc',
],
'defines': [ 'IS_DTLS_FUZZ' ],
'dependencies': [
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/fuzz/targets/lib/base/base.gyp:base',
'<(DEPTH)/fuzz/targets/lib/tls/tls.gyp:tls_server',
'nssfuzz_base',
],
},
{
'target_name': 'nssfuzz-pkcs7',
'type': 'executable',
'sources': [
'pkcs7.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/fuzz/targets/lib/asn1/asn1.gyp:asn1',
'<(DEPTH)/fuzz/targets/lib/base/base.gyp:base',
'nssfuzz_base',
],
},
{
'target_name': 'nssfuzz-pkcs8',
'type': 'executable',
'sources': [
'pkcs8.cc',
],
'dependencies': [
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/fuzz/targets/lib/asn1/asn1.gyp:asn1',
'<(DEPTH)/fuzz/targets/lib/base/base.gyp:base',
'nssfuzz_base',
],
},
{
'target_name': 'nssfuzz-pkcs12',
'type': 'executable',
'sources': [
'pkcs12.cc',
],
'dependencies': [
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/fuzz/targets/lib/asn1/asn1.gyp:asn1',
'<(DEPTH)/fuzz/targets/lib/base/base.gyp:base',
'nssfuzz_base',
],
},
{
'target_name': 'nssfuzz-quickder',
'type': 'executable',
'sources': [
'quickder.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/fuzz/targets/lib/asn1/asn1.gyp:asn1',
'<(DEPTH)/fuzz/targets/lib/base/base.gyp:base',
'nssfuzz_base',
],
},
{
'target_name': 'nssfuzz-tls-client',
'type': 'executable',
'sources': [
'tls_client.cc',
],
'dependencies': [
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/fuzz/targets/lib/base/base.gyp:base',
'<(DEPTH)/fuzz/targets/lib/tls/tls.gyp:tls_client',
'nssfuzz_base',
],
},
{
'target_name': 'nssfuzz-tls-server',
'type': 'executable',
'sources': [
'tls_server.cc',
],
'dependencies': [
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/fuzz/targets/lib/base/base.gyp:base',
'<(DEPTH)/fuzz/targets/lib/tls/tls.gyp:tls_server',
'nssfuzz_base',
],
},
{
'target_name': 'nssfuzz',
'type': 'none',
'dependencies': [
'nssfuzz-certDN',
'nssfuzz-dtls-client',
'nssfuzz-dtls-server',
'nssfuzz-pkcs7',
'nssfuzz-pkcs8',
'nssfuzz-pkcs12',
'nssfuzz-quickder',
'nssfuzz-tls-client',
'nssfuzz-tls-server',
],
},
],
}

View File

@@ -12,36 +12,31 @@
#include "ssl.h"
#include "sslimpl.h"
#include "shared.h"
#include "tls_client_config.h"
#include "tls_common.h"
#include "tls_mutators.h"
#include "tls_socket.h"
#include "base/database.h"
#include "base/mutate.h"
#include "tls/client_config.h"
#include "tls/common.h"
#include "tls/mutators.h"
#include "tls/socket.h"
#ifdef IS_DTLS_FUZZ
__attribute__((constructor)) static void set_is_dtls() {
TlsMutators::SetIsDTLS();
}
#define ImportFD DTLS_ImportFD
#else
#define ImportFD SSL_ImportFD
#endif // IS_DTLS_FUZZ
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
static NSSDatabase db = NSSDatabase();
static PRDescIdentity id = PR_GetUniqueIdentity("fuzz-client");
EnableAllProtocolVersions();
// Create and import dummy socket.
DummyPrSocket socket = DummyPrSocket(data, len);
TlsSocket::DummyPrSocket socket = TlsSocket::DummyPrSocket(data, size);
ScopedPRFileDesc prFd(DummyIOLayerMethods::CreateFD(id, &socket));
PRFileDesc* sslFd = ImportFD(nullptr, prFd.get());
assert(sslFd == prFd.get());
// Derive client config from input data.
ClientConfig config = ClientConfig(data, len);
TlsClient::Config config = TlsClient::Config(data, size);
if (ssl_trace >= 90) {
std::cerr << config << "\n";
@@ -51,15 +46,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
assert(RNG_RandomUpdate(NULL, 0) == SECSuccess);
assert(SSL_SetURL(sslFd, "fuzz.client") == SECSuccess);
FixTime(sslFd);
EnableAllCipherSuites(sslFd);
TlsCommon::EnableAllProtocolVersions();
TlsCommon::EnableAllCipherSuites(sslFd);
TlsCommon::FixTime(sslFd);
// Set socket callbacks & options from client config.
config.SetCallbacks(sslFd);
config.SetSocketOptions(sslFd);
// Perform the acutal handshake.
DoHandshake(sslFd, false);
TlsCommon::DoHandshake(sslFd, false);
// Release all SIDs.
SSL_ClearSessionCache();
@@ -68,18 +64,18 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
}
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
size_t max_size, unsigned int seed) {
size_t maxSize, unsigned int seed) {
Mutators mutators = {TlsMutators::DropRecord, TlsMutators::ShuffleRecords,
TlsMutators::DuplicateRecord,
TlsMutators::TruncateRecord,
TlsMutators::FragmentRecord};
return CustomMutate(mutators, data, size, max_size, seed);
return CustomMutate(mutators, data, size, maxSize, seed);
}
extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t* data1, size_t size1,
const uint8_t* data2, size_t size2,
uint8_t* out, size_t max_out_size,
uint8_t* out, size_t maxOutSize,
unsigned int seed) {
return TlsMutators::CrossOver(data1, size1, data2, size2, out, max_out_size,
return TlsMutators::CrossOver(data1, size1, data2, size2, out, maxOutSize,
seed);
}

View File

@@ -11,22 +11,19 @@
#include "ssl.h"
#include "sslimpl.h"
#include "shared.h"
#include "tls_common.h"
#include "tls_mutators.h"
#include "tls_server_certs.h"
#include "tls_server_config.h"
#include "tls_socket.h"
#include "base/database.h"
#include "base/mutate.h"
#include "tls/common.h"
#include "tls/mutators.h"
#include "tls/server_certs.h"
#include "tls/server_config.h"
#include "tls/socket.h"
#ifdef IS_DTLS_FUZZ
__attribute__((constructor)) static void set_is_dtls() {
TlsMutators::SetIsDTLS();
}
#define ImportFD DTLS_ImportFD
#else
#define ImportFD SSL_ImportFD
#endif
#endif // IS_DTLS_FUZZ
class SSLServerSessionCache {
public:
@@ -42,13 +39,13 @@ class SSLServerSessionCache {
static PRStatus InitModelSocket(void* arg) {
PRFileDesc* fd = reinterpret_cast<PRFileDesc*>(arg);
EnableAllCipherSuites(fd);
InstallServerCertificates(fd);
TlsCommon::EnableAllCipherSuites(fd);
TlsServer::InstallServerCertificates(fd);
return PR_SUCCESS;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
static NSSDatabase db = NSSDatabase();
static SSLServerSessionCache cache = SSLServerSessionCache();
static PRDescIdentity id = PR_GetUniqueIdentity("fuzz-server");
@@ -61,16 +58,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
static PRCallOnceType initModelOnce;
PR_CallOnceWithArg(&initModelOnce, InitModelSocket, model.get());
EnableAllProtocolVersions();
// Create and import dummy socket.
DummyPrSocket socket = DummyPrSocket(data, len);
TlsSocket::DummyPrSocket socket = TlsSocket::DummyPrSocket(data, size);
ScopedPRFileDesc prFd(DummyIOLayerMethods::CreateFD(id, &socket));
PRFileDesc* sslFd = ImportFD(model.get(), prFd.get());
assert(sslFd == prFd.get());
// Derive server config from input data.
ServerConfig config = ServerConfig(data, len);
TlsServer::Config config = TlsServer::Config(data, size);
if (ssl_trace >= 90) {
std::cerr << config << "\n";
@@ -80,15 +75,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
assert(RNG_RandomUpdate(NULL, 0) == SECSuccess);
assert(SSL_SetURL(sslFd, "fuzz.server") == SECSuccess);
FixTime(sslFd);
EnableAllCipherSuites(sslFd);
TlsCommon::EnableAllProtocolVersions();
TlsCommon::EnableAllCipherSuites(sslFd);
TlsCommon::FixTime(sslFd);
// Set socket options from server config.
config.SetCallbacks(sslFd);
config.SetSocketOptions(sslFd);
// Perform the acutal handshake.
DoHandshake(sslFd, true);
TlsCommon::DoHandshake(sslFd, true);
// Clear the cache. We never want to resume as we couldn't reproduce that.
SSL_ClearSessionCache();
@@ -97,18 +93,18 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
}
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
size_t max_size, unsigned int seed) {
size_t maxSize, unsigned int seed) {
return CustomMutate(
{TlsMutators::DropRecord, TlsMutators::ShuffleRecords,
TlsMutators::DuplicateRecord, TlsMutators::TruncateRecord,
TlsMutators::FragmentRecord},
data, size, max_size, seed);
data, size, maxSize, seed);
}
extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t* data1, size_t size1,
const uint8_t* data2, size_t size2,
uint8_t* out, size_t max_out_size,
uint8_t* out, size_t maxOutSize,
unsigned int seed) {
return TlsMutators::CrossOver(data1, size1, data2, size2, out, max_out_size,
return TlsMutators::CrossOver(data1, size1, data2, size2, out, maxOutSize,
seed);
}

View File

@@ -39,6 +39,11 @@
'UNSAFE_FUZZER_MODE',
],
}],
['gtests_corpus==1', {
'defines': [
'GTESTS_CORPUS',
]
}]
],
'msvs_settings': {
'VCCLCompilerTool': {

View File

@@ -105,6 +105,16 @@ static const PresentedMatchesReference DNSID_MATCH_PARAMS[] =
DNS_ID_MATCH("_example", "_example"),
DNS_ID_MATCH("*._._", "x._._"),
// We allow reference ID labels to start and end with hyphens for
// compatibility.
DNS_ID_MATCH("*.example.com", "-.example.com"),
DNS_ID_MATCH("*.example.com", "-hyphenstart.example.com"),
DNS_ID_MATCH("*.example.com", "hyphenend-.example.com"),
// Presented ID labels may not start or end with hyphens.
DNS_ID_BAD_DER("-.example.com", "-.example.com"),
DNS_ID_BAD_DER("-hyphenstart.example.com", "-hyphenstart.example.com"),
DNS_ID_BAD_DER("hyphenend-.example.com", "hyphenend-.example.com"),
// See bug 1139039
// A DNS-ID must not end in an all-numeric label. We don't consider
// underscores to be numeric.
@@ -371,13 +381,13 @@ static const InputValidity DNSNAMES_VALIDITY[] =
I("a...", false, false),
// Punycode
I("xn--", false, false),
I("xn--.", false, false),
I("xn--.a", false, false),
I("a.xn--", false, false),
I("a.xn--.", false, false),
I("a.xn--.b", false, false),
I("a.xn--.b", false, false),
I("xn--", true, false),
I("xn--.", true, false),
I("xn--.a", true, false),
I("a.xn--", true, false),
I("a.xn--.", true, false),
I("a.xn--.b", true, false),
I("a.xn--.b", true, false),
I("a.xn--\0.b", false, false),
I("a.xn--a.b", true, true),
I("xn--a", true, true),
@@ -416,7 +426,7 @@ static const InputValidity DNSNAMES_VALIDITY[] =
I("a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z", true, true),
I("A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z", true, true),
I("0.1.2.3.4.5.6.7.8.9.a", true, true), // "a" needed to avoid numeric last label
I("a-b", true, true), // hyphen (a label cannot start or end with a hyphen)
I("a-b", true, true), // hyphen (presented ID labels cannot start or end with a hyphen)
// Underscores
I("a_b", true, true),
@@ -469,17 +479,17 @@ static const InputValidity DNSNAMES_VALIDITY[] =
I("a.1-1", true, true),
I("a.1-a", true, true),
// labels cannot start with a hyphen
I("-", false, false),
I("-1", false, false),
// presented ID labels cannot start with a hyphen
I("-", true, false),
I("-1", true, false),
// labels cannot end with a hyphen
I("1-", false, false),
I("1-.a", false, false),
I("a-", false, false),
I("a-.a", false, false),
I("a.1-.a", false, false),
I("a.a-.a", false, false),
// presented ID labels cannot end with a hyphen
I("1-", true, false),
I("1-.a", true, false),
I("a-", true, false),
I("a-.a", true, false),
I("a.1-.a", true, false),
I("a.a-.a", true, false),
// labels can contain a hyphen in the middle
I("a-b", true, true),

View File

@@ -155,4 +155,84 @@ TEST_F(Pkcs11NonAsciiTest, LoadUnload) {
}
#endif // defined(_WIN32)
class Pkcs11ModuleLoadFunctionTest : public ::testing::Test {
public:
Pkcs11ModuleLoadFunctionTest() { library = NULL; };
void TearDown() override {
if (library != NULL) {
PR_UnloadLibrary(library);
}
}
PRLibrary *library;
};
CK_RV NotSuppoted_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) {
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_RV SupportedButNull(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) {
ppFunctionList = NULL;
return CKR_OK;
}
TEST_F(Pkcs11ModuleLoadFunctionTest, LoadModuleWithNullFunc) {
ScopedSECMODModule userModule(
SECMOD_LoadUserModuleWithFunction("LoadFunctionModule", NULL));
EXPECT_NE(userModule, nullptr);
EXPECT_FALSE(userModule->loaded);
}
TEST_F(Pkcs11ModuleLoadFunctionTest, LoadModuleWithUnsupportedFunc) {
ScopedSECMODModule userModule(SECMOD_LoadUserModuleWithFunction(
"LoadFunctionModule", &NotSuppoted_GetFunctionList));
EXPECT_FALSE(userModule->loaded);
}
TEST_F(Pkcs11ModuleLoadFunctionTest, LoadModuleWithEmptyFunctionList) {
ScopedSECMODModule userModule(SECMOD_LoadUserModuleWithFunction(
"LoadFunctionModule", &SupportedButNull));
EXPECT_NE(userModule, nullptr);
EXPECT_FALSE(userModule->loaded);
}
TEST_F(Pkcs11ModuleLoadFunctionTest, SuccessLoadModuleWithFunction) {
library = PR_LoadLibrary(DLL_PREFIX "pkcs11testmodule." DLL_SUFFIX);
EXPECT_NE(nullptr, library);
CK_C_GetFunctionList fentry = NULL;
fentry = (CK_C_GetFunctionList)PR_FindSymbol(library, "C_GetFunctionList");
EXPECT_NE(nullptr, fentry);
ScopedSECMODModule userModule(
SECMOD_LoadUserModuleWithFunction("LoadFunctionModule", fentry));
EXPECT_NE(nullptr, userModule);
EXPECT_EQ(userModule->loaded, PR_TRUE);
/* We can find the module*/
ScopedSECMODModule module(SECMOD_FindModule("LoadFunctionModule"));
EXPECT_NE(nullptr, module);
CK_INFO info;
EXPECT_EQ(SECSuccess, PK11_GetModInfo(userModule.get(), &info));
/* See pkcs11testmodule.cpp */
CK_VERSION expectedCryptokiVersion = {2, 2};
CK_VERSION expectedLibraryVersion = {0, 0};
EXPECT_EQ(info.cryptokiVersion.minor, expectedCryptokiVersion.minor);
EXPECT_EQ(info.cryptokiVersion.major, expectedCryptokiVersion.major);
EXPECT_EQ(
0, PORT_Memcmp((char *)info.manufacturerID, "Test PKCS11 Manufacturer ID",
sizeof("Test PKCS11 Manufacturer ID") - 1));
EXPECT_EQ(info.flags, 0UL);
EXPECT_EQ(0,
PORT_Memcmp((char *)info.libraryDescription, "Test PKCS11 Library",
sizeof("Test PKCS11 Library") - 1));
EXPECT_EQ(info.libraryVersion.minor, expectedLibraryVersion.minor);
EXPECT_EQ(info.libraryVersion.major, expectedLibraryVersion.major);
EXPECT_EQ(SECSuccess, SECMOD_UnloadUserModule(userModule.get()));
}
} // namespace nss_test

View File

@@ -25,48 +25,46 @@ namespace nss_test {
static std::unordered_set<PRInt32> gFuzzedSslOptions = {
SSL_SECURITY, // irrelevant
SSL_SOCKS, // irrelevant
SSL_REQUEST_CERTIFICATE, // tls_server_fuzz_target
SSL_REQUEST_CERTIFICATE, // tls_server
SSL_HANDSHAKE_AS_CLIENT, // irrelevant
SSL_HANDSHAKE_AS_SERVER, // irrelevant
SSL_ENABLE_SSL2, // obsolete
SSL_ENABLE_SSL3, // obsolete
SSL_NO_CACHE, // tls_client_fuzz_target, tls_server_fuzz_target
SSL_REQUIRE_CERTIFICATE, // tls_server_fuzz_target
SSL_NO_CACHE, // tls_client, tls_server
SSL_REQUIRE_CERTIFICATE, // tls_server
SSL_ENABLE_FDX,
SSL_V2_COMPATIBLE_HELLO, // obsolete
SSL_ENABLE_TLS, // obsolete
SSL_ROLLBACK_DETECTION,
SSL_NO_STEP_DOWN, // unsupported
SSL_BYPASS_PKCS11, // unsupported
SSL_NO_LOCKS, // tls_client_fuzz_target. tls_server_fuzz_target
SSL_ENABLE_SESSION_TICKETS, // tls_client_fuzz_target,
// tls_server_fuzz_target
SSL_ENABLE_DEFLATE, // tls_client_fuzz_target, tls_server_fuzz_target
SSL_NO_LOCKS, // tls_client, tls_server
SSL_ENABLE_SESSION_TICKETS, // tls_client, tls_server
SSL_ENABLE_DEFLATE, // tls_client, tls_server
SSL_ENABLE_RENEGOTIATION,
SSL_REQUIRE_SAFE_NEGOTIATION, // tls_client_fuzz_target,
// tls_server_fuzz_target
SSL_ENABLE_FALSE_START, // tls_client_fuzz_target
SSL_CBC_RANDOM_IV, // tls_client_fuzz_target, tls_server_fuzz_target
SSL_ENABLE_OCSP_STAPLING, // tls_client_fuzz_target
SSL_REQUIRE_SAFE_NEGOTIATION, // tls_client, tls_server
SSL_ENABLE_FALSE_START, // tls_client
SSL_CBC_RANDOM_IV, // tls_client, tls_server
SSL_ENABLE_OCSP_STAPLING, // tls_client
SSL_ENABLE_NPN, // defunct
SSL_ENABLE_ALPN, // tls_client_fuzz_target, tls_server_fuzz_target
SSL_ENABLE_ALPN, // tls_client, tls_server
SSL_REUSE_SERVER_ECDHE_KEY,
SSL_ENABLE_FALLBACK_SCSV, // tls_client_fuzz_target,
// tls_server_fuzz_target
SSL_ENABLE_FALLBACK_SCSV, // tls_client, tls_server
SSL_ENABLE_SERVER_DHE,
SSL_ENABLE_EXTENDED_MASTER_SECRET, // tls_client_fuzz_target,
// tls_server_fuzz_target
SSL_ENABLE_EXTENDED_MASTER_SECRET, // tls_client, tls_server
SSL_ENABLE_SIGNED_CERT_TIMESTAMPS,
SSL_REQUIRE_DH_NAMED_GROUPS, // tls_client_fuzz_target
SSL_ENABLE_0RTT_DATA, // tls_client_fuzz_target, tls_server_fuzz_target
SSL_REQUIRE_DH_NAMED_GROUPS, // tls_client
SSL_ENABLE_0RTT_DATA, // tls_client, tls_server
SSL_RECORD_SIZE_LIMIT,
SSL_ENABLE_TLS13_COMPAT_MODE, // tls_client_fuzz_target
SSL_ENABLE_DTLS_SHORT_HEADER, SSL_ENABLE_HELLO_DOWNGRADE_CHECK,
SSL_ENABLE_TLS13_COMPAT_MODE, // tls_client
SSL_ENABLE_DTLS_SHORT_HEADER, // tls_client, tls_server
SSL_ENABLE_HELLO_DOWNGRADE_CHECK,
SSL_ENABLE_V2_COMPATIBLE_HELLO,
SSL_ENABLE_POST_HANDSHAKE_AUTH, // tls_client_fuzz_target
SSL_ENABLE_DELEGATED_CREDENTIALS, SSL_SUPPRESS_END_OF_EARLY_DATA,
SSL_ENABLE_GREASE, // tls_client_fuzz_target, tls_server_fuzz_target
SSL_ENABLE_CH_EXTENSION_PERMUTATION, // tls_client_fuzz_target
SSL_ENABLE_POST_HANDSHAKE_AUTH, // tls_client
SSL_ENABLE_DELEGATED_CREDENTIALS, // tls_client, tls_server
SSL_SUPPRESS_END_OF_EARLY_DATA,
SSL_ENABLE_GREASE, // tls_client, tls_server
SSL_ENABLE_CH_EXTENSION_PERMUTATION, // tls_client
};
const uint8_t kShortEmptyFinished[8] = {0};

View File

@@ -8,9 +8,14 @@
#include <algorithm>
#include <cassert>
#include <fstream>
#include <iostream>
#include <iterator>
#include <memory>
#include <sstream>
#include <sys/stat.h>
#include "blapi.h"
#include "prerror.h"
#include "prlog.h"
#include "prthread.h"
@@ -25,6 +30,45 @@ namespace nss_test {
if (g_ssl_gtest_verbose) LOG(a); \
} while (false)
DummyPrSocket::~DummyPrSocket() {
#ifdef GTESTS_CORPUS
if (name_ != "client" && name_ != "server") {
return;
}
assert(variant_ == ssl_variant_stream || variant_ == ssl_variant_datagram);
assert(name_ == "client" || name_ == "server");
// We don't care if they already exist, just make sure they do at all.
mkdir("dtls-client-corpus", 0775);
mkdir("dtls-server-corpus", 0775);
mkdir("tls-client-corpus", 0775);
mkdir("tls-server-corpus", 0775);
std::stringstream filepath;
filepath << (variant_ == ssl_variant_stream ? "tls" : "dtls") << "-" << name_
<< "-corpus/";
unsigned char digest[20];
SHA1_HashBuf(digest, receivedData_.data(), receivedData_.size());
for (unsigned long i = 0; i < sizeof(digest); ++i) {
filepath << std::hex << std::setfill('0') << std::setw(2) << (int)digest[i];
}
std::ofstream file;
file.open(filepath.str(), std::ios::out | std::ofstream::binary);
if (file.fail()) {
std::cerr << "Failed to open file: " << filepath.str() << "\n";
abort();
}
std::copy(receivedData_.begin(), receivedData_.end(),
std::ostreambuf_iterator<char>(file));
#endif // GTESTS_CORPUS
}
PRDescIdentity DummyPrSocket::LayerId() {
static PRDescIdentity id = PR_GetUniqueIdentity("dummysocket");
return id;
@@ -49,6 +93,11 @@ void DummyPrSocket::Reset() {
}
void DummyPrSocket::PacketReceived(const DataBuffer &packet) {
#ifdef GTESTS_CORPUS
receivedData_.reserve(receivedData_.size() + packet.len());
std::copy(packet.data(), packet.data() + packet.len(),
std::back_inserter(receivedData_));
#endif // GTESTS_CORPUS
input_.push(Packet(packet));
}

View File

@@ -67,8 +67,9 @@ class DummyPrSocket : public DummyIOLayerMethods {
peer_(),
input_(),
filter_(nullptr),
write_error_(0) {}
virtual ~DummyPrSocket() {}
write_error_(0),
receivedData_() {}
virtual ~DummyPrSocket();
static PRDescIdentity LayerId();
@@ -117,6 +118,8 @@ class DummyPrSocket : public DummyIOLayerMethods {
std::queue<Packet> input_;
std::shared_ptr<PacketFilter> filter_;
PRErrorCode write_error_;
std::vector<uint8_t> receivedData_;
};
// Marker interface.

View File

@@ -577,9 +577,11 @@ get_token_objects_for_cache(
} else {
PRUint32 j;
for (j = 0; j < i; j++) {
/* Any token references that were removed in successful loop iterations
* need to be restored before we call nssCryptokiObjectArray_Destroy */
nssToken_AddRef(cache->objects[objectType][j]->object->token);
/* Objects that were successfully added to the cache do not own a
* token reference (they share a reference with the cache itself).
* Nulling out the pointer here prevents the token's refcount
* from being decremented in nssCryptokiObject_Destroy */
cache->objects[objectType][j]->object->token = NULL;
nssArena_Destroy(cache->objects[objectType][j]->arena);
}
nss_ZFreeIf(cache->objects[objectType]);

View File

@@ -512,7 +512,7 @@ AESKeyWrap_EncryptKWP(AESKeyWrapContext *cx, unsigned char *output,
PORT_Memcpy(iv + AES_KEY_WRAP_BLOCK_SIZE, input, inputLen);
rv = AES_Encrypt(&cx->aescx, output, pOutputLen, maxOutputLen, iv,
outLen);
PORT_Memset(iv, 0, sizeof(iv));
PORT_SafeZero(iv, sizeof(iv));
return rv;
}
@@ -528,7 +528,7 @@ AESKeyWrap_EncryptKWP(AESKeyWrapContext *cx, unsigned char *output,
PORT_ZFree(newBuf, paddedInputLen);
/* a little overkill, we only need to clear out the length, but this
* is easier to verify we got it all */
PORT_Memset(iv, 0, sizeof(iv));
PORT_SafeZero(iv, sizeof(iv));
return rv;
}
@@ -631,12 +631,12 @@ AESKeyWrap_DecryptKWP(AESKeyWrapContext *cx, unsigned char *output,
loser:
/* if we failed, make sure we don't return any data to the user */
if ((rv != SECSuccess) && (output == newBuf)) {
PORT_Memset(newBuf, 0, paddedLen);
PORT_SafeZero(newBuf, paddedLen);
}
/* clear out CSP sensitive data from the heap and stack */
if (allocBuf) {
PORT_ZFree(allocBuf, paddedLen);
}
PORT_Memset(iv, 0, sizeof(iv));
PORT_SafeZero(iv, sizeof(iv));
return rv;
}

View File

@@ -116,7 +116,7 @@ PRBool ppc_crypto_support();
#define BLAPI_CLEAR_STACK(stack_size) \
{ \
volatile char _stkclr[stack_size]; \
PORT_Memset((void *)&_stkclr[0], 0, stack_size); \
PORT_SafeZero((void *)&_stkclr[0], stack_size); \
}
#endif

View File

@@ -90,4 +90,8 @@ ifeq ($(OS_ARCH), Darwin)
EXTRA_SHARED_LIBS += -dylib_file @executable_path/libplc4.dylib:$(DIST)/lib/libplc4.dylib -dylib_file @executable_path/libplds4.dylib:$(DIST)/lib/libplds4.dylib
endif
ifdef NSS_FIPS_140_3
DEFINES += -DNSS_FIPS_140_3
endif
endif

View File

@@ -135,7 +135,7 @@ prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return,
unsigned int hash_return_len;
SHA256_Begin(&ctx);
SHA256_Update(&ctx, &counter, 1);
SHA256_Update(&ctx, (unsigned char *)&tmp, sizeof tmp);
SHA256_Update(&ctx, (unsigned char *)&tmp, sizeof(tmp));
SHA256_Update(&ctx, input_string_1, input_string_1_len);
if (input_string_2) {
SHA256_Update(&ctx, input_string_2, input_string_2_len);
@@ -168,7 +168,8 @@ prng_instantiate(RNGContext *rng, const PRUint8 *bytes, unsigned int len)
}
prng_Hash_df(V(rng), VSize(rng), bytes, len, NULL, 0);
rng->V_type = prngCGenerateType;
prng_Hash_df(rng->C, sizeof rng->C, rng->V_Data, sizeof rng->V_Data, NULL, 0);
prng_Hash_df(rng->C, sizeof(rng->C), rng->V_Data, sizeof(rng->V_Data),
NULL, 0);
PRNG_RESET_RESEED_COUNT(rng)
return SECSuccess;
}
@@ -197,7 +198,7 @@ prng_initEntropy(void)
SHA256_Update(&ctx, block, sizeof(block));
SHA256_End(&ctx, globalrng->previousEntropyHash, NULL,
sizeof(globalrng->previousEntropyHash));
PORT_Memset(block, 0, sizeof(block));
PORT_SafeZero(block, sizeof(block));
SHA256_DestroyContext(&ctx, PR_FALSE);
return PR_SUCCESS;
}
@@ -246,8 +247,8 @@ prng_getEntropy(PRUint8 *buffer, size_t requestLength)
}
out:
PORT_Memset(hash, 0, sizeof hash);
PORT_Memset(block, 0, sizeof block);
PORT_SafeZero(hash, sizeof(hash));
PORT_SafeZero(block, sizeof(block));
return rv;
}
@@ -262,14 +263,14 @@ static SECStatus
prng_reseed(RNGContext *rng, const PRUint8 *entropy, unsigned int entropy_len,
const PRUint8 *additional_input, unsigned int additional_input_len)
{
PRUint8 noiseData[(sizeof rng->V_Data) + PRNG_SEEDLEN];
PRUint8 noiseData[(sizeof(rng->V_Data)) + PRNG_SEEDLEN];
PRUint8 *noise = &noiseData[0];
SECStatus rv;
/* if entropy wasn't supplied, fetch it. (normal operation case) */
if (entropy == NULL) {
entropy_len = PRNG_SEEDLEN;
rv = prng_getEntropy(&noiseData[sizeof rng->V_Data], entropy_len);
rv = prng_getEntropy(&noiseData[sizeof(rng->V_Data)], entropy_len);
if (rv != SECSuccess) {
return SECFailure; /* error is already set */
}
@@ -277,12 +278,12 @@ prng_reseed(RNGContext *rng, const PRUint8 *entropy, unsigned int entropy_len,
/* NOTE: this code is only available for testing, not to applications */
/* if entropy was too big for the stack variable, get it from malloc */
if (entropy_len > PRNG_SEEDLEN) {
noise = PORT_Alloc(entropy_len + (sizeof rng->V_Data));
noise = PORT_Alloc(entropy_len + (sizeof(rng->V_Data)));
if (noise == NULL) {
return SECFailure;
}
}
PORT_Memcpy(&noise[sizeof rng->V_Data], entropy, entropy_len);
PORT_Memcpy(&noise[sizeof(rng->V_Data)], entropy, entropy_len);
}
if (entropy_len < 256 / PR_BITS_PER_BYTE) {
@@ -292,13 +293,14 @@ prng_reseed(RNGContext *rng, const PRUint8 *entropy, unsigned int entropy_len,
}
rng->V_type = prngReseedType;
PORT_Memcpy(noise, rng->V_Data, sizeof rng->V_Data);
prng_Hash_df(V(rng), VSize(rng), noise, (sizeof rng->V_Data) + entropy_len,
PORT_Memcpy(noise, rng->V_Data, sizeof(rng->V_Data));
prng_Hash_df(V(rng), VSize(rng), noise, (sizeof(rng->V_Data)) + entropy_len,
additional_input, additional_input_len);
/* clear potential CSP */
PORT_Memset(noise, 0, (sizeof rng->V_Data) + entropy_len);
PORT_Memset(noise, 0, (sizeof(rng->V_Data)) + entropy_len);
rng->V_type = prngCGenerateType;
prng_Hash_df(rng->C, sizeof rng->C, rng->V_Data, sizeof rng->V_Data, NULL, 0);
prng_Hash_df(rng->C, sizeof(rng->C), rng->V_Data, sizeof(rng->V_Data),
NULL, 0);
PRNG_RESET_RESEED_COUNT(rng)
if (noise != &noiseData[0]) {
@@ -379,7 +381,7 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
unsigned int carry;
SHA256_Begin(&ctx);
SHA256_Update(&ctx, data, sizeof data);
SHA256_Update(&ctx, data, sizeof(data));
SHA256_End(&ctx, thisHash, &len, SHA256_LENGTH);
if (no_of_returned_bytes < SHA256_LENGTH) {
len = no_of_returned_bytes;
@@ -390,11 +392,11 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
/* The carry parameter is a bool (increment or not).
* This increments data if no_of_returned_bytes is not zero */
carry = no_of_returned_bytes;
PRNG_ADD_CARRY_ONLY(data, (sizeof data) - 1, carry);
PRNG_ADD_CARRY_ONLY(data, (sizeof(data)) - 1, carry);
SHA256_DestroyContext(&ctx, PR_FALSE);
}
PORT_Memset(data, 0, sizeof data);
PORT_Memset(thisHash, 0, sizeof thisHash);
PORT_SafeZero(data, sizeof(data));
PORT_SafeZero(thisHash, sizeof(thisHash));
}
/*
@@ -429,11 +431,11 @@ prng_generateNewBytes(RNGContext *rng,
#define w H
rng->V_type = prngAdditionalDataType;
SHA256_Begin(&ctx);
SHA256_Update(&ctx, rng->V_Data, sizeof rng->V_Data);
SHA256_Update(&ctx, rng->V_Data, sizeof(rng->V_Data));
SHA256_Update(&ctx, additional_input, additional_input_len);
SHA256_End(&ctx, w, NULL, sizeof w);
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof w, carry)
PORT_Memset(w, 0, sizeof w);
SHA256_End(&ctx, w, NULL, sizeof(w));
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof(w), carry)
PORT_Memset(w, 0, sizeof(w));
SHA256_DestroyContext(&ctx, PR_FALSE);
#undef w
}
@@ -446,16 +448,16 @@ prng_generateNewBytes(RNGContext *rng,
}
/* advance our internal state... */
rng->V_type = prngGenerateByteType;
SHA256_HashBuf(H, rng->V_Data, sizeof rng->V_Data);
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), H, sizeof H, carry)
PRNG_ADD_BITS(V(rng), VSize(rng), rng->C, sizeof rng->C, carry);
SHA256_HashBuf(H, rng->V_Data, sizeof(rng->V_Data));
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), H, sizeof(H), carry)
PRNG_ADD_BITS(V(rng), VSize(rng), rng->C, sizeof(rng->C), carry);
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), rng->reseed_counter,
sizeof rng->reseed_counter, carry)
sizeof(rng->reseed_counter), carry)
carry = 1;
PRNG_ADD_CARRY_ONLY(rng->reseed_counter, (sizeof rng->reseed_counter) - 1, carry);
PRNG_ADD_CARRY_ONLY(rng->reseed_counter, (sizeof(rng->reseed_counter)) - 1, carry);
/* if the prng failed, don't return any output, signal softoken */
PORT_Memset(H, 0, sizeof H);
PORT_SafeZero(H, sizeof(H));
if (!rng->isValid) {
PORT_Memset(returned_bytes, 0, no_of_returned_bytes);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
@@ -491,17 +493,17 @@ rng_init(void)
}
/* Try to get some seed data for the RNG */
rv = prng_getEntropy(bytes, sizeof bytes);
rv = prng_getEntropy(bytes, sizeof(bytes));
if (rv == SECSuccess) {
/* if this is our first call, instantiate, otherwise reseed
* prng_instantiate gets a new clean state, we want to mix
* any previous entropy we may have collected */
if (V(globalrng)[0] == 0) {
rv = prng_instantiate(globalrng, bytes, sizeof bytes);
rv = prng_instantiate(globalrng, bytes, sizeof(bytes));
} else {
rv = prng_reseed_test(globalrng, bytes, sizeof bytes, NULL, 0);
rv = prng_reseed_test(globalrng, bytes, sizeof(bytes), NULL, 0);
}
memset(bytes, 0, sizeof bytes);
memset(bytes, 0, sizeof(bytes));
} else {
PZ_DestroyLock(globalrng->lock);
globalrng->lock = NULL;
@@ -532,20 +534,20 @@ rng_init(void)
static void
prng_freeRNGContext(RNGContext *rng)
{
PRUint8 inputhash[VSize(rng) + (sizeof rng->C)];
PRUint8 inputhash[VSize(rng) + (sizeof(rng->C))];
/* destroy context lock */
SKIP_AFTER_FORK(PZ_DestroyLock(globalrng->lock));
/* zero global RNG context except for C & V to preserve entropy */
prng_Hash_df(inputhash, sizeof rng->C, rng->C, sizeof rng->C, NULL, 0);
prng_Hash_df(&inputhash[sizeof rng->C], VSize(rng), V(rng), VSize(rng),
prng_Hash_df(inputhash, sizeof(rng->C), rng->C, sizeof(rng->C), NULL, 0);
prng_Hash_df(&inputhash[sizeof(rng->C)], VSize(rng), V(rng), VSize(rng),
NULL, 0);
memset(rng, 0, sizeof *rng);
memcpy(rng->C, inputhash, sizeof rng->C);
memcpy(V(rng), &inputhash[sizeof rng->C], VSize(rng));
memset(rng, 0, sizeof(*rng));
memcpy(rng->C, inputhash, sizeof(rng->C));
memcpy(V(rng), &inputhash[sizeof(rng->C)], VSize(rng));
memset(inputhash, 0, sizeof inputhash);
memset(inputhash, 0, sizeof(inputhash));
}
/*
@@ -621,7 +623,7 @@ RNG_RandomUpdate(const void *data, size_t bytes)
if (bytes > sizeof(globalrng->additionalDataCache)) {
rv = prng_reseed_test(globalrng, NULL, 0, data, (unsigned int)bytes);
/* if we aren't going to fill or overflow the buffer, just cache it */
} else if (bytes < ((sizeof globalrng->additionalDataCache) - globalrng->additionalAvail)) {
} else if (bytes < ((sizeof(globalrng->additionalDataCache)) - globalrng->additionalAvail)) {
PORT_Memcpy(globalrng->additionalDataCache + globalrng->additionalAvail,
data, bytes);
globalrng->additionalAvail += (PRUint32)bytes;
@@ -632,7 +634,7 @@ RNG_RandomUpdate(const void *data, size_t bytes)
* remainder. We know the remainder will fit in the buffer because
* we already handled the case where bytes > the size of the buffer.
*/
size_t bufRemain = (sizeof globalrng->additionalDataCache) - globalrng->additionalAvail;
size_t bufRemain = (sizeof(globalrng->additionalDataCache)) - globalrng->additionalAvail;
/* fill the rest of the buffer */
if (bufRemain) {
PORT_Memcpy(globalrng->additionalDataCache + globalrng->additionalAvail,
@@ -643,7 +645,7 @@ RNG_RandomUpdate(const void *data, size_t bytes)
/* reseed from buffer */
rv = prng_reseed_test(globalrng, NULL, 0,
globalrng->additionalDataCache,
sizeof globalrng->additionalDataCache);
sizeof(globalrng->additionalDataCache));
/* copy the rest into the cache */
PORT_Memcpy(globalrng->additionalDataCache, data, bytes);
@@ -693,21 +695,21 @@ prng_GenerateGlobalRandomBytes(RNGContext *rng,
* see if we have enough bytes to fulfill the request.
*/
if (len <= rng->dataAvail) {
memcpy(output, rng->data + ((sizeof rng->data) - rng->dataAvail), len);
memset(rng->data + ((sizeof rng->data) - rng->dataAvail), 0, len);
memcpy(output, rng->data + ((sizeof(rng->data)) - rng->dataAvail), len);
memset(rng->data + ((sizeof(rng->data)) - rng->dataAvail), 0, len);
rng->dataAvail -= len;
rv = SECSuccess;
/* if we are asking for a small number of bytes, cache the rest of
* the bytes */
} else if (len < sizeof rng->data) {
rv = prng_generateNewBytes(rng, rng->data, sizeof rng->data,
} else if (len < sizeof(rng->data)) {
rv = prng_generateNewBytes(rng, rng->data, sizeof(rng->data),
rng->additionalAvail ? rng->additionalDataCache : NULL,
rng->additionalAvail);
rng->additionalAvail = 0;
if (rv == SECSuccess) {
memcpy(output, rng->data, len);
memset(rng->data, 0, len);
rng->dataAvail = (sizeof rng->data) - len;
rng->dataAvail = (sizeof(rng->data)) - len;
}
/* we are asking for lots of bytes, just ask the generator to pass them */
} else {
@@ -858,7 +860,7 @@ PRNGTEST_Uninstantiate()
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
PORT_Memset(&testContext, 0, sizeof testContext);
PORT_Memset(&testContext, 0, sizeof(testContext));
return SECSuccess;
}
@@ -943,31 +945,31 @@ PRNGTEST_RunHealthTests()
/********************************************/
/* Generate random bytes with a known seed. */
/********************************************/
rng_status = PRNGTEST_Instantiate(entropy, sizeof entropy,
rng_status = PRNGTEST_Instantiate(entropy, sizeof(entropy),
NULL, 0, NULL, 0);
if (rng_status != SECSuccess) {
/* Error set by PRNGTEST_Instantiate */
return SECFailure;
}
rng_status = PRNGTEST_Generate(result, sizeof rng_known_result, NULL, 0);
rng_status = PRNGTEST_Generate(result, sizeof(rng_known_result), NULL, 0);
if ((rng_status != SECSuccess) ||
(PORT_Memcmp(result, rng_known_result,
sizeof rng_known_result) != 0)) {
sizeof(rng_known_result)) != 0)) {
PRNGTEST_Uninstantiate();
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
rng_status = PRNGTEST_Reseed(reseed_entropy, sizeof reseed_entropy,
additional_input, sizeof additional_input);
rng_status = PRNGTEST_Reseed(reseed_entropy, sizeof(reseed_entropy),
additional_input, sizeof(additional_input));
if (rng_status != SECSuccess) {
/* Error set by PRNG_Reseed */
PRNGTEST_Uninstantiate();
return SECFailure;
}
rng_status = PRNGTEST_Generate(result, sizeof rng_reseed_result, NULL, 0);
rng_status = PRNGTEST_Generate(result, sizeof(rng_reseed_result), NULL, 0);
if ((rng_status != SECSuccess) ||
(PORT_Memcmp(result, rng_reseed_result,
sizeof rng_reseed_result) != 0)) {
sizeof(rng_reseed_result)) != 0)) {
PRNGTEST_Uninstantiate();
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
@@ -981,13 +983,13 @@ PRNGTEST_RunHealthTests()
return SECFailure;
}
/* This generate should now reseed */
rng_status = PRNGTEST_Generate(result, sizeof rng_reseed_result, NULL, 0);
rng_status = PRNGTEST_Generate(result, sizeof(rng_reseed_result), NULL, 0);
if ((rng_status != SECSuccess) ||
/* NOTE we fail if the result is equal to the no_reseed_result.
* no_reseed_result is the value we would have gotten if we didn't
* do an automatic reseed in PRNGTEST_Generate */
(PORT_Memcmp(result, rng_no_reseed_result,
sizeof rng_no_reseed_result) == 0)) {
sizeof(rng_no_reseed_result)) == 0)) {
PRNGTEST_Uninstantiate();
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;

View File

@@ -471,7 +471,7 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
err = MP_OKAY;
signature->len = dsa_signature_len;
cleanup:
PORT_Memset(localDigestData, 0, DSA_MAX_SUBPRIME_LEN);
PORT_SafeZero(localDigestData, DSA_MAX_SUBPRIME_LEN);
mp_clear(&p);
mp_clear(&q);
mp_clear(&g);
@@ -532,7 +532,7 @@ DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
rv = dsa_SignDigest(key, signature, digest, kSeed);
} while (rv != SECSuccess && PORT_GetError() == SEC_ERROR_NEED_RANDOM &&
--retries > 0);
PORT_Memset(kSeed, 0, sizeof kSeed);
PORT_SafeZero(kSeed, sizeof kSeed);
return rv;
}
@@ -673,7 +673,7 @@ DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
verified = SECSuccess; /* Signature verified. */
}
cleanup:
PORT_Memset(localDigestData, 0, sizeof localDigestData);
PORT_SafeZero(localDigestData, sizeof localDigestData);
mp_clear(&p);
mp_clear(&q);
mp_clear(&g);

View File

@@ -480,7 +480,7 @@ gcmHash_Final(gcmHashContext *ghash, unsigned char *outbuf,
rv = SECSuccess;
cleanup:
PORT_Memset(T, 0, sizeof(T));
PORT_SafeZero(T, sizeof(T));
return rv;
}
@@ -596,15 +596,15 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher,
if (rv != SECSuccess) {
goto loser;
}
PORT_Memset(H, 0, AES_BLOCK_SIZE);
PORT_SafeZero(H, AES_BLOCK_SIZE);
gcm->ctr_context_init = PR_TRUE;
return gcm;
loser:
PORT_Memset(H, 0, AES_BLOCK_SIZE);
PORT_SafeZero(H, AES_BLOCK_SIZE);
if (ghash && ghash->mem) {
void *mem = ghash->mem;
PORT_Memset(ghash, 0, sizeof(gcmHashContext));
PORT_SafeZero(ghash, sizeof(gcmHashContext));
PORT_Free(mem);
}
if (gcm) {
@@ -682,11 +682,11 @@ gcm_InitCounter(GCMContext *gcm, const unsigned char *iv, unsigned int ivLen,
goto loser;
}
PORT_Memset(&ctrParams, 0, sizeof ctrParams);
PORT_SafeZero(&ctrParams, sizeof ctrParams);
return SECSuccess;
loser:
PORT_Memset(&ctrParams, 0, sizeof ctrParams);
PORT_SafeZero(&ctrParams, sizeof ctrParams);
if (freeCtr) {
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
}
@@ -866,10 +866,10 @@ GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
if (NSS_SecureMemcmp(tag, intag, tagBytes) != 0) {
/* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
PORT_SetError(SEC_ERROR_BAD_DATA);
PORT_Memset(tag, 0, sizeof(tag));
PORT_SafeZero(tag, sizeof(tag));
return SECFailure;
}
PORT_Memset(tag, 0, sizeof(tag));
PORT_SafeZero(tag, sizeof(tag));
/* finish the decryption */
return CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
inbuf, inlen, AES_BLOCK_SIZE);
@@ -1159,10 +1159,10 @@ GCM_DecryptAEAD(GCMContext *gcm, unsigned char *outbuf,
/* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
PORT_SetError(SEC_ERROR_BAD_DATA);
PORT_Memset(tag, 0, sizeof(tag));
PORT_SafeZero(tag, sizeof(tag));
return SECFailure;
}
PORT_Memset(tag, 0, sizeof(tag));
PORT_SafeZero(tag, sizeof(tag));
/* finish the decryption */
rv = CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
inbuf, inlen, AES_BLOCK_SIZE);

View File

@@ -274,10 +274,10 @@ MAC(unsigned char *mdOut,
hashObj->end(mdState, mdOut, mdOutLen, mdOutMax);
hashObj->destroy(mdState, PR_TRUE);
PORT_Memset(lengthBytes, 0, sizeof lengthBytes);
PORT_Memset(hmacPad, 0, sizeof hmacPad);
PORT_Memset(firstBlock, 0, sizeof firstBlock);
PORT_Memset(macOut, 0, sizeof macOut);
PORT_SafeZero(lengthBytes, sizeof lengthBytes);
PORT_SafeZero(hmacPad, sizeof hmacPad);
PORT_SafeZero(firstBlock, sizeof firstBlock);
PORT_SafeZero(macOut, sizeof macOut);
return SECSuccess;
}

View File

@@ -195,7 +195,7 @@ intel_aes_gcmInitCounter(intel_AES_GCMContext *gcm,
void
intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit)
{
PORT_Memset(gcm, 0, sizeof(intel_AES_GCMContext));
PORT_SafeZero(gcm, sizeof(intel_AES_GCMContext));
if (freeit) {
PORT_Free(gcm);
}

View File

@@ -169,7 +169,7 @@ ppc_aes_gcmInitCounter(ppc_AES_GCMContext *gcm,
void
ppc_AES_GCM_DestroyContext(ppc_AES_GCMContext *gcm, PRBool freeit)
{
PORT_Memset(gcm, 0, sizeof(ppc_AES_GCMContext));
PORT_SafeZero(gcm, sizeof(ppc_AES_GCMContext));
if (freeit) {
PORT_Free(gcm);
}

View File

@@ -703,7 +703,7 @@ cleanup:
mp_clear(&a);
mp_clear(&z);
mp_clear(&two_length_minus_1);
PORT_Memset(x, 0, sizeof(x));
PORT_SafeZero(x, sizeof(x));
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
@@ -859,7 +859,7 @@ cleanup:
mp_clear(&c);
mp_clear(&c0);
mp_clear(&one);
PORT_Memset(x, 0, sizeof(x));
PORT_SafeZero(x, sizeof(x));
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
@@ -1072,7 +1072,7 @@ makePfromQandSeed(
CHECK_MPI_OK(mp_sub_d(&c, 1, &c)); /* c -= 1 */
CHECK_MPI_OK(mp_sub(&X, &c, P)); /* P = X - c */
cleanup:
PORT_Memset(V_j, 0, sizeof V_j);
PORT_SafeZero(V_j, sizeof V_j);
mp_clear(&W);
mp_clear(&X);
mp_clear(&c);
@@ -1221,7 +1221,7 @@ makeGfromIndex(HASH_HashType hashtype,
/* step 11.
* return valid G */
cleanup:
PORT_Memset(data, 0, sizeof(data));
PORT_SafeZero(data, sizeof(data));
if (hashcx) {
hashobj->destroy(hashcx, PR_TRUE);
}

View File

@@ -1251,7 +1251,7 @@ AES_DestroyContext(AESContext *cx, PRBool freeit)
cx->worker_cx = NULL;
cx->destroy = NULL;
}
PORT_Memset(cx, 0, sizeof(AESContext));
PORT_SafeZero(cx, sizeof(AESContext));
if (freeit) {
PORT_Free(mem);
} else {

View File

@@ -978,14 +978,14 @@ rsa_GetHMACContext(const SECHashObject *hash, RSAPrivateKey *key,
/* now create the hmac key */
hmac = HMAC_Create(hash, keyHash, keyLen, PR_TRUE);
if (hmac == NULL) {
PORT_Memset(keyHash, 0, sizeof(keyHash));
PORT_SafeZero(keyHash, sizeof(keyHash));
return NULL;
}
HMAC_Begin(hmac);
HMAC_Update(hmac, input, inputLen);
rv = HMAC_Finish(hmac, keyHash, &keyLen, sizeof(keyHash));
if (rv != SECSuccess) {
PORT_Memset(keyHash, 0, sizeof(keyHash));
PORT_SafeZero(keyHash, sizeof(keyHash));
HMAC_Destroy(hmac, PR_TRUE);
return NULL;
}
@@ -993,7 +993,7 @@ rsa_GetHMACContext(const SECHashObject *hash, RSAPrivateKey *key,
* reuse the original context allocated above so we don't
* need to allocate and free another one */
rv = HMAC_ReInit(hmac, hash, keyHash, keyLen, PR_TRUE);
PORT_Memset(keyHash, 0, sizeof(keyHash));
PORT_SafeZero(keyHash, sizeof(keyHash));
if (rv != SECSuccess) {
HMAC_Destroy(hmac, PR_TRUE);
return NULL;
@@ -1043,7 +1043,7 @@ rsa_HMACPrf(HMACContext *hmac, const char *label, int labelLen,
return rv;
}
PORT_Memcpy(output, hmacLast, left);
PORT_Memset(hmacLast, 0, sizeof(hmacLast));
PORT_SafeZero(hmacLast, sizeof(hmacLast));
}
return rv;
}
@@ -1088,7 +1088,7 @@ rsa_GetErrorLength(HMACContext *hmac, int hashLen, int maxLegalLen)
outLength = PORT_CT_SEL(PORT_CT_LT(candidate, maxLegalLen),
candidate, outLength);
}
PORT_Memset(out, 0, sizeof(out));
PORT_SafeZero(out, sizeof(out));
return outLength;
}

View File

@@ -365,7 +365,7 @@ blapi_SHVerifyDSACheck(PRFileDesc *shFD, const SECHashObject *hashObj,
/* verify the hash against the check file */
rv = DSA_VerifyDigest(key, signature, &hash);
PORT_Memset(hashBuf, 0, sizeof hashBuf);
PORT_SafeZero(hashBuf, sizeof hashBuf);
return (rv == SECSuccess) ? PR_TRUE : PR_FALSE;
}
#endif
@@ -427,7 +427,7 @@ blapi_SHVerifyHMACCheck(PRFileDesc *shFD, const SECHashObject *hashObj,
if (rv == SECSuccess) {
result = SECITEM_ItemsAreEqual(signature, &hash);
}
PORT_Memset(hashBuf, 0, sizeof hashBuf);
PORT_SafeZero(hashBuf, sizeof hashBuf);
return result;
}
@@ -451,7 +451,7 @@ blapi_SHVerifyFile(const char *shName, PRBool self, PRBool rerun)
#ifndef NSS_STRICT_INTEGRITY
DSAPublicKey key;
PORT_Memset(&key, 0, sizeof(key));
PORT_SafeZero(&key, sizeof(key));
#endif
/* If our integrity check was never ran or failed, fail any other
@@ -597,7 +597,7 @@ blapi_SHVerifyFile(const char *shName, PRBool self, PRBool rerun)
shFD = NULL;
loser:
PORT_Memset(&header, 0, sizeof header);
PORT_SafeZero(&header, sizeof header);
if (checkName != NULL) {
PORT_Free(checkName);
}

View File

@@ -144,6 +144,7 @@ STUB_DECLARE(void, PORT_Free_Util, (void *ptr));
STUB_DECLARE(void, PORT_FreeArena_Util, (PLArenaPool * arena, PRBool zero));
STUB_DECLARE(int, PORT_GetError_Util, (void));
STUB_DECLARE(PLArenaPool *, PORT_NewArena_Util, (unsigned long chunksize));
STUB_DECLARE(void, PORT_SafeZero, (void *p, size_t n));
STUB_DECLARE(void, PORT_SetError_Util, (int value));
STUB_DECLARE(void *, PORT_ZAlloc_Util, (size_t len));
STUB_DECLARE(void *, PORT_ZAllocAligned_Util, (size_t bytes, size_t alignment, void **mem));
@@ -488,6 +489,20 @@ PORT_GetError_stub(void)
return errno;
}
extern void
PORT_SafeZero(void *p, size_t n)
{
STUB_SAFE_CALL2(PORT_SafeZero, p, n);
/* just use a generic call in the case where we are running
* standalone freebl */
if (p != NULL) {
volatile unsigned char *__vl = (unsigned char *)p;
size_t __nl = n;
while (__nl--)
*__vl++ = 0;
}
}
extern void
PORT_SetError_stub(int value)
{

View File

@@ -27,6 +27,7 @@
#define PORT_FreeArena PORT_FreeArena_stub
#define PORT_GetError PORT_GetError_stub
#define PORT_NewArena PORT_NewArena_stub
#define PORT_SaveZero PORT_SaveZero_stub
#define PORT_SetError PORT_SetError_stub
#define PORT_ZAlloc PORT_ZAlloc_stub
#define PORT_ZFree PORT_ZFree_stub

View File

@@ -8,7 +8,9 @@
#include "seccomon.h"
#if defined(XP_UNIX) && defined(SEED_ONLY_DEV_URANDOM)
#if defined(XP_UNIX) && defined(NSS_FIPS_140_3)
#include "unix_fips140_3.c"
#elif defined(XP_UNIX) && defined(SEED_ONLY_DEV_URANDOM)
#include "unix_urandom.c"
#elif defined(XP_UNIX)
#include "unix_rand.c"

View File

@@ -82,8 +82,8 @@ loser:
/* clear out state so it's not left on the stack */
if (cx)
HMAC_Destroy(cx, PR_TRUE);
PORT_Memset(state, 0, sizeof(state));
PORT_Memset(outbuf, 0, sizeof(outbuf));
PORT_SafeZero(state, sizeof(state));
PORT_SafeZero(outbuf, sizeof(outbuf));
return rv;
}

View File

@@ -0,0 +1,80 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include "secerr.h"
#include "secrng.h"
#include "prprf.h"
#include <sys/random.h>
#include "prinit.h"
#ifndef GRND_RANDOM
/* if you don't have get random, you'll need to add your platform specific
* support for FIPS 104-3 compliant random seed source here */
PR_STATIC_ASSERT("You'll need to add our platform specific solution for FIPS 140-3 RNG" == NULL);
#endif
/* syscall getentropy() is limited to retrieving 256 bytes */
#define GETENTROPY_MAX_BYTES 256
void
RNG_SystemInfoForRNG(void)
{
PRUint8 bytes[SYSTEM_RNG_SEED_COUNT];
size_t numBytes = RNG_SystemRNG(bytes, SYSTEM_RNG_SEED_COUNT);
if (!numBytes) {
/* error is set */
return;
}
RNG_RandomUpdate(bytes, numBytes);
PORT_SaveZero(bytes, sizeof(bytes));
}
static unsigned int rng_grndFlags = 0;
static PRCallOnceType rng_KernelFips;
static PRStatus
rng_getKernelFips()
{
if (NSS_GetSystemFIPSEnabled()) {
rng_grndFlags = GRND_RANDOM;
}
return PR_SUCCESS;
}
size_t
RNG_SystemRNG(void *dest, size_t maxLen)
{
size_t fileBytes = 0;
unsigned char *buffer = dest;
ssize_t result;
PR_CallOnce(&rng_KernelFips, rng_getKernelFips);
while (fileBytes < maxLen) {
size_t getBytes = maxLen - fileBytes;
if (getBytes > GETENTROPY_MAX_BYTES) {
getBytes = GETENTROPY_MAX_BYTES;
}
/* FIP 140-3 requires full kernel reseeding for chained entropy sources
* so we need to use getrandom with GRND_RANDOM.
* getrandom returns -1 on failure, otherwise returns
* the number of bytes, which can be less than getBytes */
result = getrandom(buffer, getBytes, rng_grndFlags);
if (result < 0) {
break;
}
fileBytes += result;
buffer += result;
}
if (fileBytes == maxLen) { /* success */
return maxLen;
}
/* in FIPS 104-3 we don't fallback, just fail */
PORT_SetError(SEC_ERROR_NEED_RANDOM);
return 0;
}

View File

@@ -22,7 +22,7 @@ RNG_SystemInfoForRNG(void)
return;
}
RNG_RandomUpdate(bytes, numBytes);
PORT_Memset(bytes, 0, sizeof bytes);
PORT_SafeZero(bytes, sizeof bytes);
}
size_t
@@ -41,6 +41,9 @@ RNG_SystemRNG(void *dest, size_t maxLen)
if (getBytes > GETENTROPY_MAX_BYTES) {
getBytes = GETENTROPY_MAX_BYTES;
}
/* get entropy returns 0 on success and always return
* getBytes on success */
result = getentropy(buffer, getBytes);
if (result == 0) { /* success */
fileBytes += getBytes;
@@ -61,7 +64,7 @@ RNG_SystemRNG(void *dest, size_t maxLen)
/* ENOSYS means the kernel doesn't support getentropy()/getrandom().
* Reset the number of bytes to get and fall back to /dev/urandom. */
fileBytes = 0;
#endif
#endif /* platorm has getentropy */
fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);

View File

@@ -1967,8 +1967,9 @@ IsValidDNSID(Input hostname, IDRole idRole, AllowWildcards allowWildcards)
}
switch (b) {
case '-':
if (labelLength == 0) {
return false; // Labels must not start with a hyphen.
// Only reference ID labels can start with a hyphen.
if (labelLength == 0 && idRole != IDRole::ReferenceID) {
return false;
}
labelIsAllNumeric = false;
labelEndsWithHyphen = true;
@@ -2028,8 +2029,9 @@ IsValidDNSID(Input hostname, IDRole idRole, AllowWildcards allowWildcards)
(idRole != IDRole::NameConstraint || !isFirstByte)) {
return false;
}
if (labelEndsWithHyphen) {
return false; // Labels must not end with a hyphen.
// Only reference ID labels can end with a hyphen.
if (labelEndsWithHyphen && idRole != IDRole::ReferenceID) {
return false;
}
labelLength = 0;
break;
@@ -2046,8 +2048,9 @@ IsValidDNSID(Input hostname, IDRole idRole, AllowWildcards allowWildcards)
return false;
}
if (labelEndsWithHyphen) {
return false; // Labels must not end with a hyphen.
// Only reference ID labels can end with a hyphen.
if (labelEndsWithHyphen && idRole != IDRole::ReferenceID) {
return false;
}
if (labelIsAllNumeric) {

View File

@@ -1270,3 +1270,9 @@ SECKEY_PrivateKeyStrengthInBits;
;+ local:
;+ *;
;+};
;+NSS_3.107 { # NSS 3.107 release
;+ global:
SECMOD_LoadUserModuleWithFunction;
;+ local:
;+ *;
;+};

View File

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

View File

@@ -387,19 +387,12 @@ CK_RV NSC_GetInterface(CK_UTF8CHAR_PTR pInterfaceName,
char **NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args);
#endif
/*
* load a new module into our address space and initialize it.
*/
SECStatus
secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
secmod_DetermineModuleFunctionList(SECMODModule *mod)
{
PRLibrary *library = NULL;
CK_C_GetInterface ientry = NULL;
CK_C_GetFunctionList fentry = NULL;
CK_INFO info;
CK_ULONG slotCount = 0;
SECStatus rv;
PRBool alreadyLoaded = PR_FALSE;
char *disableUnload = NULL;
#ifndef NSS_STATIC_SOFTOKEN
const char *nss_interface;
@@ -407,11 +400,6 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
#endif
CK_INTERFACE_PTR interface;
if (mod->loaded)
return SECSuccess;
mod->fipsIndicator = NULL;
/* internal modules get loaded from their internal list */
if (mod->internal && (mod->dllName == NULL)) {
#ifdef NSS_STATIC_SOFTOKEN
@@ -553,6 +541,25 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
}
#endif
return SECSuccess;
fail:
mod->functionList = NULL;
disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
if (library && !disableUnload) {
PR_UnloadLibrary(library);
}
return SECFailure;
}
SECStatus
secmod_InitializeModuleAndGetSlotInfo(SECMODModule *mod, SECMODModule **oldModule)
{
CK_INFO info;
CK_ULONG slotCount = 0;
SECStatus rv;
PRBool alreadyLoaded = PR_FALSE;
/* This test operation makes sure our locking system is
* consistent even if we are using non-thread safe tokens by
* simulating unsafe tokens with safe ones. */
@@ -643,13 +650,80 @@ fail2:
}
fail:
mod->functionList = NULL;
disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
if (library && !disableUnload) {
PR_UnloadLibrary(library);
}
return SECFailure;
}
/*
* load a new module into our address space and initialize it.
*/
SECStatus
secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
{
SECStatus rv = SECFailure;
if (mod->loaded) {
return SECSuccess;
}
mod->fipsIndicator = NULL;
rv = secmod_DetermineModuleFunctionList(mod);
if (rv != SECSuccess) { // The error code is set up by secmod_DetermineModuleFunctionList.
return rv;
}
if (mod->loaded == PR_TRUE) {
return SECSuccess;
}
rv = secmod_InitializeModuleAndGetSlotInfo(mod, oldModule);
if (rv != SECSuccess) { // The error code is set up by secmod_InitializeModuleAndGetSlotInfo
return rv;
}
return SECSuccess;
}
/*
* load a new module using provided fentry function
*/
SECStatus
secmod_LoadPKCS11ModuleFromFunction(SECMODModule *mod, SECMODModule **oldModule,
CK_C_GetFunctionList fentry)
{
SECStatus rv = SECFailure;
CK_RV crv;
if (mod->loaded) {
return SECSuccess;
}
mod->fipsIndicator = NULL;
if (!fentry) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
crv = fentry((CK_FUNCTION_LIST_PTR *)&mod->functionList);
if (crv != CKR_OK) {
mod->functionList = NULL;
PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
if (mod->functionList == NULL) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
mod->flags = 0;
rv = secmod_InitializeModuleAndGetSlotInfo(mod, oldModule);
if (rv != SECSuccess) {
return rv;
}
return SECSuccess;
}
SECStatus
SECMOD_UnloadModule(SECMODModule *mod)
{
@@ -692,9 +766,9 @@ SECMOD_UnloadModule(SECMODModule *mod)
}
library = (PRLibrary *)mod->library;
/* paranoia */
/* if no library, then we should not unload it */
if (library == NULL) {
return SECFailure;
return SECSuccess;
}
disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");

View File

@@ -1719,10 +1719,19 @@ PK11_ParamToAlgid(SECOidTag algTag, SECItem *param,
case CKM_JUNIPER_CBC128:
case CKM_JUNIPER_COUNTER:
case CKM_JUNIPER_SHUFFLE:
if (param && param->len > 0) {
newParams = SEC_ASN1EncodeItem(NULL, NULL, param,
SEC_ASN1_GET(SEC_OctetStringTemplate));
if (newParams == NULL)
break;
} else {
/* if no parameters have been supplied, then use NULL params
* The SECOID_SetAlgorithmID encoder will encode that as no
* params (since params are optional) or with an explicit NULL
* (for some historical cases where explicit NULL is expected).
*/
newParams = NULL;
}
rv = SECSuccess;
break;
}

View File

@@ -2240,6 +2240,72 @@ loser:
return module;
}
SECMODModule *
SECMOD_LoadModuleWithFunction(const char *moduleName, CK_C_GetFunctionList fentry)
{
SECMODModule *module = NULL;
SECMODModule *oldModule = NULL;
SECStatus rv;
/* initialize the underlying module structures */
SECMOD_Init();
module = secmod_NewModule();
if (module == NULL) {
goto loser;
}
module->commonName = PORT_ArenaStrdup(module->arena, moduleName ? moduleName : "");
module->internal = PR_FALSE;
module->isFIPS = PR_FALSE;
/* if the system FIPS mode is enabled, force FIPS to be on */
if (SECMOD_GetSystemFIPSEnabled()) {
module->isFIPS = PR_TRUE;
}
module->isCritical = PR_FALSE;
/* new field */
module->trustOrder = NSSUTIL_DEFAULT_TRUST_ORDER;
/* new field */
module->cipherOrder = NSSUTIL_DEFAULT_CIPHER_ORDER;
/* new field */
module->isModuleDB = PR_FALSE;
module->moduleDBOnly = PR_FALSE;
module->ssl[0] = 0;
module->ssl[1] = 0;
secmod_PrivateModuleCount++;
/* load it */
rv = secmod_LoadPKCS11ModuleFromFunction(module, &oldModule, fentry);
if (rv != SECSuccess) {
goto loser;
}
/* if we just reload an old module, no need to add it to any lists.
* we simple release all our references */
if (oldModule) {
/* This module already exists, don't link it anywhere. This
* will probably destroy this module */
SECMOD_DestroyModule(module);
return oldModule;
}
SECMOD_AddModuleToList(module);
/* handle any additional work here */
return module;
loser:
if (module) {
if (module->loaded) {
SECMOD_UnloadModule(module);
}
SECMOD_AddModuleToUnloadList(module);
}
return module;
}
/*
* load a PKCS#11 module and add it to the default NSS trust domain
*/
@@ -2262,6 +2328,25 @@ SECMOD_LoadUserModule(char *modulespec, SECMODModule *parent, PRBool recurse)
return newmod;
}
SECMODModule *
SECMOD_LoadUserModuleWithFunction(const char *moduleName, CK_C_GetFunctionList fentry)
{
SECStatus rv = SECSuccess;
SECMODModule *newmod = SECMOD_LoadModuleWithFunction(moduleName, fentry);
SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
if (newmod) {
SECMOD_GetReadLock(moduleLock);
rv = STAN_AddModuleToDefaultTrustDomain(newmod);
SECMOD_ReleaseReadLock(moduleLock);
if (SECSuccess != rv) {
SECMOD_DestroyModule(newmod);
return NULL;
}
}
return newmod;
}
/*
* remove the PKCS#11 module from the default NSS trust domain, call
* C_Finalize, and destroy the module structure

View File

@@ -770,9 +770,10 @@ sec_pkcs5CreateAlgorithmID(SECOidTag algorithm,
algorithm = sec_pkcs5v2_get_pbe(cipherAlgorithm);
}
SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm);
/* set the PKCS5v2 specific parameters */
if (keyLength == 0) {
SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm);
if (hashAlg != SEC_OID_UNKNOWN) {
keyLength = HASH_ResultLenByOidTag(hashAlg);
} else {
@@ -787,18 +788,25 @@ sec_pkcs5CreateAlgorithmID(SECOidTag algorithm,
prfAlg = SEC_OID_HMAC_SHA1;
}
/* build the PKCS5v2 cipher algorithm id */
/* build the PKCS5v2 cipher algorithm id, if cipher
* is an HMAC, the cipherParams should be NULL */
if (hashAlg == SEC_OID_UNKNOWN) {
cipherParams = pk11_GenerateNewParamWithKeyLen(
PK11_AlgtagToMechanism(cipherAlgorithm), keyLength);
if (!cipherParams) {
goto loser;
}
} else {
cipherParams = NULL;
}
PORT_Memset(&pbeV2_param, 0, sizeof(pbeV2_param));
rv = PK11_ParamToAlgid(cipherAlgorithm, cipherParams,
poolp, &pbeV2_param.cipherAlgId);
if (cipherParams) {
SECITEM_FreeItem(cipherParams, PR_TRUE);
}
if (rv != SECSuccess) {
goto loser;
}

View File

@@ -6,6 +6,7 @@
#include "seccomon.h"
#include "secmodt.h"
#include "prinrval.h"
#include "pkcs11.h"
/* These mechanisms flags are visible to all other libraries. */
/* They must be converted to internal SECMOD_*_FLAG */
@@ -60,6 +61,9 @@ extern SECMODModule *SECMOD_LoadModule(char *moduleSpec, SECMODModule *parent,
extern SECMODModule *SECMOD_LoadUserModule(char *moduleSpec, SECMODModule *parent,
PRBool recurse);
extern SECMODModule *SECMOD_LoadUserModuleWithFunction(const char *moduleName,
CK_C_GetFunctionList fentry);
SECStatus SECMOD_UnloadUserModule(SECMODModule *mod);
SECMODModule *SECMOD_CreateModule(const char *lib, const char *name,

View File

@@ -57,6 +57,8 @@ extern unsigned long SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags
/* Library functions */
SECStatus secmod_LoadPKCS11Module(SECMODModule *, SECMODModule **oldModule);
SECStatus secmod_LoadPKCS11ModuleFromFunction(SECMODModule *, SECMODModule **oldModule, CK_C_GetFunctionList f);
SECStatus SECMOD_UnloadModule(SECMODModule *);
void SECMOD_SetInternalModule(SECMODModule *);
PRBool secmod_IsInternalKeySlot(SECMODModule *);

View File

@@ -1918,7 +1918,7 @@ sec_pkcs12_set_nickname_for_cert(sec_PKCS12SafeBag *cert,
static SECItem *
sec_pkcs12_get_der_cert(sec_PKCS12SafeBag *cert)
{
if (!cert) {
if (!cert || !cert->safeBagContent.certBag) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
@@ -3179,6 +3179,12 @@ SEC_PKCS12DecoderIterateNext(SEC_PKCS12DecoderContext *p12dcx,
p12dcx->decitem.der = sec_pkcs12_get_der_cert(bag);
p12dcx->decitem.friendlyName = sec_pkcs12_get_friendlyName(bag);
p12dcx->decitem.hasKey = sec_pkcs12_bagHasKey(p12dcx, bag);
/* if we don't understand the cert, or it's not parsable, skip it */
/* as per the comment above, friendlyName may be null legitimately */
if (!p12dcx->decitem.der) {
p12dcx->decitem.type = 0; /* clear out the type we are ignoring */
continue;
}
break;
case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
p12dcx->decitem.shroudAlg = PORT_ZNew(SECAlgorithmID);
@@ -3195,6 +3201,7 @@ SEC_PKCS12DecoderIterateNext(SEC_PKCS12DecoderContext *p12dcx,
break;
case SEC_OID_UNKNOWN:
/* ignore these */
p12dcx->decitem.type = 0; /* clear out the type we are ignoring */
continue;
}
*ipp = &p12dcx->decitem;

View File

@@ -102,7 +102,7 @@ sec_pkcs12_integrity_key(PK11SlotInfo *slot, sec_PKCS12MacData *macData,
*hmacMech = PK11_AlgtagToMechanism(hmacAlg);
/* pkcs12v2 hmac uses UTF8 rather than unicode */
if (!sec_pkcs12_convert_item_to_unicode(NULL, &utf8Pw, pwitem,
PR_TRUE, PR_FALSE, PR_FALSE)) {
PR_FALSE, PR_FALSE, PR_FALSE)) {
return NULL;
}
symKey = PK11_PBEKeyGen(slot, prfAlgid, &utf8Pw, PR_FALSE, pwarg);

View File

@@ -520,6 +520,8 @@ CERT_DecodeCertFromPackage(char *certbuf, int certlen)
CERTCertificate *cert = NULL;
collectArgs.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
collectArgs.cert.data = NULL;
collectArgs.cert.len = 0;
rv = CERT_DecodeCertPackage(certbuf, certlen, collect_certs,
(void *)&collectArgs);

View File

@@ -1765,16 +1765,20 @@ sftk_fips_pbkdf_PowerUpSelfTests(void)
unsigned char iteration_count = 5;
unsigned char keyLen = 64;
char *inKeyData = TEST_KEY;
static const unsigned char saltData[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
static const unsigned char saltData[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
static const unsigned char pbkdf_known_answer[] = {
0x31, 0xf0, 0xe5, 0x39, 0x9f, 0x39, 0xb9, 0x29,
0x68, 0xac, 0xf2, 0xe9, 0x53, 0x9b, 0xb4, 0x9c,
0x28, 0x59, 0x8b, 0x5c, 0xd8, 0xd4, 0x02, 0x37,
0x18, 0x22, 0xc1, 0x92, 0xd0, 0xfa, 0x72, 0x90,
0x2c, 0x8d, 0x19, 0xd4, 0x56, 0xfb, 0x16, 0xfa,
0x8d, 0x5c, 0x06, 0x33, 0xd1, 0x5f, 0x17, 0xb1,
0x22, 0xd9, 0x9c, 0xaf, 0x5e, 0x3f, 0xf3, 0x66,
0xc6, 0x14, 0xfe, 0x83, 0xfa, 0x1a, 0x2a, 0xc5
0x73, 0x8c, 0xfa, 0x02, 0xe8, 0xdb, 0x43, 0xe4,
0x99, 0xc5, 0xfd, 0xd9, 0x4d, 0x8e, 0x3e, 0x7b,
0xc4, 0xda, 0x22, 0x1b, 0xe1, 0xae, 0x23, 0x7a,
0x21, 0x27, 0xbd, 0xcc, 0x78, 0xc4, 0xe6, 0xc5,
0x33, 0x38, 0x35, 0xe0, 0x68, 0x1a, 0x1e, 0x06,
0xad, 0xaf, 0x7f, 0xd7, 0x3f, 0x0e, 0xc0, 0x90,
0x17, 0x97, 0x73, 0x75, 0x7b, 0x88, 0x49, 0xd8,
0x6f, 0x78, 0x5a, 0xde, 0x50, 0x20, 0x55, 0x33
};
sftk_PBELockInit();

View File

@@ -3211,14 +3211,15 @@ SFTK_DestroySlotData(SFTKSlot *slot)
char **
NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args)
{
#ifndef NSS_DISABLE_DBM
#ifdef NSS_DISABLE_DBM
return NSSUTIL_DoModuleDBFunction(function, parameters, args);
#else
char *secmod = NULL;
char *appName = NULL;
char *filename = NULL;
NSSDBType dbType = NSS_DB_TYPE_NONE;
PRBool rw;
static char *success = "Success";
#endif /* NSS_DISABLE_DBM */
char **rvstr = NULL;
rvstr = NSSUTIL_DoModuleDBFunction(function, parameters, args);
@@ -3230,7 +3231,6 @@ NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args)
return NULL;
}
#ifndef NSS_DISABLE_DBM
/* The legacy database uses the old dbm, which is only linked with the
* legacy DB handler, which is only callable from softoken */
@@ -3322,8 +3322,8 @@ loser:
PORT_Free(appName);
if (filename)
PORT_Free(filename);
#endif /* NSS_DISABLE_DBM */
return rvstr;
#endif /* NSS_DISABLE_DBM */
}
static void

View File

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

View File

@@ -107,6 +107,9 @@ HASH_GetHashOidTagByHMACOidTag(SECOidTag hmacOid)
switch (hmacOid) {
/* no oid exists for HMAC_MD2 */
/* NSS does not define a oid for HMAC_MD4 */
case SEC_OID_HMAC_MD5:
hashOid = SEC_OID_MD5;
break;
case SEC_OID_HMAC_SHA1:
hashOid = SEC_OID_SHA1;
break;
@@ -150,6 +153,9 @@ HASH_GetHMACOidTagByHashOidTag(SECOidTag hashOid)
switch (hashOid) {
/* no oid exists for HMAC_MD2 */
/* NSS does not define a oid for HMAC_MD4 */
case SEC_OID_MD5:
hmacOid = SEC_OID_HMAC_MD5;
break;
case SEC_OID_SHA1:
hmacOid = SEC_OID_HMAC_SHA1;
break;

View File

@@ -372,3 +372,9 @@ NSS_SetAlgorithmPolicyAll;
;+ local:
;+ *;
;+};
;+NSSUTIL_3.108 { # NSS Utilities 3.108 release
;+ global:
PORT_SafeZero;
;+ local:
;+ *;
;+};

View File

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

View File

@@ -2274,6 +2274,11 @@ SECOID_FindOID(const SECItem *oid)
return NULL;
}
if ((oid == NULL) || (oid->data == NULL)) {
PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID);
return NULL;
}
ret = PL_HashTableLookupConst(oidhash, oid);
if (ret == NULL) {
ret = secoid_FindDynamic(oid);

View File

@@ -209,6 +209,44 @@ PORT_GetError(void)
return (PR_GetError());
}
void
PORT_SafeZero(void *p, size_t n)
{
/* there are cases where the compiler optimizes away our attempt to clear
* out our stack variables. There are multiple solutions for this problem,
* but they aren't universally accepted on all platforms. This attempts
* to select the best solution available given our os, compilier, and
* libc */
#ifdef __STDC_LIB_EXT1__
/* if the os implements C11 annex K, use memset_s */
memset_s(p, n, 0, n);
#else
/* _DEFAULT_SORUCE == BSD source in GCC based environments
* if other environmens support explicit_bzero, their defines
* should be added here */
#if (defined(_DEFAULT_SOURCE) || defined(_BSD_SOURCE)) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
explicit_bzero(p, n);
#else
#ifdef XP_WIN
/* windows has a secure zero funtion */
SecureZeroMemory(p, n);
#else
/* if the os doesn't support one of the above, but does support
* memset_explicit, you can add the definition for memset with the
* appropriate define check here */
/* define an explicitly implementated Safe zero if the OS
* doesn't provide one */
if (p != NULL) {
volatile unsigned char *__vl = (unsigned char *)p;
size_t __nl = n;
while (__nl--)
*__vl++ = 0;
}
#endif /* no windows SecureZeroMemory */
#endif /* no explicit_bzero */
#endif /* no memset_s */
}
/********************* Arena code follows *****************************
* ArenaPools are like heaps. The memory in them consists of large blocks,
* called arenas, which are allocated from the/a system heap. Inside an

View File

@@ -36,6 +36,9 @@
#include <sys/types.h>
#include <ctype.h>
/* ask for Annex K for memset_s. will set the appropriate #define
* if Annex K is supported */
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
@@ -255,6 +258,7 @@ sec_port_iso88591_utf8_conversion_function(
extern int NSS_PutEnv(const char *envVarName, const char *envValue);
extern void PORT_SafeZero(void *p, size_t n);
extern int NSS_SecureMemcmp(const void *a, const void *b, size_t n);
extern unsigned int NSS_SecureMemcmpZero(const void *mem, size_t n);
extern void NSS_SecureSelect(void *dest, const void *src0, const void *src1, size_t n, unsigned char b);

View File

@@ -308,6 +308,7 @@ nssutil_growList(char ***pModuleList, int *useCount, int last)
return SECSuccess;
}
#ifndef NSS_DISABLE_DBM
static char *
_NSSUTIL_GetOldSecmodName(const char *dbname, const char *filename)
{
@@ -332,6 +333,7 @@ _NSSUTIL_GetOldSecmodName(const char *dbname, const char *filename)
PORT_Free(dirPath);
return file;
}
#endif // NSS_DISABLE_DBM
static SECStatus nssutil_AddSecmodDBEntry(const char *appName,
const char *filename,
@@ -567,6 +569,7 @@ nssutil_ReadSecmodDB(const char *appName,
moduleString = NULL;
}
done:
#ifndef NSS_DISABLE_DBM
/* if we couldn't open a pkcs11 database, look for the old one */
if (fd == NULL) {
char *olddbname = _NSSUTIL_GetOldSecmodName(dbname, filename);
@@ -591,6 +594,7 @@ done:
PR_smprintf_free(olddbname);
}
}
#endif // NSS_DISABLE_DBM
return_default:

View File

@@ -213,7 +213,7 @@ class covAction(argparse.Action):
# Don't exit immediately on error
symbol_retcode = subprocess.call([
"sancov",
"-blacklist=" + os.path.join(cwd, ".sancov-blacklist"),
"-ignorelist=" + os.path.join(cwd, ".sancov-blacklist"),
"-symbolize", sancov_file,
os.path.join(cwd, "../dist/Debug/bin/ssl_gtest")
], stdout=out)

View File

@@ -315,7 +315,7 @@
'target_name': 'fuzz',
'type': 'none',
'dependencies': [
'fuzz/fuzz.gyp:nssfuzz',
'fuzz/fuzz.gyp:fuzz',
],
},
],

View File

@@ -21,7 +21,7 @@ name=`basename $request .req`
echo ">>>>> $name"
sed -e 's;
;;g' -e 's; ; ;g' -e '/^#/d' $extraneous_response ${TESTDIR}/resp/${name}.rsp > /tmp/y1
# if we didn't generate any output, flag that as an error
# if we didn't generate any output, flag that as an error
size=`sum /tmp/y1 | awk '{ print $1 }'`
if [ $size -eq 0 ]; then
echo "${TESTDIR}/resp/${name}.rsp: empty"

View File

@@ -65,11 +65,6 @@ gtest_start()
pushd "$DIR"
GTESTREPORT="$DIR/report.xml"
PARSED_REPORT="$DIR/report.parsed"
# The mozilla::pkix gtests cause an ODR violation that we ignore.
# See bug 1588567.
if [ "$i" = "mozpkix_gtest" ]; then
EXTRA_ASAN_OPTIONS="detect_odr_violation=0"
fi
# NSS CI sets a lower max for PBE iterations, otherwise cert.sh
# is very slow. Unset this maxiumum for softoken_gtest, as it
# needs to check the default value.
@@ -78,9 +73,8 @@ gtest_start()
unset NSS_MAX_MP_PBE_ITERATION_COUNT
fi
echo "executing $i"
ASAN_OPTIONS="$ASAN_OPTIONS:$EXTRA_ASAN_OPTIONS" "${BINDIR}/$i" \
-s "${SOURCE_DIR}/gtests/$i" \
-d "$DIR" -w --gtest_output=xml:"${GTESTREPORT}" \
"${BINDIR}/$i" -s "${SOURCE_DIR}/gtests/$i" -d "$DIR" -w \
--gtest_output=xml:"${GTESTREPORT}" \
--gtest_filter="${GTESTFILTER:-*}"
html_msg $? 0 "$i run successfully"
if [ "$i" = "softoken_gtest" ]; then

View File

@@ -56,7 +56,7 @@ tlsfuzzer_init()
# Install tlslite-ng dependencies
${QADIR}/../fuzz/config/git-copy.sh https://github.com/warner/python-ecdsa master python-ecdsa
${QADIR}/../fuzz/config/git-copy.sh https://github.com/benjaminp/six master six
${QADIR}/../fuzz/config/git-copy.sh https://github.com/benjaminp/six main six
pushd "$TLSFUZZER"
ln -s ../python-ecdsa/src/ecdsa ecdsa

View File

@@ -127,6 +127,7 @@ tools_init()
cp ${QADIR}/tools/pbmac1-invalid-bad-iter.p12 ${TOOLSDIR}/data
cp ${QADIR}/tools/pbmac1-invalid-bad-salt.p12 ${TOOLSDIR}/data
cp ${QADIR}/tools/pbmac1-invalid-no-length.p12 ${TOOLSDIR}/data
cp ${QADIR}/tools/corrupted_cert_bag.p12 ${TOOLSDIR}/data
cd ${TOOLSDIR}
}
@@ -501,6 +502,12 @@ tools_p12_import_old_files()
html_msg $ret 0 "Importing PKCS#12 file with and implicit KDF value"
check_tmpfile
echo "pk12util -I -l corrupted_cert_bag.p12 -W start"
${BINDIR}/pk12util -I -l ${TOOLSDIR}/data/corrupted_cert_bag.p12 -W start 2>&1
ret=$?
html_msg $ret 17 "Listing a PKCS#12 file with corrupted certificate bag"
check_tmpfile
}
tools_p12_import_rsa_pss_private_key()
@@ -541,24 +548,24 @@ tools_p12_import_pbmac1_samples()
html_msg $ret 0 "Importing private key pbmac1 hmac-sha-512 from PKCS#12 file"
check_tmpfile
echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-iter.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234'"
${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-iter.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' 2>&1
echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-iter.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I"
${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-iter.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I 2>&1
ret=$?
html_msg $ret 17 "Fail to list private key with bad iterator"
html_msg $ret 19 "Fail to list private key with bad iterator"
check_tmpfile
echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-salt.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234'"
${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-salt.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' 2>&1
echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-salt.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I"
${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-salt.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I 2>&1
ret=$?
echo "Fail to list private key with bad salt val=$ret"
html_msg $ret 17 "Fail to import private key with bad salt"
html_msg $ret 19 "Fail to import private key with bad salt"
check_tmpfile
echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-no-length.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234'"
${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-no-length.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' 2>&1
echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-no-length.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I "
${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-no-length.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I 2>&1
ret=$?
echo "Fail to import private key with no length val=$ret"
html_msg $ret 17 "Fail to import private key with no length"
html_msg $ret 19 "Fail to import private key with no length"
check_tmpfile
}