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:
@@ -13,7 +13,7 @@ system_lib_option(
|
|||||||
imply_option("--with-system-nspr", True, when="--with-system-nss")
|
imply_option("--with-system-nspr", True, when="--with-system-nss")
|
||||||
|
|
||||||
nss_pkg = pkg_check_modules(
|
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")
|
set_config("MOZ_SYSTEM_NSS", True, when="--with-system-nss")
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
NSS_3_107_RTM
|
NSS_3_108_BETA1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
1 Added function:
|
||||||
|
|
||||||
|
'function SECMODModule* SECMOD_LoadUserModuleWithFunction(const char*, CK_C_GetFunctionList)' {SECMOD_LoadUserModuleWithFunction@@NSS_3.107}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
1 Added function:
|
||||||
|
|
||||||
|
'function void PORT_SafeZero(void*, size_t)' {PORT_SafeZero@@NSSUTIL_3.108}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
NSS_3_106_BRANCH
|
NSS_3_107_BRANCH
|
||||||
|
|||||||
@@ -218,6 +218,7 @@ export default async function main() {
|
|||||||
NSS_DISABLE_UNLOAD: "1",
|
NSS_DISABLE_UNLOAD: "1",
|
||||||
CC: "clang",
|
CC: "clang",
|
||||||
CCC: "clang++",
|
CCC: "clang++",
|
||||||
|
CFLAGS: "-O2",
|
||||||
},
|
},
|
||||||
platform: "linux64",
|
platform: "linux64",
|
||||||
collection: "asan",
|
collection: "asan",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ source $(dirname "$0")/tools.sh
|
|||||||
export CRYPTOFUZZ_VERSION="687d3064c5cef2b0fe1f30824065a2f2c9c0bbd8"
|
export CRYPTOFUZZ_VERSION="687d3064c5cef2b0fe1f30824065a2f2c9c0bbd8"
|
||||||
export BOTAN_VERSION="3.6.1"
|
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 -C cryptofuzz checkout "$CRYPTOFUZZ_VERSION"
|
||||||
|
|
||||||
git clone -q https://github.com/randombit/botan.git
|
git clone -q https://github.com/randombit/botan.git
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ popd
|
|||||||
./cryptofuzz/generate_dict
|
./cryptofuzz/generate_dict
|
||||||
|
|
||||||
# Run Cryptofuzz.
|
# 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.
|
# Alert if version is older than half a year.
|
||||||
cryptofuzz_timestamp=$(git -C cryptofuzz show -s --format=%ct $CRYPTOFUZZ_VERSION)
|
cryptofuzz_timestamp=$(git -C cryptofuzz show -s --format=%ct $CRYPTOFUZZ_VERSION)
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ while [ $# -gt 0 ]; do
|
|||||||
--fuzz) fuzz=1 ;;
|
--fuzz) fuzz=1 ;;
|
||||||
--fuzz=oss) fuzz=1; fuzz_oss=1 ;;
|
--fuzz=oss) fuzz=1; fuzz_oss=1 ;;
|
||||||
--fuzz=tls) fuzz=1; fuzz_tls=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; gyp_params+=(-Dcoverage=1) ;;
|
||||||
--sancov=?*) enable_sancov "${1#*=}"; gyp_params+=(-Dcoverage=1) ;;
|
--sancov=?*) enable_sancov "${1#*=}"; gyp_params+=(-Dcoverage=1) ;;
|
||||||
--emit-llvm) gyp_params+=(-Demit_llvm=1 -Dsign_libs=0) ;;
|
--emit-llvm) gyp_params+=(-Demit_llvm=1 -Dsign_libs=0) ;;
|
||||||
|
|||||||
@@ -32,12 +32,12 @@ static void
|
|||||||
Usage()
|
Usage()
|
||||||
{
|
{
|
||||||
#define FPS PR_fprintf(PR_STDERR,
|
#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);
|
progName);
|
||||||
FPS "\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
|
FPS "\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
|
||||||
FPS "\t\t [-v]\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);
|
progName);
|
||||||
FPS "\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
|
FPS "\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
|
||||||
FPS "\t\t [-v]\n");
|
FPS "\t\t [-v]\n");
|
||||||
@@ -351,7 +351,8 @@ P12U_InitSlot(PK11SlotInfo *slot, secuPWData *slotPw)
|
|||||||
*/
|
*/
|
||||||
SEC_PKCS12DecoderContext *
|
SEC_PKCS12DecoderContext *
|
||||||
p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot,
|
p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot,
|
||||||
secuPWData *slotPw, secuPWData *p12FilePw)
|
secuPWData *slotPw, secuPWData *p12FilePw,
|
||||||
|
PRBool ignoreIntegrity)
|
||||||
{
|
{
|
||||||
SEC_PKCS12DecoderContext *p12dcx = NULL;
|
SEC_PKCS12DecoderContext *p12dcx = NULL;
|
||||||
p12uContext *p12cxt = NULL;
|
p12uContext *p12cxt = NULL;
|
||||||
@@ -458,7 +459,10 @@ p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot,
|
|||||||
/* rv has been set at this point */
|
/* rv has been set at this point */
|
||||||
|
|
||||||
done:
|
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) {
|
if (p12dcx != NULL) {
|
||||||
SEC_PKCS12DecoderFinish(p12dcx);
|
SEC_PKCS12DecoderFinish(p12dcx);
|
||||||
p12dcx = NULL;
|
p12dcx = NULL;
|
||||||
@@ -490,7 +494,8 @@ done:
|
|||||||
*/
|
*/
|
||||||
PRIntn
|
PRIntn
|
||||||
P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot,
|
P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot,
|
||||||
secuPWData *slotPw, secuPWData *p12FilePw)
|
secuPWData *slotPw, secuPWData *p12FilePw,
|
||||||
|
PRBool ignoreIntegrity)
|
||||||
{
|
{
|
||||||
SEC_PKCS12DecoderContext *p12dcx = NULL;
|
SEC_PKCS12DecoderContext *p12dcx = NULL;
|
||||||
SECItem uniPwitem = { 0 };
|
SECItem uniPwitem = { 0 };
|
||||||
@@ -509,7 +514,8 @@ P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot,
|
|||||||
do {
|
do {
|
||||||
trypw = PR_FALSE; /* normally we do this once */
|
trypw = PR_FALSE; /* normally we do this once */
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, p12FilePw);
|
p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw,
|
||||||
|
p12FilePw, ignoreIntegrity);
|
||||||
|
|
||||||
if (p12dcx == NULL) {
|
if (p12dcx == NULL) {
|
||||||
goto loser;
|
goto loser;
|
||||||
@@ -777,14 +783,16 @@ loser:
|
|||||||
|
|
||||||
PRIntn
|
PRIntn
|
||||||
P12U_ListPKCS12File(char *in_file, PK11SlotInfo *slot,
|
P12U_ListPKCS12File(char *in_file, PK11SlotInfo *slot,
|
||||||
secuPWData *slotPw, secuPWData *p12FilePw)
|
secuPWData *slotPw, secuPWData *p12FilePw,
|
||||||
|
PRBool ignoreIntegrity)
|
||||||
{
|
{
|
||||||
SEC_PKCS12DecoderContext *p12dcx = NULL;
|
SEC_PKCS12DecoderContext *p12dcx = NULL;
|
||||||
SECItem uniPwitem = { 0 };
|
SECItem uniPwitem = { 0 };
|
||||||
SECStatus rv = SECFailure;
|
SECStatus rv = SECFailure;
|
||||||
const SEC_PKCS12DecoderItem *dip;
|
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? */
|
/* did the blob authenticate properly? */
|
||||||
if (p12dcx == NULL) {
|
if (p12dcx == NULL) {
|
||||||
SECU_PrintError(progName, "PKCS12 decode not verified");
|
SECU_PrintError(progName, "PKCS12 decode not verified");
|
||||||
@@ -997,7 +1005,8 @@ enum {
|
|||||||
opt_CertCipher,
|
opt_CertCipher,
|
||||||
opt_KeyLength,
|
opt_KeyLength,
|
||||||
opt_CertKeyLength,
|
opt_CertKeyLength,
|
||||||
opt_Mac
|
opt_Mac,
|
||||||
|
opt_IgnoreIntegrity
|
||||||
};
|
};
|
||||||
|
|
||||||
static secuCommandFlag pk12util_options[] = {
|
static secuCommandFlag pk12util_options[] = {
|
||||||
@@ -1018,7 +1027,8 @@ static secuCommandFlag pk12util_options[] = {
|
|||||||
{ /* opt_CertCipher */ 'C', PR_TRUE, 0, PR_FALSE },
|
{ /* opt_CertCipher */ 'C', PR_TRUE, 0, PR_FALSE },
|
||||||
{ /* opt_KeyLength */ 'm', PR_TRUE, 0, PR_FALSE, "key_len" },
|
{ /* opt_KeyLength */ 'm', PR_TRUE, 0, PR_FALSE, "key_len" },
|
||||||
{ /* opt_CertKeyLength */ 0, PR_TRUE, 0, PR_FALSE, "cert_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
|
int
|
||||||
@@ -1039,6 +1049,7 @@ main(int argc, char **argv)
|
|||||||
int certKeyLen = 0;
|
int certKeyLen = 0;
|
||||||
secuCommand pk12util;
|
secuCommand pk12util;
|
||||||
PRInt32 forceUnicode;
|
PRInt32 forceUnicode;
|
||||||
|
PRBool ignoreIntegrity = PR_FALSE;
|
||||||
|
|
||||||
#ifdef _CRTDBG_MAP_ALLOC
|
#ifdef _CRTDBG_MAP_ALLOC
|
||||||
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
||||||
@@ -1113,6 +1124,9 @@ main(int argc, char **argv)
|
|||||||
if (pk12util.options[opt_Raw].activated) {
|
if (pk12util.options[opt_Raw].activated) {
|
||||||
dumpRawFile = PR_TRUE;
|
dumpRawFile = PR_TRUE;
|
||||||
}
|
}
|
||||||
|
if (pk12util.options[opt_IgnoreIntegrity].activated) {
|
||||||
|
ignoreIntegrity = PR_TRUE;
|
||||||
|
}
|
||||||
if (pk12util.options[opt_KeyLength].activated) {
|
if (pk12util.options[opt_KeyLength].activated) {
|
||||||
keyLen = atoi(pk12util.options[opt_KeyLength].arg);
|
keyLen = atoi(pk12util.options[opt_KeyLength].arg);
|
||||||
}
|
}
|
||||||
@@ -1183,7 +1197,8 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pk12util.options[opt_Import].activated) {
|
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) {
|
} else if (pk12util.options[opt_Export].activated) {
|
||||||
P12U_ExportPKCS12Object(pk12util.options[opt_Nickname].arg,
|
P12U_ExportPKCS12Object(pk12util.options[opt_Nickname].arg,
|
||||||
@@ -1191,7 +1206,8 @@ main(int argc, char **argv)
|
|||||||
hash, &slotPw, &p12FilePw);
|
hash, &slotPw, &p12FilePw);
|
||||||
|
|
||||||
} else if (pk12util.options[opt_List].activated) {
|
} else if (pk12util.options[opt_List].activated) {
|
||||||
P12U_ListPKCS12File(import_file, slot, &slotPw, &p12FilePw);
|
P12U_ListPKCS12File(import_file, slot, &slotPw, &p12FilePw,
|
||||||
|
ignoreIntegrity);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Usage();
|
Usage();
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
'dependencies': [
|
'dependencies': [
|
||||||
'<(DEPTH)/exports.gyp:dbm_exports',
|
'<(DEPTH)/exports.gyp:dbm_exports',
|
||||||
'<(DEPTH)/exports.gyp:nss_exports',
|
'<(DEPTH)/exports.gyp:nss_exports',
|
||||||
'<(DEPTH)/lib/ssl/ssl.gyp:ssl',
|
|
||||||
'<(DEPTH)/lib/zlib/zlib.gyp:nss_zlib'
|
'<(DEPTH)/lib/zlib/zlib.gyp:nss_zlib'
|
||||||
],
|
],
|
||||||
'include_dirs': [
|
'include_dirs': [
|
||||||
|
|||||||
@@ -125,6 +125,7 @@
|
|||||||
'fuzz%': 0,
|
'fuzz%': 0,
|
||||||
'fuzz_tls%': 0,
|
'fuzz_tls%': 0,
|
||||||
'fuzz_oss%': 0,
|
'fuzz_oss%': 0,
|
||||||
|
'gtests_corpus%': 0,
|
||||||
'sign_libs%': 1,
|
'sign_libs%': 1,
|
||||||
'use_pprof%': 0,
|
'use_pprof%': 0,
|
||||||
'ct_verif%': 0,
|
'ct_verif%': 0,
|
||||||
|
|||||||
@@ -10,4 +10,3 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#error "Do not include this header file."
|
#error "Do not include this header file."
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
<arg>-P dbprefix</arg>
|
<arg>-P dbprefix</arg>
|
||||||
<arg>-r</arg>
|
<arg>-r</arg>
|
||||||
<arg>-v</arg>
|
<arg>-v</arg>
|
||||||
|
<arg>-I</arg>
|
||||||
<arg>--cert-key-len certKeyLength</arg>
|
<arg>--cert-key-len certKeyLength</arg>
|
||||||
<arg>-k slotPasswordFile|-K slotPassword</arg>
|
<arg>-k slotPasswordFile|-K slotPassword</arg>
|
||||||
<arg>-w p12filePasswordFile|-W p12filePassword</arg>
|
<arg>-w p12filePasswordFile|-W p12filePassword</arg>
|
||||||
@@ -146,6 +147,11 @@
|
|||||||
<listitem><para>Enable debug logging when importing.</para></listitem>
|
<listitem><para>Enable debug logging when importing.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>-I </term>
|
||||||
|
<listitem><para>Ignore integrity check results on importing and listing.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>-w p12filePasswordFile</term>
|
<term>-w p12filePasswordFile</term>
|
||||||
<listitem><para>Specify the text file containing the pkcs #12 file password.</para></listitem>
|
<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">
|
<refsection id="encryption">
|
||||||
<title>Password Encryption</title>
|
<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>The private key is always protected with strong encryption by default.</para>
|
||||||
<para>Several types of ciphers are supported.</para>
|
<para>Several types of ciphers are supported.</para>
|
||||||
<variablelist>
|
<variablelist>
|
||||||
@@ -327,6 +333,7 @@ Certificate Friendly Name: Thawte Freemail Member's Thawte Consulting (Pty) L
|
|||||||
<listitem>
|
<listitem>
|
||||||
<itemizedlist>
|
<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 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>
|
</itemizedlist>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|||||||
@@ -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': [
|
'includes': [
|
||||||
'../coreconf/config.gypi',
|
'../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': [
|
'targets': [
|
||||||
{
|
{
|
||||||
'target_name': 'fuzz_base',
|
'target_name': 'fuzz',
|
||||||
'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',
|
|
||||||
'type': 'none',
|
'type': 'none',
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'nssfuzz-certDN',
|
'<(DEPTH)/fuzz/targets/targets.gyp:nssfuzz',
|
||||||
'nssfuzz-dtls-client',
|
|
||||||
'nssfuzz-dtls-server',
|
|
||||||
'nssfuzz-pkcs7',
|
|
||||||
'nssfuzz-pkcs8',
|
|
||||||
'nssfuzz-pkcs12',
|
|
||||||
'nssfuzz-quickder',
|
|
||||||
'nssfuzz-tls-client',
|
|
||||||
'nssfuzz-tls-server',
|
|
||||||
],
|
],
|
||||||
}
|
},
|
||||||
],
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
17
security/nss/fuzz/targets/lib/asn1/asn1.gyp
Normal file
17
security/nss/fuzz/targets/lib/asn1/asn1.gyp
Normal 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',
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
@@ -2,57 +2,56 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "mutators.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
#include "asn1_mutators.h"
|
static std::tuple<uint8_t *, size_t> ParseItem(uint8_t *data,
|
||||||
|
size_t maxLength) {
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
static 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.
|
// Short form. Bit 8 has value "0" and bits 7-1 give the length.
|
||||||
if ((Data[1] & 0x80) == 0) {
|
if ((data[1] & 0x80) == 0) {
|
||||||
size_t length = min(static_cast<size_t>(Data[1]), MaxLength - 2);
|
size_t length = std::min(static_cast<size_t>(data[1]), maxLength - 2);
|
||||||
return make_tuple(&Data[2], length);
|
return std::make_tuple(&data[2], length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructed, indefinite length. Read until {0x00, 0x00}.
|
// Constructed, indefinite length. Read until {0x00, 0x00}.
|
||||||
if (Data[1] == 0x80) {
|
if (data[1] == 0x80) {
|
||||||
void *offset = memmem(&Data[2], MaxLength - 2, "\0", 2);
|
void *offset = memmem(&data[2], maxLength - 2, "\0", 2);
|
||||||
size_t length = offset ? (static_cast<uint8_t *>(offset) - &Data[2]) + 2
|
size_t length = offset ? (static_cast<uint8_t *>(offset) - &data[2]) + 2
|
||||||
: MaxLength - 2;
|
: maxLength - 2;
|
||||||
return make_tuple(&Data[2], length);
|
return std::make_tuple(&data[2], length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Long form. Two to 127 octets. Bit 8 of first octet has value "1"
|
// 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.
|
// 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.
|
// Handle lengths bigger than 32 bits.
|
||||||
if (octets > 4) {
|
if (octets > 4) {
|
||||||
// Ignore any further children, assign remaining length.
|
// 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.
|
// Parse the length.
|
||||||
size_t length = 0;
|
size_t length = 0;
|
||||||
for (size_t j = 0; j < octets; j++) {
|
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);
|
length = std::min(length, maxLength - 2 - octets);
|
||||||
return make_tuple(&Data[2] + octets, length);
|
return std::make_tuple(&data[2] + octets, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static vector<uint8_t *> ParseItems(uint8_t *Data, size_t Size) {
|
static std::vector<uint8_t *> ParseItems(uint8_t *data, size_t size) {
|
||||||
vector<uint8_t *> items;
|
std::vector<uint8_t *> items;
|
||||||
vector<size_t> lengths;
|
std::vector<size_t> lengths;
|
||||||
|
|
||||||
// The first item is always the whole corpus.
|
// The first item is always the whole corpus.
|
||||||
items.push_back(Data);
|
items.push_back(data);
|
||||||
lengths.push_back(Size);
|
lengths.push_back(size);
|
||||||
|
|
||||||
// Can't use iterators here because the `items` vector is modified inside the
|
// 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
|
// 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;
|
uint8_t *content;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
|
||||||
tie(content, length) = ParseItem(item, remaining);
|
std::tie(content, length) = ParseItem(item, remaining);
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
// Record the item.
|
// Record the item.
|
||||||
@@ -94,25 +93,25 @@ static vector<uint8_t *> ParseItems(uint8_t *Data, size_t Size) {
|
|||||||
|
|
||||||
namespace ASN1Mutators {
|
namespace ASN1Mutators {
|
||||||
|
|
||||||
size_t FlipConstructed(uint8_t *Data, size_t Size, size_t MaxSize,
|
size_t FlipConstructed(uint8_t *data, size_t size, size_t maxSize,
|
||||||
unsigned int Seed) {
|
unsigned int seed) {
|
||||||
auto items = ParseItems(Data, Size);
|
auto items = ParseItems(data, size);
|
||||||
|
|
||||||
std::mt19937 rng(Seed);
|
std::mt19937 rng(seed);
|
||||||
std::uniform_int_distribution<size_t> dist(0, items.size() - 1);
|
std::uniform_int_distribution<size_t> dist(0, items.size() - 1);
|
||||||
uint8_t *item = items.at(dist(rng));
|
uint8_t *item = items.at(dist(rng));
|
||||||
|
|
||||||
// Flip "constructed" type bit.
|
// Flip "constructed" type bit.
|
||||||
item[0] ^= 0x20;
|
item[0] ^= 0x20;
|
||||||
|
|
||||||
return Size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ChangeType(uint8_t *Data, size_t Size, size_t MaxSize,
|
size_t ChangeType(uint8_t *data, size_t size, size_t maxSize,
|
||||||
unsigned int Seed) {
|
unsigned int seed) {
|
||||||
auto items = ParseItems(Data, Size);
|
auto items = ParseItems(data, size);
|
||||||
|
|
||||||
std::mt19937 rng(Seed);
|
std::mt19937 rng(seed);
|
||||||
std::uniform_int_distribution<size_t> dist(0, items.size() - 1);
|
std::uniform_int_distribution<size_t> dist(0, items.size() - 1);
|
||||||
uint8_t *item = items.at(dist(rng));
|
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);
|
static std::uniform_int_distribution<size_t> tdist(0, 30);
|
||||||
item[0] = tdist(rng);
|
item[0] = tdist(rng);
|
||||||
|
|
||||||
return Size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ASN1Mutators
|
} // namespace ASN1Mutators
|
||||||
17
security/nss/fuzz/targets/lib/base/base.gyp
Normal file
17
security/nss/fuzz/targets/lib/base/base.gyp
Normal 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',
|
||||||
|
],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
19
security/nss/fuzz/targets/lib/base/database.h
Normal file
19
security/nss/fuzz/targets/lib/base/database.h
Normal 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_
|
||||||
@@ -2,21 +2,21 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "shared.h"
|
#include "mutate.h"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
size_t CustomMutate(Mutators mutators, uint8_t* data, size_t size,
|
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);
|
std::mt19937 rng(seed);
|
||||||
static std::bernoulli_distribution bdist;
|
static std::bernoulli_distribution bdist;
|
||||||
|
|
||||||
if (bdist(rng)) {
|
if (bdist(rng)) {
|
||||||
std::uniform_int_distribution<size_t> idist(0, mutators.size() - 1);
|
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);
|
||||||
}
|
}
|
||||||
@@ -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
|
/* 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,
|
* 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/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#ifndef SHARED_H_
|
#ifndef BASE_MUTATE_H_
|
||||||
#define SHARED_H_
|
#define BASE_MUTATE_H_
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "nss.h"
|
|
||||||
|
|
||||||
extern "C" size_t LLVMFuzzerMutate(uint8_t* data, size_t size, size_t maxSize);
|
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,
|
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
|
||||||
size_t maxSize, unsigned int seed);
|
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;
|
typedef std::vector<decltype(LLVMFuzzerCustomMutator)*> Mutators;
|
||||||
|
|
||||||
size_t CustomMutate(Mutators mutators, uint8_t* data, size_t size,
|
size_t CustomMutate(Mutators mutators, uint8_t* data, size_t size,
|
||||||
size_t maxSize, unsigned int seed);
|
size_t maxSize, unsigned int seed);
|
||||||
|
|
||||||
#endif // SHARED_H_
|
#endif // BASE_MUTATE_H_
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "tls_client_config.h"
|
#include "client_config.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@@ -16,23 +16,24 @@
|
|||||||
#include "ssl.h"
|
#include "ssl.h"
|
||||||
#include "sslexp.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
|
#ifndef IS_DTLS_FUZZ
|
||||||
const char kEchConfigs[] =
|
const char kEchConfigs[] =
|
||||||
"AEX+"
|
"AEX+"
|
||||||
"DQBBcQAgACDh4IuiuhhInUcKZx5uYcehlG9PQ1ZlzhvVZyjJl7dscQAEAAEAAQASY2xvdWRmbG"
|
"DQBBcQAgACDh4IuiuhhInUcKZx5uYcehlG9PQ1ZlzhvVZyjJl7dscQAEAAEAAQASY2xvdWRmbG"
|
||||||
"FyZS1lY2guY29tAAA=";
|
"FyZS1lY2guY29tAAA=";
|
||||||
#endif // IS_DTLS_FUZZ
|
#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,
|
static SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checksig,
|
||||||
PRBool isServer) {
|
PRBool isServer) {
|
||||||
assert(!isServer);
|
assert(!isServer);
|
||||||
|
|
||||||
auto config = reinterpret_cast<ClientConfig*>(arg);
|
auto config = reinterpret_cast<TlsClient::Config*>(arg);
|
||||||
if (config->FailCertificateAuthentication()) return SECFailure;
|
if (config->FailCertificateAuthentication()) return SECFailure;
|
||||||
|
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
@@ -44,10 +45,12 @@ static SECStatus CanFalseStartCallback(PRFileDesc* fd, void* arg,
|
|||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace TlsClient {
|
||||||
|
|
||||||
// XOR 64-bit chunks of data to build a bitmap of config options derived from
|
// 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
|
// the fuzzing input. This seems the only way to fuzz various options while
|
||||||
// still maintaining compatibility with BoringSSL or OpenSSL fuzzers.
|
// 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 {
|
union {
|
||||||
uint64_t bitmap;
|
uint64_t bitmap;
|
||||||
struct {
|
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);
|
SECStatus rv = SSL_AuthCertificateHook(fd, AuthCertificateHook, this);
|
||||||
assert(rv == SECSuccess);
|
assert(rv == SECSuccess);
|
||||||
|
|
||||||
@@ -86,7 +89,7 @@ void ClientConfig::SetCallbacks(PRFileDesc* fd) {
|
|||||||
assert(rv == SECSuccess);
|
assert(rv == SECSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientConfig::SetSocketOptions(PRFileDesc* fd) {
|
void Config::SetSocketOptions(PRFileDesc* fd) {
|
||||||
SECStatus rv = SSL_OptionSet(fd, SSL_ENABLE_EXTENDED_MASTER_SECRET,
|
SECStatus rv = SSL_OptionSet(fd, SSL_ENABLE_EXTENDED_MASTER_SECRET,
|
||||||
this->EnableExtendedMasterSecret());
|
this->EnableExtendedMasterSecret());
|
||||||
assert(rv == SECSuccess);
|
assert(rv == SECSuccess);
|
||||||
@@ -168,6 +171,20 @@ void ClientConfig::SetSocketOptions(PRFileDesc* fd) {
|
|||||||
rv = SSL_OptionSet(fd, SSL_NO_LOCKS, this->NoLocks());
|
rv = SSL_OptionSet(fd, SSL_NO_LOCKS, this->NoLocks());
|
||||||
assert(rv == SECSuccess);
|
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
|
#ifndef IS_DTLS_FUZZ
|
||||||
rv =
|
rv =
|
||||||
SSL_OptionSet(fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED);
|
SSL_OptionSet(fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED);
|
||||||
@@ -184,7 +201,7 @@ void ClientConfig::SetSocketOptions(PRFileDesc* fd) {
|
|||||||
#endif // IS_DTLS_FUZZ
|
#endif // IS_DTLS_FUZZ
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, ClientConfig& config) {
|
std::ostream& operator<<(std::ostream& out, Config& config) {
|
||||||
out << "============= ClientConfig ============="
|
out << "============= ClientConfig ============="
|
||||||
<< "\n";
|
<< "\n";
|
||||||
out << "SSL_NO_CACHE: " << config.NoCache() << "\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: "
|
out << "SSL_ENABLE_TLS13_COMPAT_MODE: "
|
||||||
<< config.EnableTls13CompatMode() << "\n";
|
<< config.EnableTls13CompatMode() << "\n";
|
||||||
out << "SSL_NO_LOCKS: " << config.NoLocks() << "\n";
|
out << "SSL_NO_LOCKS: " << config.NoLocks() << "\n";
|
||||||
|
out << "SSL_EnableTls13GreaseEch: "
|
||||||
|
<< config.EnableTls13GreaseEch() << "\n";
|
||||||
|
out << "SSL_SetDtls13VersionWorkaround: "
|
||||||
|
<< config.SetDtls13VersionWorkaround() << "\n";
|
||||||
out << "SSL_SetClientEchConfigs: "
|
out << "SSL_SetClientEchConfigs: "
|
||||||
<< config.SetClientEchConfigs() << "\n";
|
<< config.SetClientEchConfigs() << "\n";
|
||||||
out << "========================================";
|
out << "========================================";
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace TlsClient
|
||||||
@@ -19,9 +19,11 @@
|
|||||||
#endif
|
#endif
|
||||||
#define SSL_VERSION_RANGE_MAX_VALID 0x0304
|
#define SSL_VERSION_RANGE_MAX_VALID 0x0304
|
||||||
|
|
||||||
class ClientConfig {
|
namespace TlsClient {
|
||||||
|
|
||||||
|
class Config {
|
||||||
public:
|
public:
|
||||||
ClientConfig(const uint8_t* data, size_t len);
|
Config(const uint8_t* data, size_t len);
|
||||||
|
|
||||||
void SetCallbacks(PRFileDesc* fd);
|
void SetCallbacks(PRFileDesc* fd);
|
||||||
void SetSocketOptions(PRFileDesc* fd);
|
void SetSocketOptions(PRFileDesc* fd);
|
||||||
@@ -33,6 +35,8 @@ class ClientConfig {
|
|||||||
};
|
};
|
||||||
SSLVersionRange SslVersionRange() { return ssl_version_range_; };
|
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 FailCertificateAuthentication() { return config_ & (1 << 0); };
|
||||||
bool EnableExtendedMasterSecret() { return config_ & (1 << 1); };
|
bool EnableExtendedMasterSecret() { return config_ & (1 << 1); };
|
||||||
bool RequireDhNamedGroups() { return config_ & (1 << 2); };
|
bool RequireDhNamedGroups() { return config_ & (1 << 2); };
|
||||||
@@ -55,12 +59,18 @@ class ClientConfig {
|
|||||||
bool EnableSessionTickets() { return config_ & (1 << 19); };
|
bool EnableSessionTickets() { return config_ & (1 << 19); };
|
||||||
bool EnableTls13CompatMode() { return config_ & (1 << 20); };
|
bool EnableTls13CompatMode() { return config_ & (1 << 20); };
|
||||||
bool NoLocks() { return config_ & (1 << 21); };
|
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:
|
private:
|
||||||
uint32_t config_;
|
uint32_t config_;
|
||||||
SSLVersionRange ssl_version_range_;
|
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_
|
#endif // TLS_CLIENT_CONFIG_H_
|
||||||
@@ -2,18 +2,21 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "tls_common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "prio.h"
|
#include "prio.h"
|
||||||
|
#include "secport.h"
|
||||||
#include "ssl.h"
|
#include "ssl.h"
|
||||||
#include "sslexp.h"
|
#include "sslexp.h"
|
||||||
|
|
||||||
static PRTime FixedTime(void*) { return 1234; }
|
static PRTime FixedTime(void*) { return 1234; }
|
||||||
|
|
||||||
|
namespace TlsCommon {
|
||||||
|
|
||||||
// Fix the time input, to avoid any time-based variation.
|
// Fix the time input, to avoid any time-based variation.
|
||||||
void FixTime(PRFileDesc* fd) {
|
void FixTime(PRFileDesc* fd) {
|
||||||
SECStatus rv = SSL_SetTimeFunc(fd, FixedTime, nullptr);
|
SECStatus rv = SSL_SetTimeFunc(fd, FixedTime, nullptr);
|
||||||
@@ -68,7 +71,7 @@ void DoHandshake(PRFileDesc* fd, bool isServer) {
|
|||||||
|
|
||||||
SECStatus DummyCompressionEncode(const SECItem* input, SECItem* output) {
|
SECStatus DummyCompressionEncode(const SECItem* input, SECItem* output) {
|
||||||
if (!input || !input->data || input->len == 0 || !output) {
|
if (!input || !input->data || input->len == 0 || !output) {
|
||||||
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,12 +83,12 @@ SECStatus DummyCompressionEncode(const SECItem* input, SECItem* output) {
|
|||||||
SECStatus DummyCompressionDecode(const SECItem* input, unsigned char* output,
|
SECStatus DummyCompressionDecode(const SECItem* input, unsigned char* output,
|
||||||
size_t outputLen, size_t* usedLen) {
|
size_t outputLen, size_t* usedLen) {
|
||||||
if (!input || !input->data || input->len == 0 || !output || outputLen == 0) {
|
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;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input->len > outputLen) {
|
if (input->len > outputLen) {
|
||||||
PR_SetError(SEC_ERROR_BAD_DATA, 0);
|
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,3 +97,5 @@ SECStatus DummyCompressionDecode(const SECItem* input, unsigned char* output,
|
|||||||
|
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace TlsCommon
|
||||||
@@ -10,6 +10,8 @@
|
|||||||
#include "prio.h"
|
#include "prio.h"
|
||||||
#include "seccomon.h"
|
#include "seccomon.h"
|
||||||
|
|
||||||
|
namespace TlsCommon {
|
||||||
|
|
||||||
void FixTime(PRFileDesc* fd);
|
void FixTime(PRFileDesc* fd);
|
||||||
void EnableAllProtocolVersions();
|
void EnableAllProtocolVersions();
|
||||||
void EnableAllCipherSuites(PRFileDesc* fd);
|
void EnableAllCipherSuites(PRFileDesc* fd);
|
||||||
@@ -19,4 +21,6 @@ SECStatus DummyCompressionEncode(const SECItem* input, SECItem* output);
|
|||||||
SECStatus DummyCompressionDecode(const SECItem* input, unsigned char* output,
|
SECStatus DummyCompressionDecode(const SECItem* input, unsigned char* output,
|
||||||
size_t outputLen, size_t* usedLen);
|
size_t outputLen, size_t* usedLen);
|
||||||
|
|
||||||
|
} // namespace TlsCommon
|
||||||
|
|
||||||
#endif // TLS_COMMON_H_
|
#endif // TLS_COMMON_H_
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "mutators.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@@ -11,12 +13,6 @@
|
|||||||
|
|
||||||
#include "tls_parser.h"
|
#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.
|
// Helper class to simplify TLS record manipulation.
|
||||||
class Record {
|
class Record {
|
||||||
public:
|
public:
|
||||||
@@ -40,9 +36,9 @@ class Record {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void truncate(size_t length) {
|
void truncate(size_t length) {
|
||||||
assert(length >= 5 + gExtraHeaderBytes);
|
assert(length >= 5 + EXTRA_HEADER_BYTES);
|
||||||
uint8_t *dest = const_cast<uint8_t *>(data_);
|
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[3] = (l >> 8) & 0xff;
|
||||||
dest[4] = l & 0xff;
|
dest[4] = l & 0xff;
|
||||||
memmove(dest + length, data_ + size_, remaining_);
|
memmove(dest + length, data_ + size_, remaining_);
|
||||||
@@ -70,23 +66,23 @@ class Record {
|
|||||||
std::vector<std::unique_ptr<Record>> ParseRecords(const uint8_t *data,
|
std::vector<std::unique_ptr<Record>> ParseRecords(const uint8_t *data,
|
||||||
size_t size) {
|
size_t size) {
|
||||||
std::vector<std::unique_ptr<Record>> records;
|
std::vector<std::unique_ptr<Record>> records;
|
||||||
TlsParser parser(data, size);
|
nss_test::TlsParser parser(data, size);
|
||||||
|
|
||||||
while (parser.remaining()) {
|
while (parser.remaining()) {
|
||||||
size_t offset = parser.consumed();
|
size_t offset = parser.consumed();
|
||||||
|
|
||||||
// Skip type, version, and DTLS seqnums.
|
// Skip type, version, and DTLS seqnums.
|
||||||
if (!parser.Skip(3 + gExtraHeaderBytes)) {
|
if (!parser.Skip(3 + EXTRA_HEADER_BYTES)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataBuffer fragment;
|
nss_test::DataBuffer fragment;
|
||||||
if (!parser.ReadVariable(&fragment, 2)) {
|
if (!parser.ReadVariable(&fragment, 2)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
records.push_back(Record::Create(data + offset,
|
records.push_back(Record::Create(data + offset,
|
||||||
fragment.len() + 5 + gExtraHeaderBytes,
|
fragment.len() + 5 + EXTRA_HEADER_BYTES,
|
||||||
parser.remaining()));
|
parser.remaining()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,11 +91,8 @@ std::vector<std::unique_ptr<Record>> ParseRecords(const uint8_t *data,
|
|||||||
|
|
||||||
namespace TlsMutators {
|
namespace TlsMutators {
|
||||||
|
|
||||||
// Handle seqnums in DTLS transcripts.
|
|
||||||
void SetIsDTLS() { gExtraHeaderBytes = 8; }
|
|
||||||
|
|
||||||
// Mutator that drops whole TLS records.
|
// 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) {
|
unsigned int seed) {
|
||||||
std::mt19937 rng(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.
|
// 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) {
|
unsigned int seed) {
|
||||||
std::mt19937 rng(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.
|
// 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) {
|
unsigned int seed) {
|
||||||
std::mt19937 rng(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.
|
// Pick a record to duplicate at random.
|
||||||
std::uniform_int_distribution<size_t> dist(0, records.size() - 1);
|
std::uniform_int_distribution<size_t> dist(0, records.size() - 1);
|
||||||
auto &rec = records.at(dist(rng));
|
auto &rec = records.at(dist(rng));
|
||||||
if (size + rec->size() > max_size) {
|
if (size + rec->size() > maxSize) {
|
||||||
return 0;
|
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.
|
// 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) {
|
unsigned int seed) {
|
||||||
std::mt19937 rng(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));
|
auto &rec = records.at(dist(rng));
|
||||||
|
|
||||||
// Need a record with data.
|
// Need a record with data.
|
||||||
if (rec->size() <= 5 + gExtraHeaderBytes) {
|
if (rec->size() <= 5 + EXTRA_HEADER_BYTES) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Truncate.
|
// Truncate.
|
||||||
std::uniform_int_distribution<size_t> dist2(5 + gExtraHeaderBytes,
|
std::uniform_int_distribution<size_t> dist2(5 + EXTRA_HEADER_BYTES,
|
||||||
rec->size() - 1);
|
rec->size() - 1);
|
||||||
size_t new_length = dist2(rng);
|
size_t new_length = dist2(rng);
|
||||||
rec->truncate(new_length);
|
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.
|
// 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) {
|
unsigned int seed) {
|
||||||
std::mt19937 rng(seed);
|
std::mt19937 rng(seed);
|
||||||
|
|
||||||
// We can't deal with DTLS yet.
|
// We can't deal with DTLS yet.
|
||||||
if (gExtraHeaderBytes > 0) {
|
if (EXTRA_HEADER_BYTES > 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size + 5 > max_size) {
|
if (size + 5 > maxSize) {
|
||||||
return 0;
|
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.
|
// 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 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) {
|
unsigned int seed) {
|
||||||
std::mt19937 rng(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;
|
size_t total = 0;
|
||||||
for (auto &rec : records1) {
|
for (auto &rec : records1) {
|
||||||
size_t length = rec->size();
|
size_t length = rec->size();
|
||||||
if (total + length > max_out_size) {
|
if (total + length > maxOutSize) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,4 +288,4 @@ size_t CrossOver(const uint8_t *data1, size_t size1, const uint8_t *data2,
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace TlsMutators
|
} // namespace TlsMutators
|
||||||
@@ -8,23 +8,29 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#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 {
|
namespace TlsMutators {
|
||||||
|
|
||||||
void SetIsDTLS();
|
size_t DropRecord(uint8_t *data, size_t size, size_t maxSize,
|
||||||
|
|
||||||
size_t DropRecord(uint8_t *data, size_t size, size_t max_size,
|
|
||||||
unsigned int seed);
|
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);
|
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);
|
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);
|
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);
|
unsigned int seed);
|
||||||
|
|
||||||
size_t CrossOver(const uint8_t *data1, size_t size1, const uint8_t *data2,
|
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);
|
unsigned int seed);
|
||||||
|
|
||||||
} // namespace TlsMutators
|
} // namespace TlsMutators
|
||||||
@@ -2,14 +2,15 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include <assert.h>
|
#include "server_certs.h"
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "ssl.h"
|
#include <cassert>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
#include "cpputil.h"
|
#include "cpputil.h"
|
||||||
#include "nss_scoped_ptrs.h"
|
#include "nss_scoped_ptrs.h"
|
||||||
#include "tls_server_certs.h"
|
#include "ssl.h"
|
||||||
|
|
||||||
const uint8_t kP256ServerCert[] = {
|
const uint8_t kP256ServerCert[] = {
|
||||||
0x30, 0x82, 0x01, 0xcf, 0x30, 0x82, 0x01, 0x76, 0xa0, 0x03, 0x02, 0x01,
|
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,
|
0xfe, 0xbf, 0xda, 0x0e, 0xce, 0x28, 0xb9, 0xdb, 0x9b, 0xcf, 0x6e, 0xa8,
|
||||||
0xe4, 0x60, 0xca, 0x98};
|
0xe4, 0x60, 0xca, 0x98};
|
||||||
|
|
||||||
void InstallServerCertificate(PRFileDesc* fd, const uint8_t* cert_data,
|
static void InstallServerCertificate(PRFileDesc* fd, const uint8_t* certData,
|
||||||
size_t cert_len, const uint8_t* key_data,
|
size_t certLen, const uint8_t* keyData,
|
||||||
size_t key_len) {
|
size_t keyLen) {
|
||||||
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||||
assert(slot);
|
assert(slot);
|
||||||
|
|
||||||
SECItem certItem = {siBuffer, toUcharPtr(cert_data),
|
SECItem certItem = {siBuffer, toUcharPtr(certData),
|
||||||
static_cast<unsigned int>(cert_len)};
|
static_cast<unsigned int>(certLen)};
|
||||||
SECItem pkcs8Item = {siBuffer, toUcharPtr(key_data),
|
SECItem pkcs8Item = {siBuffer, toUcharPtr(keyData),
|
||||||
static_cast<unsigned int>(key_len)};
|
static_cast<unsigned int>(keyLen)};
|
||||||
|
|
||||||
// Import the certificate.
|
// Import the certificate.
|
||||||
static CERTCertDBHandle* certDB = CERT_GetDefaultCertDB();
|
static CERTCertDBHandle* certDB = CERT_GetDefaultCertDB();
|
||||||
@@ -284,6 +285,8 @@ void InstallServerCertificate(PRFileDesc* fd, const uint8_t* cert_data,
|
|||||||
assert(rv == SECSuccess);
|
assert(rv == SECSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace TlsServer {
|
||||||
|
|
||||||
void InstallServerCertificates(PRFileDesc* fd) {
|
void InstallServerCertificates(PRFileDesc* fd) {
|
||||||
// ECDSA P-256 certificate.
|
// ECDSA P-256 certificate.
|
||||||
InstallServerCertificate(fd, kP256ServerCert, sizeof(kP256ServerCert),
|
InstallServerCertificate(fd, kP256ServerCert, sizeof(kP256ServerCert),
|
||||||
@@ -292,4 +295,8 @@ void InstallServerCertificates(PRFileDesc* fd) {
|
|||||||
// RSA-2048 certificate.
|
// RSA-2048 certificate.
|
||||||
InstallServerCertificate(fd, kRsaServerCert, sizeof(kRsaServerCert),
|
InstallServerCertificate(fd, kRsaServerCert, sizeof(kRsaServerCert),
|
||||||
kRsaServerKey, sizeof(kRsaServerKey));
|
kRsaServerKey, sizeof(kRsaServerKey));
|
||||||
|
|
||||||
|
// TODO(mdauer): Install more different cerificate types.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace TlsServer
|
||||||
@@ -2,11 +2,15 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
* 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/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#ifndef tls_server_certs_h__
|
#ifndef TLS_SERVER_CERT_H_
|
||||||
#define tls_server_certs_h__
|
#define TLS_SERVER_CERT_H_
|
||||||
|
|
||||||
#include "prio.h"
|
#include "prio.h"
|
||||||
|
|
||||||
|
namespace TlsServer {
|
||||||
|
|
||||||
void InstallServerCertificates(PRFileDesc* fd);
|
void InstallServerCertificates(PRFileDesc* fd);
|
||||||
|
|
||||||
#endif // tls_server_certs_h__
|
} // namespace TlsServer
|
||||||
|
|
||||||
|
#endif // TLS_SERVER_CERT_H_
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "tls_server_config.h"
|
#include "server_config.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
@@ -16,16 +16,17 @@
|
|||||||
#include "sslexp.h"
|
#include "sslexp.h"
|
||||||
#include "sslt.h"
|
#include "sslt.h"
|
||||||
|
|
||||||
#include "tls_common.h"
|
#include "common.h"
|
||||||
|
|
||||||
const SSLCertificateCompressionAlgorithm kCompressionAlg = {
|
const SSLCertificateCompressionAlgorithm kCompressionAlg = {
|
||||||
0x1337, "fuzz", DummyCompressionEncode, DummyCompressionDecode};
|
0x1337, "fuzz", TlsCommon::DummyCompressionEncode,
|
||||||
|
TlsCommon::DummyCompressionDecode};
|
||||||
const PRUint8 kPskIdentity[] = "fuzz-psk-identity";
|
const PRUint8 kPskIdentity[] = "fuzz-psk-identity";
|
||||||
|
|
||||||
static SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checksig,
|
static SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checksig,
|
||||||
PRBool isServer) {
|
PRBool isServer) {
|
||||||
assert(isServer);
|
assert(isServer);
|
||||||
auto config = reinterpret_cast<ServerConfig*>(arg);
|
auto config = reinterpret_cast<TlsServer::Config*>(arg);
|
||||||
if (config->FailCertificateAuthentication()) return SECFailure;
|
if (config->FailCertificateAuthentication()) return SECFailure;
|
||||||
|
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
@@ -37,10 +38,12 @@ static SECStatus CanFalseStartCallback(PRFileDesc* fd, void* arg,
|
|||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace TlsServer {
|
||||||
|
|
||||||
// XOR 64-bit chunks of data to build a bitmap of config options derived from
|
// 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
|
// the fuzzing input. This seems the only way to fuzz various options while
|
||||||
// still maintaining compatibility with BoringSSL or OpenSSL fuzzers.
|
// 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 {
|
union {
|
||||||
uint64_t bitmap;
|
uint64_t bitmap;
|
||||||
struct {
|
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);
|
SECStatus rv = SSL_AuthCertificateHook(fd, AuthCertificateHook, this);
|
||||||
assert(rv == SECSuccess);
|
assert(rv == SECSuccess);
|
||||||
|
|
||||||
@@ -79,7 +82,7 @@ void ServerConfig::SetCallbacks(PRFileDesc* fd) {
|
|||||||
assert(rv == SECSuccess);
|
assert(rv == SECSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerConfig::SetSocketOptions(PRFileDesc* fd) {
|
void Config::SetSocketOptions(PRFileDesc* fd) {
|
||||||
SECStatus rv = SSL_OptionSet(fd, SSL_ENABLE_EXTENDED_MASTER_SECRET,
|
SECStatus rv = SSL_OptionSet(fd, SSL_ENABLE_EXTENDED_MASTER_SECRET,
|
||||||
this->EnableExtendedMasterSecret());
|
this->EnableExtendedMasterSecret());
|
||||||
assert(rv == SECSuccess);
|
assert(rv == SECSuccess);
|
||||||
@@ -145,6 +148,17 @@ void ServerConfig::SetSocketOptions(PRFileDesc* fd) {
|
|||||||
rv = SSL_OptionSet(fd, SSL_NO_LOCKS, this->NoLocks());
|
rv = SSL_OptionSet(fd, SSL_NO_LOCKS, this->NoLocks());
|
||||||
assert(rv == SECSuccess);
|
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
|
#ifndef IS_DTLS_FUZZ
|
||||||
rv =
|
rv =
|
||||||
SSL_OptionSet(fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED);
|
SSL_OptionSet(fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED);
|
||||||
@@ -152,7 +166,7 @@ void ServerConfig::SetSocketOptions(PRFileDesc* fd) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, ServerConfig& config) {
|
std::ostream& operator<<(std::ostream& out, Config& config) {
|
||||||
out << "============= ServerConfig ============="
|
out << "============= ServerConfig ============="
|
||||||
<< "\n";
|
<< "\n";
|
||||||
out << "SSL_NO_CACHE: " << config.NoCache() << "\n";
|
out << "SSL_NO_CACHE: " << config.NoCache() << "\n";
|
||||||
@@ -195,3 +209,5 @@ std::ostream& operator<<(std::ostream& out, ServerConfig& config) {
|
|||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace TlsServer
|
||||||
@@ -19,9 +19,11 @@
|
|||||||
#endif
|
#endif
|
||||||
#define SSL_VERSION_RANGE_MAX_VALID 0x0304
|
#define SSL_VERSION_RANGE_MAX_VALID 0x0304
|
||||||
|
|
||||||
class ServerConfig {
|
namespace TlsServer {
|
||||||
|
|
||||||
|
class Config {
|
||||||
public:
|
public:
|
||||||
ServerConfig(const uint8_t* data, size_t len);
|
Config(const uint8_t* data, size_t len);
|
||||||
|
|
||||||
void SetCallbacks(PRFileDesc* fd);
|
void SetCallbacks(PRFileDesc* fd);
|
||||||
void SetSocketOptions(PRFileDesc* fd);
|
void SetSocketOptions(PRFileDesc* fd);
|
||||||
@@ -33,6 +35,8 @@ class ServerConfig {
|
|||||||
};
|
};
|
||||||
SSLVersionRange SslVersionRange() { return ssl_version_range_; };
|
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 EnableExtendedMasterSecret() { return config_ & (1 << 0); };
|
||||||
bool RequestCertificate() { return config_ & (1 << 1); };
|
bool RequestCertificate() { return config_ & (1 << 1); };
|
||||||
bool RequireCertificate() { return config_ & (1 << 2); };
|
bool RequireCertificate() { return config_ & (1 << 2); };
|
||||||
@@ -50,12 +54,17 @@ class ServerConfig {
|
|||||||
bool EnableSessionTickets() { return config_ & (1 << 14); };
|
bool EnableSessionTickets() { return config_ & (1 << 14); };
|
||||||
bool NoLocks() { return config_ & (1 << 15); };
|
bool NoLocks() { return config_ & (1 << 15); };
|
||||||
bool FailCertificateAuthentication() { return config_ & (1 << 16); }
|
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:
|
private:
|
||||||
uint32_t config_;
|
uint32_t config_;
|
||||||
SSLVersionRange ssl_version_range_;
|
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_
|
#endif // TLS_SERVER_CONFIG_H_
|
||||||
@@ -2,16 +2,19 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include <assert.h>
|
#include "socket.h"
|
||||||
#include <string.h>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include "prerror.h"
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "prinrval.h"
|
||||||
#include "prio.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);
|
assert(data && len > 0);
|
||||||
|
|
||||||
int32_t amount = std::min(len, static_cast<int32_t>(len_));
|
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;
|
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;
|
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) {
|
int32_t flags, PRIntervalTime to) {
|
||||||
assert(flags == 0);
|
assert(flags == 0);
|
||||||
return Read(f, buf, buflen);
|
return Read(fd, buf, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace TlsSocket
|
||||||
@@ -2,19 +2,24 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
* 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/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#ifndef tls_socket_h__
|
#ifndef TLS_SOCKET_H_
|
||||||
#define tls_socket_h__
|
#define TLS_SOCKET_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
#include "dummy_io.h"
|
#include "dummy_io.h"
|
||||||
|
#include "prinrval.h"
|
||||||
|
#include "prio.h"
|
||||||
|
|
||||||
|
namespace TlsSocket {
|
||||||
|
|
||||||
class DummyPrSocket : public DummyIOLayerMethods {
|
class DummyPrSocket : public DummyIOLayerMethods {
|
||||||
public:
|
public:
|
||||||
DummyPrSocket(const uint8_t *buf, size_t len) : buf_(buf), len_(len) {}
|
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 Read(PRFileDesc *fd, void *data, int32_t len) override;
|
||||||
int32_t Write(PRFileDesc *f, const void *buf, int32_t length) override;
|
int32_t Write(PRFileDesc *fd, const void *buf, int32_t length) override;
|
||||||
int32_t Recv(PRFileDesc *f, void *buf, int32_t buflen, int32_t flags,
|
int32_t Recv(PRFileDesc *fd, void *buf, int32_t buflen, int32_t flags,
|
||||||
PRIntervalTime to) override;
|
PRIntervalTime to) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -22,4 +27,6 @@ class DummyPrSocket : public DummyIOLayerMethods {
|
|||||||
size_t len_;
|
size_t len_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // tls_socket_h__
|
} // namespace TlsSocket
|
||||||
|
|
||||||
|
#endif // TLS_SOCKET_H_
|
||||||
43
security/nss/fuzz/targets/lib/tls/tls.gyp
Normal file
43
security/nss/fuzz/targets/lib/tls/tls.gyp
Normal 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',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
@@ -5,15 +5,15 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "nss_scoped_ptrs.h"
|
#include "nss_scoped_ptrs.h"
|
||||||
#include "p12.h"
|
#include "p12.h"
|
||||||
#include "pk11pub.h"
|
#include "pk11pub.h"
|
||||||
#include "seccomon.h"
|
#include "seccomon.h"
|
||||||
|
|
||||||
#include "asn1_mutators.h"
|
#include "asn1/mutators.h"
|
||||||
#include "shared.h"
|
#include "base/database.h"
|
||||||
|
#include "base/mutate.h"
|
||||||
|
|
||||||
static SECItem* nicknameCollision(SECItem* oldNick, PRBool* cancel,
|
static SECItem* nicknameCollision(SECItem* oldNick, PRBool* cancel,
|
||||||
void* wincx) {
|
void* wincx) {
|
||||||
@@ -22,7 +22,7 @@ static SECItem* nicknameCollision(SECItem* oldNick, PRBool* cancel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
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());
|
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||||
assert(slot);
|
assert(slot);
|
||||||
@@ -4,32 +4,18 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "cert.h"
|
#include "cert.h"
|
||||||
#include "seccomon.h"
|
|
||||||
|
|
||||||
#include "asn1_mutators.h"
|
#include "asn1/mutators.h"
|
||||||
#include "shared.h"
|
#include "base/database.h"
|
||||||
|
#include "base/mutate.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2,32 +2,33 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "keyhi.h"
|
#include "keyhi.h"
|
||||||
|
#include "nss_scoped_ptrs.h"
|
||||||
#include "pk11pub.h"
|
#include "pk11pub.h"
|
||||||
|
|
||||||
#include "asn1_mutators.h"
|
#include "asn1/mutators.h"
|
||||||
#include "shared.h"
|
#include "base/database.h"
|
||||||
|
#include "base/mutate.h"
|
||||||
|
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
|
static NSSDatabase db = NSSDatabase();
|
||||||
|
|
||||||
PK11SlotInfo *slot = PK11_GetInternalSlot();
|
|
||||||
assert(slot);
|
|
||||||
|
|
||||||
SECItem derPki = {siBuffer, (unsigned char *)data, (unsigned int)size};
|
SECItem derPki = {siBuffer, (unsigned char *)data, (unsigned int)size};
|
||||||
|
|
||||||
|
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||||
|
assert(slot);
|
||||||
|
|
||||||
SECKEYPrivateKey *key = nullptr;
|
SECKEYPrivateKey *key = nullptr;
|
||||||
if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, &derPki, nullptr, nullptr,
|
if (PK11_ImportDERPrivateKeyInfoAndReturnKey(slot.get(), &derPki, nullptr,
|
||||||
false, false, KU_ALL, &key,
|
nullptr, false, false, KU_ALL,
|
||||||
nullptr) == SECSuccess) {
|
&key, nullptr) == SECSuccess) {
|
||||||
SECKEY_DestroyPrivateKey(key);
|
SECKEY_DestroyPrivateKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
PK11_FreeSlot(slot);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6,11 +6,13 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "asn1_mutators.h"
|
|
||||||
#include "certt.h"
|
#include "certt.h"
|
||||||
#include "keythi.h"
|
#include "keythi.h"
|
||||||
#include "secdert.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 = {
|
const std::vector<const SEC_ASN1Template *> templates = {
|
||||||
CERT_AttributeTemplate,
|
CERT_AttributeTemplate,
|
||||||
@@ -68,19 +70,19 @@ const std::vector<const SEC_ASN1Template *> templates = {
|
|||||||
SECKEY_RSAPublicKeyTemplate,
|
SECKEY_RSAPublicKeyTemplate,
|
||||||
SECOID_AlgorithmIDTemplate};
|
SECOID_AlgorithmIDTemplate};
|
||||||
|
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
char *dest[2048];
|
static char *dest[2048];
|
||||||
|
|
||||||
|
PORTCheapArenaPool pool;
|
||||||
|
PORT_InitCheapArena(&pool, DER_DEFAULT_CHUNKSIZE);
|
||||||
|
|
||||||
for (auto tpl : templates) {
|
for (auto tpl : templates) {
|
||||||
PORTCheapArenaPool pool;
|
SECItem buf = {siBuffer, (unsigned char *)data, (unsigned int)size};
|
||||||
SECItem buf = {siBuffer, const_cast<unsigned char *>(Data),
|
|
||||||
static_cast<unsigned int>(Size)};
|
|
||||||
|
|
||||||
PORT_InitCheapArena(&pool, DER_DEFAULT_CHUNKSIZE);
|
|
||||||
(void)SEC_QuickDERDecodeItem(&pool.arena, dest, tpl, &buf);
|
(void)SEC_QuickDERDecodeItem(&pool.arena, dest, tpl, &buf);
|
||||||
PORT_DestroyCheapArena(&pool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PORT_DestroyCheapArena(&pool);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
202
security/nss/fuzz/targets/targets.gyp
Normal file
202
security/nss/fuzz/targets/targets.gyp
Normal 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',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
@@ -12,36 +12,31 @@
|
|||||||
#include "ssl.h"
|
#include "ssl.h"
|
||||||
#include "sslimpl.h"
|
#include "sslimpl.h"
|
||||||
|
|
||||||
#include "shared.h"
|
#include "base/database.h"
|
||||||
#include "tls_client_config.h"
|
#include "base/mutate.h"
|
||||||
#include "tls_common.h"
|
#include "tls/client_config.h"
|
||||||
#include "tls_mutators.h"
|
#include "tls/common.h"
|
||||||
#include "tls_socket.h"
|
#include "tls/mutators.h"
|
||||||
|
#include "tls/socket.h"
|
||||||
|
|
||||||
#ifdef IS_DTLS_FUZZ
|
#ifdef IS_DTLS_FUZZ
|
||||||
__attribute__((constructor)) static void set_is_dtls() {
|
|
||||||
TlsMutators::SetIsDTLS();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ImportFD DTLS_ImportFD
|
#define ImportFD DTLS_ImportFD
|
||||||
#else
|
#else
|
||||||
#define ImportFD SSL_ImportFD
|
#define ImportFD SSL_ImportFD
|
||||||
#endif // IS_DTLS_FUZZ
|
#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 NSSDatabase db = NSSDatabase();
|
||||||
static PRDescIdentity id = PR_GetUniqueIdentity("fuzz-client");
|
static PRDescIdentity id = PR_GetUniqueIdentity("fuzz-client");
|
||||||
|
|
||||||
EnableAllProtocolVersions();
|
|
||||||
|
|
||||||
// Create and import dummy socket.
|
// Create and import dummy socket.
|
||||||
DummyPrSocket socket = DummyPrSocket(data, len);
|
TlsSocket::DummyPrSocket socket = TlsSocket::DummyPrSocket(data, size);
|
||||||
ScopedPRFileDesc prFd(DummyIOLayerMethods::CreateFD(id, &socket));
|
ScopedPRFileDesc prFd(DummyIOLayerMethods::CreateFD(id, &socket));
|
||||||
PRFileDesc* sslFd = ImportFD(nullptr, prFd.get());
|
PRFileDesc* sslFd = ImportFD(nullptr, prFd.get());
|
||||||
assert(sslFd == prFd.get());
|
assert(sslFd == prFd.get());
|
||||||
|
|
||||||
// Derive client config from input data.
|
// Derive client config from input data.
|
||||||
ClientConfig config = ClientConfig(data, len);
|
TlsClient::Config config = TlsClient::Config(data, size);
|
||||||
|
|
||||||
if (ssl_trace >= 90) {
|
if (ssl_trace >= 90) {
|
||||||
std::cerr << config << "\n";
|
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(RNG_RandomUpdate(NULL, 0) == SECSuccess);
|
||||||
assert(SSL_SetURL(sslFd, "fuzz.client") == SECSuccess);
|
assert(SSL_SetURL(sslFd, "fuzz.client") == SECSuccess);
|
||||||
|
|
||||||
FixTime(sslFd);
|
TlsCommon::EnableAllProtocolVersions();
|
||||||
EnableAllCipherSuites(sslFd);
|
TlsCommon::EnableAllCipherSuites(sslFd);
|
||||||
|
TlsCommon::FixTime(sslFd);
|
||||||
|
|
||||||
// Set socket callbacks & options from client config.
|
// Set socket callbacks & options from client config.
|
||||||
config.SetCallbacks(sslFd);
|
config.SetCallbacks(sslFd);
|
||||||
config.SetSocketOptions(sslFd);
|
config.SetSocketOptions(sslFd);
|
||||||
|
|
||||||
// Perform the acutal handshake.
|
// Perform the acutal handshake.
|
||||||
DoHandshake(sslFd, false);
|
TlsCommon::DoHandshake(sslFd, false);
|
||||||
|
|
||||||
// Release all SIDs.
|
// Release all SIDs.
|
||||||
SSL_ClearSessionCache();
|
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,
|
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,
|
Mutators mutators = {TlsMutators::DropRecord, TlsMutators::ShuffleRecords,
|
||||||
TlsMutators::DuplicateRecord,
|
TlsMutators::DuplicateRecord,
|
||||||
TlsMutators::TruncateRecord,
|
TlsMutators::TruncateRecord,
|
||||||
TlsMutators::FragmentRecord};
|
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,
|
extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t* data1, size_t size1,
|
||||||
const uint8_t* data2, size_t size2,
|
const uint8_t* data2, size_t size2,
|
||||||
uint8_t* out, size_t max_out_size,
|
uint8_t* out, size_t maxOutSize,
|
||||||
unsigned int seed) {
|
unsigned int seed) {
|
||||||
return TlsMutators::CrossOver(data1, size1, data2, size2, out, max_out_size,
|
return TlsMutators::CrossOver(data1, size1, data2, size2, out, maxOutSize,
|
||||||
seed);
|
seed);
|
||||||
}
|
}
|
||||||
@@ -11,22 +11,19 @@
|
|||||||
#include "ssl.h"
|
#include "ssl.h"
|
||||||
#include "sslimpl.h"
|
#include "sslimpl.h"
|
||||||
|
|
||||||
#include "shared.h"
|
#include "base/database.h"
|
||||||
#include "tls_common.h"
|
#include "base/mutate.h"
|
||||||
#include "tls_mutators.h"
|
#include "tls/common.h"
|
||||||
#include "tls_server_certs.h"
|
#include "tls/mutators.h"
|
||||||
#include "tls_server_config.h"
|
#include "tls/server_certs.h"
|
||||||
#include "tls_socket.h"
|
#include "tls/server_config.h"
|
||||||
|
#include "tls/socket.h"
|
||||||
|
|
||||||
#ifdef IS_DTLS_FUZZ
|
#ifdef IS_DTLS_FUZZ
|
||||||
__attribute__((constructor)) static void set_is_dtls() {
|
|
||||||
TlsMutators::SetIsDTLS();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ImportFD DTLS_ImportFD
|
#define ImportFD DTLS_ImportFD
|
||||||
#else
|
#else
|
||||||
#define ImportFD SSL_ImportFD
|
#define ImportFD SSL_ImportFD
|
||||||
#endif
|
#endif // IS_DTLS_FUZZ
|
||||||
|
|
||||||
class SSLServerSessionCache {
|
class SSLServerSessionCache {
|
||||||
public:
|
public:
|
||||||
@@ -42,13 +39,13 @@ class SSLServerSessionCache {
|
|||||||
static PRStatus InitModelSocket(void* arg) {
|
static PRStatus InitModelSocket(void* arg) {
|
||||||
PRFileDesc* fd = reinterpret_cast<PRFileDesc*>(arg);
|
PRFileDesc* fd = reinterpret_cast<PRFileDesc*>(arg);
|
||||||
|
|
||||||
EnableAllCipherSuites(fd);
|
TlsCommon::EnableAllCipherSuites(fd);
|
||||||
InstallServerCertificates(fd);
|
TlsServer::InstallServerCertificates(fd);
|
||||||
|
|
||||||
return PR_SUCCESS;
|
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 NSSDatabase db = NSSDatabase();
|
||||||
static SSLServerSessionCache cache = SSLServerSessionCache();
|
static SSLServerSessionCache cache = SSLServerSessionCache();
|
||||||
static PRDescIdentity id = PR_GetUniqueIdentity("fuzz-server");
|
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;
|
static PRCallOnceType initModelOnce;
|
||||||
PR_CallOnceWithArg(&initModelOnce, InitModelSocket, model.get());
|
PR_CallOnceWithArg(&initModelOnce, InitModelSocket, model.get());
|
||||||
|
|
||||||
EnableAllProtocolVersions();
|
|
||||||
|
|
||||||
// Create and import dummy socket.
|
// Create and import dummy socket.
|
||||||
DummyPrSocket socket = DummyPrSocket(data, len);
|
TlsSocket::DummyPrSocket socket = TlsSocket::DummyPrSocket(data, size);
|
||||||
ScopedPRFileDesc prFd(DummyIOLayerMethods::CreateFD(id, &socket));
|
ScopedPRFileDesc prFd(DummyIOLayerMethods::CreateFD(id, &socket));
|
||||||
PRFileDesc* sslFd = ImportFD(model.get(), prFd.get());
|
PRFileDesc* sslFd = ImportFD(model.get(), prFd.get());
|
||||||
assert(sslFd == prFd.get());
|
assert(sslFd == prFd.get());
|
||||||
|
|
||||||
// Derive server config from input data.
|
// Derive server config from input data.
|
||||||
ServerConfig config = ServerConfig(data, len);
|
TlsServer::Config config = TlsServer::Config(data, size);
|
||||||
|
|
||||||
if (ssl_trace >= 90) {
|
if (ssl_trace >= 90) {
|
||||||
std::cerr << config << "\n";
|
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(RNG_RandomUpdate(NULL, 0) == SECSuccess);
|
||||||
assert(SSL_SetURL(sslFd, "fuzz.server") == SECSuccess);
|
assert(SSL_SetURL(sslFd, "fuzz.server") == SECSuccess);
|
||||||
|
|
||||||
FixTime(sslFd);
|
TlsCommon::EnableAllProtocolVersions();
|
||||||
EnableAllCipherSuites(sslFd);
|
TlsCommon::EnableAllCipherSuites(sslFd);
|
||||||
|
TlsCommon::FixTime(sslFd);
|
||||||
|
|
||||||
// Set socket options from server config.
|
// Set socket options from server config.
|
||||||
config.SetCallbacks(sslFd);
|
config.SetCallbacks(sslFd);
|
||||||
config.SetSocketOptions(sslFd);
|
config.SetSocketOptions(sslFd);
|
||||||
|
|
||||||
// Perform the acutal handshake.
|
// 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.
|
// Clear the cache. We never want to resume as we couldn't reproduce that.
|
||||||
SSL_ClearSessionCache();
|
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,
|
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(
|
return CustomMutate(
|
||||||
{TlsMutators::DropRecord, TlsMutators::ShuffleRecords,
|
{TlsMutators::DropRecord, TlsMutators::ShuffleRecords,
|
||||||
TlsMutators::DuplicateRecord, TlsMutators::TruncateRecord,
|
TlsMutators::DuplicateRecord, TlsMutators::TruncateRecord,
|
||||||
TlsMutators::FragmentRecord},
|
TlsMutators::FragmentRecord},
|
||||||
data, size, max_size, seed);
|
data, size, maxSize, seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t* data1, size_t size1,
|
extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t* data1, size_t size1,
|
||||||
const uint8_t* data2, size_t size2,
|
const uint8_t* data2, size_t size2,
|
||||||
uint8_t* out, size_t max_out_size,
|
uint8_t* out, size_t maxOutSize,
|
||||||
unsigned int seed) {
|
unsigned int seed) {
|
||||||
return TlsMutators::CrossOver(data1, size1, data2, size2, out, max_out_size,
|
return TlsMutators::CrossOver(data1, size1, data2, size2, out, maxOutSize,
|
||||||
seed);
|
seed);
|
||||||
}
|
}
|
||||||
@@ -39,6 +39,11 @@
|
|||||||
'UNSAFE_FUZZER_MODE',
|
'UNSAFE_FUZZER_MODE',
|
||||||
],
|
],
|
||||||
}],
|
}],
|
||||||
|
['gtests_corpus==1', {
|
||||||
|
'defines': [
|
||||||
|
'GTESTS_CORPUS',
|
||||||
|
]
|
||||||
|
}]
|
||||||
],
|
],
|
||||||
'msvs_settings': {
|
'msvs_settings': {
|
||||||
'VCCLCompilerTool': {
|
'VCCLCompilerTool': {
|
||||||
|
|||||||
@@ -105,6 +105,16 @@ static const PresentedMatchesReference DNSID_MATCH_PARAMS[] =
|
|||||||
DNS_ID_MATCH("_example", "_example"),
|
DNS_ID_MATCH("_example", "_example"),
|
||||||
DNS_ID_MATCH("*._._", "x._._"),
|
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
|
// See bug 1139039
|
||||||
// A DNS-ID must not end in an all-numeric label. We don't consider
|
// A DNS-ID must not end in an all-numeric label. We don't consider
|
||||||
// underscores to be numeric.
|
// underscores to be numeric.
|
||||||
@@ -371,13 +381,13 @@ static const InputValidity DNSNAMES_VALIDITY[] =
|
|||||||
I("a...", false, false),
|
I("a...", false, false),
|
||||||
|
|
||||||
// Punycode
|
// Punycode
|
||||||
I("xn--", false, false),
|
I("xn--", true, false),
|
||||||
I("xn--.", false, false),
|
I("xn--.", true, false),
|
||||||
I("xn--.a", false, false),
|
I("xn--.a", true, false),
|
||||||
I("a.xn--", false, false),
|
I("a.xn--", true, false),
|
||||||
I("a.xn--.", false, false),
|
I("a.xn--.", true, false),
|
||||||
I("a.xn--.b", false, false),
|
I("a.xn--.b", true, false),
|
||||||
I("a.xn--.b", false, false),
|
I("a.xn--.b", true, false),
|
||||||
I("a.xn--\0.b", false, false),
|
I("a.xn--\0.b", false, false),
|
||||||
I("a.xn--a.b", true, true),
|
I("a.xn--a.b", true, true),
|
||||||
I("xn--a", 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("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("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
|
// Underscores
|
||||||
I("a_b", true, true),
|
I("a_b", true, true),
|
||||||
@@ -469,17 +479,17 @@ static const InputValidity DNSNAMES_VALIDITY[] =
|
|||||||
I("a.1-1", true, true),
|
I("a.1-1", true, true),
|
||||||
I("a.1-a", true, true),
|
I("a.1-a", true, true),
|
||||||
|
|
||||||
// labels cannot start with a hyphen
|
// presented ID labels cannot start with a hyphen
|
||||||
I("-", false, false),
|
I("-", true, false),
|
||||||
I("-1", false, false),
|
I("-1", true, false),
|
||||||
|
|
||||||
// labels cannot end with a hyphen
|
// presented ID labels cannot end with a hyphen
|
||||||
I("1-", false, false),
|
I("1-", true, false),
|
||||||
I("1-.a", false, false),
|
I("1-.a", true, false),
|
||||||
I("a-", false, false),
|
I("a-", true, false),
|
||||||
I("a-.a", false, false),
|
I("a-.a", true, false),
|
||||||
I("a.1-.a", false, false),
|
I("a.1-.a", true, false),
|
||||||
I("a.a-.a", false, false),
|
I("a.a-.a", true, false),
|
||||||
|
|
||||||
// labels can contain a hyphen in the middle
|
// labels can contain a hyphen in the middle
|
||||||
I("a-b", true, true),
|
I("a-b", true, true),
|
||||||
|
|||||||
@@ -155,4 +155,84 @@ TEST_F(Pkcs11NonAsciiTest, LoadUnload) {
|
|||||||
}
|
}
|
||||||
#endif // defined(_WIN32)
|
#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
|
} // namespace nss_test
|
||||||
|
|||||||
@@ -25,48 +25,46 @@ namespace nss_test {
|
|||||||
static std::unordered_set<PRInt32> gFuzzedSslOptions = {
|
static std::unordered_set<PRInt32> gFuzzedSslOptions = {
|
||||||
SSL_SECURITY, // irrelevant
|
SSL_SECURITY, // irrelevant
|
||||||
SSL_SOCKS, // irrelevant
|
SSL_SOCKS, // irrelevant
|
||||||
SSL_REQUEST_CERTIFICATE, // tls_server_fuzz_target
|
SSL_REQUEST_CERTIFICATE, // tls_server
|
||||||
SSL_HANDSHAKE_AS_CLIENT, // irrelevant
|
SSL_HANDSHAKE_AS_CLIENT, // irrelevant
|
||||||
SSL_HANDSHAKE_AS_SERVER, // irrelevant
|
SSL_HANDSHAKE_AS_SERVER, // irrelevant
|
||||||
SSL_ENABLE_SSL2, // obsolete
|
SSL_ENABLE_SSL2, // obsolete
|
||||||
SSL_ENABLE_SSL3, // obsolete
|
SSL_ENABLE_SSL3, // obsolete
|
||||||
SSL_NO_CACHE, // tls_client_fuzz_target, tls_server_fuzz_target
|
SSL_NO_CACHE, // tls_client, tls_server
|
||||||
SSL_REQUIRE_CERTIFICATE, // tls_server_fuzz_target
|
SSL_REQUIRE_CERTIFICATE, // tls_server
|
||||||
SSL_ENABLE_FDX,
|
SSL_ENABLE_FDX,
|
||||||
SSL_V2_COMPATIBLE_HELLO, // obsolete
|
SSL_V2_COMPATIBLE_HELLO, // obsolete
|
||||||
SSL_ENABLE_TLS, // obsolete
|
SSL_ENABLE_TLS, // obsolete
|
||||||
SSL_ROLLBACK_DETECTION,
|
SSL_ROLLBACK_DETECTION,
|
||||||
SSL_NO_STEP_DOWN, // unsupported
|
SSL_NO_STEP_DOWN, // unsupported
|
||||||
SSL_BYPASS_PKCS11, // unsupported
|
SSL_BYPASS_PKCS11, // unsupported
|
||||||
SSL_NO_LOCKS, // tls_client_fuzz_target. tls_server_fuzz_target
|
SSL_NO_LOCKS, // tls_client, tls_server
|
||||||
SSL_ENABLE_SESSION_TICKETS, // tls_client_fuzz_target,
|
SSL_ENABLE_SESSION_TICKETS, // tls_client, tls_server
|
||||||
// tls_server_fuzz_target
|
SSL_ENABLE_DEFLATE, // tls_client, tls_server
|
||||||
SSL_ENABLE_DEFLATE, // tls_client_fuzz_target, tls_server_fuzz_target
|
|
||||||
SSL_ENABLE_RENEGOTIATION,
|
SSL_ENABLE_RENEGOTIATION,
|
||||||
SSL_REQUIRE_SAFE_NEGOTIATION, // tls_client_fuzz_target,
|
SSL_REQUIRE_SAFE_NEGOTIATION, // tls_client, tls_server
|
||||||
// tls_server_fuzz_target
|
SSL_ENABLE_FALSE_START, // tls_client
|
||||||
SSL_ENABLE_FALSE_START, // tls_client_fuzz_target
|
SSL_CBC_RANDOM_IV, // tls_client, tls_server
|
||||||
SSL_CBC_RANDOM_IV, // tls_client_fuzz_target, tls_server_fuzz_target
|
SSL_ENABLE_OCSP_STAPLING, // tls_client
|
||||||
SSL_ENABLE_OCSP_STAPLING, // tls_client_fuzz_target
|
SSL_ENABLE_NPN, // defunct
|
||||||
SSL_ENABLE_NPN, // defunct
|
SSL_ENABLE_ALPN, // tls_client, tls_server
|
||||||
SSL_ENABLE_ALPN, // tls_client_fuzz_target, tls_server_fuzz_target
|
|
||||||
SSL_REUSE_SERVER_ECDHE_KEY,
|
SSL_REUSE_SERVER_ECDHE_KEY,
|
||||||
SSL_ENABLE_FALLBACK_SCSV, // tls_client_fuzz_target,
|
SSL_ENABLE_FALLBACK_SCSV, // tls_client, tls_server
|
||||||
// tls_server_fuzz_target
|
|
||||||
SSL_ENABLE_SERVER_DHE,
|
SSL_ENABLE_SERVER_DHE,
|
||||||
SSL_ENABLE_EXTENDED_MASTER_SECRET, // tls_client_fuzz_target,
|
SSL_ENABLE_EXTENDED_MASTER_SECRET, // tls_client, tls_server
|
||||||
// tls_server_fuzz_target
|
|
||||||
SSL_ENABLE_SIGNED_CERT_TIMESTAMPS,
|
SSL_ENABLE_SIGNED_CERT_TIMESTAMPS,
|
||||||
SSL_REQUIRE_DH_NAMED_GROUPS, // tls_client_fuzz_target
|
SSL_REQUIRE_DH_NAMED_GROUPS, // tls_client
|
||||||
SSL_ENABLE_0RTT_DATA, // tls_client_fuzz_target, tls_server_fuzz_target
|
SSL_ENABLE_0RTT_DATA, // tls_client, tls_server
|
||||||
SSL_RECORD_SIZE_LIMIT,
|
SSL_RECORD_SIZE_LIMIT,
|
||||||
SSL_ENABLE_TLS13_COMPAT_MODE, // tls_client_fuzz_target
|
SSL_ENABLE_TLS13_COMPAT_MODE, // tls_client
|
||||||
SSL_ENABLE_DTLS_SHORT_HEADER, SSL_ENABLE_HELLO_DOWNGRADE_CHECK,
|
SSL_ENABLE_DTLS_SHORT_HEADER, // tls_client, tls_server
|
||||||
|
SSL_ENABLE_HELLO_DOWNGRADE_CHECK,
|
||||||
SSL_ENABLE_V2_COMPATIBLE_HELLO,
|
SSL_ENABLE_V2_COMPATIBLE_HELLO,
|
||||||
SSL_ENABLE_POST_HANDSHAKE_AUTH, // tls_client_fuzz_target
|
SSL_ENABLE_POST_HANDSHAKE_AUTH, // tls_client
|
||||||
SSL_ENABLE_DELEGATED_CREDENTIALS, SSL_SUPPRESS_END_OF_EARLY_DATA,
|
SSL_ENABLE_DELEGATED_CREDENTIALS, // tls_client, tls_server
|
||||||
SSL_ENABLE_GREASE, // tls_client_fuzz_target, tls_server_fuzz_target
|
SSL_SUPPRESS_END_OF_EARLY_DATA,
|
||||||
SSL_ENABLE_CH_EXTENSION_PERMUTATION, // tls_client_fuzz_target
|
SSL_ENABLE_GREASE, // tls_client, tls_server
|
||||||
|
SSL_ENABLE_CH_EXTENSION_PERMUTATION, // tls_client
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t kShortEmptyFinished[8] = {0};
|
const uint8_t kShortEmptyFinished[8] = {0};
|
||||||
|
|||||||
@@ -8,9 +8,14 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <sstream>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "blapi.h"
|
||||||
#include "prerror.h"
|
#include "prerror.h"
|
||||||
#include "prlog.h"
|
#include "prlog.h"
|
||||||
#include "prthread.h"
|
#include "prthread.h"
|
||||||
@@ -25,6 +30,45 @@ namespace nss_test {
|
|||||||
if (g_ssl_gtest_verbose) LOG(a); \
|
if (g_ssl_gtest_verbose) LOG(a); \
|
||||||
} while (false)
|
} 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() {
|
PRDescIdentity DummyPrSocket::LayerId() {
|
||||||
static PRDescIdentity id = PR_GetUniqueIdentity("dummysocket");
|
static PRDescIdentity id = PR_GetUniqueIdentity("dummysocket");
|
||||||
return id;
|
return id;
|
||||||
@@ -49,6 +93,11 @@ void DummyPrSocket::Reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DummyPrSocket::PacketReceived(const DataBuffer &packet) {
|
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));
|
input_.push(Packet(packet));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,8 +67,9 @@ class DummyPrSocket : public DummyIOLayerMethods {
|
|||||||
peer_(),
|
peer_(),
|
||||||
input_(),
|
input_(),
|
||||||
filter_(nullptr),
|
filter_(nullptr),
|
||||||
write_error_(0) {}
|
write_error_(0),
|
||||||
virtual ~DummyPrSocket() {}
|
receivedData_() {}
|
||||||
|
virtual ~DummyPrSocket();
|
||||||
|
|
||||||
static PRDescIdentity LayerId();
|
static PRDescIdentity LayerId();
|
||||||
|
|
||||||
@@ -117,6 +118,8 @@ class DummyPrSocket : public DummyIOLayerMethods {
|
|||||||
std::queue<Packet> input_;
|
std::queue<Packet> input_;
|
||||||
std::shared_ptr<PacketFilter> filter_;
|
std::shared_ptr<PacketFilter> filter_;
|
||||||
PRErrorCode write_error_;
|
PRErrorCode write_error_;
|
||||||
|
|
||||||
|
std::vector<uint8_t> receivedData_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Marker interface.
|
// Marker interface.
|
||||||
|
|||||||
@@ -577,9 +577,11 @@ get_token_objects_for_cache(
|
|||||||
} else {
|
} else {
|
||||||
PRUint32 j;
|
PRUint32 j;
|
||||||
for (j = 0; j < i; j++) {
|
for (j = 0; j < i; j++) {
|
||||||
/* Any token references that were removed in successful loop iterations
|
/* Objects that were successfully added to the cache do not own a
|
||||||
* need to be restored before we call nssCryptokiObjectArray_Destroy */
|
* token reference (they share a reference with the cache itself).
|
||||||
nssToken_AddRef(cache->objects[objectType][j]->object->token);
|
* 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);
|
nssArena_Destroy(cache->objects[objectType][j]->arena);
|
||||||
}
|
}
|
||||||
nss_ZFreeIf(cache->objects[objectType]);
|
nss_ZFreeIf(cache->objects[objectType]);
|
||||||
|
|||||||
@@ -512,7 +512,7 @@ AESKeyWrap_EncryptKWP(AESKeyWrapContext *cx, unsigned char *output,
|
|||||||
PORT_Memcpy(iv + AES_KEY_WRAP_BLOCK_SIZE, input, inputLen);
|
PORT_Memcpy(iv + AES_KEY_WRAP_BLOCK_SIZE, input, inputLen);
|
||||||
rv = AES_Encrypt(&cx->aescx, output, pOutputLen, maxOutputLen, iv,
|
rv = AES_Encrypt(&cx->aescx, output, pOutputLen, maxOutputLen, iv,
|
||||||
outLen);
|
outLen);
|
||||||
PORT_Memset(iv, 0, sizeof(iv));
|
PORT_SafeZero(iv, sizeof(iv));
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,7 +528,7 @@ AESKeyWrap_EncryptKWP(AESKeyWrapContext *cx, unsigned char *output,
|
|||||||
PORT_ZFree(newBuf, paddedInputLen);
|
PORT_ZFree(newBuf, paddedInputLen);
|
||||||
/* a little overkill, we only need to clear out the length, but this
|
/* a little overkill, we only need to clear out the length, but this
|
||||||
* is easier to verify we got it all */
|
* is easier to verify we got it all */
|
||||||
PORT_Memset(iv, 0, sizeof(iv));
|
PORT_SafeZero(iv, sizeof(iv));
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -631,12 +631,12 @@ AESKeyWrap_DecryptKWP(AESKeyWrapContext *cx, unsigned char *output,
|
|||||||
loser:
|
loser:
|
||||||
/* if we failed, make sure we don't return any data to the user */
|
/* if we failed, make sure we don't return any data to the user */
|
||||||
if ((rv != SECSuccess) && (output == newBuf)) {
|
if ((rv != SECSuccess) && (output == newBuf)) {
|
||||||
PORT_Memset(newBuf, 0, paddedLen);
|
PORT_SafeZero(newBuf, paddedLen);
|
||||||
}
|
}
|
||||||
/* clear out CSP sensitive data from the heap and stack */
|
/* clear out CSP sensitive data from the heap and stack */
|
||||||
if (allocBuf) {
|
if (allocBuf) {
|
||||||
PORT_ZFree(allocBuf, paddedLen);
|
PORT_ZFree(allocBuf, paddedLen);
|
||||||
}
|
}
|
||||||
PORT_Memset(iv, 0, sizeof(iv));
|
PORT_SafeZero(iv, sizeof(iv));
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,10 +113,10 @@ PRBool ppc_crypto_support();
|
|||||||
#ifdef NSS_FIPS_DISABLED
|
#ifdef NSS_FIPS_DISABLED
|
||||||
#define BLAPI_CLEAR_STACK(stack_size)
|
#define BLAPI_CLEAR_STACK(stack_size)
|
||||||
#else
|
#else
|
||||||
#define BLAPI_CLEAR_STACK(stack_size) \
|
#define BLAPI_CLEAR_STACK(stack_size) \
|
||||||
{ \
|
{ \
|
||||||
volatile char _stkclr[stack_size]; \
|
volatile char _stkclr[stack_size]; \
|
||||||
PORT_Memset((void *)&_stkclr[0], 0, stack_size); \
|
PORT_SafeZero((void *)&_stkclr[0], stack_size); \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
EXTRA_SHARED_LIBS += -dylib_file @executable_path/libplc4.dylib:$(DIST)/lib/libplc4.dylib -dylib_file @executable_path/libplds4.dylib:$(DIST)/lib/libplds4.dylib
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef NSS_FIPS_140_3
|
||||||
|
DEFINES += -DNSS_FIPS_140_3
|
||||||
|
endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ prng_Hash_df(PRUint8 *requested_bytes, unsigned int no_of_bytes_to_return,
|
|||||||
unsigned int hash_return_len;
|
unsigned int hash_return_len;
|
||||||
SHA256_Begin(&ctx);
|
SHA256_Begin(&ctx);
|
||||||
SHA256_Update(&ctx, &counter, 1);
|
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);
|
SHA256_Update(&ctx, input_string_1, input_string_1_len);
|
||||||
if (input_string_2) {
|
if (input_string_2) {
|
||||||
SHA256_Update(&ctx, input_string_2, input_string_2_len);
|
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);
|
prng_Hash_df(V(rng), VSize(rng), bytes, len, NULL, 0);
|
||||||
rng->V_type = prngCGenerateType;
|
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)
|
PRNG_RESET_RESEED_COUNT(rng)
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
@@ -197,7 +198,7 @@ prng_initEntropy(void)
|
|||||||
SHA256_Update(&ctx, block, sizeof(block));
|
SHA256_Update(&ctx, block, sizeof(block));
|
||||||
SHA256_End(&ctx, globalrng->previousEntropyHash, NULL,
|
SHA256_End(&ctx, globalrng->previousEntropyHash, NULL,
|
||||||
sizeof(globalrng->previousEntropyHash));
|
sizeof(globalrng->previousEntropyHash));
|
||||||
PORT_Memset(block, 0, sizeof(block));
|
PORT_SafeZero(block, sizeof(block));
|
||||||
SHA256_DestroyContext(&ctx, PR_FALSE);
|
SHA256_DestroyContext(&ctx, PR_FALSE);
|
||||||
return PR_SUCCESS;
|
return PR_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -246,8 +247,8 @@ prng_getEntropy(PRUint8 *buffer, size_t requestLength)
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
PORT_Memset(hash, 0, sizeof hash);
|
PORT_SafeZero(hash, sizeof(hash));
|
||||||
PORT_Memset(block, 0, sizeof block);
|
PORT_SafeZero(block, sizeof(block));
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,14 +263,14 @@ static SECStatus
|
|||||||
prng_reseed(RNGContext *rng, const PRUint8 *entropy, unsigned int entropy_len,
|
prng_reseed(RNGContext *rng, const PRUint8 *entropy, unsigned int entropy_len,
|
||||||
const PRUint8 *additional_input, unsigned int additional_input_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];
|
PRUint8 *noise = &noiseData[0];
|
||||||
SECStatus rv;
|
SECStatus rv;
|
||||||
|
|
||||||
/* if entropy wasn't supplied, fetch it. (normal operation case) */
|
/* if entropy wasn't supplied, fetch it. (normal operation case) */
|
||||||
if (entropy == NULL) {
|
if (entropy == NULL) {
|
||||||
entropy_len = PRNG_SEEDLEN;
|
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) {
|
if (rv != SECSuccess) {
|
||||||
return SECFailure; /* error is already set */
|
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 */
|
/* 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 was too big for the stack variable, get it from malloc */
|
||||||
if (entropy_len > PRNG_SEEDLEN) {
|
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) {
|
if (noise == NULL) {
|
||||||
return SECFailure;
|
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) {
|
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;
|
rng->V_type = prngReseedType;
|
||||||
PORT_Memcpy(noise, rng->V_Data, sizeof rng->V_Data);
|
PORT_Memcpy(noise, rng->V_Data, sizeof(rng->V_Data));
|
||||||
prng_Hash_df(V(rng), VSize(rng), noise, (sizeof rng->V_Data) + entropy_len,
|
prng_Hash_df(V(rng), VSize(rng), noise, (sizeof(rng->V_Data)) + entropy_len,
|
||||||
additional_input, additional_input_len);
|
additional_input, additional_input_len);
|
||||||
/* clear potential CSP */
|
/* 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;
|
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)
|
PRNG_RESET_RESEED_COUNT(rng)
|
||||||
|
|
||||||
if (noise != &noiseData[0]) {
|
if (noise != &noiseData[0]) {
|
||||||
@@ -379,7 +381,7 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
|
|||||||
unsigned int carry;
|
unsigned int carry;
|
||||||
|
|
||||||
SHA256_Begin(&ctx);
|
SHA256_Begin(&ctx);
|
||||||
SHA256_Update(&ctx, data, sizeof data);
|
SHA256_Update(&ctx, data, sizeof(data));
|
||||||
SHA256_End(&ctx, thisHash, &len, SHA256_LENGTH);
|
SHA256_End(&ctx, thisHash, &len, SHA256_LENGTH);
|
||||||
if (no_of_returned_bytes < SHA256_LENGTH) {
|
if (no_of_returned_bytes < SHA256_LENGTH) {
|
||||||
len = no_of_returned_bytes;
|
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).
|
/* The carry parameter is a bool (increment or not).
|
||||||
* This increments data if no_of_returned_bytes is not zero */
|
* This increments data if no_of_returned_bytes is not zero */
|
||||||
carry = no_of_returned_bytes;
|
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);
|
SHA256_DestroyContext(&ctx, PR_FALSE);
|
||||||
}
|
}
|
||||||
PORT_Memset(data, 0, sizeof data);
|
PORT_SafeZero(data, sizeof(data));
|
||||||
PORT_Memset(thisHash, 0, sizeof thisHash);
|
PORT_SafeZero(thisHash, sizeof(thisHash));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -429,11 +431,11 @@ prng_generateNewBytes(RNGContext *rng,
|
|||||||
#define w H
|
#define w H
|
||||||
rng->V_type = prngAdditionalDataType;
|
rng->V_type = prngAdditionalDataType;
|
||||||
SHA256_Begin(&ctx);
|
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_Update(&ctx, additional_input, additional_input_len);
|
||||||
SHA256_End(&ctx, w, NULL, sizeof w);
|
SHA256_End(&ctx, w, NULL, sizeof(w));
|
||||||
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof w, carry)
|
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof(w), carry)
|
||||||
PORT_Memset(w, 0, sizeof w);
|
PORT_Memset(w, 0, sizeof(w));
|
||||||
SHA256_DestroyContext(&ctx, PR_FALSE);
|
SHA256_DestroyContext(&ctx, PR_FALSE);
|
||||||
#undef w
|
#undef w
|
||||||
}
|
}
|
||||||
@@ -446,16 +448,16 @@ prng_generateNewBytes(RNGContext *rng,
|
|||||||
}
|
}
|
||||||
/* advance our internal state... */
|
/* advance our internal state... */
|
||||||
rng->V_type = prngGenerateByteType;
|
rng->V_type = prngGenerateByteType;
|
||||||
SHA256_HashBuf(H, rng->V_Data, sizeof rng->V_Data);
|
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_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(V(rng), VSize(rng), rng->C, sizeof(rng->C), carry);
|
||||||
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), rng->reseed_counter,
|
PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), rng->reseed_counter,
|
||||||
sizeof rng->reseed_counter, carry)
|
sizeof(rng->reseed_counter), carry)
|
||||||
carry = 1;
|
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 */
|
/* 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) {
|
if (!rng->isValid) {
|
||||||
PORT_Memset(returned_bytes, 0, no_of_returned_bytes);
|
PORT_Memset(returned_bytes, 0, no_of_returned_bytes);
|
||||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||||
@@ -491,17 +493,17 @@ rng_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Try to get some seed data for the RNG */
|
/* 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 (rv == SECSuccess) {
|
||||||
/* if this is our first call, instantiate, otherwise reseed
|
/* if this is our first call, instantiate, otherwise reseed
|
||||||
* prng_instantiate gets a new clean state, we want to mix
|
* prng_instantiate gets a new clean state, we want to mix
|
||||||
* any previous entropy we may have collected */
|
* any previous entropy we may have collected */
|
||||||
if (V(globalrng)[0] == 0) {
|
if (V(globalrng)[0] == 0) {
|
||||||
rv = prng_instantiate(globalrng, bytes, sizeof bytes);
|
rv = prng_instantiate(globalrng, bytes, sizeof(bytes));
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
PZ_DestroyLock(globalrng->lock);
|
PZ_DestroyLock(globalrng->lock);
|
||||||
globalrng->lock = NULL;
|
globalrng->lock = NULL;
|
||||||
@@ -532,20 +534,20 @@ rng_init(void)
|
|||||||
static void
|
static void
|
||||||
prng_freeRNGContext(RNGContext *rng)
|
prng_freeRNGContext(RNGContext *rng)
|
||||||
{
|
{
|
||||||
PRUint8 inputhash[VSize(rng) + (sizeof rng->C)];
|
PRUint8 inputhash[VSize(rng) + (sizeof(rng->C))];
|
||||||
|
|
||||||
/* destroy context lock */
|
/* destroy context lock */
|
||||||
SKIP_AFTER_FORK(PZ_DestroyLock(globalrng->lock));
|
SKIP_AFTER_FORK(PZ_DestroyLock(globalrng->lock));
|
||||||
|
|
||||||
/* zero global RNG context except for C & V to preserve entropy */
|
/* 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), 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)], VSize(rng), V(rng), VSize(rng),
|
||||||
NULL, 0);
|
NULL, 0);
|
||||||
memset(rng, 0, sizeof *rng);
|
memset(rng, 0, sizeof(*rng));
|
||||||
memcpy(rng->C, inputhash, sizeof rng->C);
|
memcpy(rng->C, inputhash, sizeof(rng->C));
|
||||||
memcpy(V(rng), &inputhash[sizeof rng->C], VSize(rng));
|
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)) {
|
if (bytes > sizeof(globalrng->additionalDataCache)) {
|
||||||
rv = prng_reseed_test(globalrng, NULL, 0, data, (unsigned int)bytes);
|
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 */
|
/* 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,
|
PORT_Memcpy(globalrng->additionalDataCache + globalrng->additionalAvail,
|
||||||
data, bytes);
|
data, bytes);
|
||||||
globalrng->additionalAvail += (PRUint32)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
|
* remainder. We know the remainder will fit in the buffer because
|
||||||
* we already handled the case where bytes > the size of the buffer.
|
* 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 */
|
/* fill the rest of the buffer */
|
||||||
if (bufRemain) {
|
if (bufRemain) {
|
||||||
PORT_Memcpy(globalrng->additionalDataCache + globalrng->additionalAvail,
|
PORT_Memcpy(globalrng->additionalDataCache + globalrng->additionalAvail,
|
||||||
@@ -643,7 +645,7 @@ RNG_RandomUpdate(const void *data, size_t bytes)
|
|||||||
/* reseed from buffer */
|
/* reseed from buffer */
|
||||||
rv = prng_reseed_test(globalrng, NULL, 0,
|
rv = prng_reseed_test(globalrng, NULL, 0,
|
||||||
globalrng->additionalDataCache,
|
globalrng->additionalDataCache,
|
||||||
sizeof globalrng->additionalDataCache);
|
sizeof(globalrng->additionalDataCache));
|
||||||
|
|
||||||
/* copy the rest into the cache */
|
/* copy the rest into the cache */
|
||||||
PORT_Memcpy(globalrng->additionalDataCache, data, bytes);
|
PORT_Memcpy(globalrng->additionalDataCache, data, bytes);
|
||||||
@@ -693,21 +695,21 @@ prng_GenerateGlobalRandomBytes(RNGContext *rng,
|
|||||||
* see if we have enough bytes to fulfill the request.
|
* see if we have enough bytes to fulfill the request.
|
||||||
*/
|
*/
|
||||||
if (len <= rng->dataAvail) {
|
if (len <= rng->dataAvail) {
|
||||||
memcpy(output, rng->data + ((sizeof rng->data) - rng->dataAvail), len);
|
memcpy(output, rng->data + ((sizeof(rng->data)) - rng->dataAvail), len);
|
||||||
memset(rng->data + ((sizeof rng->data) - rng->dataAvail), 0, len);
|
memset(rng->data + ((sizeof(rng->data)) - rng->dataAvail), 0, len);
|
||||||
rng->dataAvail -= len;
|
rng->dataAvail -= len;
|
||||||
rv = SECSuccess;
|
rv = SECSuccess;
|
||||||
/* if we are asking for a small number of bytes, cache the rest of
|
/* if we are asking for a small number of bytes, cache the rest of
|
||||||
* the bytes */
|
* the bytes */
|
||||||
} else if (len < sizeof rng->data) {
|
} else if (len < sizeof(rng->data)) {
|
||||||
rv = prng_generateNewBytes(rng, rng->data, sizeof rng->data,
|
rv = prng_generateNewBytes(rng, rng->data, sizeof(rng->data),
|
||||||
rng->additionalAvail ? rng->additionalDataCache : NULL,
|
rng->additionalAvail ? rng->additionalDataCache : NULL,
|
||||||
rng->additionalAvail);
|
rng->additionalAvail);
|
||||||
rng->additionalAvail = 0;
|
rng->additionalAvail = 0;
|
||||||
if (rv == SECSuccess) {
|
if (rv == SECSuccess) {
|
||||||
memcpy(output, rng->data, len);
|
memcpy(output, rng->data, len);
|
||||||
memset(rng->data, 0, 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 */
|
/* we are asking for lots of bytes, just ask the generator to pass them */
|
||||||
} else {
|
} else {
|
||||||
@@ -858,7 +860,7 @@ PRNGTEST_Uninstantiate()
|
|||||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
PORT_Memset(&testContext, 0, sizeof testContext);
|
PORT_Memset(&testContext, 0, sizeof(testContext));
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -943,31 +945,31 @@ PRNGTEST_RunHealthTests()
|
|||||||
/********************************************/
|
/********************************************/
|
||||||
/* Generate random bytes with a known seed. */
|
/* 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);
|
NULL, 0, NULL, 0);
|
||||||
if (rng_status != SECSuccess) {
|
if (rng_status != SECSuccess) {
|
||||||
/* Error set by PRNGTEST_Instantiate */
|
/* Error set by PRNGTEST_Instantiate */
|
||||||
return SECFailure;
|
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) ||
|
if ((rng_status != SECSuccess) ||
|
||||||
(PORT_Memcmp(result, rng_known_result,
|
(PORT_Memcmp(result, rng_known_result,
|
||||||
sizeof rng_known_result) != 0)) {
|
sizeof(rng_known_result)) != 0)) {
|
||||||
PRNGTEST_Uninstantiate();
|
PRNGTEST_Uninstantiate();
|
||||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
rng_status = PRNGTEST_Reseed(reseed_entropy, sizeof reseed_entropy,
|
rng_status = PRNGTEST_Reseed(reseed_entropy, sizeof(reseed_entropy),
|
||||||
additional_input, sizeof additional_input);
|
additional_input, sizeof(additional_input));
|
||||||
if (rng_status != SECSuccess) {
|
if (rng_status != SECSuccess) {
|
||||||
/* Error set by PRNG_Reseed */
|
/* Error set by PRNG_Reseed */
|
||||||
PRNGTEST_Uninstantiate();
|
PRNGTEST_Uninstantiate();
|
||||||
return SECFailure;
|
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) ||
|
if ((rng_status != SECSuccess) ||
|
||||||
(PORT_Memcmp(result, rng_reseed_result,
|
(PORT_Memcmp(result, rng_reseed_result,
|
||||||
sizeof rng_reseed_result) != 0)) {
|
sizeof(rng_reseed_result)) != 0)) {
|
||||||
PRNGTEST_Uninstantiate();
|
PRNGTEST_Uninstantiate();
|
||||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
@@ -981,13 +983,13 @@ PRNGTEST_RunHealthTests()
|
|||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
/* This generate should now reseed */
|
/* 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) ||
|
if ((rng_status != SECSuccess) ||
|
||||||
/* NOTE we fail if the result is equal to the no_reseed_result.
|
/* 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
|
* no_reseed_result is the value we would have gotten if we didn't
|
||||||
* do an automatic reseed in PRNGTEST_Generate */
|
* do an automatic reseed in PRNGTEST_Generate */
|
||||||
(PORT_Memcmp(result, rng_no_reseed_result,
|
(PORT_Memcmp(result, rng_no_reseed_result,
|
||||||
sizeof rng_no_reseed_result) == 0)) {
|
sizeof(rng_no_reseed_result)) == 0)) {
|
||||||
PRNGTEST_Uninstantiate();
|
PRNGTEST_Uninstantiate();
|
||||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
|
|||||||
err = MP_OKAY;
|
err = MP_OKAY;
|
||||||
signature->len = dsa_signature_len;
|
signature->len = dsa_signature_len;
|
||||||
cleanup:
|
cleanup:
|
||||||
PORT_Memset(localDigestData, 0, DSA_MAX_SUBPRIME_LEN);
|
PORT_SafeZero(localDigestData, DSA_MAX_SUBPRIME_LEN);
|
||||||
mp_clear(&p);
|
mp_clear(&p);
|
||||||
mp_clear(&q);
|
mp_clear(&q);
|
||||||
mp_clear(&g);
|
mp_clear(&g);
|
||||||
@@ -532,7 +532,7 @@ DSA_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest)
|
|||||||
rv = dsa_SignDigest(key, signature, digest, kSeed);
|
rv = dsa_SignDigest(key, signature, digest, kSeed);
|
||||||
} while (rv != SECSuccess && PORT_GetError() == SEC_ERROR_NEED_RANDOM &&
|
} while (rv != SECSuccess && PORT_GetError() == SEC_ERROR_NEED_RANDOM &&
|
||||||
--retries > 0);
|
--retries > 0);
|
||||||
PORT_Memset(kSeed, 0, sizeof kSeed);
|
PORT_SafeZero(kSeed, sizeof kSeed);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,7 +673,7 @@ DSA_VerifyDigest(DSAPublicKey *key, const SECItem *signature,
|
|||||||
verified = SECSuccess; /* Signature verified. */
|
verified = SECSuccess; /* Signature verified. */
|
||||||
}
|
}
|
||||||
cleanup:
|
cleanup:
|
||||||
PORT_Memset(localDigestData, 0, sizeof localDigestData);
|
PORT_SafeZero(localDigestData, sizeof localDigestData);
|
||||||
mp_clear(&p);
|
mp_clear(&p);
|
||||||
mp_clear(&q);
|
mp_clear(&q);
|
||||||
mp_clear(&g);
|
mp_clear(&g);
|
||||||
|
|||||||
@@ -480,7 +480,7 @@ gcmHash_Final(gcmHashContext *ghash, unsigned char *outbuf,
|
|||||||
rv = SECSuccess;
|
rv = SECSuccess;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
PORT_Memset(T, 0, sizeof(T));
|
PORT_SafeZero(T, sizeof(T));
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,15 +596,15 @@ GCM_CreateContext(void *context, freeblCipherFunc cipher,
|
|||||||
if (rv != SECSuccess) {
|
if (rv != SECSuccess) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
PORT_Memset(H, 0, AES_BLOCK_SIZE);
|
PORT_SafeZero(H, AES_BLOCK_SIZE);
|
||||||
gcm->ctr_context_init = PR_TRUE;
|
gcm->ctr_context_init = PR_TRUE;
|
||||||
return gcm;
|
return gcm;
|
||||||
|
|
||||||
loser:
|
loser:
|
||||||
PORT_Memset(H, 0, AES_BLOCK_SIZE);
|
PORT_SafeZero(H, AES_BLOCK_SIZE);
|
||||||
if (ghash && ghash->mem) {
|
if (ghash && ghash->mem) {
|
||||||
void *mem = ghash->mem;
|
void *mem = ghash->mem;
|
||||||
PORT_Memset(ghash, 0, sizeof(gcmHashContext));
|
PORT_SafeZero(ghash, sizeof(gcmHashContext));
|
||||||
PORT_Free(mem);
|
PORT_Free(mem);
|
||||||
}
|
}
|
||||||
if (gcm) {
|
if (gcm) {
|
||||||
@@ -682,11 +682,11 @@ gcm_InitCounter(GCMContext *gcm, const unsigned char *iv, unsigned int ivLen,
|
|||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|
||||||
PORT_Memset(&ctrParams, 0, sizeof ctrParams);
|
PORT_SafeZero(&ctrParams, sizeof ctrParams);
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
|
|
||||||
loser:
|
loser:
|
||||||
PORT_Memset(&ctrParams, 0, sizeof ctrParams);
|
PORT_SafeZero(&ctrParams, sizeof ctrParams);
|
||||||
if (freeCtr) {
|
if (freeCtr) {
|
||||||
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
|
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) {
|
if (NSS_SecureMemcmp(tag, intag, tagBytes) != 0) {
|
||||||
/* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
|
/* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
|
||||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||||
PORT_Memset(tag, 0, sizeof(tag));
|
PORT_SafeZero(tag, sizeof(tag));
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
PORT_Memset(tag, 0, sizeof(tag));
|
PORT_SafeZero(tag, sizeof(tag));
|
||||||
/* finish the decryption */
|
/* finish the decryption */
|
||||||
return CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
|
return CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
|
||||||
inbuf, inlen, AES_BLOCK_SIZE);
|
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 */
|
/* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
|
||||||
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
|
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
|
||||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||||
PORT_Memset(tag, 0, sizeof(tag));
|
PORT_SafeZero(tag, sizeof(tag));
|
||||||
return SECFailure;
|
return SECFailure;
|
||||||
}
|
}
|
||||||
PORT_Memset(tag, 0, sizeof(tag));
|
PORT_SafeZero(tag, sizeof(tag));
|
||||||
/* finish the decryption */
|
/* finish the decryption */
|
||||||
rv = CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
|
rv = CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
|
||||||
inbuf, inlen, AES_BLOCK_SIZE);
|
inbuf, inlen, AES_BLOCK_SIZE);
|
||||||
|
|||||||
@@ -274,10 +274,10 @@ MAC(unsigned char *mdOut,
|
|||||||
hashObj->end(mdState, mdOut, mdOutLen, mdOutMax);
|
hashObj->end(mdState, mdOut, mdOutLen, mdOutMax);
|
||||||
hashObj->destroy(mdState, PR_TRUE);
|
hashObj->destroy(mdState, PR_TRUE);
|
||||||
|
|
||||||
PORT_Memset(lengthBytes, 0, sizeof lengthBytes);
|
PORT_SafeZero(lengthBytes, sizeof lengthBytes);
|
||||||
PORT_Memset(hmacPad, 0, sizeof hmacPad);
|
PORT_SafeZero(hmacPad, sizeof hmacPad);
|
||||||
PORT_Memset(firstBlock, 0, sizeof firstBlock);
|
PORT_SafeZero(firstBlock, sizeof firstBlock);
|
||||||
PORT_Memset(macOut, 0, sizeof macOut);
|
PORT_SafeZero(macOut, sizeof macOut);
|
||||||
|
|
||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ intel_aes_gcmInitCounter(intel_AES_GCMContext *gcm,
|
|||||||
void
|
void
|
||||||
intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit)
|
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) {
|
if (freeit) {
|
||||||
PORT_Free(gcm);
|
PORT_Free(gcm);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ ppc_aes_gcmInitCounter(ppc_AES_GCMContext *gcm,
|
|||||||
void
|
void
|
||||||
ppc_AES_GCM_DestroyContext(ppc_AES_GCMContext *gcm, PRBool freeit)
|
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) {
|
if (freeit) {
|
||||||
PORT_Free(gcm);
|
PORT_Free(gcm);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -703,7 +703,7 @@ cleanup:
|
|||||||
mp_clear(&a);
|
mp_clear(&a);
|
||||||
mp_clear(&z);
|
mp_clear(&z);
|
||||||
mp_clear(&two_length_minus_1);
|
mp_clear(&two_length_minus_1);
|
||||||
PORT_Memset(x, 0, sizeof(x));
|
PORT_SafeZero(x, sizeof(x));
|
||||||
if (err) {
|
if (err) {
|
||||||
MP_TO_SEC_ERROR(err);
|
MP_TO_SEC_ERROR(err);
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
@@ -859,7 +859,7 @@ cleanup:
|
|||||||
mp_clear(&c);
|
mp_clear(&c);
|
||||||
mp_clear(&c0);
|
mp_clear(&c0);
|
||||||
mp_clear(&one);
|
mp_clear(&one);
|
||||||
PORT_Memset(x, 0, sizeof(x));
|
PORT_SafeZero(x, sizeof(x));
|
||||||
if (err) {
|
if (err) {
|
||||||
MP_TO_SEC_ERROR(err);
|
MP_TO_SEC_ERROR(err);
|
||||||
rv = SECFailure;
|
rv = SECFailure;
|
||||||
@@ -1072,7 +1072,7 @@ makePfromQandSeed(
|
|||||||
CHECK_MPI_OK(mp_sub_d(&c, 1, &c)); /* c -= 1 */
|
CHECK_MPI_OK(mp_sub_d(&c, 1, &c)); /* c -= 1 */
|
||||||
CHECK_MPI_OK(mp_sub(&X, &c, P)); /* P = X - c */
|
CHECK_MPI_OK(mp_sub(&X, &c, P)); /* P = X - c */
|
||||||
cleanup:
|
cleanup:
|
||||||
PORT_Memset(V_j, 0, sizeof V_j);
|
PORT_SafeZero(V_j, sizeof V_j);
|
||||||
mp_clear(&W);
|
mp_clear(&W);
|
||||||
mp_clear(&X);
|
mp_clear(&X);
|
||||||
mp_clear(&c);
|
mp_clear(&c);
|
||||||
@@ -1221,7 +1221,7 @@ makeGfromIndex(HASH_HashType hashtype,
|
|||||||
/* step 11.
|
/* step 11.
|
||||||
* return valid G */
|
* return valid G */
|
||||||
cleanup:
|
cleanup:
|
||||||
PORT_Memset(data, 0, sizeof(data));
|
PORT_SafeZero(data, sizeof(data));
|
||||||
if (hashcx) {
|
if (hashcx) {
|
||||||
hashobj->destroy(hashcx, PR_TRUE);
|
hashobj->destroy(hashcx, PR_TRUE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1251,7 +1251,7 @@ AES_DestroyContext(AESContext *cx, PRBool freeit)
|
|||||||
cx->worker_cx = NULL;
|
cx->worker_cx = NULL;
|
||||||
cx->destroy = NULL;
|
cx->destroy = NULL;
|
||||||
}
|
}
|
||||||
PORT_Memset(cx, 0, sizeof(AESContext));
|
PORT_SafeZero(cx, sizeof(AESContext));
|
||||||
if (freeit) {
|
if (freeit) {
|
||||||
PORT_Free(mem);
|
PORT_Free(mem);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -978,14 +978,14 @@ rsa_GetHMACContext(const SECHashObject *hash, RSAPrivateKey *key,
|
|||||||
/* now create the hmac key */
|
/* now create the hmac key */
|
||||||
hmac = HMAC_Create(hash, keyHash, keyLen, PR_TRUE);
|
hmac = HMAC_Create(hash, keyHash, keyLen, PR_TRUE);
|
||||||
if (hmac == NULL) {
|
if (hmac == NULL) {
|
||||||
PORT_Memset(keyHash, 0, sizeof(keyHash));
|
PORT_SafeZero(keyHash, sizeof(keyHash));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
HMAC_Begin(hmac);
|
HMAC_Begin(hmac);
|
||||||
HMAC_Update(hmac, input, inputLen);
|
HMAC_Update(hmac, input, inputLen);
|
||||||
rv = HMAC_Finish(hmac, keyHash, &keyLen, sizeof(keyHash));
|
rv = HMAC_Finish(hmac, keyHash, &keyLen, sizeof(keyHash));
|
||||||
if (rv != SECSuccess) {
|
if (rv != SECSuccess) {
|
||||||
PORT_Memset(keyHash, 0, sizeof(keyHash));
|
PORT_SafeZero(keyHash, sizeof(keyHash));
|
||||||
HMAC_Destroy(hmac, PR_TRUE);
|
HMAC_Destroy(hmac, PR_TRUE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -993,7 +993,7 @@ rsa_GetHMACContext(const SECHashObject *hash, RSAPrivateKey *key,
|
|||||||
* reuse the original context allocated above so we don't
|
* reuse the original context allocated above so we don't
|
||||||
* need to allocate and free another one */
|
* need to allocate and free another one */
|
||||||
rv = HMAC_ReInit(hmac, hash, keyHash, keyLen, PR_TRUE);
|
rv = HMAC_ReInit(hmac, hash, keyHash, keyLen, PR_TRUE);
|
||||||
PORT_Memset(keyHash, 0, sizeof(keyHash));
|
PORT_SafeZero(keyHash, sizeof(keyHash));
|
||||||
if (rv != SECSuccess) {
|
if (rv != SECSuccess) {
|
||||||
HMAC_Destroy(hmac, PR_TRUE);
|
HMAC_Destroy(hmac, PR_TRUE);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1043,7 +1043,7 @@ rsa_HMACPrf(HMACContext *hmac, const char *label, int labelLen,
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
PORT_Memcpy(output, hmacLast, left);
|
PORT_Memcpy(output, hmacLast, left);
|
||||||
PORT_Memset(hmacLast, 0, sizeof(hmacLast));
|
PORT_SafeZero(hmacLast, sizeof(hmacLast));
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -1088,7 +1088,7 @@ rsa_GetErrorLength(HMACContext *hmac, int hashLen, int maxLegalLen)
|
|||||||
outLength = PORT_CT_SEL(PORT_CT_LT(candidate, maxLegalLen),
|
outLength = PORT_CT_SEL(PORT_CT_LT(candidate, maxLegalLen),
|
||||||
candidate, outLength);
|
candidate, outLength);
|
||||||
}
|
}
|
||||||
PORT_Memset(out, 0, sizeof(out));
|
PORT_SafeZero(out, sizeof(out));
|
||||||
return outLength;
|
return outLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ blapi_SHVerifyDSACheck(PRFileDesc *shFD, const SECHashObject *hashObj,
|
|||||||
|
|
||||||
/* verify the hash against the check file */
|
/* verify the hash against the check file */
|
||||||
rv = DSA_VerifyDigest(key, signature, &hash);
|
rv = DSA_VerifyDigest(key, signature, &hash);
|
||||||
PORT_Memset(hashBuf, 0, sizeof hashBuf);
|
PORT_SafeZero(hashBuf, sizeof hashBuf);
|
||||||
return (rv == SECSuccess) ? PR_TRUE : PR_FALSE;
|
return (rv == SECSuccess) ? PR_TRUE : PR_FALSE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -427,7 +427,7 @@ blapi_SHVerifyHMACCheck(PRFileDesc *shFD, const SECHashObject *hashObj,
|
|||||||
if (rv == SECSuccess) {
|
if (rv == SECSuccess) {
|
||||||
result = SECITEM_ItemsAreEqual(signature, &hash);
|
result = SECITEM_ItemsAreEqual(signature, &hash);
|
||||||
}
|
}
|
||||||
PORT_Memset(hashBuf, 0, sizeof hashBuf);
|
PORT_SafeZero(hashBuf, sizeof hashBuf);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,7 +451,7 @@ blapi_SHVerifyFile(const char *shName, PRBool self, PRBool rerun)
|
|||||||
#ifndef NSS_STRICT_INTEGRITY
|
#ifndef NSS_STRICT_INTEGRITY
|
||||||
DSAPublicKey key;
|
DSAPublicKey key;
|
||||||
|
|
||||||
PORT_Memset(&key, 0, sizeof(key));
|
PORT_SafeZero(&key, sizeof(key));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If our integrity check was never ran or failed, fail any other
|
/* 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;
|
shFD = NULL;
|
||||||
|
|
||||||
loser:
|
loser:
|
||||||
PORT_Memset(&header, 0, sizeof header);
|
PORT_SafeZero(&header, sizeof header);
|
||||||
if (checkName != NULL) {
|
if (checkName != NULL) {
|
||||||
PORT_Free(checkName);
|
PORT_Free(checkName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ STUB_DECLARE(void, PORT_Free_Util, (void *ptr));
|
|||||||
STUB_DECLARE(void, PORT_FreeArena_Util, (PLArenaPool * arena, PRBool zero));
|
STUB_DECLARE(void, PORT_FreeArena_Util, (PLArenaPool * arena, PRBool zero));
|
||||||
STUB_DECLARE(int, PORT_GetError_Util, (void));
|
STUB_DECLARE(int, PORT_GetError_Util, (void));
|
||||||
STUB_DECLARE(PLArenaPool *, PORT_NewArena_Util, (unsigned long chunksize));
|
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_SetError_Util, (int value));
|
||||||
STUB_DECLARE(void *, PORT_ZAlloc_Util, (size_t len));
|
STUB_DECLARE(void *, PORT_ZAlloc_Util, (size_t len));
|
||||||
STUB_DECLARE(void *, PORT_ZAllocAligned_Util, (size_t bytes, size_t alignment, void **mem));
|
STUB_DECLARE(void *, PORT_ZAllocAligned_Util, (size_t bytes, size_t alignment, void **mem));
|
||||||
@@ -488,6 +489,20 @@ PORT_GetError_stub(void)
|
|||||||
return errno;
|
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
|
extern void
|
||||||
PORT_SetError_stub(int value)
|
PORT_SetError_stub(int value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#define PORT_FreeArena PORT_FreeArena_stub
|
#define PORT_FreeArena PORT_FreeArena_stub
|
||||||
#define PORT_GetError PORT_GetError_stub
|
#define PORT_GetError PORT_GetError_stub
|
||||||
#define PORT_NewArena PORT_NewArena_stub
|
#define PORT_NewArena PORT_NewArena_stub
|
||||||
|
#define PORT_SaveZero PORT_SaveZero_stub
|
||||||
#define PORT_SetError PORT_SetError_stub
|
#define PORT_SetError PORT_SetError_stub
|
||||||
#define PORT_ZAlloc PORT_ZAlloc_stub
|
#define PORT_ZAlloc PORT_ZAlloc_stub
|
||||||
#define PORT_ZFree PORT_ZFree_stub
|
#define PORT_ZFree PORT_ZFree_stub
|
||||||
|
|||||||
@@ -8,7 +8,9 @@
|
|||||||
|
|
||||||
#include "seccomon.h"
|
#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"
|
#include "unix_urandom.c"
|
||||||
#elif defined(XP_UNIX)
|
#elif defined(XP_UNIX)
|
||||||
#include "unix_rand.c"
|
#include "unix_rand.c"
|
||||||
|
|||||||
@@ -82,8 +82,8 @@ loser:
|
|||||||
/* clear out state so it's not left on the stack */
|
/* clear out state so it's not left on the stack */
|
||||||
if (cx)
|
if (cx)
|
||||||
HMAC_Destroy(cx, PR_TRUE);
|
HMAC_Destroy(cx, PR_TRUE);
|
||||||
PORT_Memset(state, 0, sizeof(state));
|
PORT_SafeZero(state, sizeof(state));
|
||||||
PORT_Memset(outbuf, 0, sizeof(outbuf));
|
PORT_SafeZero(outbuf, sizeof(outbuf));
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
80
security/nss/lib/freebl/unix_fips140_3.c
Normal file
80
security/nss/lib/freebl/unix_fips140_3.c
Normal 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;
|
||||||
|
}
|
||||||
@@ -22,7 +22,7 @@ RNG_SystemInfoForRNG(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RNG_RandomUpdate(bytes, numBytes);
|
RNG_RandomUpdate(bytes, numBytes);
|
||||||
PORT_Memset(bytes, 0, sizeof bytes);
|
PORT_SafeZero(bytes, sizeof bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
@@ -41,6 +41,9 @@ RNG_SystemRNG(void *dest, size_t maxLen)
|
|||||||
if (getBytes > GETENTROPY_MAX_BYTES) {
|
if (getBytes > GETENTROPY_MAX_BYTES) {
|
||||||
getBytes = GETENTROPY_MAX_BYTES;
|
getBytes = GETENTROPY_MAX_BYTES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* get entropy returns 0 on success and always return
|
||||||
|
* getBytes on success */
|
||||||
result = getentropy(buffer, getBytes);
|
result = getentropy(buffer, getBytes);
|
||||||
if (result == 0) { /* success */
|
if (result == 0) { /* success */
|
||||||
fileBytes += getBytes;
|
fileBytes += getBytes;
|
||||||
@@ -61,7 +64,7 @@ RNG_SystemRNG(void *dest, size_t maxLen)
|
|||||||
/* ENOSYS means the kernel doesn't support getentropy()/getrandom().
|
/* ENOSYS means the kernel doesn't support getentropy()/getrandom().
|
||||||
* Reset the number of bytes to get and fall back to /dev/urandom. */
|
* Reset the number of bytes to get and fall back to /dev/urandom. */
|
||||||
fileBytes = 0;
|
fileBytes = 0;
|
||||||
#endif
|
#endif /* platorm has getentropy */
|
||||||
fd = open("/dev/urandom", O_RDONLY);
|
fd = open("/dev/urandom", O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
PORT_SetError(SEC_ERROR_NEED_RANDOM);
|
PORT_SetError(SEC_ERROR_NEED_RANDOM);
|
||||||
|
|||||||
@@ -1967,8 +1967,9 @@ IsValidDNSID(Input hostname, IDRole idRole, AllowWildcards allowWildcards)
|
|||||||
}
|
}
|
||||||
switch (b) {
|
switch (b) {
|
||||||
case '-':
|
case '-':
|
||||||
if (labelLength == 0) {
|
// Only reference ID labels can start with a hyphen.
|
||||||
return false; // Labels must not start with a hyphen.
|
if (labelLength == 0 && idRole != IDRole::ReferenceID) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
labelIsAllNumeric = false;
|
labelIsAllNumeric = false;
|
||||||
labelEndsWithHyphen = true;
|
labelEndsWithHyphen = true;
|
||||||
@@ -2028,8 +2029,9 @@ IsValidDNSID(Input hostname, IDRole idRole, AllowWildcards allowWildcards)
|
|||||||
(idRole != IDRole::NameConstraint || !isFirstByte)) {
|
(idRole != IDRole::NameConstraint || !isFirstByte)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (labelEndsWithHyphen) {
|
// Only reference ID labels can end with a hyphen.
|
||||||
return false; // Labels must not end with a hyphen.
|
if (labelEndsWithHyphen && idRole != IDRole::ReferenceID) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
labelLength = 0;
|
labelLength = 0;
|
||||||
break;
|
break;
|
||||||
@@ -2046,8 +2048,9 @@ IsValidDNSID(Input hostname, IDRole idRole, AllowWildcards allowWildcards)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labelEndsWithHyphen) {
|
// Only reference ID labels can end with a hyphen.
|
||||||
return false; // Labels must not end with a hyphen.
|
if (labelEndsWithHyphen && idRole != IDRole::ReferenceID) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (labelIsAllNumeric) {
|
if (labelIsAllNumeric) {
|
||||||
|
|||||||
@@ -1270,3 +1270,9 @@ SECKEY_PrivateKeyStrengthInBits;
|
|||||||
;+ local:
|
;+ local:
|
||||||
;+ *;
|
;+ *;
|
||||||
;+};
|
;+};
|
||||||
|
;+NSS_3.107 { # NSS 3.107 release
|
||||||
|
;+ global:
|
||||||
|
SECMOD_LoadUserModuleWithFunction;
|
||||||
|
;+ local:
|
||||||
|
;+ *;
|
||||||
|
;+};
|
||||||
|
|||||||
@@ -22,12 +22,12 @@
|
|||||||
* The format of the version string should be
|
* The format of the version string should be
|
||||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
|
* "<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_VMAJOR 3
|
||||||
#define NSS_VMINOR 107
|
#define NSS_VMINOR 108
|
||||||
#define NSS_VPATCH 0
|
#define NSS_VPATCH 0
|
||||||
#define NSS_VBUILD 0
|
#define NSS_VBUILD 0
|
||||||
#define NSS_BETA PR_FALSE
|
#define NSS_BETA PR_TRUE
|
||||||
|
|
||||||
#ifndef RC_INVOKED
|
#ifndef RC_INVOKED
|
||||||
|
|
||||||
|
|||||||
@@ -387,19 +387,12 @@ CK_RV NSC_GetInterface(CK_UTF8CHAR_PTR pInterfaceName,
|
|||||||
char **NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args);
|
char **NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* load a new module into our address space and initialize it.
|
|
||||||
*/
|
|
||||||
SECStatus
|
SECStatus
|
||||||
secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
|
secmod_DetermineModuleFunctionList(SECMODModule *mod)
|
||||||
{
|
{
|
||||||
PRLibrary *library = NULL;
|
PRLibrary *library = NULL;
|
||||||
CK_C_GetInterface ientry = NULL;
|
CK_C_GetInterface ientry = NULL;
|
||||||
CK_C_GetFunctionList fentry = NULL;
|
CK_C_GetFunctionList fentry = NULL;
|
||||||
CK_INFO info;
|
|
||||||
CK_ULONG slotCount = 0;
|
|
||||||
SECStatus rv;
|
|
||||||
PRBool alreadyLoaded = PR_FALSE;
|
|
||||||
char *disableUnload = NULL;
|
char *disableUnload = NULL;
|
||||||
#ifndef NSS_STATIC_SOFTOKEN
|
#ifndef NSS_STATIC_SOFTOKEN
|
||||||
const char *nss_interface;
|
const char *nss_interface;
|
||||||
@@ -407,11 +400,6 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
|
|||||||
#endif
|
#endif
|
||||||
CK_INTERFACE_PTR interface;
|
CK_INTERFACE_PTR interface;
|
||||||
|
|
||||||
if (mod->loaded)
|
|
||||||
return SECSuccess;
|
|
||||||
|
|
||||||
mod->fipsIndicator = NULL;
|
|
||||||
|
|
||||||
/* internal modules get loaded from their internal list */
|
/* internal modules get loaded from their internal list */
|
||||||
if (mod->internal && (mod->dllName == NULL)) {
|
if (mod->internal && (mod->dllName == NULL)) {
|
||||||
#ifdef NSS_STATIC_SOFTOKEN
|
#ifdef NSS_STATIC_SOFTOKEN
|
||||||
@@ -553,6 +541,25 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
/* This test operation makes sure our locking system is
|
||||||
* consistent even if we are using non-thread safe tokens by
|
* consistent even if we are using non-thread safe tokens by
|
||||||
* simulating unsafe tokens with safe ones. */
|
* simulating unsafe tokens with safe ones. */
|
||||||
@@ -643,13 +650,80 @@ fail2:
|
|||||||
}
|
}
|
||||||
fail:
|
fail:
|
||||||
mod->functionList = NULL;
|
mod->functionList = NULL;
|
||||||
disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
|
|
||||||
if (library && !disableUnload) {
|
|
||||||
PR_UnloadLibrary(library);
|
|
||||||
}
|
|
||||||
return SECFailure;
|
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
|
SECStatus
|
||||||
SECMOD_UnloadModule(SECMODModule *mod)
|
SECMOD_UnloadModule(SECMODModule *mod)
|
||||||
{
|
{
|
||||||
@@ -692,9 +766,9 @@ SECMOD_UnloadModule(SECMODModule *mod)
|
|||||||
}
|
}
|
||||||
|
|
||||||
library = (PRLibrary *)mod->library;
|
library = (PRLibrary *)mod->library;
|
||||||
/* paranoia */
|
/* if no library, then we should not unload it */
|
||||||
if (library == NULL) {
|
if (library == NULL) {
|
||||||
return SECFailure;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
|
disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
|
||||||
|
|||||||
@@ -1719,10 +1719,19 @@ PK11_ParamToAlgid(SECOidTag algTag, SECItem *param,
|
|||||||
case CKM_JUNIPER_CBC128:
|
case CKM_JUNIPER_CBC128:
|
||||||
case CKM_JUNIPER_COUNTER:
|
case CKM_JUNIPER_COUNTER:
|
||||||
case CKM_JUNIPER_SHUFFLE:
|
case CKM_JUNIPER_SHUFFLE:
|
||||||
newParams = SEC_ASN1EncodeItem(NULL, NULL, param,
|
if (param && param->len > 0) {
|
||||||
SEC_ASN1_GET(SEC_OctetStringTemplate));
|
newParams = SEC_ASN1EncodeItem(NULL, NULL, param,
|
||||||
if (newParams == NULL)
|
SEC_ASN1_GET(SEC_OctetStringTemplate));
|
||||||
break;
|
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;
|
rv = SECSuccess;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2240,6 +2240,72 @@ loser:
|
|||||||
return module;
|
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
|
* 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;
|
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
|
* remove the PKCS#11 module from the default NSS trust domain, call
|
||||||
* C_Finalize, and destroy the module structure
|
* C_Finalize, and destroy the module structure
|
||||||
|
|||||||
@@ -770,9 +770,10 @@ sec_pkcs5CreateAlgorithmID(SECOidTag algorithm,
|
|||||||
algorithm = sec_pkcs5v2_get_pbe(cipherAlgorithm);
|
algorithm = sec_pkcs5v2_get_pbe(cipherAlgorithm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm);
|
||||||
|
|
||||||
/* set the PKCS5v2 specific parameters */
|
/* set the PKCS5v2 specific parameters */
|
||||||
if (keyLength == 0) {
|
if (keyLength == 0) {
|
||||||
SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm);
|
|
||||||
if (hashAlg != SEC_OID_UNKNOWN) {
|
if (hashAlg != SEC_OID_UNKNOWN) {
|
||||||
keyLength = HASH_ResultLenByOidTag(hashAlg);
|
keyLength = HASH_ResultLenByOidTag(hashAlg);
|
||||||
} else {
|
} else {
|
||||||
@@ -787,18 +788,25 @@ sec_pkcs5CreateAlgorithmID(SECOidTag algorithm,
|
|||||||
prfAlg = SEC_OID_HMAC_SHA1;
|
prfAlg = SEC_OID_HMAC_SHA1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build the PKCS5v2 cipher algorithm id */
|
/* build the PKCS5v2 cipher algorithm id, if cipher
|
||||||
cipherParams = pk11_GenerateNewParamWithKeyLen(
|
* is an HMAC, the cipherParams should be NULL */
|
||||||
PK11_AlgtagToMechanism(cipherAlgorithm), keyLength);
|
if (hashAlg == SEC_OID_UNKNOWN) {
|
||||||
if (!cipherParams) {
|
cipherParams = pk11_GenerateNewParamWithKeyLen(
|
||||||
goto loser;
|
PK11_AlgtagToMechanism(cipherAlgorithm), keyLength);
|
||||||
|
if (!cipherParams) {
|
||||||
|
goto loser;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cipherParams = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PORT_Memset(&pbeV2_param, 0, sizeof(pbeV2_param));
|
PORT_Memset(&pbeV2_param, 0, sizeof(pbeV2_param));
|
||||||
|
|
||||||
rv = PK11_ParamToAlgid(cipherAlgorithm, cipherParams,
|
rv = PK11_ParamToAlgid(cipherAlgorithm, cipherParams,
|
||||||
poolp, &pbeV2_param.cipherAlgId);
|
poolp, &pbeV2_param.cipherAlgId);
|
||||||
SECITEM_FreeItem(cipherParams, PR_TRUE);
|
if (cipherParams) {
|
||||||
|
SECITEM_FreeItem(cipherParams, PR_TRUE);
|
||||||
|
}
|
||||||
if (rv != SECSuccess) {
|
if (rv != SECSuccess) {
|
||||||
goto loser;
|
goto loser;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "seccomon.h"
|
#include "seccomon.h"
|
||||||
#include "secmodt.h"
|
#include "secmodt.h"
|
||||||
#include "prinrval.h"
|
#include "prinrval.h"
|
||||||
|
#include "pkcs11.h"
|
||||||
|
|
||||||
/* These mechanisms flags are visible to all other libraries. */
|
/* These mechanisms flags are visible to all other libraries. */
|
||||||
/* They must be converted to internal SECMOD_*_FLAG */
|
/* 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,
|
extern SECMODModule *SECMOD_LoadUserModule(char *moduleSpec, SECMODModule *parent,
|
||||||
PRBool recurse);
|
PRBool recurse);
|
||||||
|
|
||||||
|
extern SECMODModule *SECMOD_LoadUserModuleWithFunction(const char *moduleName,
|
||||||
|
CK_C_GetFunctionList fentry);
|
||||||
|
|
||||||
SECStatus SECMOD_UnloadUserModule(SECMODModule *mod);
|
SECStatus SECMOD_UnloadUserModule(SECMODModule *mod);
|
||||||
|
|
||||||
SECMODModule *SECMOD_CreateModule(const char *lib, const char *name,
|
SECMODModule *SECMOD_CreateModule(const char *lib, const char *name,
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ extern unsigned long SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags
|
|||||||
|
|
||||||
/* Library functions */
|
/* Library functions */
|
||||||
SECStatus secmod_LoadPKCS11Module(SECMODModule *, SECMODModule **oldModule);
|
SECStatus secmod_LoadPKCS11Module(SECMODModule *, SECMODModule **oldModule);
|
||||||
|
SECStatus secmod_LoadPKCS11ModuleFromFunction(SECMODModule *, SECMODModule **oldModule, CK_C_GetFunctionList f);
|
||||||
|
|
||||||
SECStatus SECMOD_UnloadModule(SECMODModule *);
|
SECStatus SECMOD_UnloadModule(SECMODModule *);
|
||||||
void SECMOD_SetInternalModule(SECMODModule *);
|
void SECMOD_SetInternalModule(SECMODModule *);
|
||||||
PRBool secmod_IsInternalKeySlot(SECMODModule *);
|
PRBool secmod_IsInternalKeySlot(SECMODModule *);
|
||||||
|
|||||||
@@ -1918,7 +1918,7 @@ sec_pkcs12_set_nickname_for_cert(sec_PKCS12SafeBag *cert,
|
|||||||
static SECItem *
|
static SECItem *
|
||||||
sec_pkcs12_get_der_cert(sec_PKCS12SafeBag *cert)
|
sec_pkcs12_get_der_cert(sec_PKCS12SafeBag *cert)
|
||||||
{
|
{
|
||||||
if (!cert) {
|
if (!cert || !cert->safeBagContent.certBag) {
|
||||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -3179,6 +3179,12 @@ SEC_PKCS12DecoderIterateNext(SEC_PKCS12DecoderContext *p12dcx,
|
|||||||
p12dcx->decitem.der = sec_pkcs12_get_der_cert(bag);
|
p12dcx->decitem.der = sec_pkcs12_get_der_cert(bag);
|
||||||
p12dcx->decitem.friendlyName = sec_pkcs12_get_friendlyName(bag);
|
p12dcx->decitem.friendlyName = sec_pkcs12_get_friendlyName(bag);
|
||||||
p12dcx->decitem.hasKey = sec_pkcs12_bagHasKey(p12dcx, 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;
|
break;
|
||||||
case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
|
case SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID:
|
||||||
p12dcx->decitem.shroudAlg = PORT_ZNew(SECAlgorithmID);
|
p12dcx->decitem.shroudAlg = PORT_ZNew(SECAlgorithmID);
|
||||||
@@ -3195,6 +3201,7 @@ SEC_PKCS12DecoderIterateNext(SEC_PKCS12DecoderContext *p12dcx,
|
|||||||
break;
|
break;
|
||||||
case SEC_OID_UNKNOWN:
|
case SEC_OID_UNKNOWN:
|
||||||
/* ignore these */
|
/* ignore these */
|
||||||
|
p12dcx->decitem.type = 0; /* clear out the type we are ignoring */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*ipp = &p12dcx->decitem;
|
*ipp = &p12dcx->decitem;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ sec_pkcs12_integrity_key(PK11SlotInfo *slot, sec_PKCS12MacData *macData,
|
|||||||
*hmacMech = PK11_AlgtagToMechanism(hmacAlg);
|
*hmacMech = PK11_AlgtagToMechanism(hmacAlg);
|
||||||
/* pkcs12v2 hmac uses UTF8 rather than unicode */
|
/* pkcs12v2 hmac uses UTF8 rather than unicode */
|
||||||
if (!sec_pkcs12_convert_item_to_unicode(NULL, &utf8Pw, pwitem,
|
if (!sec_pkcs12_convert_item_to_unicode(NULL, &utf8Pw, pwitem,
|
||||||
PR_TRUE, PR_FALSE, PR_FALSE)) {
|
PR_FALSE, PR_FALSE, PR_FALSE)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
symKey = PK11_PBEKeyGen(slot, prfAlgid, &utf8Pw, PR_FALSE, pwarg);
|
symKey = PK11_PBEKeyGen(slot, prfAlgid, &utf8Pw, PR_FALSE, pwarg);
|
||||||
|
|||||||
@@ -520,6 +520,8 @@ CERT_DecodeCertFromPackage(char *certbuf, int certlen)
|
|||||||
CERTCertificate *cert = NULL;
|
CERTCertificate *cert = NULL;
|
||||||
|
|
||||||
collectArgs.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
collectArgs.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||||
|
collectArgs.cert.data = NULL;
|
||||||
|
collectArgs.cert.len = 0;
|
||||||
|
|
||||||
rv = CERT_DecodeCertPackage(certbuf, certlen, collect_certs,
|
rv = CERT_DecodeCertPackage(certbuf, certlen, collect_certs,
|
||||||
(void *)&collectArgs);
|
(void *)&collectArgs);
|
||||||
|
|||||||
@@ -1765,16 +1765,20 @@ sftk_fips_pbkdf_PowerUpSelfTests(void)
|
|||||||
unsigned char iteration_count = 5;
|
unsigned char iteration_count = 5;
|
||||||
unsigned char keyLen = 64;
|
unsigned char keyLen = 64;
|
||||||
char *inKeyData = TEST_KEY;
|
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[] = {
|
static const unsigned char pbkdf_known_answer[] = {
|
||||||
0x31, 0xf0, 0xe5, 0x39, 0x9f, 0x39, 0xb9, 0x29,
|
0x73, 0x8c, 0xfa, 0x02, 0xe8, 0xdb, 0x43, 0xe4,
|
||||||
0x68, 0xac, 0xf2, 0xe9, 0x53, 0x9b, 0xb4, 0x9c,
|
0x99, 0xc5, 0xfd, 0xd9, 0x4d, 0x8e, 0x3e, 0x7b,
|
||||||
0x28, 0x59, 0x8b, 0x5c, 0xd8, 0xd4, 0x02, 0x37,
|
0xc4, 0xda, 0x22, 0x1b, 0xe1, 0xae, 0x23, 0x7a,
|
||||||
0x18, 0x22, 0xc1, 0x92, 0xd0, 0xfa, 0x72, 0x90,
|
0x21, 0x27, 0xbd, 0xcc, 0x78, 0xc4, 0xe6, 0xc5,
|
||||||
0x2c, 0x8d, 0x19, 0xd4, 0x56, 0xfb, 0x16, 0xfa,
|
0x33, 0x38, 0x35, 0xe0, 0x68, 0x1a, 0x1e, 0x06,
|
||||||
0x8d, 0x5c, 0x06, 0x33, 0xd1, 0x5f, 0x17, 0xb1,
|
0xad, 0xaf, 0x7f, 0xd7, 0x3f, 0x0e, 0xc0, 0x90,
|
||||||
0x22, 0xd9, 0x9c, 0xaf, 0x5e, 0x3f, 0xf3, 0x66,
|
0x17, 0x97, 0x73, 0x75, 0x7b, 0x88, 0x49, 0xd8,
|
||||||
0xc6, 0x14, 0xfe, 0x83, 0xfa, 0x1a, 0x2a, 0xc5
|
0x6f, 0x78, 0x5a, 0xde, 0x50, 0x20, 0x55, 0x33
|
||||||
};
|
};
|
||||||
|
|
||||||
sftk_PBELockInit();
|
sftk_PBELockInit();
|
||||||
|
|||||||
@@ -3211,14 +3211,15 @@ SFTK_DestroySlotData(SFTKSlot *slot)
|
|||||||
char **
|
char **
|
||||||
NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args)
|
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 *secmod = NULL;
|
||||||
char *appName = NULL;
|
char *appName = NULL;
|
||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
NSSDBType dbType = NSS_DB_TYPE_NONE;
|
NSSDBType dbType = NSS_DB_TYPE_NONE;
|
||||||
PRBool rw;
|
PRBool rw;
|
||||||
static char *success = "Success";
|
static char *success = "Success";
|
||||||
#endif /* NSS_DISABLE_DBM */
|
|
||||||
char **rvstr = NULL;
|
char **rvstr = NULL;
|
||||||
|
|
||||||
rvstr = NSSUTIL_DoModuleDBFunction(function, parameters, args);
|
rvstr = NSSUTIL_DoModuleDBFunction(function, parameters, args);
|
||||||
@@ -3230,7 +3231,6 @@ NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NSS_DISABLE_DBM
|
|
||||||
/* The legacy database uses the old dbm, which is only linked with the
|
/* The legacy database uses the old dbm, which is only linked with the
|
||||||
* legacy DB handler, which is only callable from softoken */
|
* legacy DB handler, which is only callable from softoken */
|
||||||
|
|
||||||
@@ -3322,8 +3322,8 @@ loser:
|
|||||||
PORT_Free(appName);
|
PORT_Free(appName);
|
||||||
if (filename)
|
if (filename)
|
||||||
PORT_Free(filename);
|
PORT_Free(filename);
|
||||||
#endif /* NSS_DISABLE_DBM */
|
|
||||||
return rvstr;
|
return rvstr;
|
||||||
|
#endif /* NSS_DISABLE_DBM */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -17,11 +17,11 @@
|
|||||||
* The format of the version string should be
|
* The format of the version string should be
|
||||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
|
* "<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_VMAJOR 3
|
||||||
#define SOFTOKEN_VMINOR 107
|
#define SOFTOKEN_VMINOR 108
|
||||||
#define SOFTOKEN_VPATCH 0
|
#define SOFTOKEN_VPATCH 0
|
||||||
#define SOFTOKEN_VBUILD 0
|
#define SOFTOKEN_VBUILD 0
|
||||||
#define SOFTOKEN_BETA PR_FALSE
|
#define SOFTOKEN_BETA PR_TRUE
|
||||||
|
|
||||||
#endif /* _SOFTKVER_H_ */
|
#endif /* _SOFTKVER_H_ */
|
||||||
|
|||||||
@@ -107,6 +107,9 @@ HASH_GetHashOidTagByHMACOidTag(SECOidTag hmacOid)
|
|||||||
switch (hmacOid) {
|
switch (hmacOid) {
|
||||||
/* no oid exists for HMAC_MD2 */
|
/* no oid exists for HMAC_MD2 */
|
||||||
/* NSS does not define a oid for HMAC_MD4 */
|
/* NSS does not define a oid for HMAC_MD4 */
|
||||||
|
case SEC_OID_HMAC_MD5:
|
||||||
|
hashOid = SEC_OID_MD5;
|
||||||
|
break;
|
||||||
case SEC_OID_HMAC_SHA1:
|
case SEC_OID_HMAC_SHA1:
|
||||||
hashOid = SEC_OID_SHA1;
|
hashOid = SEC_OID_SHA1;
|
||||||
break;
|
break;
|
||||||
@@ -150,6 +153,9 @@ HASH_GetHMACOidTagByHashOidTag(SECOidTag hashOid)
|
|||||||
switch (hashOid) {
|
switch (hashOid) {
|
||||||
/* no oid exists for HMAC_MD2 */
|
/* no oid exists for HMAC_MD2 */
|
||||||
/* NSS does not define a oid for HMAC_MD4 */
|
/* NSS does not define a oid for HMAC_MD4 */
|
||||||
|
case SEC_OID_MD5:
|
||||||
|
hmacOid = SEC_OID_HMAC_MD5;
|
||||||
|
break;
|
||||||
case SEC_OID_SHA1:
|
case SEC_OID_SHA1:
|
||||||
hmacOid = SEC_OID_HMAC_SHA1;
|
hmacOid = SEC_OID_HMAC_SHA1;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -372,3 +372,9 @@ NSS_SetAlgorithmPolicyAll;
|
|||||||
;+ local:
|
;+ local:
|
||||||
;+ *;
|
;+ *;
|
||||||
;+};
|
;+};
|
||||||
|
;+NSSUTIL_3.108 { # NSS Utilities 3.108 release
|
||||||
|
;+ global:
|
||||||
|
PORT_SafeZero;
|
||||||
|
;+ local:
|
||||||
|
;+ *;
|
||||||
|
;+};
|
||||||
|
|||||||
@@ -19,12 +19,12 @@
|
|||||||
* The format of the version string should be
|
* The format of the version string should be
|
||||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
|
* "<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_VMAJOR 3
|
||||||
#define NSSUTIL_VMINOR 107
|
#define NSSUTIL_VMINOR 108
|
||||||
#define NSSUTIL_VPATCH 0
|
#define NSSUTIL_VPATCH 0
|
||||||
#define NSSUTIL_VBUILD 0
|
#define NSSUTIL_VBUILD 0
|
||||||
#define NSSUTIL_BETA PR_FALSE
|
#define NSSUTIL_BETA PR_TRUE
|
||||||
|
|
||||||
SEC_BEGIN_PROTOS
|
SEC_BEGIN_PROTOS
|
||||||
|
|
||||||
|
|||||||
@@ -2274,6 +2274,11 @@ SECOID_FindOID(const SECItem *oid)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((oid == NULL) || (oid->data == NULL)) {
|
||||||
|
PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ret = PL_HashTableLookupConst(oidhash, oid);
|
ret = PL_HashTableLookupConst(oidhash, oid);
|
||||||
if (ret == NULL) {
|
if (ret == NULL) {
|
||||||
ret = secoid_FindDynamic(oid);
|
ret = secoid_FindDynamic(oid);
|
||||||
|
|||||||
@@ -209,6 +209,44 @@ PORT_GetError(void)
|
|||||||
return (PR_GetError());
|
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 *****************************
|
/********************* Arena code follows *****************************
|
||||||
* ArenaPools are like heaps. The memory in them consists of large blocks,
|
* ArenaPools are like heaps. The memory in them consists of large blocks,
|
||||||
* called arenas, which are allocated from the/a system heap. Inside an
|
* called arenas, which are allocated from the/a system heap. Inside an
|
||||||
|
|||||||
@@ -36,6 +36,9 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <ctype.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 <string.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.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 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 int NSS_SecureMemcmp(const void *a, const void *b, size_t n);
|
||||||
extern unsigned int NSS_SecureMemcmpZero(const void *mem, 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);
|
extern void NSS_SecureSelect(void *dest, const void *src0, const void *src1, size_t n, unsigned char b);
|
||||||
|
|||||||
@@ -308,6 +308,7 @@ nssutil_growList(char ***pModuleList, int *useCount, int last)
|
|||||||
return SECSuccess;
|
return SECSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NSS_DISABLE_DBM
|
||||||
static char *
|
static char *
|
||||||
_NSSUTIL_GetOldSecmodName(const char *dbname, const char *filename)
|
_NSSUTIL_GetOldSecmodName(const char *dbname, const char *filename)
|
||||||
{
|
{
|
||||||
@@ -332,6 +333,7 @@ _NSSUTIL_GetOldSecmodName(const char *dbname, const char *filename)
|
|||||||
PORT_Free(dirPath);
|
PORT_Free(dirPath);
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
#endif // NSS_DISABLE_DBM
|
||||||
|
|
||||||
static SECStatus nssutil_AddSecmodDBEntry(const char *appName,
|
static SECStatus nssutil_AddSecmodDBEntry(const char *appName,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
@@ -567,6 +569,7 @@ nssutil_ReadSecmodDB(const char *appName,
|
|||||||
moduleString = NULL;
|
moduleString = NULL;
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
|
#ifndef NSS_DISABLE_DBM
|
||||||
/* if we couldn't open a pkcs11 database, look for the old one */
|
/* if we couldn't open a pkcs11 database, look for the old one */
|
||||||
if (fd == NULL) {
|
if (fd == NULL) {
|
||||||
char *olddbname = _NSSUTIL_GetOldSecmodName(dbname, filename);
|
char *olddbname = _NSSUTIL_GetOldSecmodName(dbname, filename);
|
||||||
@@ -591,6 +594,7 @@ done:
|
|||||||
PR_smprintf_free(olddbname);
|
PR_smprintf_free(olddbname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // NSS_DISABLE_DBM
|
||||||
|
|
||||||
return_default:
|
return_default:
|
||||||
|
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ class covAction(argparse.Action):
|
|||||||
# Don't exit immediately on error
|
# Don't exit immediately on error
|
||||||
symbol_retcode = subprocess.call([
|
symbol_retcode = subprocess.call([
|
||||||
"sancov",
|
"sancov",
|
||||||
"-blacklist=" + os.path.join(cwd, ".sancov-blacklist"),
|
"-ignorelist=" + os.path.join(cwd, ".sancov-blacklist"),
|
||||||
"-symbolize", sancov_file,
|
"-symbolize", sancov_file,
|
||||||
os.path.join(cwd, "../dist/Debug/bin/ssl_gtest")
|
os.path.join(cwd, "../dist/Debug/bin/ssl_gtest")
|
||||||
], stdout=out)
|
], stdout=out)
|
||||||
|
|||||||
@@ -315,7 +315,7 @@
|
|||||||
'target_name': 'fuzz',
|
'target_name': 'fuzz',
|
||||||
'type': 'none',
|
'type': 'none',
|
||||||
'dependencies': [
|
'dependencies': [
|
||||||
'fuzz/fuzz.gyp:nssfuzz',
|
'fuzz/fuzz.gyp:fuzz',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ dbtest_main()
|
|||||||
|
|
||||||
Echo "test opening the database readonly in an empty directory"
|
Echo "test opening the database readonly in an empty directory"
|
||||||
mkdir $EMPTY_DIR
|
mkdir $EMPTY_DIR
|
||||||
${BINDIR}/tstclnt -h ${HOST} -d $EMPTY_DIR
|
${BINDIR}/tstclnt -h ${HOST} -d $EMPTY_DIR
|
||||||
ret=$?
|
ret=$?
|
||||||
if [ $ret -ne 1 ]; then
|
if [ $ret -ne 1 ]; then
|
||||||
html_failed "Tstclnt succeded in an empty directory $ret"
|
html_failed "Tstclnt succeded in an empty directory $ret"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ name=`basename $request .req`
|
|||||||
echo ">>>>> $name"
|
echo ">>>>> $name"
|
||||||
sed -e 's;
|
sed -e 's;
|
||||||
;;g' -e 's; ; ;g' -e '/^#/d' $extraneous_response ${TESTDIR}/resp/${name}.rsp > /tmp/y1
|
;;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 }'`
|
size=`sum /tmp/y1 | awk '{ print $1 }'`
|
||||||
if [ $size -eq 0 ]; then
|
if [ $size -eq 0 ]; then
|
||||||
echo "${TESTDIR}/resp/${name}.rsp: empty"
|
echo "${TESTDIR}/resp/${name}.rsp: empty"
|
||||||
|
|||||||
@@ -65,11 +65,6 @@ gtest_start()
|
|||||||
pushd "$DIR"
|
pushd "$DIR"
|
||||||
GTESTREPORT="$DIR/report.xml"
|
GTESTREPORT="$DIR/report.xml"
|
||||||
PARSED_REPORT="$DIR/report.parsed"
|
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
|
# NSS CI sets a lower max for PBE iterations, otherwise cert.sh
|
||||||
# is very slow. Unset this maxiumum for softoken_gtest, as it
|
# is very slow. Unset this maxiumum for softoken_gtest, as it
|
||||||
# needs to check the default value.
|
# needs to check the default value.
|
||||||
@@ -78,10 +73,9 @@ gtest_start()
|
|||||||
unset NSS_MAX_MP_PBE_ITERATION_COUNT
|
unset NSS_MAX_MP_PBE_ITERATION_COUNT
|
||||||
fi
|
fi
|
||||||
echo "executing $i"
|
echo "executing $i"
|
||||||
ASAN_OPTIONS="$ASAN_OPTIONS:$EXTRA_ASAN_OPTIONS" "${BINDIR}/$i" \
|
"${BINDIR}/$i" -s "${SOURCE_DIR}/gtests/$i" -d "$DIR" -w \
|
||||||
-s "${SOURCE_DIR}/gtests/$i" \
|
--gtest_output=xml:"${GTESTREPORT}" \
|
||||||
-d "$DIR" -w --gtest_output=xml:"${GTESTREPORT}" \
|
--gtest_filter="${GTESTFILTER:-*}"
|
||||||
--gtest_filter="${GTESTFILTER:-*}"
|
|
||||||
html_msg $? 0 "$i run successfully"
|
html_msg $? 0 "$i run successfully"
|
||||||
if [ "$i" = "softoken_gtest" ]; then
|
if [ "$i" = "softoken_gtest" ]; then
|
||||||
export NSS_MAX_MP_PBE_ITERATION_COUNT=$OLD_MAX_PBE_ITERATIONS
|
export NSS_MAX_MP_PBE_ITERATION_COUNT=$OLD_MAX_PBE_ITERATIONS
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ tlsfuzzer_init()
|
|||||||
|
|
||||||
# Install tlslite-ng dependencies
|
# 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/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"
|
pushd "$TLSFUZZER"
|
||||||
ln -s ../python-ecdsa/src/ecdsa ecdsa
|
ln -s ../python-ecdsa/src/ecdsa ecdsa
|
||||||
|
|||||||
0
security/nss/tests/tools/corrupted_cert_bag.pk12
Normal file
0
security/nss/tests/tools/corrupted_cert_bag.pk12
Normal file
@@ -127,6 +127,7 @@ tools_init()
|
|||||||
cp ${QADIR}/tools/pbmac1-invalid-bad-iter.p12 ${TOOLSDIR}/data
|
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-bad-salt.p12 ${TOOLSDIR}/data
|
||||||
cp ${QADIR}/tools/pbmac1-invalid-no-length.p12 ${TOOLSDIR}/data
|
cp ${QADIR}/tools/pbmac1-invalid-no-length.p12 ${TOOLSDIR}/data
|
||||||
|
cp ${QADIR}/tools/corrupted_cert_bag.p12 ${TOOLSDIR}/data
|
||||||
|
|
||||||
cd ${TOOLSDIR}
|
cd ${TOOLSDIR}
|
||||||
}
|
}
|
||||||
@@ -501,6 +502,12 @@ tools_p12_import_old_files()
|
|||||||
html_msg $ret 0 "Importing PKCS#12 file with and implicit KDF value"
|
html_msg $ret 0 "Importing PKCS#12 file with and implicit KDF value"
|
||||||
check_tmpfile
|
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()
|
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"
|
html_msg $ret 0 "Importing private key pbmac1 hmac-sha-512 from PKCS#12 file"
|
||||||
check_tmpfile
|
check_tmpfile
|
||||||
|
|
||||||
echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-iter.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234'"
|
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' 2>&1
|
${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-iter.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I 2>&1
|
||||||
ret=$?
|
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
|
check_tmpfile
|
||||||
|
|
||||||
echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-salt.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234'"
|
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' 2>&1
|
${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-salt.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I 2>&1
|
||||||
ret=$?
|
ret=$?
|
||||||
echo "Fail to list private key with bad salt val=$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
|
check_tmpfile
|
||||||
|
|
||||||
echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-no-length.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234'"
|
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' 2>&1
|
${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-no-length.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I 2>&1
|
||||||
ret=$?
|
ret=$?
|
||||||
echo "Fail to import private key with no length val=$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
|
check_tmpfile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user