mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1258375, NSS_3_24_BETA6 and required adjustments to PSM and packaging, r=martin.thomson, r=glandium
This commit is contained in:
parent
3ce084784c
commit
70551ded71
@ -813,7 +813,11 @@
|
||||
@BINPATH@/@DLL_PREFIX@ssl3@DLL_SUFFIX@
|
||||
#endif
|
||||
@BINPATH@/@DLL_PREFIX@softokn3@DLL_SUFFIX@
|
||||
#if defined(XP_LINUX) && !defined(ANDROID)
|
||||
@BINPATH@/@DLL_PREFIX@freeblpriv3@DLL_SUFFIX@
|
||||
#else
|
||||
@BINPATH@/@DLL_PREFIX@freebl3@DLL_SUFFIX@
|
||||
#endif
|
||||
#ifndef CROSS_COMPILE
|
||||
@BINPATH@/@DLL_PREFIX@freebl3.chk
|
||||
@BINPATH@/@DLL_PREFIX@softokn3.chk
|
||||
|
@ -753,7 +753,11 @@
|
||||
; meaning their .chk files are created there directly.
|
||||
;
|
||||
#ifndef MOZ_SYSTEM_NSS
|
||||
#if defined(XP_LINUX) && !defined(ANDROID)
|
||||
@BINPATH@/@DLL_PREFIX@freeblpriv3@DLL_SUFFIX@
|
||||
#else
|
||||
@BINPATH@/@DLL_PREFIX@freebl3@DLL_SUFFIX@
|
||||
#endif
|
||||
@BINPATH@/@DLL_PREFIX@nss3@DLL_SUFFIX@
|
||||
@BINPATH@/@DLL_PREFIX@nssckbi@DLL_SUFFIX@
|
||||
#ifndef NSS_DISABLE_DBM
|
||||
|
14
config/external/nss/Makefile.in
vendored
14
config/external/nss/Makefile.in
vendored
@ -68,9 +68,18 @@ endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS_TARGET),Linux)
|
||||
HAVE_FREEBL_LIBS =
|
||||
HAVE_FREEBL_LIBS_PRIV = 1
|
||||
FREEBL_LOWHASH_FLAG = FREEBL_LOWHASH=1
|
||||
endif
|
||||
|
||||
ifdef HAVE_FREEBL_LIBS
|
||||
NSS_EXTRA_DLLS += freebl3
|
||||
endif
|
||||
ifdef HAVE_FREEBL_LIBS_PRIV
|
||||
NSS_EXTRA_DLLS += freeblpriv3
|
||||
endif
|
||||
ifdef HAVE_FREEBL_LIBS_32INT32
|
||||
NSS_EXTRA_DLLS += freebl_32int_3
|
||||
endif
|
||||
@ -229,10 +238,7 @@ DEFAULT_GMAKE_FLAGS += \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
DEFAULT_GMAKE_FLAGS += FREEBL_NO_DEPEND=0
|
||||
ifeq ($(OS_TARGET),Linux)
|
||||
DEFAULT_GMAKE_FLAGS += FREEBL_LOWHASH=1
|
||||
endif
|
||||
DEFAULT_GMAKE_FLAGS += FREEBL_NO_DEPEND=0 $(FREEBL_LOWHASH_FLAG)
|
||||
|
||||
ifdef MOZ_NO_WLZDEFS
|
||||
DEFAULT_GMAKE_FLAGS += ZDEFS_FLAG=
|
||||
|
2
config/external/nss/nss.symbols
vendored
2
config/external/nss/nss.symbols
vendored
@ -452,12 +452,14 @@ PORT_ArenaStrdup_Util
|
||||
PORT_ArenaUnmark_Util
|
||||
PORT_ArenaZAlloc
|
||||
PORT_ArenaZAlloc_Util
|
||||
PORT_DestroyCheapArena
|
||||
PORT_Free
|
||||
PORT_FreeArena
|
||||
PORT_FreeArena_Util
|
||||
PORT_Free_Util
|
||||
PORT_GetError
|
||||
PORT_GetError_Util
|
||||
PORT_InitCheapArena
|
||||
PORT_NewArena
|
||||
PORT_NewArena_Util
|
||||
PORT_Realloc_Util
|
||||
|
@ -83,7 +83,16 @@ ifdef USE_STATIC_RTL
|
||||
NSPR_CONFIGURE_OPTS += --enable-static-rtl
|
||||
endif
|
||||
ifdef NS_USE_GCC
|
||||
NSPR_COMPILERS = CC=gcc CXX=g++
|
||||
NSPR_CONFIGURE_ENV = CC=gcc CXX=g++
|
||||
endif
|
||||
|
||||
ifdef SANITIZER_CFLAGS
|
||||
ifdef BUILD_OPT
|
||||
NSPR_CONFIGURE_OPTS += --enable-debug-symbols
|
||||
endif
|
||||
NSPR_CONFIGURE_ENV += CFLAGS='$(SANITIZER_CFLAGS)' \
|
||||
CXXFLAGS='$(SANITIZER_CFLAGS)' \
|
||||
LDFLAGS='$(SANITIZER_LDFLAGS)'
|
||||
endif
|
||||
|
||||
#
|
||||
@ -110,7 +119,7 @@ endif
|
||||
$(NSPR_CONFIG_STATUS): $(NSPR_CONFIGURE)
|
||||
mkdir -p $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)
|
||||
cd $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME) ; \
|
||||
$(NSPR_COMPILERS) sh ../configure \
|
||||
$(NSPR_CONFIGURE_ENV) sh ../configure \
|
||||
$(NSPR_CONFIGURE_OPTS) \
|
||||
--with-dist-prefix='$(NSPR_PREFIX)' \
|
||||
--with-dist-includedir='$(NSPR_PREFIX)/include'
|
||||
|
@ -1 +1 @@
|
||||
NSS_3_23_RTM
|
||||
NSS_3_24_BETA6
|
||||
|
@ -288,14 +288,19 @@ prepare()
|
||||
mv ${OUTPUTDIR} ${OUTPUTDIR}.last >/dev/null 2>&1
|
||||
mkdir -p ${OUTPUTDIR}
|
||||
|
||||
cd ${HGDIR}/nss
|
||||
|
||||
if [ -z "${NSS_DISABLE_ECC}" -a -n "${NSS_ECC_MORE_THAN_SUITE_B}" ]; then
|
||||
cd ${HGDIR}/nss
|
||||
ECF="lib/freebl/ecl/ecl-curve.h"
|
||||
print_log "hg revert -r NSS_3_11_1_RTM ${ECF}"
|
||||
hg revert -r NSS_3_11_1_RTM security/nss/${ECF}
|
||||
cp -f security/nss/${ECF} ${ECF}
|
||||
fi
|
||||
|
||||
if [ -n "${FEWER_STRESS_ITERATIONS}" ]; then
|
||||
sed -i 's/-c_1000_/-c_500_/g' tests/ssl/sslstress.txt
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,9 @@ checkout:
|
||||
test:
|
||||
override:
|
||||
- make nss_build_all
|
||||
- cd tests; NSS_TESTS="ssl_gtests pk11_gtests der_gtests" NSS_CYCLES=standard ./all.sh
|
||||
- cd tests; NSS_TESTS="ssl_gtests pk11_gtests der_gtests util_gtests" NSS_CYCLES=standard ./all.sh
|
||||
- BUILD_OPT=1 make nss_build_all
|
||||
- cd tests; BUILD_OPT=1 NSS_TESTS="ssl_gtests pk11_gtests der_gtests" NSS_CYCLES=standard ./all.sh
|
||||
- cd tests; BUILD_OPT=1 NSS_TESTS="ssl_gtests pk11_gtests der_gtests util_gtests" NSS_CYCLES=standard ./all.sh
|
||||
|
||||
machine:
|
||||
environment:
|
||||
|
@ -3749,7 +3749,7 @@ int main(int argc, char **argv)
|
||||
|
||||
/* Do FIPS self-test */
|
||||
if (bltest.commands[cmd_FIPS].activated) {
|
||||
CK_RV ckrv = sftk_fipsPowerUpSelfTest();
|
||||
CK_RV ckrv = sftk_FIPSEntryOK();
|
||||
fprintf(stdout, "CK_RV: %ld.\n", ckrv);
|
||||
PORT_Free(cipherInfo);
|
||||
if (ckrv == CKR_OK)
|
||||
|
@ -441,7 +441,6 @@ outputCertOrExtension(CERTCertificate *the_cert, PRBool raw, PRBool ascii,
|
||||
SECU_PrintSystemError(progName, "error writing extension");
|
||||
rv = SECFailure;
|
||||
}
|
||||
rv = SECSuccess;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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/.
|
||||
|
||||
#
|
||||
#
|
||||
# A Bourne shell script for running the NIST AES Algorithm Validation Suite
|
||||
#
|
||||
@ -12,6 +13,12 @@
|
||||
# directory where the REQUEST (.req) files reside. The script generates the
|
||||
# RESPONSE (.rsp) files in the same directory.
|
||||
|
||||
BASEDIR=${1-.}
|
||||
TESTDIR=${BASEDIR}/AES
|
||||
COMMAND=${2-run}
|
||||
REQDIR=${TESTDIR}/req
|
||||
RSPDIR=${TESTDIR}/resp
|
||||
|
||||
cbc_kat_requests="
|
||||
CBCGFSbox128.req
|
||||
CBCGFSbox192.req
|
||||
@ -66,33 +73,40 @@ ECBMMT192.req
|
||||
ECBMMT256.req
|
||||
"
|
||||
|
||||
for request in $ecb_kat_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest aes kat ecb $request > $response
|
||||
done
|
||||
for request in $ecb_mmt_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest aes mmt ecb $request > $response
|
||||
done
|
||||
for request in $ecb_mct_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest aes mct ecb $request > $response
|
||||
done
|
||||
if [ ${COMMAND} = "verify" ]; then
|
||||
for request in $cbc_kat_requests $cbc_mct_requests $cbc_mmt_requests $ecb_kat_requests $ecb_mct_requests $ecb_mmt_requests; do
|
||||
sh ./validate1.sh ${TESTDIR} $request
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for request in $cbc_kat_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest aes kat cbc $request > $response
|
||||
done
|
||||
for request in $cbc_mmt_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest aes mmt cbc $request > $response
|
||||
fipstest aes kat cbc ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
for request in $cbc_mct_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest aes mct cbc $request > $response
|
||||
fipstest aes mct cbc ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
for request in $cbc_mmt_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest aes mmt cbc ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
for request in $ecb_kat_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest aes kat ecb ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
for request in $ecb_mct_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest aes mct ecb ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
for request in $ecb_mmt_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest aes mmt ecb ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
|
67
security/nss/cmd/fipstest/aesgcm.sh
Normal file
67
security/nss/cmd/fipstest/aesgcm.sh
Normal file
@ -0,0 +1,67 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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/.
|
||||
#
|
||||
# A Bourne shell script for running the NIST AES Algorithm Validation Suite
|
||||
#
|
||||
# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
|
||||
# variables appropriately so that the fipstest command and the NSPR and NSS
|
||||
# shared libraries/DLLs are on the search path. Then run this script in the
|
||||
# directory where the REQUEST (.req) files reside. The script generates the
|
||||
# RESPONSE (.rsp) files in the same directory.
|
||||
|
||||
BASEDIR=${1-.}
|
||||
TESTDIR=${BASEDIR}/AES_GCM
|
||||
COMMAND=${2-run}
|
||||
REQDIR=${TESTDIR}/req
|
||||
RSPDIR=${TESTDIR}/resp
|
||||
|
||||
gcm_decrypt_requests="
|
||||
gcmDecrypt128.req
|
||||
gcmDecrypt192.req
|
||||
gcmDecrypt256.req
|
||||
"
|
||||
|
||||
gcm_encrypt_extiv_requests="
|
||||
gcmEncryptExtIV128.req
|
||||
gcmEncryptExtIV192.req
|
||||
gcmEncryptExtIV256.req
|
||||
"
|
||||
gcm_encrypt_intiv_requests="
|
||||
"
|
||||
|
||||
#gcm_encrypt_intiv_requests="
|
||||
#gcmEncryptIntIV128.req
|
||||
#gcmEncryptIntIV192.req
|
||||
#gcmEncryptIntIV256.req
|
||||
#"
|
||||
|
||||
if [ ${COMMAND} = "verify" ]; then
|
||||
for request in $gcm_decrypt_requests $gcm_encrypt_extiv_requests; do
|
||||
sh ./validate1.sh ${TESTDIR} $request ' ' '-e /Reason:/d'
|
||||
done
|
||||
for request in $gcm_encrypt_intiv_requests; do
|
||||
name=`basename $request .req`
|
||||
echo ">>>>> $name"
|
||||
fipstest aes gcm decrypt ${RSPDIR}/$name.rsp | grep FAIL
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for request in $gcm_decrypt_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest aes gcm decrypt ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
for request in $gcm_encrypt_intiv_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest aes gcm encrypt_intiv ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
for request in $gcm_encrypt_extiv_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest aes gcm encrypt_extiv ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
@ -1,8 +1,8 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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/.
|
||||
|
||||
#
|
||||
# A Bourne shell script for running the NIST DSA Validation System
|
||||
#
|
||||
@ -11,28 +11,61 @@
|
||||
# shared libraries/DLLs are on the search path. Then run this script in the
|
||||
# directory where the REQUEST (.req) files reside. The script generates the
|
||||
# RESPONSE (.rsp) files in the same directory.
|
||||
BASEDIR=${1-.}
|
||||
TESTDIR=${BASEDIR}/DSA2
|
||||
COMMAND=${2-run}
|
||||
REQDIR=${TESTDIR}/req
|
||||
RSPDIR=${TESTDIR}/resp
|
||||
|
||||
|
||||
#
|
||||
# several of the DSA tests do use known answer tests to verify the result.
|
||||
# in those cases, feed generated tests back into the fipstest tool and
|
||||
# see if we can verify those value. NOTE: th PQGVer and SigVer tests verify
|
||||
# the dsa pqgver and dsa sigver functions, so we know they can detect errors
|
||||
# in those PQGGen and SigGen. Only the KeyPair verify is potentially circular.
|
||||
#
|
||||
if [ ${COMMAND} = "verify" ]; then
|
||||
# verify generated keys
|
||||
name=KeyPair
|
||||
echo ">>>>> $name"
|
||||
fipstest dsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F
|
||||
# verify generated pqg values
|
||||
name=PQGGen
|
||||
echo ">>>>> $name"
|
||||
fipstest dsa pqgver ${RSPDIR}/$name.rsp | grep ^Result.=.F
|
||||
# verify PQGVer with known answer
|
||||
# sh ./validate1.sh ${TESTDIR} PQGVer.req ' ' '-e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
|
||||
# verify signatures
|
||||
name=SigGen
|
||||
echo ">>>>> $name"
|
||||
fipstest dsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
|
||||
# verify SigVer with known answer
|
||||
sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);;'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
request=KeyPair.req
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest dsa keypair $request > $response
|
||||
fipstest dsa keypair ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
|
||||
request=PQGGen.req
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest dsa pqggen $request > $response
|
||||
fipstest dsa pqggen ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
|
||||
request=PQGVer.req
|
||||
request=PQGVer1863.req
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest dsa pqgver $request > $response
|
||||
fipstest dsa pqgver ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
|
||||
request=SigGen.req
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest dsa siggen $request > $response
|
||||
fipstest dsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
|
||||
request=SigVer.req
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest dsa sigver $request > $response
|
||||
fipstest dsa sigver ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
|
@ -1,8 +1,8 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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/.
|
||||
|
||||
#
|
||||
# A Bourne shell script for running the NIST ECDSA Validation System
|
||||
#
|
||||
@ -11,23 +11,50 @@
|
||||
# shared libraries/DLLs are on the search path. Then run this script in the
|
||||
# directory where the REQUEST (.req) files reside. The script generates the
|
||||
# RESPONSE (.rsp) files in the same directory.
|
||||
BASEDIR=${1-.}
|
||||
TESTDIR=${BASEDIR}/ECDSA2
|
||||
COMMAND=${2-run}
|
||||
REQDIR=${TESTDIR}/req
|
||||
RSPDIR=${TESTDIR}/resp
|
||||
|
||||
#
|
||||
# several of the ECDSA tests do not use known answer tests to verify the result.
|
||||
# In those cases, feed generated tests back into the fipstest tool and
|
||||
# see if we can verify those value. NOTE: PQGVer and SigVer tests verify
|
||||
# the dsa pqgver and dsa sigver functions, so we know they can detect errors
|
||||
# in those PQGGen and SigGen. Only the KeyPair verify is potentially circular.
|
||||
#
|
||||
if [ ${COMMAND} = "verify" ]; then
|
||||
# verify generated keys
|
||||
name=KeyPair
|
||||
echo ">>>>> $name"
|
||||
fipstest ecdsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F
|
||||
sh ./validate1.sh ${TESTDIR} PKV.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
|
||||
# verify signatures
|
||||
name=SigGen
|
||||
echo ">>>>> $name"
|
||||
fipstest ecdsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
|
||||
# verify SigVer with known answer
|
||||
sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
request=KeyPair.req
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest ecdsa keypair $request > $response
|
||||
fipstest ecdsa keypair ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
|
||||
request=PKV.req
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest ecdsa pkv $request > $response
|
||||
fipstest ecdsa pkv ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
|
||||
request=SigGen.req
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest ecdsa siggen $request > $response
|
||||
fipstest ecdsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
|
||||
request=SigVer.req
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest ecdsa sigver $request > $response
|
||||
fipstest ecdsa sigver ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
|
@ -3368,6 +3368,24 @@ drbg(char *reqfn)
|
||||
}
|
||||
}
|
||||
loser:
|
||||
if (predictedreturn_bytes) {
|
||||
PORT_Free(predictedreturn_bytes);
|
||||
}
|
||||
if (return_bytes) {
|
||||
PORT_Free(return_bytes);
|
||||
}
|
||||
if (additionalInput) {
|
||||
PORT_Free(additionalInput);
|
||||
}
|
||||
if (personalizationString) {
|
||||
PORT_Free(personalizationString);
|
||||
}
|
||||
if (nonce) {
|
||||
PORT_Free(nonce);
|
||||
}
|
||||
if (entropyInput) {
|
||||
PORT_Free(entropyInput);
|
||||
}
|
||||
fclose(rngreq);
|
||||
}
|
||||
|
||||
@ -5132,7 +5150,7 @@ rsa_keypair_test(char *reqfn)
|
||||
FILE *rsaresp; /* output stream to the RESPONSE file */
|
||||
int count;
|
||||
int i;
|
||||
int keySize; /* key size in bits*/
|
||||
int keySize = 1; /* key size in bits*/
|
||||
int len = 0; /* key size in bytes */
|
||||
int len2 = 0; /* key size in bytes/2 (prime size) */
|
||||
SECItem e;
|
||||
|
@ -1,8 +1,8 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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/.
|
||||
|
||||
#
|
||||
# A Bourne shell script for running the NIST HMAC Algorithm Validation Suite
|
||||
#
|
||||
@ -11,14 +11,26 @@
|
||||
# shared libraries/DLLs are on the search path. Then run this script in the
|
||||
# directory where the REQUEST (.req) files reside. The script generates the
|
||||
# RESPONSE (.rsp) files in the same directory.
|
||||
|
||||
BASEDIR=${1-.}
|
||||
TESTDIR=${BASEDIR}/HMAC
|
||||
COMMAND=${2-run}
|
||||
REQDIR=${TESTDIR}/req
|
||||
RSPDIR=${TESTDIR}/resp
|
||||
|
||||
hmac_requests="
|
||||
HMAC.req
|
||||
"
|
||||
|
||||
if [ ${COMMAND} = "verify" ]; then
|
||||
for request in $hmac_requests; do
|
||||
sh ./validate1.sh ${TESTDIR} $request
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
for request in $hmac_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest hmac $request > $response
|
||||
fipstest hmac ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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/.
|
||||
|
||||
#
|
||||
# A Bourne shell script for running the NIST RNG Validation Suite
|
||||
#
|
||||
@ -11,13 +11,24 @@
|
||||
# shared libraries/DLLs are on the search path. Then run this script in the
|
||||
# directory where the REQUEST (.req) files reside. The script generates the
|
||||
# RESPONSE (.rsp) files in the same directory.
|
||||
BASEDIR=${1-.}
|
||||
TESTDIR=${BASEDIR}/DRBG800-90A
|
||||
COMMAND=${2-run}
|
||||
REQDIR=${TESTDIR}/req
|
||||
RSPDIR=${TESTDIR}/resp
|
||||
|
||||
drbg_requests="
|
||||
SHA256_DRBG.req
|
||||
Hash_DRBG.req
|
||||
"
|
||||
|
||||
if [ ${COMMAND} = "verify" ]; then
|
||||
for request in $drbg_requests; do
|
||||
sh ./validate1.sh ${TESTDIR} $request
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
for request in $drbg_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest drbg $request > $response
|
||||
fipstest drbg ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
|
@ -1,8 +1,8 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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/.
|
||||
|
||||
#
|
||||
# A Bourne shell script for running the NIST RSA Validation System
|
||||
#
|
||||
@ -11,14 +11,40 @@
|
||||
# shared libraries/DLLs are on the search path. Then run this script in the
|
||||
# directory where the REQUEST (.req) files reside. The script generates the
|
||||
# RESPONSE (.rsp) files in the same directory.
|
||||
BASEDIR=${1-.}
|
||||
TESTDIR=${BASEDIR}/RSA2
|
||||
COMMAND=${2-run}
|
||||
REQDIR=${TESTDIR}/req
|
||||
RSPDIR=${TESTDIR}/resp
|
||||
|
||||
if [ ${COMMAND} = "verify" ]; then
|
||||
#verify the signatures. The fax file does not have any known answers, so
|
||||
#use our own verify function.
|
||||
name=SigGen15_186-3
|
||||
echo ">>>>> $name"
|
||||
fipstest rsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
|
||||
# fipstest rsa sigver ${REQDIR}/SigVer15_186-3.req | grep ^Result.=.F
|
||||
#The Fax file has the private exponent and the salt value, remove it
|
||||
#also remove the false reason
|
||||
sh ./validate1.sh ${TESTDIR} SigVer15_186-3.req ' ' '-e /^SaltVal/d -e/^d.=/d -e /^p.=/d -e /^q.=/d -e /^EM.with/d -e /^Result.=.F/s;.(.*);;'
|
||||
#
|
||||
# currently don't have a way to verify the RSA keygen
|
||||
#
|
||||
exit 0
|
||||
fi
|
||||
|
||||
request=SigGen15.req
|
||||
request=SigGen15_186-3.req
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest rsa siggen $request > $response
|
||||
fipstest rsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
|
||||
request=SigVer15.req
|
||||
request=SigVer15_186-3.req
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest rsa sigver $request > $response
|
||||
fipstest rsa sigver ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
|
||||
#request=KeyGen_186-3.req
|
||||
request=KeyGen_RandomProbablyPrime3_3.req
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest rsa keypair ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
|
17
security/nss/cmd/fipstest/runtest.sh
Normal file
17
security/nss/cmd/fipstest/runtest.sh
Normal file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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/.
|
||||
#
|
||||
TESTDIR=${1-.}
|
||||
COMMAND=${2-run}
|
||||
TESTS="aes aesgcm dsa ecdsa hmac tls rng rsa sha tdea"
|
||||
if [ ${NSS_ENABLE_ECC}x = 1x ]; then
|
||||
TESTS=${TESTS} ecdsa
|
||||
fi
|
||||
for i in $TESTS
|
||||
do
|
||||
echo "********************Running $i tests"
|
||||
sh ./${i}.sh ${TESTDIR} ${COMMAND}
|
||||
done
|
@ -1,8 +1,8 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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/.
|
||||
|
||||
#
|
||||
# A Bourne shell script for running the NIST SHA Algorithm Validation Suite
|
||||
#
|
||||
@ -11,9 +11,15 @@
|
||||
# shared libraries/DLLs are on the search path. Then run this script in the
|
||||
# directory where the REQUEST (.req) files reside. The script generates the
|
||||
# RESPONSE (.rsp) files in the same directory.
|
||||
BASEDIR=${1-.}
|
||||
TESTDIR=${BASEDIR}/SHA
|
||||
COMMAND=${2-run}
|
||||
REQDIR=${TESTDIR}/req
|
||||
RSPDIR=${TESTDIR}/resp
|
||||
|
||||
sha_ShortMsg_requests="
|
||||
SHA1ShortMsg.req
|
||||
SHA224ShortMsg.req
|
||||
SHA256ShortMsg.req
|
||||
SHA384ShortMsg.req
|
||||
SHA512ShortMsg.req
|
||||
@ -21,6 +27,7 @@ SHA512ShortMsg.req
|
||||
|
||||
sha_LongMsg_requests="
|
||||
SHA1LongMsg.req
|
||||
SHA224LongMsg.req
|
||||
SHA256LongMsg.req
|
||||
SHA384LongMsg.req
|
||||
SHA512LongMsg.req
|
||||
@ -28,23 +35,32 @@ SHA512LongMsg.req
|
||||
|
||||
sha_Monte_requests="
|
||||
SHA1Monte.req
|
||||
SHA224Monte.req
|
||||
SHA256Monte.req
|
||||
SHA384Monte.req
|
||||
SHA512Monte.req
|
||||
"
|
||||
|
||||
if [ ${COMMAND} = "verify" ]; then
|
||||
for request in $sha_ShortMsg_requests $sha_LongMsg_requests $sha_Monte_requests; do
|
||||
sh ./validate1.sh ${TESTDIR} $request
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for request in $sha_ShortMsg_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest sha $request > $response
|
||||
fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
for request in $sha_LongMsg_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest sha $request > $response
|
||||
fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
for request in $sha_Monte_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest sha $request > $response
|
||||
fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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/.
|
||||
|
||||
#
|
||||
# A Bourne shell script for running the NIST tdea Algorithm Validation Suite
|
||||
#
|
||||
@ -12,6 +12,12 @@
|
||||
# directory where the REQUEST (.req) files reside. The script generates the
|
||||
# RESPONSE (.rsp) files in the same directory.
|
||||
|
||||
BASEDIR=${1-.}
|
||||
TESTDIR=${BASEDIR}/TDES
|
||||
COMMAND=${2-run}
|
||||
REQDIR=${TESTDIR}/req
|
||||
RSPDIR=${TESTDIR}/resp
|
||||
|
||||
#CBC_Known_Answer_tests
|
||||
#Initial Permutation KAT
|
||||
#Permutation Operation KAT
|
||||
@ -59,33 +65,42 @@ TECBMMT2.req
|
||||
TECBMMT3.req
|
||||
"
|
||||
|
||||
for request in $ecb_mmt_requests; do
|
||||
|
||||
if [ ${COMMAND} = "verify" ]; then
|
||||
for request in $cbc_kat_requests $cbc_monte_requests $cbc_mmt_requests $ecb_kat_requests $ecb_monte_requests $ecb_mmt_requests
|
||||
do
|
||||
sh ./validate1.sh ${TESTDIR} $request "-e /^NumKeys/d"
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for request in $cbc_kat_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest tdea mmt ecb $request > $response
|
||||
done
|
||||
for request in $ecb_kat_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest tdea kat ecb $request > $response
|
||||
done
|
||||
for request in $ecb_monte_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest tdea mct ecb $request > $response
|
||||
fipstest tdea kat cbc ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
for request in $cbc_mmt_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest tdea mmt cbc $request > $response
|
||||
done
|
||||
for request in $cbc_kat_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest tdea kat cbc $request > $response
|
||||
fipstest tdea mmt cbc ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
for request in $cbc_monte_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest tdea mct cbc $request > $response
|
||||
fipstest tdea mct cbc ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
for request in $ecb_kat_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest tdea kat ecb ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
for request in $ecb_mmt_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest tdea mmt ecb ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
for request in $ecb_monte_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest tdea mct ecb ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
||||
|
34
security/nss/cmd/fipstest/tls.sh
Normal file
34
security/nss/cmd/fipstest/tls.sh
Normal file
@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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/.
|
||||
#
|
||||
# A Bourne shell script for running the NIST RNG Validation Suite
|
||||
#
|
||||
# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
|
||||
# variables appropriately so that the fipstest command and the NSPR and NSS
|
||||
# shared libraries/DLLs are on the search path. Then run this script in the
|
||||
# directory where the REQUEST (.req) files reside. The script generates the
|
||||
# RESPONSE (.rsp) files in the same directory.
|
||||
BASEDIR=${1-.}
|
||||
TESTDIR=${BASEDIR}/KDF135
|
||||
COMMAND=${2-run}
|
||||
REQDIR=${TESTDIR}/req
|
||||
RSPDIR=${TESTDIR}/resp
|
||||
|
||||
drbg_requests="
|
||||
tls.req
|
||||
"
|
||||
|
||||
if [ ${COMMAND} = "verify" ]; then
|
||||
for request in $drbg_requests; do
|
||||
sh ./validate1.sh ${TESTDIR} $request
|
||||
done
|
||||
exit 0
|
||||
fi
|
||||
for request in $drbg_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest tls ${REQDIR}/$request > ${RSPDIR}/$response
|
||||
done
|
@ -1,6 +1,7 @@
|
||||
#
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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/.
|
||||
|
||||
pk11test.c: pk11test.h pkcs11.h
|
||||
#
|
||||
sh ./runtest.sh ${1-.} verify
|
30
security/nss/cmd/fipstest/validate1.sh
Normal file
30
security/nss/cmd/fipstest/validate1.sh
Normal file
@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# 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/.
|
||||
#
|
||||
# Validate1.sh is a helper shell script that each of the base test shell
|
||||
# scripts call to help validate that the generated response (response)
|
||||
# matches the known answer response (fax). Sometimes (depending on the
|
||||
# individual tests) there are extraneous output in either or both response
|
||||
# and fax files. These allow the caller to pass in additional sed commands
|
||||
# to clear out those extraneous outputs before we compare the two files.
|
||||
# The sed line always clears out Windows line endings, replaces tabs with
|
||||
# spaces, and removed comments.
|
||||
#
|
||||
TESTDIR=${1-.}
|
||||
request=${2}
|
||||
extraneous_response=${3}
|
||||
extraneous_fax=${4}
|
||||
name=`basename $request .req`
|
||||
echo ">>>>> $name"
|
||||
sed -e 's;
;;g' -e 's; ; ;g' -e '/^#/d' $extraneous_response ${TESTDIR}/resp/${name}.rsp > /tmp/y1
|
||||
# if we didn't generate any output, flag that as an error
|
||||
size=`sum /tmp/y1 | awk '{ print $NF }'`
|
||||
if [ $size -eq 0 ]; then
|
||||
echo "${TESTDIR}/resp/${name}.rsp: empty"
|
||||
exit 1;
|
||||
fi
|
||||
sed -e 's;
;;g' -e 's; ; ;g' -e '/^#/d' $extraneous_fax ${TESTDIR}/fax/${name}.fax > /tmp/y2
|
||||
diff -i -w -B /tmp/y1 /tmp/y2
|
@ -3697,10 +3697,6 @@ SECU_GetSSLVersionFromName(const char *buf, size_t bufLen, PRUint16 *version)
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (!PL_strncasecmp(buf, "ssl2", bufLen)) {
|
||||
*version = SSL_LIBRARY_VERSION_2;
|
||||
return SECSuccess;
|
||||
}
|
||||
if (!PL_strncasecmp(buf, "ssl3", bufLen)) {
|
||||
*version = SSL_LIBRARY_VERSION_3_0;
|
||||
return SECSuccess;
|
||||
@ -3730,21 +3726,26 @@ SECU_GetSSLVersionFromName(const char *buf, size_t bufLen, PRUint16 *version)
|
||||
SECStatus
|
||||
SECU_ParseSSLVersionRangeString(const char *input,
|
||||
const SSLVersionRange defaultVersionRange,
|
||||
const PRBool defaultEnableSSL2,
|
||||
SSLVersionRange *vrange, PRBool *enableSSL2)
|
||||
SSLVersionRange *vrange)
|
||||
{
|
||||
const char *colonPos;
|
||||
size_t colonIndex;
|
||||
const char *maxStr;
|
||||
|
||||
if (!input || !vrange || !enableSSL2) {
|
||||
if (!input || !vrange) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
// We don't support SSL2 any longer.
|
||||
if (defaultVersionRange.min < SSL_LIBRARY_VERSION_3_0 ||
|
||||
defaultVersionRange.max < SSL_LIBRARY_VERSION_3_0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (!strcmp(input, ":")) {
|
||||
/* special value, use default */
|
||||
*enableSSL2 = defaultEnableSSL2;
|
||||
*vrange = defaultVersionRange;
|
||||
return SECSuccess;
|
||||
}
|
||||
@ -3760,7 +3761,6 @@ SECU_ParseSSLVersionRangeString(const char *input,
|
||||
|
||||
if (!colonIndex) {
|
||||
/* colon was first character, min version is empty */
|
||||
*enableSSL2 = defaultEnableSSL2;
|
||||
vrange->min = defaultVersionRange.min;
|
||||
} else {
|
||||
PRUint16 version;
|
||||
@ -3770,13 +3770,7 @@ SECU_ParseSSLVersionRangeString(const char *input,
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (version == SSL_LIBRARY_VERSION_2) {
|
||||
*enableSSL2 = PR_TRUE;
|
||||
vrange->min = defaultVersionRange.min;
|
||||
} else {
|
||||
*enableSSL2 = PR_FALSE;
|
||||
vrange->min = version;
|
||||
}
|
||||
vrange->min = version;
|
||||
}
|
||||
|
||||
if (!*maxStr) {
|
||||
@ -3790,18 +3784,12 @@ SECU_ParseSSLVersionRangeString(const char *input,
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (version == SSL_LIBRARY_VERSION_2) {
|
||||
/* consistency checking, require that min allows enableSSL2, too */
|
||||
if (!*enableSSL2) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
/* we use 0 because SSL_LIBRARY_VERSION_NONE is private: */
|
||||
vrange->min = 0;
|
||||
vrange->max = 0;
|
||||
} else {
|
||||
vrange->max = version;
|
||||
}
|
||||
vrange->max = version;
|
||||
}
|
||||
|
||||
if (vrange->min > vrange->max) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
|
@ -398,21 +398,15 @@ SECU_SECItemHexStringToBinary(SECItem* srcdest);
|
||||
* and all implemented versions greater than or equal to min will be enabled.
|
||||
* A string consisting of a colon only means "all versions enabled".
|
||||
*
|
||||
* Because output parameter type SSLVersionRange doesn't allow to set
|
||||
* version 2 values, we use a separate boolean output parameter
|
||||
* to return whether SSL 2 is enabled.
|
||||
*
|
||||
* In order to avoid a link dependency from libsectool to libssl,
|
||||
* the caller must provide the desired default values for the min/max values,
|
||||
* by providing defaultEnableSSL2 and defaultVersionRange
|
||||
* (which can be obtained from libssl by calling SSL_VersionRangeGetSupported).
|
||||
* by providing defaultVersionRange (which can be obtained from libssl by
|
||||
* calling SSL_VersionRangeGetSupported).
|
||||
*/
|
||||
SECStatus
|
||||
SECU_ParseSSLVersionRangeString(const char *input,
|
||||
const SSLVersionRange defaultVersionRange,
|
||||
const PRBool defaultEnableSSL2,
|
||||
SSLVersionRange *vrange,
|
||||
PRBool *enableSSL2);
|
||||
SSLVersionRange *vrange);
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -54,8 +54,7 @@ int main(int argc, char **argv)
|
||||
info.keaTypeName, info.authAlgorithmName, info.symCipherName,
|
||||
info.effectiveKeyBits, info.macAlgorithmName,
|
||||
enabled ? "Enabled" : "Disabled",
|
||||
info.isFIPS ? "FIPS" :
|
||||
(SSL_IS_SSL2_CIPHER(info.cipherSuite) ? "SSL2" : ""),
|
||||
info.isFIPS ? "FIPS" : "",
|
||||
info.isExportable ? "Export" : "Domestic",
|
||||
info.nonStandard ? "nonStandard" : "");
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ struct Pk11Install_Info_str {
|
||||
Pk11Install_Info*
|
||||
Pk11Install_Info_new();
|
||||
void
|
||||
Pk11Install_Info_init();
|
||||
Pk11Install_Info_init(Pk11Install_Info* _this);
|
||||
void
|
||||
Pk11Install_Info_delete(Pk11Install_Info* _this);
|
||||
/*// Returns NULL for success, error message if parse error.*/
|
||||
|
@ -77,7 +77,7 @@ ExportPublicKey(FILE *outFile, CERTCertificate *cert)
|
||||
|
||||
if (!cert)
|
||||
return -1;
|
||||
|
||||
|
||||
publicKey = CERT_ExtractPublicKey(cert);
|
||||
if (!publicKey)
|
||||
return -1;
|
||||
@ -86,17 +86,17 @@ ExportPublicKey(FILE *outFile, CERTCertificate *cert)
|
||||
SECKEY_DestroyPublicKey(publicKey);
|
||||
if (!item)
|
||||
return -1;
|
||||
|
||||
|
||||
data = PL_Base64Encode((const char*)item->data, item->len, NULL);
|
||||
SECITEM_FreeItem(item, PR_TRUE);
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
|
||||
fputs("pubkey:\n", outFile);
|
||||
fputs(data, outFile);
|
||||
fputs("\n", outFile);
|
||||
PR_Free(data);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -105,66 +105,86 @@ SignFile(FILE *outFile, PRFileDesc *inFile, CERTCertificate *cert)
|
||||
{
|
||||
SECItem data2sign;
|
||||
SECStatus rv;
|
||||
char *data;
|
||||
SECKEYPrivateKey *privKey;
|
||||
SECOidTag algID;
|
||||
PLArenaPool *arena;
|
||||
CERTSignedData sd;
|
||||
SECItem *result;
|
||||
SECKEYPrivateKey *privKey = NULL;
|
||||
char *data = NULL;
|
||||
PLArenaPool *arena = NULL;
|
||||
SECItem *result = NULL;
|
||||
int returnValue = 0;
|
||||
|
||||
if (outFile == NULL || inFile == NULL || cert == NULL)
|
||||
if (outFile == NULL || inFile == NULL || cert == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* suck the file in */
|
||||
if (SECU_ReadDERFromFile(&data2sign, inFile, PR_FALSE,
|
||||
PR_FALSE) != SECSuccess)
|
||||
PR_FALSE) != SECSuccess) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
privKey = NULL;
|
||||
privKey = NULL;
|
||||
privKey = PK11_FindKeyByAnyCert(cert, NULL);
|
||||
if (!privKey) {
|
||||
returnValue = -1;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
|
||||
if (algID == SEC_OID_UNKNOWN)
|
||||
return -1;
|
||||
|
||||
if (algID == SEC_OID_UNKNOWN) {
|
||||
returnValue = -1;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
|
||||
|
||||
PORT_Memset(&sd, 0, sizeof(CERTSignedData));
|
||||
|
||||
|
||||
rv = SEC_SignData(&(sd.signature), data2sign.data, data2sign.len, privKey, algID);
|
||||
if (rv != SECSuccess) {
|
||||
fprintf (stderr, "Could not sign.\n");
|
||||
return -1;
|
||||
returnValue = -1;
|
||||
goto loser;
|
||||
}
|
||||
sd.signature.len = sd.signature.len << 3;
|
||||
|
||||
|
||||
rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, algID, 0);
|
||||
if (rv != SECSuccess) {
|
||||
fprintf (stderr, "Could not set alg id.\n");
|
||||
return -1;
|
||||
returnValue = -1;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
result = SEC_ASN1EncodeItem(arena, NULL, &sd, CERTSignatureDataTemplate);
|
||||
SECITEM_FreeItem(&(sd.signature), PR_FALSE);
|
||||
|
||||
|
||||
if (!result) {
|
||||
fprintf (stderr, "Could not encode.\n");
|
||||
return -1;
|
||||
returnValue = -1;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
data = PL_Base64Encode((const char*)result->data, result->len, NULL);
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
if (!data){
|
||||
returnValue = -1;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
fputs("signature:\n", outFile);
|
||||
fputs(data, outFile);
|
||||
fputs("\n", outFile);
|
||||
ExportPublicKey(outFile, cert);
|
||||
|
||||
SECKEY_DestroyPrivateKey(privKey);
|
||||
|
||||
loser:
|
||||
if (privKey) {
|
||||
SECKEY_DestroyPrivateKey(privKey);
|
||||
}
|
||||
if (data) {
|
||||
PORT_Free(data);
|
||||
}
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
|
||||
return 0;
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -94,16 +94,6 @@ typedef enum ocspStaplingModeEnum ocspStaplingModeType;
|
||||
static char *ocspStaplingCA = NULL;
|
||||
static SECItemArray *certStatus[kt_kea_size] = { NULL };
|
||||
|
||||
const int ssl2CipherSuites[] = {
|
||||
SSL_EN_RC4_128_WITH_MD5, /* A */
|
||||
SSL_EN_RC4_128_EXPORT40_WITH_MD5, /* B */
|
||||
SSL_EN_RC2_128_CBC_WITH_MD5, /* C */
|
||||
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
|
||||
SSL_EN_DES_64_CBC_WITH_MD5, /* E */
|
||||
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
|
||||
0
|
||||
};
|
||||
|
||||
const int ssl3CipherSuites[] = {
|
||||
-1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
|
||||
-1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA * b */
|
||||
@ -178,7 +168,7 @@ PrintParameterUsage()
|
||||
fputs(
|
||||
"-V [min]:[max] restricts the set of enabled SSL/TLS protocol versions.\n"
|
||||
" All versions are enabled by default.\n"
|
||||
" Possible values for min/max: ssl2 ssl3 tls1.0 tls1.1 tls1.2\n"
|
||||
" Possible values for min/max: ssl3 tls1.0 tls1.1 tls1.2\n"
|
||||
" Example: \"-V ssl3:\" enables SSL 3 and newer.\n"
|
||||
"-B bypasses the PKCS11 layer for SSL encryption and MACing\n"
|
||||
"-q checks for bypassability\n"
|
||||
@ -242,13 +232,6 @@ PrintCipherUsage(const char *progName)
|
||||
PrintUsageHeader(progName);
|
||||
fputs(
|
||||
"-c ciphers Letter(s) chosen from the following list\n"
|
||||
"A SSL2 RC4 128 WITH MD5\n"
|
||||
"B SSL2 RC4 128 EXPORT40 WITH MD5\n"
|
||||
"C SSL2 RC2 128 CBC WITH MD5\n"
|
||||
"D SSL2 RC2 128 CBC EXPORT40 WITH MD5\n"
|
||||
"E SSL2 DES 64 CBC WITH MD5\n"
|
||||
"F SSL2 DES 192 EDE3 CBC WITH MD5\n"
|
||||
"\n"
|
||||
"c SSL3 RSA WITH RC4 128 MD5\n"
|
||||
"d SSL3 RSA WITH 3DES EDE CBC SHA\n"
|
||||
"e SSL3 RSA WITH DES CBC SHA\n"
|
||||
@ -828,7 +811,6 @@ logger(void *arg)
|
||||
|
||||
PRBool useModelSocket = PR_FALSE;
|
||||
static SSLVersionRange enabledVersions;
|
||||
PRBool enableSSL2 = PR_TRUE;
|
||||
PRBool disableRollBack = PR_FALSE;
|
||||
PRBool NoReuse = PR_FALSE;
|
||||
PRBool hasSidCache = PR_FALSE;
|
||||
@ -1865,8 +1847,7 @@ server_main(
|
||||
}
|
||||
|
||||
/* do SSL configuration. */
|
||||
rv = SSL_OptionSet(model_sock, SSL_SECURITY,
|
||||
enableSSL2 || enabledVersions.min != 0);
|
||||
rv = SSL_OptionSet(model_sock, SSL_SECURITY, enabledVersions.min != 0);
|
||||
if (rv < 0) {
|
||||
errExit("SSL_OptionSet SSL_SECURITY");
|
||||
}
|
||||
@ -1876,11 +1857,6 @@ server_main(
|
||||
errExit("error setting SSL/TLS version range ");
|
||||
}
|
||||
|
||||
rv = SSL_OptionSet(model_sock, SSL_ENABLE_SSL2, enableSSL2);
|
||||
if (rv != SECSuccess) {
|
||||
errExit("error enabling SSLv2 ");
|
||||
}
|
||||
|
||||
rv = SSL_OptionSet(model_sock, SSL_ROLLBACK_DETECTION, !disableRollBack);
|
||||
if (rv != SECSuccess) {
|
||||
errExit("error enabling RollBack detection ");
|
||||
@ -2282,8 +2258,7 @@ main(int argc, char **argv)
|
||||
case 'U': configureReuseECDHE = (PORT_Atoi(optstate->value) != 0); break;
|
||||
|
||||
case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
|
||||
enabledVersions, enableSSL2,
|
||||
&enabledVersions, &enableSSL2) != SECSuccess) {
|
||||
enabledVersions, &enabledVersions) != SECSuccess) {
|
||||
Usage(progName);
|
||||
}
|
||||
break;
|
||||
@ -2544,7 +2519,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
/* all the SSL2 and SSL3 cipher suites are enabled by default. */
|
||||
/* all SSL3 cipher suites are enabled by default. */
|
||||
if (cipherString) {
|
||||
char *cstringSaved = cipherString;
|
||||
int ndx;
|
||||
@ -2553,12 +2528,11 @@ main(int argc, char **argv)
|
||||
disableAllSSLCiphers();
|
||||
|
||||
while (0 != (ndx = *cipherString++)) {
|
||||
int cipher;
|
||||
int cipher = 0;
|
||||
|
||||
if (ndx == ':') {
|
||||
int ctmp;
|
||||
|
||||
cipher = 0;
|
||||
HEXCHAR_TO_INT(*cipherString, ctmp)
|
||||
cipher |= (ctmp << 12);
|
||||
cipherString++;
|
||||
@ -2572,16 +2546,15 @@ main(int argc, char **argv)
|
||||
cipher |= ctmp;
|
||||
cipherString++;
|
||||
} else {
|
||||
const int *cptr;
|
||||
|
||||
if (! isalpha(ndx)) {
|
||||
fprintf(stderr,
|
||||
"Non-alphabetic char in cipher string (-c arg).\n");
|
||||
exit(9);
|
||||
}
|
||||
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
|
||||
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
|
||||
/* do nothing */;
|
||||
ndx = tolower(ndx) - 'a';
|
||||
if (ndx < PR_ARRAY_SIZE(ssl3CipherSuites)) {
|
||||
cipher = ssl3CipherSuites[ndx];
|
||||
}
|
||||
}
|
||||
if (cipher > 0) {
|
||||
SECStatus status;
|
||||
|
@ -46,16 +46,6 @@
|
||||
* cipher selection code.
|
||||
*/
|
||||
|
||||
int ssl2CipherSuites[] = {
|
||||
SSL_EN_RC4_128_WITH_MD5, /* A */
|
||||
SSL_EN_RC4_128_EXPORT40_WITH_MD5, /* B */
|
||||
SSL_EN_RC2_128_CBC_WITH_MD5, /* C */
|
||||
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
|
||||
SSL_EN_DES_64_CBC_WITH_MD5, /* E */
|
||||
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
|
||||
0
|
||||
};
|
||||
|
||||
int ssl3CipherSuites[] = {
|
||||
-1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
|
||||
-1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA * b */
|
||||
@ -122,7 +112,6 @@ static SSL3Statistics * ssl3stats;
|
||||
|
||||
static int failed_already = 0;
|
||||
static SSLVersionRange enabledVersions;
|
||||
static PRBool enableSSL2 = PR_TRUE;
|
||||
static PRBool bypassPKCS11 = PR_FALSE;
|
||||
static PRBool disableLocking = PR_FALSE;
|
||||
static PRBool ignoreErrors = PR_FALSE;
|
||||
@ -163,7 +152,7 @@ Usage(const char *progName)
|
||||
" -P means do a specified percentage of full handshakes (0-100)\n"
|
||||
" -V [min]:[max] restricts the set of enabled SSL/TLS protocols versions.\n"
|
||||
" All versions are enabled by default.\n"
|
||||
" Possible values for min/max: ssl2 ssl3 tls1.0 tls1.1 tls1.2\n"
|
||||
" Possible values for min/max: ssl3 tls1.0 tls1.1 tls1.2\n"
|
||||
" Example: \"-V ssl3:\" enables SSL 3 and newer.\n"
|
||||
" -U means enable throttling up threads\n"
|
||||
" -B bypasses the PKCS11 layer for SSL encryption and MACing\n"
|
||||
@ -338,7 +327,7 @@ printSecurityInfo(PRFileDesc *fd)
|
||||
|
||||
#define MAX_THREADS 128
|
||||
|
||||
typedef int startFn(void *a, void *b, int c);
|
||||
typedef SECStatus startFn(void *a, void *b, int c);
|
||||
|
||||
|
||||
static PRInt32 numConnected;
|
||||
@ -558,7 +547,7 @@ lockedVars_AddToCount(lockedVars * lv, int addend)
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
SECStatus
|
||||
do_writes(
|
||||
void * a,
|
||||
void * b,
|
||||
@ -719,7 +708,7 @@ myHandshakeCallback(PRFileDesc *socket, void *arg)
|
||||
/* one copy of this function is launched in a separate thread for each
|
||||
** connection to be made.
|
||||
*/
|
||||
int
|
||||
SECStatus
|
||||
do_connects(
|
||||
void * a,
|
||||
void * b,
|
||||
@ -731,7 +720,7 @@ do_connects(
|
||||
PRFileDesc * tcp_sock = 0;
|
||||
PRStatus prStatus;
|
||||
PRUint32 sleepInterval = 50; /* milliseconds */
|
||||
int rv = SECSuccess;
|
||||
SECStatus rv = SECSuccess;
|
||||
PRSocketOptionData opt;
|
||||
|
||||
retry:
|
||||
@ -795,7 +784,6 @@ retry:
|
||||
goto retry;
|
||||
}
|
||||
errWarn("PR_Connect");
|
||||
rv = SECFailure;
|
||||
goto done;
|
||||
} else {
|
||||
if (ThrottleUp) {
|
||||
@ -866,7 +854,7 @@ done:
|
||||
} else if (tcp_sock) {
|
||||
PR_Close(tcp_sock);
|
||||
}
|
||||
return SECSuccess;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@ -1097,7 +1085,7 @@ client_main(
|
||||
/* all suites except RSA_NULL_MD5 are enabled by Domestic Policy */
|
||||
NSS_SetDomesticPolicy();
|
||||
|
||||
/* all the SSL2 and SSL3 cipher suites are enabled by default. */
|
||||
/* all SSL3 cipher suites are enabled by default. */
|
||||
if (cipherString) {
|
||||
int ndx;
|
||||
|
||||
@ -1125,11 +1113,10 @@ client_main(
|
||||
}
|
||||
} else {
|
||||
if (isalpha(ndx)) {
|
||||
const int *cptr;
|
||||
|
||||
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
|
||||
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
|
||||
/* do nothing */;
|
||||
ndx = tolower(ndx) - 'a';
|
||||
if (ndx < PR_ARRAY_SIZE(ssl3CipherSuites)) {
|
||||
cipher = ssl3CipherSuites[ndx];
|
||||
}
|
||||
}
|
||||
if (cipher <= 0) {
|
||||
fprintf(stderr, "strsclnt: Invalid cipher letter: %c\n",
|
||||
@ -1163,8 +1150,7 @@ client_main(
|
||||
|
||||
/* do SSL configuration. */
|
||||
|
||||
rv = SSL_OptionSet(model_sock, SSL_SECURITY,
|
||||
enableSSL2 || enabledVersions.min != 0);
|
||||
rv = SSL_OptionSet(model_sock, SSL_SECURITY, enabledVersions.min != 0);
|
||||
if (rv < 0) {
|
||||
errExit("SSL_OptionSet SSL_SECURITY");
|
||||
}
|
||||
@ -1174,16 +1160,6 @@ client_main(
|
||||
errExit("error setting SSL/TLS version range ");
|
||||
}
|
||||
|
||||
rv = SSL_OptionSet(model_sock, SSL_ENABLE_SSL2, enableSSL2);
|
||||
if (rv != SECSuccess) {
|
||||
errExit("error enabling SSLv2 ");
|
||||
}
|
||||
|
||||
rv = SSL_OptionSet(model_sock, SSL_V2_COMPATIBLE_HELLO, enableSSL2);
|
||||
if (rv != SECSuccess) {
|
||||
errExit("error enabling SSLv2 compatible hellos ");
|
||||
}
|
||||
|
||||
if (bigBuf.data) { /* doing FDX */
|
||||
rv = SSL_OptionSet(model_sock, SSL_ENABLE_FDX, 1);
|
||||
if (rv < 0) {
|
||||
@ -1262,7 +1238,7 @@ client_main(
|
||||
|
||||
if (!NoReuse) {
|
||||
remaining_connections = 1;
|
||||
rv = launch_thread(do_connects, &addr, model_sock, 0);
|
||||
launch_thread(do_connects, &addr, model_sock, 0);
|
||||
/* wait for the first connection to terminate, then launch the rest. */
|
||||
reap_threads();
|
||||
remaining_connections = total_connections - 1 ;
|
||||
@ -1271,7 +1247,7 @@ client_main(
|
||||
active_threads = PR_MIN(active_threads, remaining_connections);
|
||||
/* Start up the threads */
|
||||
for (i=0;i<active_threads;i++) {
|
||||
rv = launch_thread(do_connects, &addr, model_sock, i);
|
||||
launch_thread(do_connects, &addr, model_sock, i);
|
||||
}
|
||||
reap_threads();
|
||||
}
|
||||
@ -1368,8 +1344,7 @@ main(int argc, char **argv)
|
||||
case 'U': ThrottleUp = PR_TRUE; break;
|
||||
|
||||
case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
|
||||
enabledVersions, enableSSL2,
|
||||
&enabledVersions, &enableSSL2) != SECSuccess) {
|
||||
enabledVersions, &enabledVersions) != SECSuccess) {
|
||||
Usage(progName);
|
||||
}
|
||||
break;
|
||||
@ -1510,22 +1485,13 @@ main(int argc, char **argv)
|
||||
PL_strfree(hostName);
|
||||
|
||||
/* some final stats. */
|
||||
if (ssl3stats->hsh_sid_cache_hits +
|
||||
ssl3stats->hsh_sid_cache_misses +
|
||||
ssl3stats->hsh_sid_cache_not_ok +
|
||||
ssl3stats->hsh_sid_stateless_resumes == 0) {
|
||||
/* presumably we were testing SSL2. */
|
||||
printf("strsclnt: SSL2 - %d server certificates tested.\n",
|
||||
certsTested);
|
||||
} else {
|
||||
printf(
|
||||
"strsclnt: %ld cache hits; %ld cache misses, %ld cache not reusable\n"
|
||||
" %ld stateless resumes\n",
|
||||
ssl3stats->hsh_sid_cache_hits,
|
||||
ssl3stats->hsh_sid_cache_misses,
|
||||
ssl3stats->hsh_sid_cache_not_ok,
|
||||
ssl3stats->hsh_sid_stateless_resumes);
|
||||
}
|
||||
printf(
|
||||
"strsclnt: %ld cache hits; %ld cache misses, %ld cache not reusable\n"
|
||||
" %ld stateless resumes\n",
|
||||
ssl3stats->hsh_sid_cache_hits,
|
||||
ssl3stats->hsh_sid_cache_misses,
|
||||
ssl3stats->hsh_sid_cache_not_ok,
|
||||
ssl3stats->hsh_sid_stateless_resumes);
|
||||
|
||||
if (!NoReuse) {
|
||||
if (enableSessionTickets)
|
||||
@ -1539,16 +1505,9 @@ main(int argc, char **argv)
|
||||
} else {
|
||||
printf("strsclnt: NoReuse - %d server certificates tested.\n",
|
||||
certsTested);
|
||||
if (ssl3stats->hsh_sid_cache_hits +
|
||||
ssl3stats->hsh_sid_cache_misses +
|
||||
ssl3stats->hsh_sid_cache_not_ok +
|
||||
ssl3stats->hsh_sid_stateless_resumes > 0) {
|
||||
exitVal = (ssl3stats->hsh_sid_cache_misses != connections) ||
|
||||
(ssl3stats->hsh_sid_stateless_resumes != 0) ||
|
||||
(certsTested != connections);
|
||||
} else { /* ssl2 connections */
|
||||
exitVal = (certsTested != connections);
|
||||
}
|
||||
exitVal = (ssl3stats->hsh_sid_cache_misses != connections) ||
|
||||
(ssl3stats->hsh_sid_stateless_resumes != 0) ||
|
||||
(certsTested != connections);
|
||||
}
|
||||
|
||||
exitVal = ( exitVal || failed_already );
|
||||
|
@ -56,16 +56,6 @@
|
||||
|
||||
PRIntervalTime maxInterval = PR_INTERVAL_NO_TIMEOUT;
|
||||
|
||||
int ssl2CipherSuites[] = {
|
||||
SSL_EN_RC4_128_WITH_MD5, /* A */
|
||||
SSL_EN_RC4_128_EXPORT40_WITH_MD5, /* B */
|
||||
SSL_EN_RC2_128_CBC_WITH_MD5, /* C */
|
||||
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
|
||||
SSL_EN_DES_64_CBC_WITH_MD5, /* E */
|
||||
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
|
||||
0
|
||||
};
|
||||
|
||||
int ssl3CipherSuites[] = {
|
||||
-1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
|
||||
-1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, * b */
|
||||
@ -219,14 +209,14 @@ static void PrintParameterUsage(void)
|
||||
fprintf(stderr,
|
||||
"%-20s Restricts the set of enabled SSL/TLS protocols versions.\n"
|
||||
"%-20s All versions are enabled by default.\n"
|
||||
"%-20s Possible values for min/max: ssl2 ssl3 tls1.0 tls1.1 tls1.2\n"
|
||||
"%-20s Possible values for min/max: ssl3 tls1.0 tls1.1 tls1.2\n"
|
||||
"%-20s Example: \"-V ssl3:\" enables SSL 3 and newer.\n",
|
||||
"-V [min]:[max]", "", "", "");
|
||||
fprintf(stderr, "%-20s Send TLS_FALLBACK_SCSV\n", "-K");
|
||||
fprintf(stderr, "%-20s Prints only payload data. Skips HTTP header.\n", "-S");
|
||||
fprintf(stderr, "%-20s Client speaks first. \n", "-f");
|
||||
fprintf(stderr, "%-20s Use synchronous certificate validation "
|
||||
"(required for SSL2)\n", "-O");
|
||||
"(currently required for TLS 1.3)\n", "-O");
|
||||
fprintf(stderr, "%-20s Override bad server cert. Make it OK.\n", "-o");
|
||||
fprintf(stderr, "%-20s Disable SSL socket locking.\n", "-s");
|
||||
fprintf(stderr, "%-20s Verbose progress reporting.\n", "-v");
|
||||
@ -273,13 +263,6 @@ static void PrintCipherUsage(const char *progName)
|
||||
fprintf(stderr, "%-20s Letter(s) chosen from the following list\n",
|
||||
"-c ciphers");
|
||||
fprintf(stderr,
|
||||
"A SSL2 RC4 128 WITH MD5\n"
|
||||
"B SSL2 RC4 128 EXPORT40 WITH MD5\n"
|
||||
"C SSL2 RC2 128 CBC WITH MD5\n"
|
||||
"D SSL2 RC2 128 CBC EXPORT40 WITH MD5\n"
|
||||
"E SSL2 DES 64 CBC WITH MD5\n"
|
||||
"F SSL2 DES 192 EDE3 CBC WITH MD5\n"
|
||||
"\n"
|
||||
"c SSL3 RSA WITH RC4 128 MD5\n"
|
||||
"d SSL3 RSA WITH 3DES EDE CBC SHA\n"
|
||||
"e SSL3 RSA WITH DES CBC SHA\n"
|
||||
@ -920,7 +903,6 @@ int main(int argc, char **argv)
|
||||
int npds;
|
||||
int override = 0;
|
||||
SSLVersionRange enabledVersions;
|
||||
PRBool enableSSL2 = PR_TRUE;
|
||||
int bypassPKCS11 = 0;
|
||||
int disableLocking = 0;
|
||||
int useExportPolicy = 0;
|
||||
@ -1035,8 +1017,7 @@ int main(int argc, char **argv)
|
||||
case 'U': enableSignedCertTimestamps = 1; break;
|
||||
|
||||
case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
|
||||
enabledVersions, enableSSL2,
|
||||
&enabledVersions, &enableSSL2) != SECSuccess) {
|
||||
enabledVersions, &enabledVersions) != SECSuccess) {
|
||||
Usage(progName);
|
||||
}
|
||||
break;
|
||||
@ -1250,7 +1231,7 @@ int main(int argc, char **argv)
|
||||
else
|
||||
NSS_SetDomesticPolicy();
|
||||
|
||||
/* all the SSL2 and SSL3 cipher suites are enabled by default. */
|
||||
/* all SSL3 cipher suites are enabled by default. */
|
||||
if (cipherString) {
|
||||
/* disable all the ciphers, then enable the ones we want. */
|
||||
disableAllSSLCiphers();
|
||||
@ -1289,18 +1270,17 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* all the SSL2 and SSL3 cipher suites are enabled by default. */
|
||||
/* all SSL3 cipher suites are enabled by default. */
|
||||
if (cipherString) {
|
||||
char *cstringSaved = cipherString;
|
||||
int ndx;
|
||||
|
||||
while (0 != (ndx = *cipherString++)) {
|
||||
int cipher;
|
||||
int cipher = 0;
|
||||
|
||||
if (ndx == ':') {
|
||||
int ctmp = 0;
|
||||
|
||||
cipher = 0;
|
||||
HEXCHAR_TO_INT(*cipherString, ctmp)
|
||||
cipher |= (ctmp << 12);
|
||||
cipherString++;
|
||||
@ -1314,13 +1294,12 @@ int main(int argc, char **argv)
|
||||
cipher |= ctmp;
|
||||
cipherString++;
|
||||
} else {
|
||||
const int *cptr;
|
||||
|
||||
if (! isalpha(ndx))
|
||||
Usage(progName);
|
||||
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
|
||||
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
|
||||
/* do nothing */;
|
||||
ndx = tolower(ndx) - 'a';
|
||||
if (ndx < PR_ARRAY_SIZE(ssl3CipherSuites)) {
|
||||
cipher = ssl3CipherSuites[ndx];
|
||||
}
|
||||
}
|
||||
if (cipher > 0) {
|
||||
SECStatus status;
|
||||
@ -1340,18 +1319,6 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
rv = SSL_OptionSet(s, SSL_ENABLE_SSL2, enableSSL2);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "error enabling SSLv2 ");
|
||||
return 1;
|
||||
}
|
||||
|
||||
rv = SSL_OptionSet(s, SSL_V2_COMPATIBLE_HELLO, enableSSL2);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "error enabling SSLv2 compatible hellos ");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* enable PKCS11 bypass */
|
||||
rv = SSL_OptionSet(s, SSL_BYPASS_PKCS11, bypassPKCS11);
|
||||
if (rv != SECSuccess) {
|
||||
@ -1613,6 +1580,12 @@ int main(int argc, char **argv)
|
||||
"%s: about to call PR_Poll on writable socket !\n",
|
||||
progName);
|
||||
cc = PR_Poll(pollset, 1, PR_INTERVAL_NO_TIMEOUT);
|
||||
if (cc < 0) {
|
||||
SECU_PrintError(progName,
|
||||
"PR_Poll failed");
|
||||
error = 1;
|
||||
goto done;
|
||||
}
|
||||
FPRINTF(stderr,
|
||||
"%s: PR_Poll returned with writable socket !\n",
|
||||
progName);
|
||||
|
@ -41,8 +41,8 @@
|
||||
|
||||
#define RD_BUF_SIZE (60 * 1024)
|
||||
|
||||
extern int ssl2CipherSuites[];
|
||||
extern int ssl3CipherSuites[];
|
||||
extern int numSSL3CipherSuites;
|
||||
|
||||
GlobalThreadMgr threadMGR;
|
||||
char *certNickname = NULL;
|
||||
@ -507,12 +507,11 @@ main(int argc, char **argv)
|
||||
disableAllSSLCiphers();
|
||||
|
||||
while (0 != (ndx = *cipherString++)) {
|
||||
int cipher;
|
||||
int cipher = 0;
|
||||
|
||||
if (ndx == ':') {
|
||||
int ctmp = 0;
|
||||
|
||||
cipher = 0;
|
||||
HEXCHAR_TO_INT(*cipherString, ctmp)
|
||||
cipher |= (ctmp << 12);
|
||||
cipherString++;
|
||||
@ -526,12 +525,12 @@ main(int argc, char **argv)
|
||||
cipher |= ctmp;
|
||||
cipherString++;
|
||||
} else {
|
||||
const int *cptr;
|
||||
if (! isalpha(ndx))
|
||||
Usage(progName);
|
||||
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
|
||||
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
|
||||
/* do nothing */;
|
||||
ndx = tolower(ndx) - 'a';
|
||||
if (ndx < numSSL3CipherSuites) {
|
||||
cipher = ssl3CipherSuites[ndx];
|
||||
}
|
||||
}
|
||||
if (cipher > 0) {
|
||||
SSL_CipherPrefSetDefault(cipher, PR_TRUE);
|
||||
|
@ -38,7 +38,6 @@
|
||||
/* Declare SSL cipher suites. */
|
||||
|
||||
extern int cipherSuites[];
|
||||
extern int ssl2CipherSuites[];
|
||||
extern int ssl3CipherSuites[];
|
||||
|
||||
/* Data buffer read from a socket. */
|
||||
|
@ -14,16 +14,6 @@ extern void dumpCertChain(CERTCertificate *, SECCertUsage);
|
||||
|
||||
/* Declare SSL cipher suites. */
|
||||
|
||||
int ssl2CipherSuites[] = {
|
||||
SSL_EN_RC4_128_WITH_MD5, /* A */
|
||||
SSL_EN_RC4_128_EXPORT40_WITH_MD5, /* B */
|
||||
SSL_EN_RC2_128_CBC_WITH_MD5, /* C */
|
||||
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
|
||||
SSL_EN_DES_64_CBC_WITH_MD5, /* E */
|
||||
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
|
||||
0
|
||||
};
|
||||
|
||||
int ssl3CipherSuites[] = {
|
||||
-1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
|
||||
-1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, * b */
|
||||
@ -53,6 +43,7 @@ int ssl3CipherSuites[] = {
|
||||
TLS_RSA_WITH_NULL_SHA, /* z */
|
||||
0
|
||||
};
|
||||
int numSSL3CipherSuites = PR_ARRAY_SIZE(ssl3CipherSuites);
|
||||
|
||||
/**************************************************************************
|
||||
**
|
||||
|
@ -21,10 +21,12 @@ endif
|
||||
ifeq (,$(filter-out i%86,$(CPU_ARCH)))
|
||||
ifdef USE_64
|
||||
CC += -arch x86_64
|
||||
CCC += -arch x86_64
|
||||
override CPU_ARCH = x86_64
|
||||
else
|
||||
OS_REL_CFLAGS = -Di386
|
||||
CC += -arch i386
|
||||
CCC += -arch i386
|
||||
override CPU_ARCH = x86
|
||||
endif
|
||||
else
|
||||
@ -33,6 +35,7 @@ ifeq (arm,$(CPU_ARCH))
|
||||
else
|
||||
OS_REL_CFLAGS = -Dppc
|
||||
CC += -arch ppc
|
||||
CCC += -arch ppc
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -136,3 +139,6 @@ ifeq (3,$(SYS_SQLITE3_VERSION_MAJOR))
|
||||
NSS_USE_SYSTEM_SQLITE = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/sanitizers.mk
|
||||
DARWIN_SDK_SHLIBFLAGS += $(SANITIZER_LDFLAGS)
|
||||
|
@ -21,7 +21,7 @@ ifeq ($(CPU_ARCH),amd64)
|
||||
CPU_ARCH = x86_64
|
||||
endif
|
||||
|
||||
OS_CFLAGS = $(DSO_CFLAGS) -ansi -Wall -Wno-switch -DFREEBSD -DHAVE_STRERROR -DHAVE_BSD_FLOCK
|
||||
OS_CFLAGS = $(DSO_CFLAGS) -Wall -Wno-switch -DFREEBSD -DHAVE_STRERROR -DHAVE_BSD_FLOCK
|
||||
|
||||
DSO_CFLAGS = -fPIC
|
||||
DSO_LDOPTS = -shared -Wl,-soname -Wl,$(notdir $@)
|
||||
|
@ -153,8 +153,12 @@ DSO_LDOPTS = -shared $(ARCHFLAG) -Wl,--gc-sections
|
||||
# The linker on Red Hat Linux 7.2 and RHEL 2.1 (GNU ld version 2.11.90.0.8)
|
||||
# incorrectly reports undefined references in the libraries we link with, so
|
||||
# we don't use -z defs there.
|
||||
# Also, -z defs conflicts with Address Sanitizer, which emits relocations
|
||||
# against the libsanitizer runtime built into the main executable.
|
||||
ZDEFS_FLAG = -Wl,-z,defs
|
||||
ifneq ($(USE_ASAN),1)
|
||||
DSO_LDOPTS += $(if $(findstring 2.11.90.0.8,$(shell ld -v)),,$(ZDEFS_FLAG))
|
||||
endif
|
||||
LDFLAGS += $(ARCHFLAG)
|
||||
|
||||
# On Maemo, we need to use the -rpath-link flag for even the standard system
|
||||
@ -210,3 +214,5 @@ PROCESS_MAP_FILE = grep -v ';-' $< | \
|
||||
ifeq ($(OS_RELEASE),2.4)
|
||||
DEFINES += -DNO_FORK_CHECK
|
||||
endif
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/sanitizers.mk
|
||||
|
@ -26,7 +26,7 @@ else
|
||||
DLL_SUFFIX = so.1.0
|
||||
endif
|
||||
|
||||
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -ansi -Wall -Wno-switch -pipe -DNETBSD -Dunix -DHAVE_STRERROR -DHAVE_BSD_FLOCK
|
||||
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wall -Wno-switch -pipe -DNETBSD -Dunix -DHAVE_STRERROR -DHAVE_BSD_FLOCK
|
||||
|
||||
OS_LIBS = -lcompat
|
||||
|
||||
|
@ -26,7 +26,7 @@ endif
|
||||
|
||||
DLL_SUFFIX = so.1.0
|
||||
|
||||
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -ansi -Wall -Wno-switch -pipe -DOPENBSD
|
||||
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wall -Wno-switch -pipe -DOPENBSD
|
||||
|
||||
OS_LIBS =
|
||||
|
||||
|
@ -5,6 +5,19 @@
|
||||
|
||||
# This sets WARNING_CFLAGS for gcc-like compilers.
|
||||
|
||||
ifndef CC_IS_CLANG
|
||||
CC_IS_CLANG := $(and $(findstring clang, $(shell $(CC) --version 2>&1)), 1)
|
||||
# Export CC_IS_CLANG to save a shell invocation when recursing.
|
||||
export CC_IS_CLANG
|
||||
endif
|
||||
|
||||
ifdef CC_IS_CLANG
|
||||
# Clang claims GCC 4.2.1 compatibility, see GCC_VERSION
|
||||
CC_IS_GCC = 1
|
||||
# Export CC_IS_GCC to save a shell invocation when recursing.
|
||||
export CC_IS_GCC
|
||||
endif
|
||||
|
||||
ifndef CC_IS_GCC
|
||||
CC_IS_GCC := $(shell $(CC) -x c -E -Wall -Werror /dev/null >/dev/null 2>&1 && echo 1)
|
||||
# Export CC_IS_GCC to save a shell invocation when recursing.
|
||||
@ -38,7 +51,7 @@ ifndef WARNING_CFLAGS
|
||||
disable_warning = $(shell $(CC) -x c -E -Werror -W$(1) /dev/null >/dev/null 2>&1 && echo -Wno-$(1))
|
||||
|
||||
WARNING_CFLAGS = -Wall
|
||||
ifeq ($(CC_NAME),clang)
|
||||
ifdef CC_IS_CLANG
|
||||
# -Qunused-arguments : clang objects to arguments that it doesn't understand
|
||||
# and fixing this would require rearchitecture
|
||||
WARNING_CFLAGS += -Qunused-arguments
|
||||
@ -62,10 +75,10 @@ ifndef WARNING_CFLAGS
|
||||
NSS_ENABLE_WERROR = 0
|
||||
$(warning OS_TARGET is Android, disabling -Werror)
|
||||
else
|
||||
ifeq ($(CC_NAME),clang)
|
||||
ifdef CC_IS_CLANG
|
||||
# Clang reports its version as an older gcc, but it's OK
|
||||
NSS_ENABLE_WERROR = 1
|
||||
else ifeq ($(CC_NAME),gcc)
|
||||
else
|
||||
ifneq (,$(filter 4.8 4.9,$(word 1,$(GCC_VERSION)).$(word 2,$(GCC_VERSION))))
|
||||
NSS_ENABLE_WERROR = 1
|
||||
endif
|
||||
|
@ -13,6 +13,7 @@
|
||||
# OS_TARGET User defined, or set to OS_ARCH
|
||||
# CPU_ARCH (from unmame -m or -p, ONLY on WINNT)
|
||||
# OS_CONFIG OS_TARGET + OS_RELEASE
|
||||
# ASAN_TAG
|
||||
# OBJDIR_TAG
|
||||
# OBJDIR_NAME
|
||||
#######################################################################
|
||||
@ -256,18 +257,28 @@ endif
|
||||
|
||||
OS_CONFIG = $(OS_TARGET)$(OS_RELEASE)
|
||||
|
||||
#
|
||||
# Set Address Sanitizer prefix.
|
||||
#
|
||||
|
||||
ifeq ($(USE_ASAN), 1)
|
||||
ASAN_TAG = _ASAN
|
||||
else
|
||||
ASAN_TAG =
|
||||
endif
|
||||
|
||||
#
|
||||
# OBJDIR_TAG depends on the predefined variable BUILD_OPT,
|
||||
# to distinguish between debug and release builds.
|
||||
#
|
||||
|
||||
ifdef BUILD_OPT
|
||||
OBJDIR_TAG = $(64BIT_TAG)_OPT
|
||||
OBJDIR_TAG = $(64BIT_TAG)$(ASAN_TAG)_OPT
|
||||
else
|
||||
ifdef BUILD_IDG
|
||||
OBJDIR_TAG = $(64BIT_TAG)_IDG
|
||||
OBJDIR_TAG = $(64BIT_TAG)$(ASAN_TAG)_IDG
|
||||
else
|
||||
OBJDIR_TAG = $(64BIT_TAG)_DBG
|
||||
OBJDIR_TAG = $(64BIT_TAG)$(ASAN_TAG)_DBG
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -174,6 +174,17 @@ ifdef NSS_PKIX_NO_LDAP
|
||||
DEFINES += -DNSS_PKIX_NO_LDAP
|
||||
endif
|
||||
|
||||
# FIPS support requires startup tests to be executed at load time of shared modules.
|
||||
# For performance reasons, these tests are disabled by default.
|
||||
# When compiling binaries that must support FIPS mode,
|
||||
# you should define NSS_FORCE_FIPS
|
||||
#
|
||||
# NSS_NO_INIT_SUPPORT is always defined on platforms that don't support
|
||||
# executing the startup tests at library load time.
|
||||
ifndef NSS_FORCE_FIPS
|
||||
DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
endif
|
||||
|
||||
# Avoid building object leak test code for optimized library
|
||||
ifndef BUILD_OPT
|
||||
ifdef PKIX_OBJECT_LEAK_TEST
|
||||
|
@ -10,4 +10,3 @@
|
||||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
19
security/nss/coreconf/sanitizers.mk
Normal file
19
security/nss/coreconf/sanitizers.mk
Normal file
@ -0,0 +1,19 @@
|
||||
# Address Sanitizer support; include this in OS-specific .mk files
|
||||
# *after* defining the variables that are appended to here.
|
||||
|
||||
ifeq ($(USE_ASAN), 1)
|
||||
SANITIZER_FLAGS_COMMON = -fsanitize=address $(EXTRA_SANITIZER_FLAGS)
|
||||
SANITIZER_CFLAGS = $(SANITIZER_FLAGS_COMMON)
|
||||
SANITIZER_LDFLAGS = $(SANITIZER_FLAGS_COMMON)
|
||||
OS_CFLAGS += $(SANITIZER_CFLAGS)
|
||||
LDFLAGS += $(SANITIZER_LDFLAGS)
|
||||
|
||||
# ASan needs frame pointers to save stack traces for allocation/free sites.
|
||||
# (Warning: some platforms, like ARM Linux in Thumb mode, don't have useful
|
||||
# frame pointers even with this option.)
|
||||
SANITIZER_CFLAGS += -fno-omit-frame-pointer
|
||||
|
||||
# You probably want to be able to get debug info for failures, even with an
|
||||
# optimized build.
|
||||
OPTIMIZER += -g
|
||||
endif
|
@ -8,6 +8,7 @@ DEPTH = ..
|
||||
DIRS = \
|
||||
google_test \
|
||||
der_gtest \
|
||||
util_gtest \
|
||||
pk11_gtest \
|
||||
ssl_gtest \
|
||||
$(NULL)
|
||||
|
@ -7,6 +7,7 @@
|
||||
/* This file contains functions for frobbing the internals of libssl */
|
||||
#include "libssl_internals.h"
|
||||
|
||||
#include "nss.h"
|
||||
#include "seccomon.h"
|
||||
#include "ssl.h"
|
||||
#include "sslimpl.h"
|
||||
@ -14,8 +15,7 @@
|
||||
SECStatus
|
||||
SSLInt_IncrementClientHandshakeVersion(PRFileDesc *fd)
|
||||
{
|
||||
sslSocket *ss = (sslSocket *)fd->secret;
|
||||
|
||||
sslSocket *ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
return SECFailure;
|
||||
}
|
||||
@ -45,3 +45,85 @@ SSLInt_DetermineKEABits(PRUint16 serverKeyBits, SSLAuthType authAlgorithm) {
|
||||
|
||||
return PR_MAX(SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyBits), minKeaBits);
|
||||
}
|
||||
|
||||
/* Use this function to update the ClientRandom of a client's handshake state
|
||||
* after replacing its ClientHello message. We for example need to do this
|
||||
* when replacing an SSLv3 ClientHello with its SSLv2 equivalent. */
|
||||
SECStatus
|
||||
SSLInt_UpdateSSLv2ClientRandom(PRFileDesc *fd, uint8_t *rnd, size_t rnd_len,
|
||||
uint8_t *msg, size_t msg_len)
|
||||
{
|
||||
sslSocket *ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
SECStatus rv = ssl3_InitState(ss);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = ssl3_RestartHandshakeHashes(ss);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Zero the client_random struct.
|
||||
PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
|
||||
|
||||
// Copy over the challenge bytes.
|
||||
size_t offset = SSL3_RANDOM_LENGTH - rnd_len;
|
||||
PORT_Memcpy(&ss->ssl3.hs.client_random.rand[offset], rnd, rnd_len);
|
||||
|
||||
// Rehash the SSLv2 client hello message.
|
||||
return ssl3_UpdateHandshakeHashes(ss, msg, msg_len);
|
||||
}
|
||||
|
||||
PRBool
|
||||
SSLInt_ExtensionNegotiated(PRFileDesc *fd, PRUint16 ext)
|
||||
{
|
||||
sslSocket *ss = ssl_FindSocket(fd);
|
||||
return (PRBool)(ss && ssl3_ExtensionNegotiated(ss, ext));
|
||||
}
|
||||
|
||||
void
|
||||
SSLInt_ClearSessionTicketKey()
|
||||
{
|
||||
ssl3_SessionTicketShutdown(NULL, NULL);
|
||||
NSS_UnregisterShutdown(ssl3_SessionTicketShutdown, NULL);
|
||||
}
|
||||
|
||||
PRInt32 SSLInt_CountTls13CipherSpecs(PRFileDesc *fd)
|
||||
{
|
||||
PRCList *cur_p;
|
||||
PRInt32 ct = 0;
|
||||
|
||||
sslSocket *ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (cur_p = PR_NEXT_LINK(&ss->ssl3.hs.cipherSpecs);
|
||||
cur_p != &ss->ssl3.hs.cipherSpecs;
|
||||
cur_p = PR_NEXT_LINK(cur_p)) {
|
||||
++ct;
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
|
||||
/* Force a timer expiry by backdating when the timer was started.
|
||||
* We could set the remaining time to 0 but then backoff would not
|
||||
* work properly if we decide to test it. */
|
||||
void SSLInt_ForceTimerExpiry(PRFileDesc *fd)
|
||||
{
|
||||
sslSocket *ss = ssl_FindSocket(fd);
|
||||
if (!ss) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ss->ssl3.hs.rtTimerCb)
|
||||
return;
|
||||
|
||||
ss->ssl3.hs.rtTimerStarted = PR_IntervalNow() -
|
||||
PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs + 1);
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
#ifndef libssl_internals_h_
|
||||
#define libssl_internals_h_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "prio.h"
|
||||
#include "seccomon.h"
|
||||
#include "sslt.h"
|
||||
@ -16,6 +18,15 @@ SECStatus SSLInt_IncrementClientHandshakeVersion(PRFileDesc *fd);
|
||||
PRUint32 SSLInt_DetermineKEABits(PRUint16 serverKeyBits,
|
||||
SSLAuthType authAlgorithm);
|
||||
|
||||
SECStatus SSLInt_UpdateSSLv2ClientRandom(PRFileDesc *fd,
|
||||
uint8_t *rnd, size_t rnd_len,
|
||||
uint8_t *msg, size_t msg_len);
|
||||
|
||||
PRBool SSLInt_ExtensionNegotiated(PRFileDesc *fd, PRUint16 ext);
|
||||
void SSLInt_ClearSessionTicketKey();
|
||||
PRInt32 SSLInt_CountTls13CipherSpecs(PRFileDesc *fd);
|
||||
void SSLInt_ForceTimerExpiry(PRFileDesc *fd);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -12,6 +12,7 @@ CSRCS = \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
ssl_v2_client_hello_unittest.cc \
|
||||
ssl_agent_unittest.cc \
|
||||
ssl_loopback_unittest.cc \
|
||||
ssl_extension_unittest.cc \
|
||||
|
@ -15,138 +15,6 @@
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
class TlsExtensionFilter : public TlsHandshakeFilter {
|
||||
protected:
|
||||
virtual PacketFilter::Action FilterHandshake(
|
||||
const HandshakeHeader& header,
|
||||
const DataBuffer& input, DataBuffer* output) {
|
||||
if (header.handshake_type() == kTlsHandshakeClientHello) {
|
||||
TlsParser parser(input);
|
||||
if (!FindClientHelloExtensions(&parser, header)) {
|
||||
return KEEP;
|
||||
}
|
||||
return FilterExtensions(&parser, input, output);
|
||||
}
|
||||
if (header.handshake_type() == kTlsHandshakeServerHello) {
|
||||
TlsParser parser(input);
|
||||
if (!FindServerHelloExtensions(&parser, header.version())) {
|
||||
return KEEP;
|
||||
}
|
||||
return FilterExtensions(&parser, input, output);
|
||||
}
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
|
||||
const DataBuffer& input,
|
||||
DataBuffer* output) = 0;
|
||||
|
||||
public:
|
||||
static bool FindClientHelloExtensions(TlsParser* parser, const Versioned& header) {
|
||||
if (!parser->Skip(2 + 32)) { // version + random
|
||||
return false;
|
||||
}
|
||||
if (!parser->SkipVariable(1)) { // session ID
|
||||
return false;
|
||||
}
|
||||
if (header.is_dtls() && !parser->SkipVariable(1)) { // DTLS cookie
|
||||
return false;
|
||||
}
|
||||
if (!parser->SkipVariable(2)) { // cipher suites
|
||||
return false;
|
||||
}
|
||||
if (!parser->SkipVariable(1)) { // compression methods
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool FindServerHelloExtensions(TlsParser* parser, uint16_t version) {
|
||||
if (!parser->Skip(2 + 32)) { // version + random
|
||||
return false;
|
||||
}
|
||||
if (!parser->SkipVariable(1)) { // session ID
|
||||
return false;
|
||||
}
|
||||
if (!parser->Skip(2)) { // cipher suite
|
||||
return false;
|
||||
}
|
||||
if (NormalizeTlsVersion(version) <= SSL_LIBRARY_VERSION_TLS_1_2) {
|
||||
if (!parser->Skip(1)) { // compression method
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
PacketFilter::Action FilterExtensions(TlsParser* parser,
|
||||
const DataBuffer& input,
|
||||
DataBuffer* output) {
|
||||
size_t length_offset = parser->consumed();
|
||||
uint32_t all_extensions;
|
||||
if (!parser->Read(&all_extensions, 2)) {
|
||||
return KEEP; // no extensions, odd but OK
|
||||
}
|
||||
if (all_extensions != parser->remaining()) {
|
||||
return KEEP; // malformed
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
|
||||
// Write out the start of the message.
|
||||
output->Allocate(input.len());
|
||||
size_t offset = output->Write(0, input.data(), parser->consumed());
|
||||
|
||||
while (parser->remaining()) {
|
||||
uint32_t extension_type;
|
||||
if (!parser->Read(&extension_type, 2)) {
|
||||
return KEEP; // malformed
|
||||
}
|
||||
|
||||
DataBuffer extension;
|
||||
if (!parser->ReadVariable(&extension, 2)) {
|
||||
return KEEP; // malformed
|
||||
}
|
||||
|
||||
DataBuffer filtered;
|
||||
PacketFilter::Action action = FilterExtension(extension_type, extension,
|
||||
&filtered);
|
||||
if (action == DROP) {
|
||||
changed = true;
|
||||
std::cerr << "extension drop: " << extension << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
const DataBuffer* source = &extension;
|
||||
if (action == CHANGE) {
|
||||
EXPECT_GT(0x10000U, filtered.len());
|
||||
changed = true;
|
||||
std::cerr << "extension old: " << extension << std::endl;
|
||||
std::cerr << "extension new: " << filtered << std::endl;
|
||||
source = &filtered;
|
||||
}
|
||||
|
||||
// Write out extension.
|
||||
offset = output->Write(offset, extension_type, 2);
|
||||
offset = output->Write(offset, source->len(), 2);
|
||||
offset = output->Write(offset, *source);
|
||||
}
|
||||
output->Truncate(offset);
|
||||
|
||||
if (changed) {
|
||||
size_t newlen = output->len() - length_offset - 2;
|
||||
EXPECT_GT(0x10000U, newlen);
|
||||
if (newlen >= 0x10000) {
|
||||
return KEEP; // bad: size increased too much
|
||||
}
|
||||
output->Write(length_offset, newlen, 2);
|
||||
return CHANGE;
|
||||
}
|
||||
return KEEP;
|
||||
}
|
||||
};
|
||||
|
||||
class TlsExtensionTruncator : public TlsExtensionFilter {
|
||||
public:
|
||||
TlsExtensionTruncator(uint16_t extension, size_t length)
|
||||
@ -254,26 +122,6 @@ class TlsExtensionInjector : public TlsHandshakeFilter {
|
||||
const DataBuffer data_;
|
||||
};
|
||||
|
||||
class TlsExtensionCapture : public TlsExtensionFilter {
|
||||
public:
|
||||
TlsExtensionCapture(uint16_t ext)
|
||||
: extension_(ext), data_() {}
|
||||
|
||||
virtual PacketFilter::Action FilterExtension(
|
||||
uint16_t extension_type, const DataBuffer& input, DataBuffer* output) {
|
||||
if (extension_type == extension_) {
|
||||
data_.Assign(input);
|
||||
}
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
const DataBuffer& extension() const { return data_; }
|
||||
|
||||
private:
|
||||
const uint16_t extension_;
|
||||
DataBuffer data_;
|
||||
};
|
||||
|
||||
class TlsExtensionTestBase : public TlsConnectTestBase {
|
||||
protected:
|
||||
TlsExtensionTestBase(Mode mode, uint16_t version)
|
||||
@ -323,11 +171,20 @@ class TlsExtensionTestDtls
|
||||
|
||||
class TlsExtensionTest12Plus
|
||||
: public TlsExtensionTestBase,
|
||||
public ::testing::WithParamInterface<std::string> {
|
||||
public ::testing::WithParamInterface<std::tuple<std::string, uint16_t>> {
|
||||
public:
|
||||
TlsExtensionTest12Plus()
|
||||
: TlsExtensionTestBase(TlsConnectTestBase::ToMode(GetParam()),
|
||||
SSL_LIBRARY_VERSION_TLS_1_2) {}
|
||||
: TlsExtensionTestBase(TlsConnectTestBase::ToMode((std::get<0>(GetParam()))),
|
||||
std::get<1>(GetParam())) {}
|
||||
};
|
||||
|
||||
class TlsExtensionTest12
|
||||
: public TlsExtensionTestBase,
|
||||
public ::testing::WithParamInterface<std::tuple<std::string, uint16_t>> {
|
||||
public:
|
||||
TlsExtensionTest12()
|
||||
: TlsExtensionTestBase(TlsConnectTestBase::ToMode((std::get<0>(GetParam()))),
|
||||
std::get<1>(GetParam())) {}
|
||||
};
|
||||
|
||||
class TlsExtensionTest13
|
||||
@ -348,6 +205,15 @@ class TlsExtensionTestGeneric
|
||||
std::get<1>(GetParam())) {}
|
||||
};
|
||||
|
||||
class TlsExtensionTestPre13
|
||||
: public TlsExtensionTestBase,
|
||||
public ::testing::WithParamInterface<std::tuple<std::string, uint16_t>> {
|
||||
public:
|
||||
TlsExtensionTestPre13()
|
||||
: TlsExtensionTestBase(TlsConnectTestBase::ToMode((std::get<0>(GetParam()))),
|
||||
std::get<1>(GetParam())) {}
|
||||
};
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, DamageSniLength) {
|
||||
ClientHelloErrorTest(new TlsExtensionDamager(ssl_server_name_xtn, 1));
|
||||
}
|
||||
@ -431,42 +297,44 @@ TEST_P(TlsExtensionTestGeneric, AlpnMismatch) {
|
||||
ClientHelloErrorTest(nullptr, kTlsAlertNoApplicationProtocol);
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, AlpnReturnedEmptyList) {
|
||||
// Many of these tests fail in TLS 1.3 because the extension is encrypted, which
|
||||
// prevents modification of the value from the ServerHello.
|
||||
TEST_P(TlsExtensionTestPre13, AlpnReturnedEmptyList) {
|
||||
EnableAlpn();
|
||||
const uint8_t val[] = { 0x00, 0x00 };
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
ServerHelloErrorTest(new TlsExtensionReplacer(ssl_app_layer_protocol_xtn, extension));
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, AlpnReturnedEmptyName) {
|
||||
TEST_P(TlsExtensionTestPre13, AlpnReturnedEmptyName) {
|
||||
EnableAlpn();
|
||||
const uint8_t val[] = { 0x00, 0x01, 0x00 };
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
ServerHelloErrorTest(new TlsExtensionReplacer(ssl_app_layer_protocol_xtn, extension));
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, AlpnReturnedListTrailingData) {
|
||||
TEST_P(TlsExtensionTestPre13, AlpnReturnedListTrailingData) {
|
||||
EnableAlpn();
|
||||
const uint8_t val[] = { 0x00, 0x02, 0x01, 0x61, 0x00 };
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
ServerHelloErrorTest(new TlsExtensionReplacer(ssl_app_layer_protocol_xtn, extension));
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, AlpnReturnedExtraEntry) {
|
||||
TEST_P(TlsExtensionTestPre13, AlpnReturnedExtraEntry) {
|
||||
EnableAlpn();
|
||||
const uint8_t val[] = { 0x00, 0x04, 0x01, 0x61, 0x01, 0x62 };
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
ServerHelloErrorTest(new TlsExtensionReplacer(ssl_app_layer_protocol_xtn, extension));
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, AlpnReturnedBadListLength) {
|
||||
TEST_P(TlsExtensionTestPre13, AlpnReturnedBadListLength) {
|
||||
EnableAlpn();
|
||||
const uint8_t val[] = { 0x00, 0x99, 0x01, 0x61, 0x00 };
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
ServerHelloErrorTest(new TlsExtensionReplacer(ssl_app_layer_protocol_xtn, extension));
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, AlpnReturnedBadNameLength) {
|
||||
TEST_P(TlsExtensionTestPre13, AlpnReturnedBadNameLength) {
|
||||
EnableAlpn();
|
||||
const uint8_t val[] = { 0x00, 0x02, 0x99, 0x61 };
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
@ -549,35 +417,35 @@ TEST_P(TlsExtensionTestGeneric, SupportedCurvesTrailingData) {
|
||||
extension));
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, SupportedPointsEmpty) {
|
||||
TEST_P(TlsExtensionTestPre13, SupportedPointsEmpty) {
|
||||
const uint8_t val[] = { 0x00 };
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
ClientHelloErrorTest(new TlsExtensionReplacer(ssl_ec_point_formats_xtn,
|
||||
extension));
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, SupportedPointsBadLength) {
|
||||
TEST_P(TlsExtensionTestPre13, SupportedPointsBadLength) {
|
||||
const uint8_t val[] = { 0x99, 0x00, 0x00 };
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
ClientHelloErrorTest(new TlsExtensionReplacer(ssl_ec_point_formats_xtn,
|
||||
extension));
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, SupportedPointsTrailingData) {
|
||||
TEST_P(TlsExtensionTestPre13, SupportedPointsTrailingData) {
|
||||
const uint8_t val[] = { 0x01, 0x00, 0x00 };
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
ClientHelloErrorTest(new TlsExtensionReplacer(ssl_ec_point_formats_xtn,
|
||||
extension));
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, RenegotiationInfoBadLength) {
|
||||
TEST_P(TlsExtensionTestPre13, RenegotiationInfoBadLength) {
|
||||
const uint8_t val[] = { 0x99 };
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
ClientHelloErrorTest(new TlsExtensionReplacer(ssl_renegotiation_info_xtn,
|
||||
extension));
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, RenegotiationInfoMismatch) {
|
||||
TEST_P(TlsExtensionTestPre13, RenegotiationInfoMismatch) {
|
||||
const uint8_t val[] = { 0x01, 0x00 };
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
ClientHelloErrorTest(new TlsExtensionReplacer(ssl_renegotiation_info_xtn,
|
||||
@ -585,13 +453,15 @@ TEST_P(TlsExtensionTestGeneric, RenegotiationInfoMismatch) {
|
||||
}
|
||||
|
||||
// The extension has to contain a length.
|
||||
TEST_P(TlsExtensionTestGeneric, RenegotiationInfoExtensionEmpty) {
|
||||
TEST_P(TlsExtensionTestPre13, RenegotiationInfoExtensionEmpty) {
|
||||
DataBuffer extension;
|
||||
ClientHelloErrorTest(new TlsExtensionReplacer(ssl_renegotiation_info_xtn,
|
||||
extension));
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmConfiguration) {
|
||||
// This only works on TLS 1.2, since it relies on static RSA; otherwise libssl
|
||||
// picks the wrong cipher suite.
|
||||
TEST_P(TlsExtensionTest12, SignatureAlgorithmConfiguration) {
|
||||
const SSLSignatureAndHashAlg algorithms[] = {
|
||||
{ssl_hash_sha512, ssl_sign_rsa},
|
||||
{ssl_hash_sha384, ssl_sign_ecdsa}
|
||||
@ -619,6 +489,7 @@ TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmConfiguration) {
|
||||
|
||||
/*
|
||||
* Tests for Certificate Transparency (RFC 6962)
|
||||
* These don't work with TLS 1.3: see bug 1252745.
|
||||
*/
|
||||
|
||||
// Helper class - stores signed certificate timestamps as provided
|
||||
@ -647,11 +518,11 @@ class SignedCertificateTimestampsExtractor {
|
||||
}
|
||||
|
||||
void assertTimestamps(const DataBuffer& timestamps) {
|
||||
ASSERT_TRUE(auth_timestamps_);
|
||||
ASSERT_EQ(timestamps, *auth_timestamps_);
|
||||
EXPECT_TRUE(auth_timestamps_);
|
||||
EXPECT_EQ(timestamps, *auth_timestamps_);
|
||||
|
||||
ASSERT_TRUE(handshake_timestamps_);
|
||||
ASSERT_EQ(timestamps, *handshake_timestamps_);
|
||||
EXPECT_TRUE(handshake_timestamps_);
|
||||
EXPECT_EQ(timestamps, *handshake_timestamps_);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -660,7 +531,7 @@ class SignedCertificateTimestampsExtractor {
|
||||
};
|
||||
|
||||
// Test timestamps extraction during a successful handshake.
|
||||
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsHandshake) {
|
||||
TEST_P(TlsExtensionTestPre13, SignedCertificateTimestampsHandshake) {
|
||||
uint8_t val[] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
|
||||
const SECItem si_timestamps = { siBuffer, val, sizeof(val) };
|
||||
const DataBuffer timestamps(val, sizeof(val));
|
||||
@ -683,7 +554,7 @@ TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsHandshake) {
|
||||
|
||||
// Test SSL_PeerSignedCertTimestamps returning zero-length SECItem
|
||||
// when the client / the server / both have not enabled the feature.
|
||||
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveClient) {
|
||||
TEST_P(TlsExtensionTestPre13, SignedCertificateTimestampsInactiveClient) {
|
||||
uint8_t val[] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
|
||||
const SECItem si_timestamps = { siBuffer, val, sizeof(val) };
|
||||
|
||||
@ -700,7 +571,7 @@ TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveClient) {
|
||||
timestamps_extractor.assertTimestamps(DataBuffer());
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveServer) {
|
||||
TEST_P(TlsExtensionTestPre13, SignedCertificateTimestampsInactiveServer) {
|
||||
server_->StartConnect();
|
||||
|
||||
client_->StartConnect();
|
||||
@ -714,7 +585,7 @@ TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveServer) {
|
||||
timestamps_extractor.assertTimestamps(DataBuffer());
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveBoth) {
|
||||
TEST_P(TlsExtensionTestPre13, SignedCertificateTimestampsInactiveBoth) {
|
||||
server_->StartConnect();
|
||||
client_->StartConnect();
|
||||
|
||||
@ -732,21 +603,34 @@ TEST_P(TlsExtensionTest13, EmptyClientKeyShare) {
|
||||
kTlsAlertHandshakeFailure);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(ExtensionTls10, TlsExtensionTestGeneric,
|
||||
INSTANTIATE_TEST_CASE_P(ExtensionStream, TlsExtensionTestGeneric,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsModesStream,
|
||||
TlsConnectTestBase::kTlsV10));
|
||||
INSTANTIATE_TEST_CASE_P(ExtensionVariants, TlsExtensionTestGeneric,
|
||||
TlsConnectTestBase::kTlsVAll));
|
||||
INSTANTIATE_TEST_CASE_P(ExtensionDatagram, TlsExtensionTestGeneric,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsModesAll,
|
||||
TlsConnectTestBase::kTlsV11Plus));
|
||||
INSTANTIATE_TEST_CASE_P(ExtensionDatagramOnly, TlsExtensionTestDtls,
|
||||
TlsConnectTestBase::kTlsV11Plus);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(ExtensionTls12Plus, TlsExtensionTest12Plus,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsModesAll,
|
||||
TlsConnectTestBase::kTlsV12Plus));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(ExtensionPre13Stream, TlsExtensionTestPre13,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsModesStream,
|
||||
TlsConnectTestBase::kTlsV10To12));
|
||||
INSTANTIATE_TEST_CASE_P(ExtensionPre13Datagram, TlsExtensionTestPre13,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsModesAll,
|
||||
TlsConnectTestBase::kTlsV11V12));
|
||||
INSTANTIATE_TEST_CASE_P(ExtensionTls12Plus, TlsExtensionTest12Plus,
|
||||
TlsConnectTestBase::kTlsModesAll);
|
||||
|
||||
#ifdef NSS_ENABLE_TLS_1_3
|
||||
INSTANTIATE_TEST_CASE_P(ExtensionTls13, TlsExtensionTest13,
|
||||
TlsConnectTestBase::kTlsModesStream);
|
||||
TlsConnectTestBase::kTlsModesAll);
|
||||
#endif
|
||||
INSTANTIATE_TEST_CASE_P(ExtensionDgram, TlsExtensionTestDtls,
|
||||
TlsConnectTestBase::kTlsV11V12);
|
||||
|
||||
} // namespace nspr_test
|
||||
|
@ -146,13 +146,13 @@ TEST_P(TlsConnectGeneric, ConnectEcdsa) {
|
||||
CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectFalseStart) {
|
||||
TEST_P(TlsConnectGenericPre13, ConnectFalseStart) {
|
||||
client_->EnableFalseStart();
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectResumed) {
|
||||
TEST_P(TlsConnectGenericPre13, ConnectResumed) {
|
||||
ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID);
|
||||
Connect();
|
||||
|
||||
@ -164,36 +164,47 @@ TEST_P(TlsConnectGeneric, ConnectResumed) {
|
||||
TEST_P(TlsConnectGeneric, ConnectClientCacheDisabled) {
|
||||
ConfigureSessionCache(RESUME_NONE, RESUME_SESSIONID);
|
||||
Connect();
|
||||
SendReceive();
|
||||
|
||||
ResetRsa();
|
||||
ExpectResumption(RESUME_NONE);
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectServerCacheDisabled) {
|
||||
ConfigureSessionCache(RESUME_SESSIONID, RESUME_NONE);
|
||||
Connect();
|
||||
SendReceive();
|
||||
|
||||
ResetRsa();
|
||||
ExpectResumption(RESUME_NONE);
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectSessionCacheDisabled) {
|
||||
ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
|
||||
Connect();
|
||||
SendReceive();
|
||||
|
||||
ResetRsa();
|
||||
ExpectResumption(RESUME_NONE);
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectResumeSupportBoth) {
|
||||
// This prefers tickets.
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
Connect();
|
||||
SendReceive();
|
||||
|
||||
ResetRsa();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectResumeClientTicketServerBoth) {
|
||||
@ -201,57 +212,67 @@ TEST_P(TlsConnectGeneric, ConnectResumeClientTicketServerBoth) {
|
||||
// session cache to resume even with tickets.
|
||||
ConfigureSessionCache(RESUME_TICKET, RESUME_BOTH);
|
||||
Connect();
|
||||
SendReceive();
|
||||
|
||||
ResetRsa();
|
||||
ConfigureSessionCache(RESUME_TICKET, RESUME_BOTH);
|
||||
ExpectResumption(RESUME_NONE);
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectResumeClientBothTicketServerTicket) {
|
||||
// This causes a ticket resumption.
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
||||
Connect();
|
||||
SendReceive();
|
||||
|
||||
ResetRsa();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectClientServerTicketOnly) {
|
||||
TEST_P(TlsConnectGenericPre13, ConnectResumeClientServerTicketOnly) {
|
||||
// This causes no resumption because the client needs the
|
||||
// session cache to resume even with tickets.
|
||||
ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET);
|
||||
Connect();
|
||||
SendReceive();
|
||||
|
||||
ResetRsa();
|
||||
ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET);
|
||||
ExpectResumption(RESUME_NONE);
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectClientBothServerNone) {
|
||||
TEST_P(TlsConnectGenericPre13, ConnectResumeClientBothServerNone) {
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_NONE);
|
||||
Connect();
|
||||
SendReceive();
|
||||
|
||||
ResetRsa();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_NONE);
|
||||
ExpectResumption(RESUME_NONE);
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectClientNoneServerBoth) {
|
||||
TEST_P(TlsConnectGenericPre13, ConnectResumeClientNoneServerBoth) {
|
||||
ConfigureSessionCache(RESUME_NONE, RESUME_BOTH);
|
||||
Connect();
|
||||
SendReceive();
|
||||
|
||||
ResetRsa();
|
||||
ConfigureSessionCache(RESUME_NONE, RESUME_BOTH);
|
||||
ExpectResumption(RESUME_NONE);
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ResumeWithHigherVersion) {
|
||||
TEST_P(TlsConnectGenericPre13, ConnectResumeWithHigherVersion) {
|
||||
EnsureTlsSetup();
|
||||
SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_1);
|
||||
ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID);
|
||||
@ -272,15 +293,21 @@ TEST_P(TlsConnectGeneric, ResumeWithHigherVersion) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ClientAuth) {
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
TEST_P(TlsConnectGeneric, ConnectResumeClientBothTicketServerTicketForget) {
|
||||
// This causes a ticket resumption.
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa);
|
||||
SendReceive();
|
||||
|
||||
ResetRsa();
|
||||
ClearServerCache();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
||||
ExpectResumption(RESUME_NONE);
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
// Temporary copy for TLS 1.3 because 1.3 is stream only.
|
||||
TEST_P(TlsConnectStream, ClientAuth) {
|
||||
TEST_P(TlsConnectGeneric, ClientAuth) {
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
Connect();
|
||||
@ -297,7 +324,7 @@ TEST_P(TlsConnectStream, DISABLED_ClientAuthRequiredRejected) {
|
||||
ConnectExpectFail();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectStream, ClientAuthRequestedRejected) {
|
||||
TEST_P(TlsConnectGeneric, ClientAuthRequestedRejected) {
|
||||
server_->RequestClientAuth(false);
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa);
|
||||
@ -362,7 +389,7 @@ TEST_P(TlsConnectGeneric, SignatureAlgorithmServerOnly) {
|
||||
// There is no need for overlap on signatures; since we don't actually use the
|
||||
// signatures for static RSA, this should still connect successfully.
|
||||
// This should also work in TLS 1.0 and 1.1 where the algorithms aren't used.
|
||||
TEST_P(TlsConnectGeneric, SignatureAlgorithmNoOverlapStaticRsa) {
|
||||
TEST_P(TlsConnectGenericPre13, SignatureAlgorithmNoOverlapStaticRsa) {
|
||||
client_->SetSignatureAlgorithms(SignatureRsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureRsaSha384));
|
||||
server_->SetSignatureAlgorithms(SignatureRsaSha256,
|
||||
@ -372,7 +399,7 @@ TEST_P(TlsConnectGeneric, SignatureAlgorithmNoOverlapStaticRsa) {
|
||||
CheckKeys(ssl_kea_rsa, ssl_auth_rsa);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectStreamPre13, ConnectStaticRSA) {
|
||||
TEST_P(TlsConnectGenericPre13, ConnectStaticRSA) {
|
||||
DisableDheAndEcdheCiphers();
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_rsa, ssl_auth_rsa);
|
||||
@ -415,18 +442,77 @@ TEST_P(TlsConnectGeneric, ConnectAlpn) {
|
||||
server_->CheckAlpn(SSL_NEXT_PROTO_NEGOTIATED, "a");
|
||||
}
|
||||
|
||||
// Temporary copy to test Alpn with TLS 1.3.
|
||||
TEST_P(TlsConnectStream, ConnectAlpn) {
|
||||
EnableAlpn();
|
||||
Connect();
|
||||
client_->CheckAlpn(SSL_NEXT_PROTO_SELECTED, "a");
|
||||
server_->CheckAlpn(SSL_NEXT_PROTO_NEGOTIATED, "a");
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectDatagram, ConnectSrtp) {
|
||||
EnableSrtp();
|
||||
Connect();
|
||||
CheckSrtp();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
// This class selectively drops complete writes. This relies on the fact that
|
||||
// writes in libssl are on record boundaries.
|
||||
class SelectiveDropFilter : public PacketFilter, public PollTarget {
|
||||
public:
|
||||
SelectiveDropFilter(uint32_t pattern)
|
||||
: pattern_(pattern),
|
||||
counter_(0) {}
|
||||
|
||||
protected:
|
||||
virtual Action Filter(const DataBuffer& input, DataBuffer* output) override {
|
||||
if (counter_ >= 32) {
|
||||
return KEEP;
|
||||
}
|
||||
return ((1 << counter_++) & pattern_) ? DROP : KEEP;
|
||||
}
|
||||
|
||||
private:
|
||||
const uint32_t pattern_;
|
||||
uint8_t counter_;
|
||||
};
|
||||
|
||||
TEST_P(TlsConnectDatagram, DropClientFirstFlightOnce) {
|
||||
client_->SetPacketFilter(new SelectiveDropFilter(0x1));
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectDatagram, DropServerFirstFlightOnce) {
|
||||
server_->SetPacketFilter(new SelectiveDropFilter(0x1));
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
// This drops the first transmission from both the client and server of all
|
||||
// flights that they send. Note: In DTLS 1.3, the shorter handshake means that
|
||||
// this will also drop some application data, so we can't call SendReceive().
|
||||
TEST_P(TlsConnectDatagram, DropAllFirstTransmissions) {
|
||||
client_->SetPacketFilter(new SelectiveDropFilter(0x15));
|
||||
server_->SetPacketFilter(new SelectiveDropFilter(0x5));
|
||||
Connect();
|
||||
}
|
||||
|
||||
// This drops the server's first flight three times.
|
||||
TEST_P(TlsConnectDatagram, DropServerFirstFlightThrice) {
|
||||
server_->SetPacketFilter(new SelectiveDropFilter(0x7));
|
||||
Connect();
|
||||
}
|
||||
|
||||
// This drops the client's second flight once
|
||||
TEST_P(TlsConnectDatagram, DropClientSecondFlightOnce) {
|
||||
client_->SetPacketFilter(new SelectiveDropFilter(0x2));
|
||||
Connect();
|
||||
}
|
||||
|
||||
// This drops the client's second flight three times.
|
||||
TEST_P(TlsConnectDatagram, DropClientSecondFlightThrice) {
|
||||
client_->SetPacketFilter(new SelectiveDropFilter(0xe));
|
||||
Connect();
|
||||
}
|
||||
|
||||
// This drops the server's second flight three times.
|
||||
TEST_P(TlsConnectDatagram, DropServerSecondFlightThrice) {
|
||||
server_->SetPacketFilter(new SelectiveDropFilter(0xe));
|
||||
Connect();
|
||||
}
|
||||
|
||||
// 1.3 is disabled in the next few tests because we don't
|
||||
@ -447,7 +533,8 @@ TEST_P(TlsConnectStreamPre13, ConnectAndServerRenegotiate) {
|
||||
CheckConnected();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectStreamPre13, ConnectDhe) {
|
||||
// TODO implement DHE for 1.3
|
||||
TEST_P(TlsConnectGenericPre13, ConnectDhe) {
|
||||
DisableEcdheCiphers();
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_dh, ssl_auth_rsa);
|
||||
@ -486,7 +573,7 @@ TEST_P(TlsConnectStreamPre13, ConnectStaticRSABogusPMSVersionDetect) {
|
||||
// Test that a PMS with a bogus version number is ignored when
|
||||
// rollback detection is disabled. This is a positive control for
|
||||
// ConnectStaticRSABogusPMSVersionDetect.
|
||||
TEST_P(TlsConnectGeneric, ConnectStaticRSABogusPMSVersionIgnore) {
|
||||
TEST_P(TlsConnectGenericPre13, ConnectStaticRSABogusPMSVersionIgnore) {
|
||||
DisableDheAndEcdheCiphers();
|
||||
client_->SetPacketFilter(new TlsInspectorClientHelloVersionChanger(
|
||||
server_));
|
||||
@ -494,12 +581,13 @@ TEST_P(TlsConnectGeneric, ConnectStaticRSABogusPMSVersionIgnore) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectStream, ConnectEcdhe) {
|
||||
TEST_P(TlsConnectGeneric, ConnectEcdhe) {
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectStreamPre13, ConnectEcdheTwiceReuseKey) {
|
||||
// Prior to TLS 1.3, we were not fully ephemeral; though 1.3 fixes that
|
||||
TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceReuseKey) {
|
||||
TlsInspectorRecordHandshakeMessage* i1 =
|
||||
new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange);
|
||||
server_->SetPacketFilter(i1);
|
||||
@ -526,7 +614,8 @@ TEST_P(TlsConnectStreamPre13, ConnectEcdheTwiceReuseKey) {
|
||||
dhe1.public_key_.len()));
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectStreamPre13, ConnectEcdheTwiceNewKey) {
|
||||
// This test parses the ServerKeyExchange, which isn't in 1.3
|
||||
TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceNewKey) {
|
||||
server_->EnsureTlsSetup();
|
||||
SECStatus rv =
|
||||
SSL_OptionSet(server_->ssl_fd(), SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
|
||||
@ -616,7 +705,7 @@ TEST_P(TlsConnectStream, ShortRead) {
|
||||
ASSERT_EQ(1200U, client_->received_bytes());
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectExtendedMasterSecret) {
|
||||
TEST_P(TlsConnectGenericPre13, ConnectExtendedMasterSecret) {
|
||||
EnableExtendedMasterSecret();
|
||||
Connect();
|
||||
ResetRsa();
|
||||
@ -625,8 +714,7 @@ TEST_P(TlsConnectGeneric, ConnectExtendedMasterSecret) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectExtendedMasterSecretStaticRSA) {
|
||||
TEST_P(TlsConnectGenericPre13, ConnectExtendedMasterSecretStaticRSA) {
|
||||
DisableDheAndEcdheCiphers();
|
||||
EnableExtendedMasterSecret();
|
||||
Connect();
|
||||
@ -671,7 +759,7 @@ TEST_P(TlsConnectStreamPre13, ConnectExtendedMasterSecretStaticRSABogusPMSVersio
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectExtendedMasterSecretECDHE) {
|
||||
TEST_P(TlsConnectGenericPre13, ConnectExtendedMasterSecretECDHE) {
|
||||
EnableExtendedMasterSecret();
|
||||
Connect();
|
||||
|
||||
@ -734,22 +822,18 @@ TEST_P(TlsConnectGenericPre13,
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectStream, ConnectWithCompressionMaybe)
|
||||
TEST_P(TlsConnectGeneric, ConnectWithCompressionMaybe)
|
||||
{
|
||||
EnsureTlsSetup();
|
||||
client_->EnableCompression();
|
||||
server_->EnableCompression();
|
||||
Connect();
|
||||
EXPECT_EQ(client_->version() < SSL_LIBRARY_VERSION_TLS_1_3, client_->is_compressed());
|
||||
EXPECT_EQ(client_->version() < SSL_LIBRARY_VERSION_TLS_1_3 &&
|
||||
mode_ != DGRAM, client_->is_compressed());
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
|
||||
TEST_P(TlsConnectStream, ConnectSendReceive) {
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectStream, ServerNegotiateTls10) {
|
||||
uint16_t minver, maxver;
|
||||
client_->GetVersionRange(&minver, &maxver);
|
||||
@ -760,7 +844,7 @@ TEST_P(TlsConnectStream, ServerNegotiateTls10) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectStream, ServerNegotiateTls11) {
|
||||
TEST_P(TlsConnectGeneric, ServerNegotiateTls11) {
|
||||
if (version_ < SSL_LIBRARY_VERSION_TLS_1_1)
|
||||
return;
|
||||
|
||||
@ -773,7 +857,7 @@ TEST_P(TlsConnectStream, ServerNegotiateTls11) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectStream, ServerNegotiateTls12) {
|
||||
TEST_P(TlsConnectGeneric, ServerNegotiateTls12) {
|
||||
if (version_ < SSL_LIBRARY_VERSION_TLS_1_2)
|
||||
return;
|
||||
|
||||
@ -859,6 +943,65 @@ TEST_F(TlsConnectTest, TestFallbackFromTls13) {
|
||||
ConnectExpectFail();
|
||||
ASSERT_EQ(SSL_ERROR_RX_MALFORMED_SERVER_HELLO, client_->error_code());
|
||||
}
|
||||
|
||||
// Test that two TLS resumptions work and produce the same ticket.
|
||||
// This will change after bug 1257047 is fixed.
|
||||
TEST_F(TlsConnectTest, TestTls13ResumptionTwice) {
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
Connect();
|
||||
SendReceive(); // Need to read so that we absorb the session ticket.
|
||||
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa);
|
||||
|
||||
ResetRsa();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
||||
TlsExtensionCapture *c1 =
|
||||
new TlsExtensionCapture(kTlsExtensionPreSharedKey);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
Connect();
|
||||
SendReceive();
|
||||
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa);
|
||||
DataBuffer psk1(c1->extension());
|
||||
ASSERT_GE(psk1.len(), 0UL);
|
||||
|
||||
ResetRsa();
|
||||
ClearStats();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
||||
TlsExtensionCapture *c2 =
|
||||
new TlsExtensionCapture(kTlsExtensionPreSharedKey);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
Connect();
|
||||
SendReceive();
|
||||
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa);
|
||||
DataBuffer psk2(c2->extension());
|
||||
ASSERT_GE(psk2.len(), 0UL);
|
||||
|
||||
// TODO(ekr@rtfm.com): This will change when we fix bug 1257047.
|
||||
ASSERT_EQ(psk1, psk2);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectDatagram, TestDtlsHolddownExpiry) {
|
||||
Connect();
|
||||
std::cerr << "Expiring holddown timer\n";
|
||||
SSLInt_ForceTimerExpiry(client_->ssl_fd());
|
||||
SSLInt_ForceTimerExpiry(server_->ssl_fd());
|
||||
SendReceive();
|
||||
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
EXPECT_EQ(1, SSLInt_CountTls13CipherSpecs(client_->ssl_fd()));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
class BeforeFinished : public TlsRecordFilter {
|
||||
@ -934,8 +1077,7 @@ class BeforeFinished : public TlsRecordFilter {
|
||||
HandshakeState state_;
|
||||
};
|
||||
|
||||
// TODO Pre13
|
||||
TEST_P(TlsConnectGeneric, ClientWriteBetweenCCSAndFinishedWithFalseStart) {
|
||||
TEST_P(TlsConnectGenericPre13, ClientWriteBetweenCCSAndFinishedWithFalseStart) {
|
||||
client_->EnableFalseStart();
|
||||
server_->SetPacketFilter(new BeforeFinished(client_, server_, [this]() {
|
||||
EXPECT_TRUE(client_->can_falsestart_hook_called());
|
||||
@ -949,7 +1091,7 @@ TEST_P(TlsConnectGeneric, ClientWriteBetweenCCSAndFinishedWithFalseStart) {
|
||||
Receive(10);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, AuthCompleteBeforeFinishedWithFalseStart) {
|
||||
TEST_P(TlsConnectGenericPre13, AuthCompleteBeforeFinishedWithFalseStart) {
|
||||
client_->EnableFalseStart();
|
||||
client_->SetAuthCertificateCallback(
|
||||
[](TlsAgent&, PRBool, PRBool) -> SECStatus {
|
||||
@ -970,38 +1112,43 @@ TEST_P(TlsConnectGeneric, AuthCompleteBeforeFinishedWithFalseStart) {
|
||||
Receive(10);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VariantsStream10, TlsConnectGeneric,
|
||||
INSTANTIATE_TEST_CASE_P(GenericStream, TlsConnectGeneric,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsModesStream,
|
||||
TlsConnectTestBase::kTlsV10));
|
||||
INSTANTIATE_TEST_CASE_P(VariantsAll, TlsConnectGeneric,
|
||||
TlsConnectTestBase::kTlsVAll));
|
||||
INSTANTIATE_TEST_CASE_P(GenericDatagram, TlsConnectGeneric,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsModesAll,
|
||||
TlsConnectTestBase::kTlsV11V12));
|
||||
INSTANTIATE_TEST_CASE_P(VersionsDatagram, TlsConnectDatagram,
|
||||
TlsConnectTestBase::kTlsV11V12);
|
||||
INSTANTIATE_TEST_CASE_P(Variants12, TlsConnectTls12,
|
||||
TlsConnectTestBase::kTlsModesAll);
|
||||
INSTANTIATE_TEST_CASE_P(Variants12, TlsChaCha20Poly1305Test,
|
||||
TlsConnectTestBase::kTlsModesDatagram,
|
||||
TlsConnectTestBase::kTlsV11Plus));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(StreamOnly, TlsConnectStream,
|
||||
TlsConnectTestBase::kTlsVAll);
|
||||
INSTANTIATE_TEST_CASE_P(DatagramOnly, TlsConnectDatagram,
|
||||
TlsConnectTestBase::kTlsV11Plus);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(ChaCha20, TlsChaCha20Poly1305Test,
|
||||
TlsConnectTestBase::kTlsModesAll);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Pre12Stream, TlsConnectPre12,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsModesStream,
|
||||
TlsConnectTestBase::kTlsV10));
|
||||
INSTANTIATE_TEST_CASE_P(Pre12All, TlsConnectPre12,
|
||||
TlsConnectTestBase::kTlsV10V11));
|
||||
INSTANTIATE_TEST_CASE_P(Pre12Datagram, TlsConnectPre12,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsModesAll,
|
||||
TlsConnectTestBase::kTlsModesDatagram,
|
||||
TlsConnectTestBase::kTlsV11));
|
||||
INSTANTIATE_TEST_CASE_P(VersionsStream10, TlsConnectStream,
|
||||
TlsConnectTestBase::kTlsV10);
|
||||
INSTANTIATE_TEST_CASE_P(VersionsStream, TlsConnectStream,
|
||||
TlsConnectTestBase::kTlsV11V12);
|
||||
INSTANTIATE_TEST_CASE_P(VersionsStream10Pre13, TlsConnectStreamPre13,
|
||||
TlsConnectTestBase::kTlsV10);
|
||||
INSTANTIATE_TEST_CASE_P(VersionsStreamPre13, TlsConnectStreamPre13,
|
||||
TlsConnectTestBase::kTlsV11V12);
|
||||
#ifdef NSS_ENABLE_TLS_1_3
|
||||
INSTANTIATE_TEST_CASE_P(VersionsStream13, TlsConnectStream,
|
||||
TlsConnectTestBase::kTlsV13);
|
||||
#endif
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Version12Only, TlsConnectTls12,
|
||||
TlsConnectTestBase::kTlsModesAll);
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Pre13Stream, TlsConnectGenericPre13,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsModesStream,
|
||||
TlsConnectTestBase::kTlsV10To12));
|
||||
INSTANTIATE_TEST_CASE_P(Pre13Datagram, TlsConnectGenericPre13,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsModesDatagram,
|
||||
TlsConnectTestBase::kTlsV11V12));
|
||||
INSTANTIATE_TEST_CASE_P(Pre13StreamOnly, TlsConnectStreamPre13,
|
||||
TlsConnectTestBase::kTlsV10To12);
|
||||
} // namespace nspr_test
|
||||
|
@ -0,0 +1,406 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "ssl.h"
|
||||
#include "sslerr.h"
|
||||
#include "sslproto.h"
|
||||
#include "pk11pub.h"
|
||||
|
||||
extern "C" {
|
||||
// This is not something that should make you happy.
|
||||
#include "libssl_internals.h"
|
||||
}
|
||||
|
||||
#include "tls_filter.h"
|
||||
#include "tls_connect.h"
|
||||
#include "gtest_utils.h"
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
// Replaces the client hello with an SSLv2 version once.
|
||||
class SSLv2ClientHelloFilter : public PacketFilter
|
||||
{
|
||||
public:
|
||||
SSLv2ClientHelloFilter(TlsAgent* client, uint16_t version)
|
||||
: replaced_(false), client_(client), version_(version), pad_len_(0),
|
||||
reported_pad_len_(0), client_random_len_(16), ciphers_(0),
|
||||
send_escape_(false)
|
||||
{ }
|
||||
|
||||
void
|
||||
SetVersion(uint16_t version)
|
||||
{
|
||||
version_ = version;
|
||||
}
|
||||
|
||||
void
|
||||
SetCipherSuites(const std::vector<uint16_t>& ciphers)
|
||||
{
|
||||
ciphers_ = ciphers;
|
||||
}
|
||||
|
||||
// Set a padding length and announce it correctly.
|
||||
void
|
||||
SetPadding(uint8_t pad_len)
|
||||
{
|
||||
SetPadding(pad_len, pad_len);
|
||||
}
|
||||
|
||||
// Set a padding length and allow to lie about its length.
|
||||
void
|
||||
SetPadding(uint8_t pad_len, uint8_t reported_pad_len)
|
||||
{
|
||||
pad_len_ = pad_len;
|
||||
reported_pad_len_ = reported_pad_len;
|
||||
}
|
||||
|
||||
void
|
||||
SetClientRandomLength(uint16_t client_random_len)
|
||||
{
|
||||
client_random_len_ = client_random_len;
|
||||
}
|
||||
|
||||
void
|
||||
SetSendEscape(bool send_escape)
|
||||
{
|
||||
send_escape_ = send_escape;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual PacketFilter::Action
|
||||
Filter(const DataBuffer& input, DataBuffer* output)
|
||||
{
|
||||
if (replaced_) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
// Replace only the very first packet.
|
||||
replaced_ = true;
|
||||
|
||||
// The SSLv2 client hello size.
|
||||
size_t packet_len = SSL_HL_CLIENT_HELLO_HBYTES + (ciphers_.size() * 3) +
|
||||
client_random_len_ + pad_len_;
|
||||
|
||||
size_t idx = 0;
|
||||
*output = input;
|
||||
output->Allocate(packet_len);
|
||||
output->Truncate(packet_len);
|
||||
|
||||
// Write record length.
|
||||
if (pad_len_ > 0) {
|
||||
size_t masked_len = 0x3fff & packet_len;
|
||||
if (send_escape_) {
|
||||
masked_len |= 0x4000;
|
||||
}
|
||||
|
||||
idx = output->Write(idx, masked_len, 2);
|
||||
idx = output->Write(idx, reported_pad_len_, 1);
|
||||
} else {
|
||||
PR_ASSERT(!send_escape_);
|
||||
idx = output->Write(idx, 0x8000 | packet_len, 2);
|
||||
}
|
||||
|
||||
// Remember header length.
|
||||
size_t hdr_len = idx;
|
||||
|
||||
// Write client hello.
|
||||
idx = output->Write(idx, SSL_MT_CLIENT_HELLO, 1);
|
||||
idx = output->Write(idx, version_, 2);
|
||||
|
||||
// Cipher list length.
|
||||
idx = output->Write(idx, (ciphers_.size() * 3), 2);
|
||||
|
||||
// Session ID length.
|
||||
idx = output->Write(idx, static_cast<uint32_t>(0), 2);
|
||||
|
||||
// ClientRandom length.
|
||||
idx = output->Write(idx, client_random_len_, 2);
|
||||
|
||||
// Cipher suites.
|
||||
for (auto cipher : ciphers_) {
|
||||
idx = output->Write(idx, static_cast<uint32_t>(cipher), 3);
|
||||
}
|
||||
|
||||
// Challenge.
|
||||
std::vector<uint8_t> challenge(client_random_len_);
|
||||
PK11_GenerateRandom(challenge.data(), challenge.size());
|
||||
idx = output->Write(idx, challenge.data(), challenge.size());
|
||||
|
||||
// Add padding if any.
|
||||
if (pad_len_ > 0) {
|
||||
std::vector<uint8_t> pad(pad_len_);
|
||||
idx = output->Write(idx, pad.data(), pad.size());
|
||||
}
|
||||
|
||||
// Update the client random so that the handshake succeeds.
|
||||
SECStatus rv = SSLInt_UpdateSSLv2ClientRandom(client_->ssl_fd(),
|
||||
challenge.data(),
|
||||
challenge.size(),
|
||||
output->data() + hdr_len,
|
||||
output->len() - hdr_len);
|
||||
EXPECT_EQ(SECSuccess, rv);
|
||||
|
||||
return CHANGE;
|
||||
}
|
||||
|
||||
private:
|
||||
bool replaced_;
|
||||
TlsAgent* client_;
|
||||
uint16_t version_;
|
||||
uint8_t pad_len_;
|
||||
uint8_t reported_pad_len_;
|
||||
uint16_t client_random_len_;
|
||||
std::vector<uint16_t> ciphers_;
|
||||
bool send_escape_;
|
||||
};
|
||||
|
||||
class SSLv2ClientHelloTestF : public TlsConnectTestBase
|
||||
{
|
||||
public:
|
||||
SSLv2ClientHelloTestF()
|
||||
: TlsConnectTestBase(STREAM, 0), filter_(nullptr)
|
||||
{ }
|
||||
|
||||
SSLv2ClientHelloTestF(Mode mode, uint16_t version)
|
||||
: TlsConnectTestBase(mode, version), filter_(nullptr)
|
||||
{ }
|
||||
|
||||
void
|
||||
SetUp()
|
||||
{
|
||||
TlsConnectTestBase::SetUp();
|
||||
filter_ = new SSLv2ClientHelloFilter(client_, version_);
|
||||
client_->SetPacketFilter(filter_);
|
||||
}
|
||||
|
||||
void
|
||||
RequireSafeRenegotiation()
|
||||
{
|
||||
server_->EnsureTlsSetup();
|
||||
SECStatus rv =
|
||||
SSL_OptionSet(server_->ssl_fd(), SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE);
|
||||
EXPECT_EQ(rv, SECSuccess);
|
||||
}
|
||||
|
||||
void
|
||||
SetExpectedVersion(uint16_t version)
|
||||
{
|
||||
TlsConnectTestBase::SetExpectedVersion(version);
|
||||
filter_->SetVersion(version);
|
||||
}
|
||||
|
||||
void
|
||||
SetAvailableCipherSuite(uint16_t cipher)
|
||||
{
|
||||
filter_->SetCipherSuites(std::vector<uint16_t>(1, cipher));
|
||||
}
|
||||
|
||||
void
|
||||
SetAvailableCipherSuites(const std::vector<uint16_t>& ciphers)
|
||||
{
|
||||
filter_->SetCipherSuites(ciphers);
|
||||
}
|
||||
|
||||
void
|
||||
SetPadding(uint8_t pad_len)
|
||||
{
|
||||
filter_->SetPadding(pad_len);
|
||||
}
|
||||
|
||||
void
|
||||
SetPadding(uint8_t pad_len, uint8_t reported_pad_len)
|
||||
{
|
||||
filter_->SetPadding(pad_len, reported_pad_len);
|
||||
}
|
||||
|
||||
void
|
||||
SetClientRandomLength(uint16_t client_random_len)
|
||||
{
|
||||
filter_->SetClientRandomLength(client_random_len);
|
||||
}
|
||||
|
||||
void
|
||||
SetSendEscape(bool send_escape)
|
||||
{
|
||||
filter_->SetSendEscape(send_escape);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
SSLv2ClientHelloFilter* filter_;
|
||||
};
|
||||
|
||||
// Parameterized version of SSLv2ClientHelloTestF we can
|
||||
// use with TEST_P to test multiple TLS versions easily.
|
||||
class SSLv2ClientHelloTest : public SSLv2ClientHelloTestF,
|
||||
public ::testing::WithParamInterface<uint16_t>
|
||||
{
|
||||
public:
|
||||
SSLv2ClientHelloTest()
|
||||
: SSLv2ClientHelloTestF(STREAM, GetParam())
|
||||
{ }
|
||||
};
|
||||
|
||||
// Test negotiating TLS 1.0 - 1.2.
|
||||
TEST_P(SSLv2ClientHelloTest, Connect) {
|
||||
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
|
||||
Connect();
|
||||
}
|
||||
|
||||
// Test negotiating TLS 1.3.
|
||||
#ifdef NSS_ENABLE_TLS_1_3
|
||||
TEST_F(SSLv2ClientHelloTestF, Connect13) {
|
||||
SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
|
||||
std::vector<uint16_t> cipher_suites =
|
||||
{ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 };
|
||||
SetAvailableCipherSuites(cipher_suites);
|
||||
|
||||
ConnectExpectFail();
|
||||
EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Test negotiating an EC suite.
|
||||
TEST_P(SSLv2ClientHelloTest, NegotiateECSuite) {
|
||||
SetAvailableCipherSuite(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
|
||||
Connect();
|
||||
}
|
||||
|
||||
// Test negotiating TLS 1.0 - 1.2 with a padded client hello.
|
||||
TEST_P(SSLv2ClientHelloTest, AddPadding) {
|
||||
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
|
||||
SetPadding(255);
|
||||
Connect();
|
||||
}
|
||||
|
||||
// Test that sending a security escape fails the handshake.
|
||||
TEST_P(SSLv2ClientHelloTest, SendSecurityEscape) {
|
||||
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
|
||||
|
||||
// Send a security escape.
|
||||
SetSendEscape(true);
|
||||
|
||||
// Set a big padding so that the server fails instead of timing out.
|
||||
SetPadding(255);
|
||||
|
||||
ConnectExpectFail();
|
||||
}
|
||||
|
||||
// Invalid SSLv2 client hello padding must fail the handshake.
|
||||
TEST_P(SSLv2ClientHelloTest, AddErroneousPadding) {
|
||||
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
|
||||
|
||||
// Append 5 bytes of padding but say it's only 4.
|
||||
SetPadding(5, 4);
|
||||
|
||||
ConnectExpectFail();
|
||||
EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
|
||||
}
|
||||
|
||||
// Invalid SSLv2 client hello padding must fail the handshake.
|
||||
TEST_P(SSLv2ClientHelloTest, AddErroneousPadding2) {
|
||||
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
|
||||
|
||||
// Append 5 bytes of padding but say it's 6.
|
||||
SetPadding(5, 6);
|
||||
|
||||
ConnectExpectFail();
|
||||
EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
|
||||
}
|
||||
|
||||
// Wrong amount of bytes for the ClientRandom must fail the handshake.
|
||||
TEST_P(SSLv2ClientHelloTest, SmallClientRandom) {
|
||||
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
|
||||
|
||||
// Send a ClientRandom that's too small.
|
||||
SetClientRandomLength(15);
|
||||
|
||||
ConnectExpectFail();
|
||||
EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
|
||||
}
|
||||
|
||||
// Test sending the maximum accepted number of ClientRandom bytes.
|
||||
TEST_P(SSLv2ClientHelloTest, MaxClientRandom) {
|
||||
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
|
||||
SetClientRandomLength(32);
|
||||
Connect();
|
||||
}
|
||||
|
||||
// Wrong amount of bytes for the ClientRandom must fail the handshake.
|
||||
TEST_P(SSLv2ClientHelloTest, BigClientRandom) {
|
||||
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
|
||||
|
||||
// Send a ClientRandom that's too big.
|
||||
SetClientRandomLength(33);
|
||||
|
||||
ConnectExpectFail();
|
||||
EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
|
||||
}
|
||||
|
||||
// Connection must fail if we require safe renegotiation but the client doesn't
|
||||
// include TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the list of cipher suites.
|
||||
TEST_P(SSLv2ClientHelloTest, RequireSafeRenegotiation) {
|
||||
RequireSafeRenegotiation();
|
||||
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
|
||||
ConnectExpectFail();
|
||||
EXPECT_EQ(SSL_ERROR_UNSAFE_NEGOTIATION, server_->error_code());
|
||||
}
|
||||
|
||||
// Connection must succeed when requiring safe renegotiation and the client
|
||||
// includes TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the list of cipher suites.
|
||||
TEST_P(SSLv2ClientHelloTest, RequireSafeRenegotiationWithSCSV) {
|
||||
RequireSafeRenegotiation();
|
||||
std::vector<uint16_t> cipher_suites =
|
||||
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV };
|
||||
SetAvailableCipherSuites(cipher_suites);
|
||||
Connect();
|
||||
}
|
||||
|
||||
// Connect to the server with TLS 1.1, signalling that this is a fallback from
|
||||
// a higher version. As the server doesn't support anything higher than TLS 1.1
|
||||
// it must accept the connection.
|
||||
TEST_F(SSLv2ClientHelloTestF, FallbackSCSV) {
|
||||
SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_1);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_1);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_1);
|
||||
|
||||
std::vector<uint16_t> cipher_suites =
|
||||
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_FALLBACK_SCSV };
|
||||
SetAvailableCipherSuites(cipher_suites);
|
||||
Connect();
|
||||
}
|
||||
|
||||
// Connect to the server with TLS 1.1, signalling that this is a fallback from
|
||||
// a higher version. As the server supports TLS 1.2 though it must reject the
|
||||
// connection due to a possible downgrade attack.
|
||||
TEST_F(SSLv2ClientHelloTestF, InappropriateFallbackSCSV) {
|
||||
SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_1);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_1);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
|
||||
std::vector<uint16_t> cipher_suites =
|
||||
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_FALLBACK_SCSV };
|
||||
SetAvailableCipherSuites(cipher_suites);
|
||||
|
||||
ConnectExpectFail();
|
||||
EXPECT_EQ(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, server_->error_code());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(VersionsStream10Pre13, SSLv2ClientHelloTest,
|
||||
TlsConnectTestBase::kTlsV10);
|
||||
INSTANTIATE_TEST_CASE_P(VersionsStreamPre13, SSLv2ClientHelloTest,
|
||||
TlsConnectTestBase::kTlsV11V12);
|
||||
|
||||
} // namespace nss_test
|
@ -443,7 +443,8 @@ void Poller::SetTimer(uint32_t timer_ms, PollTarget *target, PollCallback cb,
|
||||
}
|
||||
|
||||
bool Poller::Poll() {
|
||||
std::cerr << "Poll() waiters = " << waiters_.size() << std::endl;
|
||||
std::cerr << "Poll() waiters = " << waiters_.size()
|
||||
<< " timers = " << timers_.size() << std::endl;
|
||||
PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
PRTime now = PR_Now();
|
||||
bool fired = false;
|
||||
|
@ -36,6 +36,7 @@ TlsAgent::TlsAgent(const std::string& name, Role role, Mode mode, SSLKEAType kea
|
||||
ssl_fd_(nullptr),
|
||||
role_(role),
|
||||
state_(STATE_INIT),
|
||||
timer_handle_(nullptr),
|
||||
falsestart_enabled_(false),
|
||||
expected_version_(0),
|
||||
expected_cipher_suite_(0),
|
||||
@ -63,6 +64,9 @@ TlsAgent::~TlsAgent() {
|
||||
if (adapter_) {
|
||||
Poller::Instance()->Cancel(READABLE_EVENT, adapter_);
|
||||
}
|
||||
if (timer_handle_) {
|
||||
timer_handle_->Cancel();
|
||||
}
|
||||
|
||||
if (pr_fd_) {
|
||||
PR_Close(pr_fd_);
|
||||
@ -414,9 +418,11 @@ void TlsAgent::CheckCallbacks() const {
|
||||
EXPECT_TRUE(handshake_callback_called_);
|
||||
}
|
||||
|
||||
// These callbacks shouldn't fire if we are resuming.
|
||||
// These callbacks shouldn't fire if we are resuming, except on TLS 1.3.
|
||||
if (role_ == SERVER) {
|
||||
EXPECT_EQ(!expect_resumption_, sni_hook_called_);
|
||||
PRBool have_sni = SSLInt_ExtensionNegotiated(ssl_fd_, ssl_server_name_xtn);
|
||||
EXPECT_EQ(((!expect_resumption_ && have_sni) ||
|
||||
expected_version_ >= SSL_LIBRARY_VERSION_TLS_1_3), sni_hook_called_);
|
||||
} else {
|
||||
EXPECT_EQ(!expect_resumption_, auth_certificate_hook_called_);
|
||||
// Note that this isn't unconditionally called, even with false start on.
|
||||
@ -445,6 +451,10 @@ void TlsAgent::Connected() {
|
||||
EXPECT_EQ(SECSuccess, rv);
|
||||
EXPECT_EQ(sizeof(csinfo_), csinfo_.length);
|
||||
|
||||
if (expected_version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
PRInt32 cipherSuites = SSLInt_CountTls13CipherSpecs(ssl_fd_);
|
||||
EXPECT_EQ(((mode_ == DGRAM) && (role_ == CLIENT)) ? 2 : 1, cipherSuites);
|
||||
}
|
||||
SetState(STATE_CONNECTED);
|
||||
}
|
||||
|
||||
@ -491,6 +501,7 @@ void TlsAgent::SetDowngradeCheckVersion(uint16_t version) {
|
||||
}
|
||||
|
||||
void TlsAgent::Handshake() {
|
||||
LOG("Handshake");
|
||||
SECStatus rv = SSL_ForceHandshake(ssl_fd_);
|
||||
if (rv == SECSuccess) {
|
||||
Connected();
|
||||
@ -504,13 +515,23 @@ void TlsAgent::Handshake() {
|
||||
switch (err) {
|
||||
case PR_WOULD_BLOCK_ERROR:
|
||||
LOG("Would have blocked");
|
||||
// TODO(ekr@rtfm.com): set DTLS timeouts
|
||||
if (mode_ == DGRAM) {
|
||||
if (timer_handle_) {
|
||||
timer_handle_->Cancel();
|
||||
}
|
||||
|
||||
PRIntervalTime timeout;
|
||||
rv = DTLS_GetHandshakeTimeout(ssl_fd_, &timeout);
|
||||
if (rv == SECSuccess) {
|
||||
Poller::Instance()->SetTimer(timeout, this,
|
||||
&TlsAgent::ReadableCallback,
|
||||
&timer_handle_);
|
||||
}
|
||||
}
|
||||
Poller::Instance()->Wait(READABLE_EVENT, adapter_, this,
|
||||
&TlsAgent::ReadableCallback);
|
||||
return;
|
||||
break;
|
||||
|
||||
// TODO(ekr@rtfm.com): needs special case for DTLS
|
||||
case SSL_ERROR_RX_MALFORMED_HANDSHAKE:
|
||||
default:
|
||||
if (IS_SSL_ERROR(err)) {
|
||||
|
@ -112,6 +112,8 @@ class TlsAgent : public PollTarget {
|
||||
void EnableCompression();
|
||||
void SetDowngradeCheckVersion(uint16_t version);
|
||||
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
Role role() const { return role_; }
|
||||
|
||||
State state() const { return state_; }
|
||||
@ -210,10 +212,12 @@ class TlsAgent : public PollTarget {
|
||||
|
||||
static void ReadableCallback(PollTarget* self, Event event) {
|
||||
TlsAgent* agent = static_cast<TlsAgent*>(self);
|
||||
if (event == TIMER_EVENT) {
|
||||
agent->timer_handle_ = nullptr;
|
||||
}
|
||||
agent->ReadableCallback_int();
|
||||
}
|
||||
|
||||
|
||||
void ReadableCallback_int() {
|
||||
LOG("Readable");
|
||||
switch (state_) {
|
||||
@ -234,7 +238,8 @@ class TlsAgent : public PollTarget {
|
||||
TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
|
||||
agent->CheckPreliminaryInfo();
|
||||
agent->sni_hook_called_ = true;
|
||||
return SSL_SNI_CURRENT_CONFIG_IS_USED;
|
||||
EXPECT_EQ(1UL, srvNameArrSize);
|
||||
return 0; // First configuration.
|
||||
}
|
||||
|
||||
static SECStatus CanFalseStartCallback(PRFileDesc *fd, void *arg,
|
||||
@ -269,6 +274,7 @@ class TlsAgent : public PollTarget {
|
||||
PRFileDesc* ssl_fd_;
|
||||
Role role_;
|
||||
State state_;
|
||||
Poller::Timer *timer_handle_;
|
||||
bool falsestart_enabled_;
|
||||
uint16_t expected_version_;
|
||||
uint16_t expected_cipher_suite_;
|
||||
|
@ -5,6 +5,9 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "tls_connect.h"
|
||||
extern "C" {
|
||||
#include "libssl_internals.h"
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@ -18,26 +21,68 @@ namespace nss_test {
|
||||
static const std::string kTlsModesStreamArr[] = {"TLS"};
|
||||
::testing::internal::ParamGenerator<std::string>
|
||||
TlsConnectTestBase::kTlsModesStream = ::testing::ValuesIn(kTlsModesStreamArr);
|
||||
static const std::string kTlsModesDatagramArr[] = {"DTLS"};
|
||||
::testing::internal::ParamGenerator<std::string>
|
||||
TlsConnectTestBase::kTlsModesDatagram =
|
||||
::testing::ValuesIn(kTlsModesDatagramArr);
|
||||
static const std::string kTlsModesAllArr[] = {"TLS", "DTLS"};
|
||||
::testing::internal::ParamGenerator<std::string>
|
||||
TlsConnectTestBase::kTlsModesAll = ::testing::ValuesIn(kTlsModesAllArr);
|
||||
|
||||
static const uint16_t kTlsV10Arr[] = {SSL_LIBRARY_VERSION_TLS_1_0};
|
||||
::testing::internal::ParamGenerator<uint16_t>
|
||||
TlsConnectTestBase::kTlsV10 = ::testing::ValuesIn(kTlsV10Arr);
|
||||
static const uint16_t kTlsV11Arr[] = {SSL_LIBRARY_VERSION_TLS_1_1};
|
||||
::testing::internal::ParamGenerator<uint16_t>
|
||||
TlsConnectTestBase::kTlsV11 = ::testing::ValuesIn(kTlsV11Arr);
|
||||
static const uint16_t kTlsV10V11Arr[] = {SSL_LIBRARY_VERSION_TLS_1_0,
|
||||
SSL_LIBRARY_VERSION_TLS_1_1};
|
||||
::testing::internal::ParamGenerator<uint16_t>
|
||||
TlsConnectTestBase::kTlsV10V11 = ::testing::ValuesIn(kTlsV10V11Arr);
|
||||
static const uint16_t kTlsV10To12Arr[] = {SSL_LIBRARY_VERSION_TLS_1_0,
|
||||
SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2};
|
||||
::testing::internal::ParamGenerator<uint16_t>
|
||||
TlsConnectTestBase::kTlsV10To12 = ::testing::ValuesIn(kTlsV10To12Arr);
|
||||
static const uint16_t kTlsV11V12Arr[] = {SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2};
|
||||
::testing::internal::ParamGenerator<uint16_t>
|
||||
TlsConnectTestBase::kTlsV11V12 = ::testing::ValuesIn(kTlsV11V12Arr);
|
||||
// TODO: add TLS 1.3
|
||||
static const uint16_t kTlsV12PlusArr[] = {SSL_LIBRARY_VERSION_TLS_1_2};
|
||||
|
||||
static const uint16_t kTlsV11PlusArr[] = {
|
||||
#ifdef NSS_ENABLE_TLS_1_3
|
||||
SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
#endif
|
||||
SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_1
|
||||
};
|
||||
::testing::internal::ParamGenerator<uint16_t>
|
||||
TlsConnectTestBase::kTlsV11Plus = ::testing::ValuesIn(kTlsV11PlusArr);
|
||||
static const uint16_t kTlsV12PlusArr[] = {
|
||||
#ifdef NSS_ENABLE_TLS_1_3
|
||||
SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
#endif
|
||||
SSL_LIBRARY_VERSION_TLS_1_2
|
||||
};
|
||||
::testing::internal::ParamGenerator<uint16_t>
|
||||
TlsConnectTestBase::kTlsV12Plus = ::testing::ValuesIn(kTlsV12PlusArr);
|
||||
static const uint16_t kTlsV13Arr[] = {SSL_LIBRARY_VERSION_TLS_1_3};
|
||||
#ifdef NSS_ENABLE_TLS_1_3
|
||||
static const uint16_t kTlsV13Arr[] = {
|
||||
SSL_LIBRARY_VERSION_TLS_1_3
|
||||
};
|
||||
::testing::internal::ParamGenerator<uint16_t>
|
||||
TlsConnectTestBase::kTlsV13 = ::testing::ValuesIn(kTlsV13Arr);
|
||||
#endif
|
||||
static const uint16_t kTlsVAllArr[] = {
|
||||
#ifdef NSS_ENABLE_TLS_1_3
|
||||
SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
#endif
|
||||
SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_0
|
||||
};
|
||||
::testing::internal::ParamGenerator<uint16_t>
|
||||
TlsConnectTestBase::kTlsVAll = ::testing::ValuesIn(kTlsVAllArr);
|
||||
|
||||
static std::string VersionString(uint16_t version) {
|
||||
switch(version) {
|
||||
@ -66,20 +111,34 @@ TlsConnectTestBase::TlsConnectTestBase(Mode mode, uint16_t version)
|
||||
expected_resumption_mode_(RESUME_NONE),
|
||||
session_ids_(),
|
||||
expect_extended_master_secret_(false) {
|
||||
std::cerr << "Version: " << mode_ << " " << VersionString(version_) << std::endl;
|
||||
std::string v;
|
||||
if (mode_ == DGRAM && version_ == SSL_LIBRARY_VERSION_TLS_1_1) {
|
||||
v = "1.0";
|
||||
} else {
|
||||
v = VersionString(version_);
|
||||
}
|
||||
std::cerr << "Version: " << mode_ << " " << v << std::endl;
|
||||
}
|
||||
|
||||
TlsConnectTestBase::~TlsConnectTestBase() {
|
||||
}
|
||||
|
||||
void TlsConnectTestBase::SetUp() {
|
||||
// Configure a fresh session cache.
|
||||
SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str());
|
||||
|
||||
void TlsConnectTestBase::ClearStats() {
|
||||
// Clear statistics.
|
||||
SSL3Statistics* stats = SSL_GetStatistics();
|
||||
memset(stats, 0, sizeof(*stats));
|
||||
}
|
||||
|
||||
void TlsConnectTestBase::ClearServerCache() {
|
||||
SSL_ShutdownServerSessionIDCache();
|
||||
SSLInt_ClearSessionTicketKey();
|
||||
SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str());
|
||||
}
|
||||
|
||||
void TlsConnectTestBase::SetUp() {
|
||||
SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str());
|
||||
SSLInt_ClearSessionTicketKey();
|
||||
ClearStats();
|
||||
Init();
|
||||
}
|
||||
|
||||
@ -88,6 +147,7 @@ void TlsConnectTestBase::TearDown() {
|
||||
delete server_;
|
||||
|
||||
SSL_ClearSessionCache();
|
||||
SSLInt_ClearSessionTicketKey();
|
||||
SSL_ShutdownServerSessionIDCache();
|
||||
}
|
||||
|
||||
@ -250,8 +310,11 @@ void TlsConnectTestBase::CheckResumption(SessionResumptionMode expected) {
|
||||
EXPECT_EQ(stateless_ct, stats->hch_sid_stateless_resumes);
|
||||
EXPECT_EQ(stateless_ct, stats->hsh_sid_stateless_resumes);
|
||||
|
||||
if (resume_ct) {
|
||||
if (resume_ct &&
|
||||
client_->version() < SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
// Check that the last two session ids match.
|
||||
// TLS 1.3 doesn't do session id-based resumption. It's all
|
||||
// tickets.
|
||||
EXPECT_EQ(2U, session_ids_.size());
|
||||
EXPECT_EQ(session_ids_[session_ids_.size()-1],
|
||||
session_ids_[session_ids_.size()-2]);
|
||||
|
@ -22,12 +22,17 @@ namespace nss_test {
|
||||
class TlsConnectTestBase : public ::testing::Test {
|
||||
public:
|
||||
static ::testing::internal::ParamGenerator<std::string> kTlsModesStream;
|
||||
static ::testing::internal::ParamGenerator<std::string> kTlsModesDatagram;
|
||||
static ::testing::internal::ParamGenerator<std::string> kTlsModesAll;
|
||||
static ::testing::internal::ParamGenerator<uint16_t> kTlsV10;
|
||||
static ::testing::internal::ParamGenerator<uint16_t> kTlsV11;
|
||||
static ::testing::internal::ParamGenerator<uint16_t> kTlsV10V11;
|
||||
static ::testing::internal::ParamGenerator<uint16_t> kTlsV11V12;
|
||||
static ::testing::internal::ParamGenerator<uint16_t> kTlsV12Plus;
|
||||
static ::testing::internal::ParamGenerator<uint16_t> kTlsV10To12;
|
||||
static ::testing::internal::ParamGenerator<uint16_t> kTlsV13;
|
||||
static ::testing::internal::ParamGenerator<uint16_t> kTlsV11Plus;
|
||||
static ::testing::internal::ParamGenerator<uint16_t> kTlsV12Plus;
|
||||
static ::testing::internal::ParamGenerator<uint16_t> kTlsVAll;
|
||||
|
||||
static inline Mode ToMode(const std::string& str) {
|
||||
return str == "TLS" ? STREAM : DGRAM;
|
||||
@ -41,6 +46,10 @@ class TlsConnectTestBase : public ::testing::Test {
|
||||
|
||||
// Initialize client and server.
|
||||
void Init();
|
||||
// Clear the statistics.
|
||||
void ClearStats();
|
||||
// Clear the server session cache.
|
||||
void ClearServerCache();
|
||||
// Re-initialize client and server with the default RSA cert.
|
||||
void ResetRsa();
|
||||
// Re-initialize client and server with an ECDSA cert on the server
|
||||
|
@ -5,6 +5,7 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "tls_filter.h"
|
||||
#include "sslproto.h"
|
||||
|
||||
#include <iostream>
|
||||
#include "gtest_utils.h"
|
||||
@ -271,4 +272,136 @@ PacketFilter::Action ChainedPacketFilter::Filter(const DataBuffer& input,
|
||||
return changed ? CHANGE : KEEP;
|
||||
}
|
||||
|
||||
PacketFilter::Action TlsExtensionFilter::FilterHandshake(
|
||||
const HandshakeHeader& header,
|
||||
const DataBuffer& input, DataBuffer* output) {
|
||||
if (header.handshake_type() == kTlsHandshakeClientHello) {
|
||||
TlsParser parser(input);
|
||||
if (!FindClientHelloExtensions(&parser, header)) {
|
||||
return KEEP;
|
||||
}
|
||||
return FilterExtensions(&parser, input, output);
|
||||
}
|
||||
if (header.handshake_type() == kTlsHandshakeServerHello) {
|
||||
TlsParser parser(input);
|
||||
if (!FindServerHelloExtensions(&parser, header.version())) {
|
||||
return KEEP;
|
||||
}
|
||||
return FilterExtensions(&parser, input, output);
|
||||
}
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
bool TlsExtensionFilter::FindClientHelloExtensions(TlsParser* parser,
|
||||
const Versioned& header) {
|
||||
if (!parser->Skip(2 + 32)) { // version + random
|
||||
return false;
|
||||
}
|
||||
if (!parser->SkipVariable(1)) { // session ID
|
||||
return false;
|
||||
}
|
||||
if (header.is_dtls() && !parser->SkipVariable(1)) { // DTLS cookie
|
||||
return false;
|
||||
}
|
||||
if (!parser->SkipVariable(2)) { // cipher suites
|
||||
return false;
|
||||
}
|
||||
if (!parser->SkipVariable(1)) { // compression methods
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TlsExtensionFilter::FindServerHelloExtensions(TlsParser* parser,
|
||||
uint16_t version) {
|
||||
if (!parser->Skip(2 + 32)) { // version + random
|
||||
return false;
|
||||
}
|
||||
if (!parser->SkipVariable(1)) { // session ID
|
||||
return false;
|
||||
}
|
||||
if (!parser->Skip(2)) { // cipher suite
|
||||
return false;
|
||||
}
|
||||
if (NormalizeTlsVersion(version) <= SSL_LIBRARY_VERSION_TLS_1_2) {
|
||||
if (!parser->Skip(1)) { // compression method
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PacketFilter::Action TlsExtensionFilter::FilterExtensions(
|
||||
TlsParser* parser, const DataBuffer& input, DataBuffer* output) {
|
||||
size_t length_offset = parser->consumed();
|
||||
uint32_t all_extensions;
|
||||
if (!parser->Read(&all_extensions, 2)) {
|
||||
return KEEP; // no extensions, odd but OK
|
||||
}
|
||||
if (all_extensions != parser->remaining()) {
|
||||
return KEEP; // malformed
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
|
||||
// Write out the start of the message.
|
||||
output->Allocate(input.len());
|
||||
size_t offset = output->Write(0, input.data(), parser->consumed());
|
||||
|
||||
while (parser->remaining()) {
|
||||
uint32_t extension_type;
|
||||
if (!parser->Read(&extension_type, 2)) {
|
||||
return KEEP; // malformed
|
||||
}
|
||||
|
||||
DataBuffer extension;
|
||||
if (!parser->ReadVariable(&extension, 2)) {
|
||||
return KEEP; // malformed
|
||||
}
|
||||
|
||||
DataBuffer filtered;
|
||||
PacketFilter::Action action = FilterExtension(extension_type, extension,
|
||||
&filtered);
|
||||
if (action == DROP) {
|
||||
changed = true;
|
||||
std::cerr << "extension drop: " << extension << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
const DataBuffer* source = &extension;
|
||||
if (action == CHANGE) {
|
||||
EXPECT_GT(0x10000U, filtered.len());
|
||||
changed = true;
|
||||
std::cerr << "extension old: " << extension << std::endl;
|
||||
std::cerr << "extension new: " << filtered << std::endl;
|
||||
source = &filtered;
|
||||
}
|
||||
|
||||
// Write out extension.
|
||||
offset = output->Write(offset, extension_type, 2);
|
||||
offset = output->Write(offset, source->len(), 2);
|
||||
offset = output->Write(offset, *source);
|
||||
}
|
||||
output->Truncate(offset);
|
||||
|
||||
if (changed) {
|
||||
size_t newlen = output->len() - length_offset - 2;
|
||||
EXPECT_GT(0x10000U, newlen);
|
||||
if (newlen >= 0x10000) {
|
||||
return KEEP; // bad: size increased too much
|
||||
}
|
||||
output->Write(length_offset, newlen, 2);
|
||||
return CHANGE;
|
||||
}
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
PacketFilter::Action TlsExtensionCapture::FilterExtension(
|
||||
uint16_t extension_type, const DataBuffer& input, DataBuffer* output) {
|
||||
if (extension_type == extension_) {
|
||||
data_.Assign(input);
|
||||
}
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
} // namespace nss_test
|
||||
|
@ -181,6 +181,41 @@ class ChainedPacketFilter : public PacketFilter {
|
||||
std::vector<PacketFilter*> filters_;
|
||||
};
|
||||
|
||||
class TlsExtensionFilter : public TlsHandshakeFilter {
|
||||
protected:
|
||||
virtual PacketFilter::Action FilterHandshake(
|
||||
const HandshakeHeader& header,
|
||||
const DataBuffer& input, DataBuffer* output);
|
||||
|
||||
virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
|
||||
const DataBuffer& input,
|
||||
DataBuffer* output) = 0;
|
||||
|
||||
public:
|
||||
static bool FindClientHelloExtensions(TlsParser* parser,
|
||||
const Versioned& header);
|
||||
static bool FindServerHelloExtensions(TlsParser* parser, uint16_t version);
|
||||
|
||||
private:
|
||||
PacketFilter::Action FilterExtensions(TlsParser* parser,
|
||||
const DataBuffer& input,
|
||||
DataBuffer* output);
|
||||
};
|
||||
|
||||
class TlsExtensionCapture : public TlsExtensionFilter {
|
||||
public:
|
||||
TlsExtensionCapture(uint16_t ext)
|
||||
: extension_(ext), data_() {}
|
||||
|
||||
virtual PacketFilter::Action FilterExtension(
|
||||
uint16_t extension_type, const DataBuffer& input, DataBuffer* output);
|
||||
const DataBuffer& extension() const { return data_; }
|
||||
|
||||
private:
|
||||
const uint16_t extension_;
|
||||
DataBuffer data_;
|
||||
};
|
||||
|
||||
} // namespace nss_test
|
||||
|
||||
#endif
|
||||
|
@ -42,6 +42,8 @@ const uint8_t kTlsAlertDecodeError = 50;
|
||||
const uint8_t kTlsAlertUnsupportedExtension = 110;
|
||||
const uint8_t kTlsAlertNoApplicationProtocol = 120;
|
||||
|
||||
const uint8_t kTlsExtensionPreSharedKey = 41;
|
||||
|
||||
const uint8_t kTlsFakeChangeCipherSpec[] = {
|
||||
kTlsChangeCipherSpecType, // Type
|
||||
0xfe, 0xff, // Version
|
||||
|
@ -21,12 +21,13 @@ include $(CORE_DEPTH)/coreconf/config.mk
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
include config.mk
|
||||
include ../common/gtest.mk
|
||||
|
||||
CFLAGS += -I$(CORE_DEPTH)/lib/util
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
@ -38,11 +39,7 @@ include $(CORE_DEPTH)/coreconf/rules.mk
|
||||
# (6) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
#include $(CORE_DEPTH)/$(MODULE)/config/rules.mk
|
||||
|
||||
#######################################################################
|
||||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
25
security/nss/external_tests/util_gtest/manifest.mn
Normal file
25
security/nss/external_tests/util_gtest/manifest.mn
Normal file
@ -0,0 +1,25 @@
|
||||
# -*- makefile -*-
|
||||
# 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/.
|
||||
CORE_DEPTH = ../..
|
||||
DEPTH = ../..
|
||||
MODULE = nss
|
||||
|
||||
CPPSRCS = \
|
||||
util_gtest.cc \
|
||||
util_utf8_unittest.cc \
|
||||
$(NULL)
|
||||
|
||||
INCLUDES += \
|
||||
-I$(CORE_DEPTH)/external_tests/google_test/gtest/include \
|
||||
-I$(CORE_DEPTH)/external_tests/common \
|
||||
$(NULL)
|
||||
|
||||
REQUIRES = nspr gtest
|
||||
|
||||
PROGRAM = util_gtest
|
||||
EXTRA_LIBS = \
|
||||
$(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)nssutil.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
9
security/nss/external_tests/util_gtest/util_gtest.cc
Normal file
9
security/nss/external_tests/util_gtest/util_gtest.cc
Normal file
@ -0,0 +1,9 @@
|
||||
#define GTEST_HAS_RTTI 0
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// Start the tests
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
1057
security/nss/external_tests/util_gtest/util_utf8_unittest.cc
Normal file
1057
security/nss/external_tests/util_gtest/util_utf8_unittest.cc
Normal file
File diff suppressed because it is too large
Load Diff
@ -1398,14 +1398,13 @@ cert_GetCertificateEmailAddresses(CERTCertificate* cert)
|
||||
char* rawEmailAddr = NULL;
|
||||
char* addrBuf = NULL;
|
||||
char* pBuf = NULL;
|
||||
PLArenaPool* tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
PORTCheapArenaPool tmpArena;
|
||||
PRUint32 maxLen = 0;
|
||||
PRInt32 finalLen = 0;
|
||||
SECStatus rv;
|
||||
SECItem subAltName;
|
||||
|
||||
if (!tmpArena)
|
||||
return addrBuf;
|
||||
PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
|
||||
|
||||
subAltName.data = NULL;
|
||||
maxLen = cert->derCert.len;
|
||||
@ -1413,35 +1412,37 @@ cert_GetCertificateEmailAddresses(CERTCertificate* cert)
|
||||
if (!maxLen)
|
||||
maxLen = 2000; /* a guess, should never happen */
|
||||
|
||||
pBuf = addrBuf = (char*)PORT_ArenaZAlloc(tmpArena, maxLen + 1);
|
||||
pBuf = addrBuf = (char*)PORT_ArenaZAlloc(&tmpArena.arena, maxLen + 1);
|
||||
if (!addrBuf)
|
||||
goto loser;
|
||||
|
||||
rawEmailAddr =
|
||||
CERT_GetNameElement(tmpArena, &cert->subject, SEC_OID_PKCS9_EMAIL_ADDRESS);
|
||||
rawEmailAddr = CERT_GetNameElement(&tmpArena.arena, &cert->subject,
|
||||
SEC_OID_PKCS9_EMAIL_ADDRESS);
|
||||
pBuf = appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
|
||||
|
||||
rawEmailAddr =
|
||||
CERT_GetNameElement(tmpArena, &cert->subject, SEC_OID_RFC1274_MAIL);
|
||||
rawEmailAddr = CERT_GetNameElement(&tmpArena.arena, &cert->subject,
|
||||
SEC_OID_RFC1274_MAIL);
|
||||
pBuf = appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
|
||||
|
||||
rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, &subAltName);
|
||||
if (rv == SECSuccess && subAltName.data) {
|
||||
CERTGeneralName* nameList = NULL;
|
||||
|
||||
if (!!(nameList = CERT_DecodeAltNameExtension(tmpArena, &subAltName))) {
|
||||
if (!!(nameList = CERT_DecodeAltNameExtension(&tmpArena.arena, &subAltName))) {
|
||||
CERTGeneralName* current = nameList;
|
||||
do {
|
||||
if (current->type == certDirectoryName) {
|
||||
rawEmailAddr =
|
||||
CERT_GetNameElement(tmpArena, ¤t->name.directoryName,
|
||||
CERT_GetNameElement(&tmpArena.arena,
|
||||
¤t->name.directoryName,
|
||||
SEC_OID_PKCS9_EMAIL_ADDRESS);
|
||||
pBuf =
|
||||
appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
|
||||
|
||||
rawEmailAddr =
|
||||
CERT_GetNameElement(
|
||||
tmpArena, ¤t->name.directoryName, SEC_OID_RFC1274_MAIL);
|
||||
CERT_GetNameElement(&tmpArena.arena,
|
||||
¤t->name.directoryName,
|
||||
SEC_OID_RFC1274_MAIL);
|
||||
pBuf =
|
||||
appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
|
||||
} else if (current->type == certRFC822Name) {
|
||||
@ -1464,8 +1465,7 @@ cert_GetCertificateEmailAddresses(CERTCertificate* cert)
|
||||
}
|
||||
}
|
||||
loser:
|
||||
if (tmpArena)
|
||||
PORT_FreeArena(tmpArena, PR_FALSE);
|
||||
PORT_DestroyCheapArena(&tmpArena);
|
||||
|
||||
return pBuf;
|
||||
}
|
||||
|
@ -257,27 +257,22 @@ SECStatus
|
||||
CERT_IssuerNameFromDERCert(SECItem *derCert, SECItem *derName)
|
||||
{
|
||||
int rv;
|
||||
PLArenaPool *arena;
|
||||
PORTCheapArenaPool tmpArena;
|
||||
CERTSignedData sd;
|
||||
void *tmpptr;
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
|
||||
if (!arena) {
|
||||
return (SECFailure);
|
||||
}
|
||||
PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
|
||||
|
||||
PORT_Memset(&sd, 0, sizeof(CERTSignedData));
|
||||
rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
|
||||
|
||||
rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &sd, CERT_SignedDataTemplate,
|
||||
derCert);
|
||||
if (rv) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
PORT_Memset(derName, 0, sizeof(SECItem));
|
||||
rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertIssuerTemplate,
|
||||
&sd.data);
|
||||
|
||||
rv = SEC_QuickDERDecodeItem(&tmpArena.arena, derName,
|
||||
SEC_CertIssuerTemplate, &sd.data);
|
||||
if (rv) {
|
||||
goto loser;
|
||||
}
|
||||
@ -290,11 +285,11 @@ CERT_IssuerNameFromDERCert(SECItem *derCert, SECItem *derName)
|
||||
|
||||
PORT_Memcpy(derName->data, tmpptr, derName->len);
|
||||
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
PORT_DestroyCheapArena(&tmpArena);
|
||||
return (SECSuccess);
|
||||
|
||||
loser:
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
PORT_DestroyCheapArena(&tmpArena);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
@ -302,27 +297,22 @@ SECStatus
|
||||
CERT_SerialNumberFromDERCert(SECItem *derCert, SECItem *derName)
|
||||
{
|
||||
int rv;
|
||||
PLArenaPool *arena;
|
||||
PORTCheapArenaPool tmpArena;
|
||||
CERTSignedData sd;
|
||||
void *tmpptr;
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
|
||||
if (!arena) {
|
||||
return (SECFailure);
|
||||
}
|
||||
PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
|
||||
|
||||
PORT_Memset(&sd, 0, sizeof(CERTSignedData));
|
||||
rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
|
||||
|
||||
rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &sd, CERT_SignedDataTemplate,
|
||||
derCert);
|
||||
if (rv) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
PORT_Memset(derName, 0, sizeof(SECItem));
|
||||
rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSerialNumberTemplate,
|
||||
&sd.data);
|
||||
|
||||
rv = SEC_QuickDERDecodeItem(&tmpArena.arena, derName,
|
||||
SEC_CertSerialNumberTemplate, &sd.data);
|
||||
if (rv) {
|
||||
goto loser;
|
||||
}
|
||||
@ -335,11 +325,11 @@ CERT_SerialNumberFromDERCert(SECItem *derCert, SECItem *derName)
|
||||
|
||||
PORT_Memcpy(derName->data, tmpptr, derName->len);
|
||||
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
PORT_DestroyCheapArena(&tmpArena);
|
||||
return (SECSuccess);
|
||||
|
||||
loser:
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
PORT_DestroyCheapArena(&tmpArena);
|
||||
return (SECFailure);
|
||||
}
|
||||
|
||||
@ -2072,36 +2062,27 @@ CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype)
|
||||
unsigned int cType = cert->nsCertType;
|
||||
PRBool ret = PR_FALSE;
|
||||
|
||||
if (cType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA |
|
||||
NS_CERT_TYPE_OBJECT_SIGNING_CA)) {
|
||||
ret = PR_TRUE;
|
||||
} else {
|
||||
SECStatus rv;
|
||||
CERTBasicConstraints constraints;
|
||||
|
||||
rv = CERT_FindBasicConstraintExten(cert, &constraints);
|
||||
if (rv == SECSuccess && constraints.isCA) {
|
||||
ret = PR_TRUE;
|
||||
cType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
|
||||
}
|
||||
}
|
||||
|
||||
/* finally check if it's an X.509 v1 root CA */
|
||||
if (!ret &&
|
||||
(cert->isRoot && cert_Version(cert) < SEC_CERTIFICATE_VERSION_3)) {
|
||||
ret = PR_TRUE;
|
||||
/*
|
||||
* Check if the constraints are available and it's a CA, OR if it's
|
||||
* a X.509 v1 Root CA.
|
||||
*/
|
||||
CERTBasicConstraints constraints;
|
||||
if ((CERT_FindBasicConstraintExten(cert, &constraints) == SECSuccess &&
|
||||
constraints.isCA) ||
|
||||
(cert->isRoot && cert_Version(cert) < SEC_CERTIFICATE_VERSION_3))
|
||||
cType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
|
||||
}
|
||||
/* Now apply trust overrides, if any */
|
||||
|
||||
/*
|
||||
* Apply trust overrides, if any.
|
||||
*/
|
||||
cType = cert_ComputeTrustOverrides(cert, cType);
|
||||
ret = (cType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA |
|
||||
NS_CERT_TYPE_OBJECT_SIGNING_CA))
|
||||
? PR_TRUE
|
||||
: PR_FALSE;
|
||||
NS_CERT_TYPE_OBJECT_SIGNING_CA)) ? PR_TRUE : PR_FALSE;
|
||||
|
||||
if (rettype != NULL) {
|
||||
if (rettype) {
|
||||
*rettype = cType;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -129,18 +129,15 @@ CERT_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem)
|
||||
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID,
|
||||
&encodedValue);
|
||||
if (rv == SECSuccess) {
|
||||
PLArenaPool *tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (tmpArena) {
|
||||
rv = SEC_QuickDERDecodeItem(tmpArena, &decodedValue,
|
||||
SEC_ASN1_GET(SEC_OctetStringTemplate),
|
||||
&encodedValue);
|
||||
if (rv == SECSuccess) {
|
||||
rv = SECITEM_CopyItem(NULL, retItem, &decodedValue);
|
||||
}
|
||||
PORT_FreeArena(tmpArena, PR_FALSE);
|
||||
} else {
|
||||
rv = SECFailure;
|
||||
PORTCheapArenaPool tmpArena;
|
||||
PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
|
||||
rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &decodedValue,
|
||||
SEC_ASN1_GET(SEC_OctetStringTemplate),
|
||||
&encodedValue);
|
||||
if (rv == SECSuccess) {
|
||||
rv = SECITEM_CopyItem(NULL, retItem, &decodedValue);
|
||||
}
|
||||
PORT_DestroyCheapArena(&tmpArena);
|
||||
}
|
||||
SECITEM_FreeItem(&encodedValue, PR_FALSE);
|
||||
return rv;
|
||||
|
@ -394,24 +394,21 @@ CERT_FindBitStringExtension(CERTCertExtension **extensions, int tag,
|
||||
{
|
||||
SECItem wrapperItem, tmpItem = { siBuffer, 0 };
|
||||
SECStatus rv;
|
||||
PLArenaPool *arena = NULL;
|
||||
PORTCheapArenaPool tmpArena;
|
||||
|
||||
wrapperItem.data = NULL;
|
||||
tmpItem.data = NULL;
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
|
||||
if (!arena) {
|
||||
return (SECFailure);
|
||||
}
|
||||
PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
|
||||
|
||||
rv = cert_FindExtension(extensions, tag, &wrapperItem);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = SEC_QuickDERDecodeItem(
|
||||
arena, &tmpItem, SEC_ASN1_GET(SEC_BitStringTemplate), &wrapperItem);
|
||||
rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &tmpItem,
|
||||
SEC_ASN1_GET(SEC_BitStringTemplate),
|
||||
&wrapperItem);
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
@ -432,9 +429,7 @@ loser:
|
||||
rv = SECFailure;
|
||||
|
||||
done:
|
||||
if (arena) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
}
|
||||
PORT_DestroyCheapArena(&tmpArena);
|
||||
|
||||
if (wrapperItem.data) {
|
||||
PORT_Free(wrapperItem.data);
|
||||
|
@ -608,7 +608,7 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
|
||||
const SEC_ASN1Template *theTemplate = NULL;
|
||||
enum { conv_none, conv_ucs4, conv_ucs2, conv_iso88591 } convert = conv_none;
|
||||
SECItem avaValue = { siBuffer, 0 };
|
||||
PLArenaPool *newarena = NULL;
|
||||
PORTCheapArenaPool tmpArena;
|
||||
|
||||
if (!derAVAValue || !derAVAValue->len || !derAVAValue->data) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
@ -648,20 +648,17 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
|
||||
}
|
||||
|
||||
PORT_Memset(&avaValue, 0, sizeof(SECItem));
|
||||
newarena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!newarena) {
|
||||
return NULL;
|
||||
}
|
||||
if (SEC_QuickDERDecodeItem(newarena, &avaValue, theTemplate, derAVAValue) !=
|
||||
SECSuccess) {
|
||||
PORT_FreeArena(newarena, PR_FALSE);
|
||||
PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
|
||||
if (SEC_QuickDERDecodeItem(&tmpArena.arena, &avaValue, theTemplate,
|
||||
derAVAValue) != SECSuccess) {
|
||||
PORT_DestroyCheapArena(&tmpArena);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (convert != conv_none) {
|
||||
unsigned int utf8ValLen = avaValue.len * 3;
|
||||
unsigned char *utf8Val =
|
||||
(unsigned char *)PORT_ArenaZAlloc(newarena, utf8ValLen);
|
||||
(unsigned char *)PORT_ArenaZAlloc(&tmpArena.arena, utf8ValLen);
|
||||
|
||||
switch (convert) {
|
||||
case conv_ucs4:
|
||||
@ -669,7 +666,7 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
|
||||
!PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data,
|
||||
avaValue.len, utf8Val, utf8ValLen,
|
||||
&utf8ValLen)) {
|
||||
PORT_FreeArena(newarena, PR_FALSE);
|
||||
PORT_DestroyCheapArena(&tmpArena);
|
||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||
return NULL;
|
||||
}
|
||||
@ -679,7 +676,7 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
|
||||
!PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data,
|
||||
avaValue.len, utf8Val, utf8ValLen,
|
||||
&utf8ValLen)) {
|
||||
PORT_FreeArena(newarena, PR_FALSE);
|
||||
PORT_DestroyCheapArena(&tmpArena);
|
||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||
return NULL;
|
||||
}
|
||||
@ -688,7 +685,7 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
|
||||
if (!PORT_ISO88591_UTF8Conversion(avaValue.data, avaValue.len,
|
||||
utf8Val, utf8ValLen,
|
||||
&utf8ValLen)) {
|
||||
PORT_FreeArena(newarena, PR_FALSE);
|
||||
PORT_DestroyCheapArena(&tmpArena);
|
||||
PORT_SetError(SEC_ERROR_INVALID_AVA);
|
||||
return NULL;
|
||||
}
|
||||
@ -703,6 +700,6 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
|
||||
}
|
||||
|
||||
retItem = SECITEM_DupItem(&avaValue);
|
||||
PORT_FreeArena(newarena, PR_FALSE);
|
||||
PORT_DestroyCheapArena(&tmpArena);
|
||||
return retItem;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ CERT_DecodeBasicConstraintValue(CERTBasicConstraints *value,
|
||||
const SECItem *encodedValue)
|
||||
{
|
||||
EncodedContext decodeContext;
|
||||
PLArenaPool *our_pool;
|
||||
PORTCheapArenaPool tmpArena;
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
do {
|
||||
@ -104,13 +104,9 @@ CERT_DecodeBasicConstraintValue(CERTBasicConstraints *value,
|
||||
decodeContext.isCA.data = &hexFalse;
|
||||
decodeContext.isCA.len = 1;
|
||||
|
||||
our_pool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
|
||||
if (our_pool == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
GEN_BREAK(SECFailure);
|
||||
}
|
||||
PORT_InitCheapArena(&tmpArena, SEC_ASN1_DEFAULT_ARENA_SIZE);
|
||||
|
||||
rv = SEC_QuickDERDecodeItem(our_pool, &decodeContext,
|
||||
rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &decodeContext,
|
||||
CERTBasicConstraintsTemplate, encodedValue);
|
||||
if (rv == SECFailure)
|
||||
break;
|
||||
@ -140,8 +136,8 @@ CERT_DecodeBasicConstraintValue(CERTBasicConstraints *value,
|
||||
GEN_BREAK(SECFailure);
|
||||
break;
|
||||
}
|
||||
|
||||
} while (0);
|
||||
PORT_FreeArena(our_pool, PR_FALSE);
|
||||
|
||||
PORT_DestroyCheapArena(&tmpArena);
|
||||
return (rv);
|
||||
}
|
||||
|
@ -355,6 +355,9 @@ crmf_copy_poposigningkey(PLArenaPool *poolp,
|
||||
if (inPopoSignKey->derInput.data != NULL) {
|
||||
rv = SECITEM_CopyItem(poolp, &destPopoSignKey->derInput,
|
||||
&inPopoSignKey->derInput);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
destPopoSignKey->algorithmIdentifier = (poolp == NULL) ? PORT_ZNew(SECAlgorithmID)
|
||||
: PORT_ArenaZNew(poolp, SECAlgorithmID);
|
||||
|
@ -1020,7 +1020,7 @@ __expand_table(HTAB *hashp)
|
||||
hashp->DSIZE = dirsize << 1;
|
||||
}
|
||||
if ((hashp->dir[new_segnum] =
|
||||
(SEGMENT)calloc((size_t)hashp->SGSIZE, sizeof(SEGMENT))) == NULL)
|
||||
(SEGMENT)calloc((size_t)hashp->SGSIZE, sizeof(BUFHEAD *))) == NULL)
|
||||
return (-1);
|
||||
hashp->exsegs++;
|
||||
hashp->nsegs++;
|
||||
@ -1091,13 +1091,13 @@ alloc_segs(
|
||||
register SEGMENT store;
|
||||
|
||||
if ((hashp->dir =
|
||||
(SEGMENT *)calloc((size_t)hashp->DSIZE, sizeof(SEGMENT *))) == NULL) {
|
||||
(SEGMENT *)calloc((size_t)hashp->DSIZE, sizeof(SEGMENT))) == NULL) {
|
||||
errno = ENOMEM;
|
||||
return (-1);
|
||||
}
|
||||
/* Allocate segments */
|
||||
if ((store =
|
||||
(SEGMENT)calloc((size_t)nsegs << hashp->SSHIFT, sizeof(SEGMENT))) == NULL) {
|
||||
(SEGMENT)calloc((size_t)nsegs << hashp->SSHIFT, sizeof(BUFHEAD *))) == NULL) {
|
||||
errno = ENOMEM;
|
||||
return (-1);
|
||||
}
|
||||
|
@ -46,13 +46,24 @@ ifeq ($(FREEBL_NO_DEPEND),1)
|
||||
endif
|
||||
|
||||
ifeq ($(FREEBL_LOWHASH),1)
|
||||
DEFINES += -DFREEBL_LOWHASH
|
||||
LOWHASH_SRCS = nsslowhash.c
|
||||
LOWHASH_EXPORTS = nsslowhash.h
|
||||
MAPFILE_SOURCE = freebl_hash.def
|
||||
MAPFILE_SOURCE = freebl_hash_vector.def
|
||||
NEED_STUB_BUILD = 1
|
||||
else
|
||||
MAPFILE_SOURCE = freebl.def
|
||||
endif
|
||||
|
||||
ifdef USE_STUB_BUILD
|
||||
CSRCS = lowhash_vector.c
|
||||
SIMPLE_OBJS = $(CSRCS:.c=$(OBJ_SUFFIX))
|
||||
OBJS = $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(SIMPLE_OBJS))
|
||||
ALL_TRASH := $(TARGETS) $(OBJS) $(OBJDIR) LOGS TAGS $(GARBAGE) \
|
||||
$(NOSUCHFILE) so_locations
|
||||
MAPFILE_SOURCE = freebl_hash.def
|
||||
endif
|
||||
|
||||
# FREEBL_USE_PRELINK
|
||||
#
|
||||
# Most modern version of Linux support a speed optimization scheme where an
|
||||
@ -87,6 +98,10 @@ ifdef LINUX
|
||||
DEFINES += -D__GNU_SOURCE=1
|
||||
endif
|
||||
endif
|
||||
ifdef NSS_NO_INIT_SUPPORT
|
||||
DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
endif
|
||||
|
||||
ifdef FREEBL_PRELINK_COMMAND
|
||||
DEFINES +=-DFREEBL_PRELINK_COMMAND=\"$(FREEBL_PRELINK_COMMAND)\"
|
||||
endif
|
||||
@ -112,7 +127,7 @@ ifeq (OS2,$(OS_TARGET))
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
DEFINES += -DMP_ASSEMBLY_DIV_2DX1D
|
||||
DEFINES += -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
|
||||
DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
|
||||
DEFINES += -DMP_IS_LITTLE_ENDIAN
|
||||
endif
|
||||
|
||||
ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET)))
|
||||
@ -148,7 +163,7 @@ else
|
||||
endif
|
||||
else
|
||||
# -DMP_NO_MP_WORD
|
||||
DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
|
||||
DEFINES += -DMP_IS_LITTLE_ENDIAN
|
||||
ifdef NS_USE_GCC
|
||||
# Ideally, we should use amd64 assembly code, but it's not yet mingw-w64
|
||||
# compatible.
|
||||
@ -203,7 +218,7 @@ ifeq ($(CPU_ARCH),x86_64)
|
||||
ASFLAGS += -fPIC -Wa,--noexecstack
|
||||
DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
|
||||
DEFINES += -DNSS_USE_COMBA
|
||||
DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
|
||||
DEFINES += -DMP_IS_LITTLE_ENDIAN
|
||||
# DEFINES += -DMPI_AMD64_ADD
|
||||
# comment the next four lines to turn off Intel HW acceleration.
|
||||
DEFINES += -DUSE_HW_AES -DINTEL_GCM
|
||||
@ -216,7 +231,7 @@ ifeq ($(CPU_ARCH),x86)
|
||||
ASFILES = mpi_x86.s
|
||||
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
|
||||
DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT
|
||||
DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
|
||||
DEFINES += -DMP_IS_LITTLE_ENDIAN
|
||||
# The floating point ECC code doesn't work on Linux x86 (bug 311432).
|
||||
#ECL_USE_FP = 1
|
||||
endif
|
||||
@ -226,6 +241,11 @@ ifeq ($(CPU_ARCH),arm)
|
||||
DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512
|
||||
MPI_SRCS += mpi_arm.c
|
||||
endif
|
||||
ifeq ($(CPU_ARCH),ppc)
|
||||
ifdef USE_64
|
||||
DEFINES += -DNSS_NO_INIT_SUPPORT
|
||||
endif # USE_64
|
||||
endif # ppc
|
||||
endif # Linux
|
||||
|
||||
ifeq ($(OS_TARGET),AIX)
|
||||
@ -454,7 +474,7 @@ else
|
||||
# Intel acceleration for GCM does not build currently with Studio
|
||||
endif
|
||||
DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
|
||||
DEFINES += -DNSS_USE_COMBA -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
|
||||
DEFINES += -DNSS_USE_COMBA -DMP_IS_LITTLE_ENDIAN
|
||||
# comment the next two lines to turn off Intel HW acceleration
|
||||
DEFINES += -DUSE_HW_AES
|
||||
ASFILES += intel-aes.s
|
||||
@ -484,7 +504,7 @@ endif
|
||||
|
||||
# poly1305-donna-x64-sse2-incremental-source.c requires __int128 support
|
||||
# in GCC 4.6.0.
|
||||
ifeq ($(CC_NAME),clang)
|
||||
ifdef CC_IS_CLANG
|
||||
HAVE_INT128_SUPPORT = 1
|
||||
else ifeq (1,$(CC_IS_GCC))
|
||||
ifneq (,$(filter 4.6 4.7 4.8 4.9,$(word 1,$(GCC_VERSION)).$(word 2,$(GCC_VERSION))))
|
||||
@ -598,6 +618,17 @@ release_md libs:: $(SINGLE_SHLIB_DIR)
|
||||
|
||||
endif
|
||||
|
||||
ifdef NEED_STUB_BUILD
|
||||
SINGLE_SHLIB_DIR = $(OBJDIR)/$(OS_TARGET)_SINGLE_SHLIB
|
||||
ALL_TRASH += $(SINGLE_SHLIB_DIR)
|
||||
$(SINGLE_SHLIB_DIR):
|
||||
-mkdir $(SINGLE_SHLIB_DIR)
|
||||
|
||||
release_md libs:: $(SINGLE_SHLIB_DIR)
|
||||
$(MAKE) FREEBL_CHILD_BUILD=1 USE_STUB_BUILD=1 \
|
||||
OBJDIR=$(SINGLE_SHLIB_DIR) $@
|
||||
endif
|
||||
|
||||
# multiple shared libraries
|
||||
|
||||
######################## ABI32_FPU stuff #########################
|
||||
@ -697,8 +728,8 @@ $(OBJDIR)/$(PROG_PREFIX)intel-gcm-wrap$(OBJ_SUFFIX): CFLAGS += -mssse3
|
||||
# symbolic names to registers, for example,
|
||||
# .set Htbl, %rdi
|
||||
# So we can't use Clang's integrated assembler with intel-gcm.s.
|
||||
ifneq (,$(findstring clang,$(shell $(AS) --version)))
|
||||
$(OBJDIR)/$(PROG_PREFIX)intel-gcm$(OBJ_SUFFIX): ASFLAGS += -no-integrated-as
|
||||
ifdef CC_IS_CLANG
|
||||
$(OBJDIR)/$(PROG_PREFIX)intel-gcm$(OBJ_SUFFIX): CFLAGS += -no-integrated-as
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -21,6 +21,9 @@ typedef void (*freeblDestroyFunc)(void *cx, PRBool freeit);
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
SECStatus BL_FIPSEntryOK(PRBool freeblOnly);
|
||||
PRBool BL_POSTRan(PRBool freeblOnly);
|
||||
|
||||
#if defined(XP_UNIX) && !defined(NO_FORK_CHECK)
|
||||
|
||||
extern PRBool bl_parentForkedAfterC_Initialize;
|
||||
|
98
security/nss/lib/freebl/blname.c
Normal file
98
security/nss/lib/freebl/blname.c
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* * blname.c - determine the freebl library name.
|
||||
* *
|
||||
* * 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/. */
|
||||
|
||||
#if defined(FREEBL_LOWHASH)
|
||||
static const char* default_name =
|
||||
SHLIB_PREFIX"freeblpriv"SHLIB_VERSION"."SHLIB_SUFFIX;
|
||||
#else
|
||||
static const char* default_name =
|
||||
SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX;
|
||||
#endif
|
||||
|
||||
/* getLibName() returns the name of the library to load. */
|
||||
|
||||
#if defined(SOLARIS) && defined(__sparc)
|
||||
#include <stddef.h>
|
||||
#include <strings.h>
|
||||
#include <sys/systeminfo.h>
|
||||
|
||||
|
||||
#if defined(NSS_USE_64)
|
||||
|
||||
const static char fpu_hybrid_shared_lib[] = "libfreebl_64fpu_3.so";
|
||||
const static char int_hybrid_shared_lib[] = "libfreebl_64int_3.so";
|
||||
const static char non_hybrid_shared_lib[] = "libfreebl_64fpu_3.so";
|
||||
|
||||
const static char int_hybrid_isa[] = "sparcv9";
|
||||
const static char fpu_hybrid_isa[] = "sparcv9+vis";
|
||||
|
||||
#else
|
||||
|
||||
const static char fpu_hybrid_shared_lib[] = "libfreebl_32fpu_3.so";
|
||||
const static char int_hybrid_shared_lib[] = "libfreebl_32int64_3.so";
|
||||
/* This was for SPARC V8, now obsolete. */
|
||||
const static char *const non_hybrid_shared_lib = NULL;
|
||||
|
||||
const static char int_hybrid_isa[] = "sparcv8plus";
|
||||
const static char fpu_hybrid_isa[] = "sparcv8plus+vis";
|
||||
|
||||
#endif
|
||||
|
||||
static const char *
|
||||
getLibName(void)
|
||||
{
|
||||
char * found_int_hybrid;
|
||||
char * found_fpu_hybrid;
|
||||
long buflen;
|
||||
char buf[256];
|
||||
|
||||
buflen = sysinfo(SI_ISALIST, buf, sizeof buf);
|
||||
if (buflen <= 0)
|
||||
return NULL;
|
||||
/* sysinfo output is always supposed to be NUL terminated, but ... */
|
||||
if (buflen < sizeof buf)
|
||||
buf[buflen] = '\0';
|
||||
else
|
||||
buf[(sizeof buf) - 1] = '\0';
|
||||
/* The ISA list is a space separated string of names of ISAs and
|
||||
* ISA extensions, in order of decreasing performance.
|
||||
* There are two different ISAs with which NSS's crypto code can be
|
||||
* accelerated. If both are in the list, we take the first one.
|
||||
* If one is in the list, we use it, and if neither then we use
|
||||
* the base unaccelerated code.
|
||||
*/
|
||||
found_int_hybrid = strstr(buf, int_hybrid_isa);
|
||||
found_fpu_hybrid = strstr(buf, fpu_hybrid_isa);
|
||||
if (found_fpu_hybrid &&
|
||||
(!found_int_hybrid ||
|
||||
(found_int_hybrid - found_fpu_hybrid) >= 0)) {
|
||||
return fpu_hybrid_shared_lib;
|
||||
}
|
||||
if (found_int_hybrid) {
|
||||
return int_hybrid_shared_lib;
|
||||
}
|
||||
return non_hybrid_shared_lib;
|
||||
}
|
||||
|
||||
#elif defined(HPUX) && !defined(NSS_USE_64) && !defined(__ia64)
|
||||
#include <unistd.h>
|
||||
|
||||
/* This code tests to see if we're running on a PA2.x CPU.
|
||||
** It returns true (1) if so, and false (0) otherwise.
|
||||
*/
|
||||
static const char *
|
||||
getLibName(void)
|
||||
{
|
||||
long cpu = sysconf(_SC_CPU_VERSION);
|
||||
return (cpu == CPU_PA_RISC2_0)
|
||||
? "libfreebl_32fpu_3.sl"
|
||||
: "libfreebl_32int_3.sl" ;
|
||||
}
|
||||
#else
|
||||
/* default case, for platforms/ABIs that have only one freebl shared lib. */
|
||||
static const char * getLibName(void) { return default_name; }
|
||||
#endif
|
@ -30,6 +30,7 @@ CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher,
|
||||
}
|
||||
|
||||
/* Invariant: 0 < ctr->bufPtr <= blocksize */
|
||||
ctr->checkWrap = PR_FALSE;
|
||||
ctr->bufPtr = blocksize; /* no unused data in the buffer */
|
||||
ctr->cipher = cipher;
|
||||
ctr->context = context;
|
||||
@ -40,6 +41,10 @@ CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher,
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_Memcpy(ctr->counter, ctrParams->cb, blocksize);
|
||||
if (ctr->counterBits < 64) {
|
||||
PORT_Memcpy(ctr->counterFirst, ctr->counter, blocksize);
|
||||
ctr->checkWrap = PR_TRUE;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
@ -147,6 +152,12 @@ CTR_Update(CTRContext *ctr, unsigned char *outbuf,
|
||||
rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
|
||||
ctr->counter, blocksize, blocksize);
|
||||
ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
|
||||
if (ctr->checkWrap) {
|
||||
if (PORT_Memcmp(ctr->counter, ctr->counterFirst, blocksize) == 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
@ -162,6 +173,12 @@ CTR_Update(CTRContext *ctr, unsigned char *outbuf,
|
||||
rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
|
||||
ctr->counter, blocksize, blocksize);
|
||||
ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
|
||||
if (ctr->checkWrap) {
|
||||
if (PORT_Memcmp(ctr->counter, ctr->counterFirst, blocksize) == 0) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ struct CTRContextStr {
|
||||
void *context;
|
||||
unsigned char counter[MAX_BLOCK_SIZE];
|
||||
unsigned char buffer[MAX_BLOCK_SIZE];
|
||||
unsigned char counterFirst[MAX_BLOCK_SIZE]; /* counter overlfow value */
|
||||
PRBool checkWrap; /*check for counter overflow*/
|
||||
unsigned long counterBits;
|
||||
unsigned int bufPtr;
|
||||
};
|
||||
|
@ -97,6 +97,7 @@ CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf,
|
||||
unsigned int tmp;
|
||||
int fullblocks;
|
||||
int written;
|
||||
unsigned char *saveout = outbuf;
|
||||
SECStatus rv;
|
||||
|
||||
if (inlen < blocksize) {
|
||||
@ -141,6 +142,8 @@ CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf,
|
||||
PORT_Memset(lastBlock, 0, blocksize);
|
||||
if (rv == SECSuccess) {
|
||||
*outlen = written + blocksize;
|
||||
} else {
|
||||
PORT_Memset(saveout, 0, written+blocksize);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@ -184,6 +187,7 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
|
||||
unsigned char Cn[MAX_BLOCK_SIZE]; /* block Cn */
|
||||
unsigned char lastBlock[MAX_BLOCK_SIZE];
|
||||
const unsigned char *tmp;
|
||||
unsigned char *saveout = outbuf;
|
||||
unsigned int tmpLen;
|
||||
unsigned int fullblocks, pad;
|
||||
unsigned int i;
|
||||
@ -280,6 +284,8 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
|
||||
rv = (*cts->cipher)(cts->context, Pn, &tmpLen, blocksize, lastBlock,
|
||||
blocksize, blocksize);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_Memset(lastBlock, 0, blocksize);
|
||||
PORT_Memset(saveout, 0, *outlen);
|
||||
return SECFailure;
|
||||
}
|
||||
/* make up for the out of order CBC decryption */
|
||||
|
@ -173,8 +173,8 @@ DH_NewKey(DHParams *params, DHPrivateKey **privKey)
|
||||
/* Generate private key xa */
|
||||
SECITEM_AllocItem(arena, &key->privateValue,
|
||||
dh_GetSecretKeyLen(params->prime.len));
|
||||
RNG_GenerateGlobalRandomBytes(key->privateValue.data,
|
||||
key->privateValue.len);
|
||||
CHECK_SEC_OK(RNG_GenerateGlobalRandomBytes(key->privateValue.data,
|
||||
key->privateValue.len));
|
||||
SECITEM_TO_MPINT( key->privateValue, &xa );
|
||||
/* xa < p */
|
||||
CHECK_MPI_OK( mp_mod(&xa, &p, &xa) );
|
||||
@ -191,8 +191,10 @@ cleanup:
|
||||
MP_TO_SEC_ERROR(err);
|
||||
rv = SECFailure;
|
||||
}
|
||||
if (rv)
|
||||
if (rv) {
|
||||
*privKey = NULL;
|
||||
PORT_FreeArena(arena, PR_TRUE);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -272,6 +274,10 @@ DH_Derive(SECItem *publicValue,
|
||||
|
||||
/* allocate a buffer which can hold the entire derived secret. */
|
||||
secret = PORT_Alloc(len);
|
||||
if (secret == NULL) {
|
||||
err = MP_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
/* grab the derived secret */
|
||||
err = mp_to_unsigned_octets(&ZZ, secret, len);
|
||||
if (err >= 0) err = MP_OKAY;
|
||||
@ -285,7 +291,10 @@ DH_Derive(SECItem *publicValue,
|
||||
nb = outBytes;
|
||||
else
|
||||
nb = len;
|
||||
SECITEM_AllocItem(NULL, derivedSecret, nb);
|
||||
if (SECITEM_AllocItem(NULL, derivedSecret, nb) == NULL) {
|
||||
err = MP_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
if (len < nb) {
|
||||
unsigned int offset = nb - len;
|
||||
memset(derivedSecret->data, 0, offset);
|
||||
@ -360,11 +369,19 @@ KEA_Derive(SECItem *prime,
|
||||
/* allocate a buffer for the full derived secret */
|
||||
len = mp_unsigned_octet_size(&w);
|
||||
secret = PORT_Alloc(len);
|
||||
if (secret == NULL) {
|
||||
err = MP_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
/* grab the secret */
|
||||
err = mp_to_unsigned_octets(&w, secret, len);
|
||||
if (err > 0) err = MP_OKAY;
|
||||
/* allocate output buffer */
|
||||
SECITEM_AllocItem(NULL, derivedSecret, KEA_DERIVED_SECRET_LEN);
|
||||
if (SECITEM_AllocItem(NULL, derivedSecret, KEA_DERIVED_SECRET_LEN)
|
||||
== NULL) {
|
||||
err = MP_MEM;
|
||||
goto cleanup;
|
||||
}
|
||||
memset(derivedSecret->data, 0, derivedSecret->len);
|
||||
/* copy in the 128 lsb of the secret */
|
||||
if (len >= KEA_DERIVED_SECRET_LEN) {
|
||||
@ -387,6 +404,8 @@ cleanup:
|
||||
PORT_ZFree(secret, len);
|
||||
if (err) {
|
||||
MP_TO_SEC_ERROR(err);
|
||||
if (derivedSecret->data)
|
||||
PORT_ZFree(derivedSecret->data, derivedSecret->len);
|
||||
return SECFailure;
|
||||
}
|
||||
return SECSuccess;
|
||||
|
@ -76,7 +76,7 @@ struct RNGContextStr {
|
||||
#define V(rng) (((rng)->V_Data)+1)
|
||||
#define VSize(rng) ((sizeof (rng)->V_Data) -1)
|
||||
PRUint8 C[PRNG_SEEDLEN]; /* internal state variables */
|
||||
PRUint8 oldV[PRNG_SEEDLEN]; /* for continuous rng checking */
|
||||
PRUint8 lastOutput[SHA256_LENGTH]; /* for continuous rng checking */
|
||||
/* If we get calls for the PRNG to return less than the length of our
|
||||
* hash, we extend the request for a full hash (since we'll be doing
|
||||
* the full hash anyway). Future requests for random numbers are fulfilled
|
||||
@ -286,6 +286,8 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
|
||||
unsigned int no_of_returned_bytes)
|
||||
{
|
||||
PRUint8 data[VSize(rng)];
|
||||
PRUint8 thisHash[SHA256_LENGTH];
|
||||
PRUint8 *lastHash = rng->lastOutput;
|
||||
|
||||
PORT_Memcpy(data, V(rng), VSize(rng));
|
||||
while (no_of_returned_bytes) {
|
||||
@ -295,7 +297,16 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
|
||||
|
||||
SHA256_Begin(&ctx);
|
||||
SHA256_Update(&ctx, data, sizeof data);
|
||||
SHA256_End(&ctx, returned_bytes, &len, no_of_returned_bytes);
|
||||
SHA256_End(&ctx, thisHash, &len, SHA256_LENGTH);
|
||||
if (PORT_Memcmp(lastHash, thisHash, len) == 0) {
|
||||
rng->isValid = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
if (no_of_returned_bytes < SHA256_LENGTH) {
|
||||
len = no_of_returned_bytes;
|
||||
}
|
||||
PORT_Memcpy(returned_bytes, thisHash, len);
|
||||
lastHash = returned_bytes;
|
||||
returned_bytes += len;
|
||||
no_of_returned_bytes -= len;
|
||||
/* The carry parameter is a bool (increment or not).
|
||||
@ -303,7 +314,9 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
|
||||
carry = no_of_returned_bytes;
|
||||
PRNG_ADD_CARRY_ONLY(data, (sizeof data)- 1, carry);
|
||||
}
|
||||
PORT_Memcpy(rng->lastOutput, thisHash, SHA256_LENGTH);
|
||||
PORT_Memset(data, 0, sizeof data);
|
||||
PORT_Memset(thisHash, 0, sizeof thisHash);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -347,8 +360,13 @@ prng_generateNewBytes(RNGContext *rng,
|
||||
}
|
||||
|
||||
if (no_of_returned_bytes == SHA256_LENGTH) {
|
||||
/* short_cut to hashbuf and save a copy and a clear */
|
||||
/* short_cut to hashbuf and a couple of copies and clears */
|
||||
SHA256_HashBuf(returned_bytes, V(rng), VSize(rng) );
|
||||
/* continuous rng check */
|
||||
if (memcmp(rng->lastOutput, returned_bytes, SHA256_LENGTH) == 0) {
|
||||
rng->isValid = PR_FALSE;
|
||||
}
|
||||
PORT_Memcpy(rng->lastOutput, returned_bytes, sizeof rng->lastOutput);
|
||||
} else {
|
||||
prng_Hashgen(rng, returned_bytes, no_of_returned_bytes);
|
||||
}
|
||||
@ -362,13 +380,12 @@ prng_generateNewBytes(RNGContext *rng,
|
||||
carry = 1;
|
||||
PRNG_ADD_CARRY_ONLY(rng->reseed_counter,(sizeof rng->reseed_counter)-1, carry);
|
||||
|
||||
/* continuous rng check */
|
||||
if (memcmp(V(rng), rng->oldV, sizeof rng->oldV) == 0) {
|
||||
rng->isValid = PR_FALSE;
|
||||
/* if the prng failed, don't return any output, signal softoken */
|
||||
if (!rng->isValid) {
|
||||
PORT_Memset(returned_bytes, 0, no_of_returned_bytes);
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_Memcpy(rng->oldV, V(rng), sizeof rng->oldV);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
@ -61,16 +61,16 @@ ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
|
||||
printf("\n");
|
||||
|
||||
if (k1 != NULL) {
|
||||
mp_tohex(k1, mpstr);
|
||||
mp_tohex((mp_int*)k1, mpstr);
|
||||
printf("ec_points_mul: scalar k1: %s\n", mpstr);
|
||||
mp_todecimal(k1, mpstr);
|
||||
mp_todecimal((mp_int*)k1, mpstr);
|
||||
printf("ec_points_mul: scalar k1: %s (dec)\n", mpstr);
|
||||
}
|
||||
|
||||
if (k2 != NULL) {
|
||||
mp_tohex(k2, mpstr);
|
||||
mp_tohex((mp_int*)k2, mpstr);
|
||||
printf("ec_points_mul: scalar k2: %s\n", mpstr);
|
||||
mp_todecimal(k2, mpstr);
|
||||
mp_todecimal((mp_int*)k2, mpstr);
|
||||
printf("ec_points_mul: scalar k2: %s (dec)\n", mpstr);
|
||||
}
|
||||
|
||||
@ -376,7 +376,7 @@ cleanup:
|
||||
rv = SECFailure;
|
||||
}
|
||||
if (rv != SECSuccess && privKeyBytes) {
|
||||
PORT_Free(privKeyBytes);
|
||||
PORT_ZFree(privKeyBytes,2*len);
|
||||
privKeyBytes = NULL;
|
||||
}
|
||||
return privKeyBytes;
|
||||
@ -1075,7 +1075,7 @@ cleanup:
|
||||
mp_clear(&v);
|
||||
mp_clear(&n);
|
||||
|
||||
if (pointC.data) SECITEM_FreeItem(&pointC, PR_FALSE);
|
||||
if (pointC.data) SECITEM_ZfreeItem(&pointC, PR_FALSE);
|
||||
if (err) {
|
||||
MP_TO_SEC_ERROR(err);
|
||||
rv = SECFailure;
|
||||
|
@ -5,10 +5,10 @@
|
||||
/* This source file is meant to be included by other source files
|
||||
* (ecp_fp###.c, where ### is one of 160, 192, 224) and should not
|
||||
* constitute an independent compilation unit. It requires the following
|
||||
* preprocessor definitions be made: ECFP_BSIZE - the number of bits in
|
||||
* the field's prime
|
||||
* preprocessor definitions be made:
|
||||
* ECFP_BSIZE - the number of bits in the field's prime
|
||||
* ECFP_NUMDOUBLES - the number of doubles to store one
|
||||
* multi-precision integer in floating point
|
||||
* multi-precision integer in floating point */
|
||||
|
||||
/* Adds a prefix to a given token to give a unique token name. Prefixes
|
||||
* with "ecfp" + ECFP_BSIZE + "_". e.g. if ECFP_BSIZE = 160, then
|
||||
|
1774
security/nss/lib/freebl/fipsfreebl.c
Normal file
1774
security/nss/lib/freebl/fipsfreebl.c
Normal file
File diff suppressed because it is too large
Load Diff
34
security/nss/lib/freebl/freebl_hash_vector.def
Normal file
34
security/nss/lib/freebl/freebl_hash_vector.def
Normal file
@ -0,0 +1,34 @@
|
||||
;+#
|
||||
;+# 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/.
|
||||
;+#
|
||||
;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
|
||||
;+# 1. For all unix platforms, the string ";-" means "remove this line"
|
||||
;+# 2. For all unix platforms, the string " DATA " will be removed from any
|
||||
;+# line on which it occurs.
|
||||
;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
|
||||
;+# On AIX, lines containing ";+" will be removed.
|
||||
;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
|
||||
;+# 5. For all unix platforms, after the above processing has taken place,
|
||||
;+# all characters after the first ";" on the line will be removed.
|
||||
;+# And for AIX, the first ";" will also be removed.
|
||||
;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
|
||||
;+# directives are hidden behind ";", ";+", and ";-"
|
||||
;+
|
||||
;+NSSprivate_3.11 { # NSS 3.11 release
|
||||
;+ global:
|
||||
LIBRARY freebl3 ;-
|
||||
EXPORTS ;-
|
||||
FREEBL_GetVector;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
;+NSSprivate_3.16 { # NSS 3.11 release
|
||||
;+ global:
|
||||
LIBRARY freebl3 ;-
|
||||
EXPORTS ;-
|
||||
NSSLOW_GetVector;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
@ -192,9 +192,7 @@ gcmHash_DestroyContext(gcmHashContext *ghash, PRBool freeit)
|
||||
mp_clear(&ghash->H);
|
||||
mp_clear(&ghash->X);
|
||||
mp_clear(&ghash->C_i);
|
||||
MP_DIGITS(&ghash->H) = 0;
|
||||
MP_DIGITS(&ghash->X) = 0;
|
||||
MP_DIGITS(&ghash->C_i) = 0;
|
||||
PORT_Memset(ghash, 0, sizeof(gcmHashContext));
|
||||
if (freeit) {
|
||||
PORT_Free(ghash);
|
||||
}
|
||||
@ -267,6 +265,7 @@ gcm_HashMult(gcmHashContext *ghash, const unsigned char *buf,
|
||||
}
|
||||
rv = SECSuccess;
|
||||
cleanup:
|
||||
PORT_Memset(tmp_buf, 0, sizeof(tmp_buf));
|
||||
if (rv != SECSuccess) {
|
||||
MP_TO_SEC_ERROR(err);
|
||||
}
|
||||
@ -366,6 +365,7 @@ cleanup:
|
||||
static void
|
||||
gcmHash_DestroyContext(gcmHashContext *ghash, PRBool freeit)
|
||||
{
|
||||
PORT_Memset(ghash, 0, sizeof(gcmHashContext));
|
||||
if (freeit) {
|
||||
PORT_Free(ghash);
|
||||
}
|
||||
@ -423,6 +423,7 @@ gcm_HashMult(gcmHashContext *ghash, const unsigned char *buf,
|
||||
}
|
||||
GCM_TRACE_X(ghash, "X%d = ")
|
||||
}
|
||||
PORT_Memset(C_i, 0, sizeof(C_i));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
@ -538,26 +539,30 @@ gcmHash_Final(gcmHashContext *ghash, unsigned char *outbuf,
|
||||
|
||||
rv = gcmHash_Sync(ghash, blocksize);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rv = gcm_HashMult(ghash, ghash->counterBuf, (GCM_HASH_LEN_LEN*2)/blocksize,
|
||||
blocksize);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
GCM_TRACE_X(ghash, "GHASH(H,A,C) = ")
|
||||
|
||||
rv = gcm_getX(ghash, T, blocksize);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (maxout > blocksize) maxout = blocksize;
|
||||
PORT_Memcpy(outbuf, T, maxout);
|
||||
*outlen = maxout;
|
||||
return SECSuccess;
|
||||
rv = SECSuccess;
|
||||
|
||||
cleanup:
|
||||
PORT_Memset(T, 0, sizeof(T));
|
||||
return rv;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
@ -695,6 +700,8 @@ GCM_DestroyContext(GCMContext *gcm, PRBool freeit)
|
||||
* allocated data (like mp_int's) */
|
||||
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
|
||||
gcmHash_DestroyContext(&gcm->ghash_context, PR_FALSE);
|
||||
PORT_Memset(&gcm->tagBits, 0, sizeof(gcm->tagBits));
|
||||
PORT_Memset(gcm->tagKey, 0, sizeof(gcm->tagKey));
|
||||
if (freeit) {
|
||||
PORT_Free(gcm);
|
||||
}
|
||||
@ -838,8 +845,10 @@ GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
|
||||
if (NSS_SecureMemcmp(tag, intag, tagBytes) != 0) {
|
||||
/* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
PORT_Memset(tag, 0, sizeof(tag));
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_Memset(tag, 0, sizeof(tag));
|
||||
/* finish the decryption */
|
||||
return CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
|
||||
inbuf, inlen, blocksize);
|
||||
|
@ -12,7 +12,7 @@ extern int FREEBL_InitStubs(void);
|
||||
#include "loader.h"
|
||||
#include "alghmac.h"
|
||||
#include "hmacct.h"
|
||||
|
||||
#include "blapii.h"
|
||||
|
||||
static const struct FREEBLVectorStr vector =
|
||||
{
|
||||
@ -299,15 +299,54 @@ static const struct FREEBLVectorStr vector =
|
||||
/* End of Version 3.018 */
|
||||
};
|
||||
|
||||
|
||||
|
||||
const FREEBLVector *
|
||||
FREEBL_GetVector(void)
|
||||
{
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
SECStatus rv;
|
||||
#endif
|
||||
|
||||
#define NSS_VERSION_VARIABLE __nss_freebl_version
|
||||
#include "verref.h"
|
||||
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
FREEBL_InitStubs();
|
||||
/* this entry point is only valid if nspr and nss-util has been loaded */
|
||||
rv = FREEBL_InitStubs();
|
||||
if (rv != SECSuccess) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
/* make sure the Full self tests have been run before continuing */
|
||||
BL_POSTRan(PR_FALSE);
|
||||
|
||||
return &vector;
|
||||
}
|
||||
|
||||
#ifdef FREEBL_LOWHASH
|
||||
static const struct NSSLOWVectorStr nssvector =
|
||||
{
|
||||
sizeof nssvector,
|
||||
NSSLOW_VERSION,
|
||||
FREEBL_GetVector,
|
||||
NSSLOW_Init,
|
||||
NSSLOW_Shutdown,
|
||||
NSSLOW_Reset,
|
||||
NSSLOWHASH_NewContext,
|
||||
NSSLOWHASH_Begin,
|
||||
NSSLOWHASH_Update,
|
||||
NSSLOWHASH_End,
|
||||
NSSLOWHASH_Destroy,
|
||||
NSSLOWHASH_Length
|
||||
};
|
||||
|
||||
const NSSLOWVector *
|
||||
NSSLOW_GetVector(void)
|
||||
{
|
||||
/* POST check and stub init happens in FREEBL_GetVector() and
|
||||
* NSSLOW_Init() respectively */
|
||||
return &nssvector;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -10,93 +10,7 @@
|
||||
#include "prerror.h"
|
||||
#include "prinit.h"
|
||||
#include "prenv.h"
|
||||
|
||||
static const char* default_name =
|
||||
SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX;
|
||||
|
||||
/* getLibName() returns the name of the library to load. */
|
||||
|
||||
#if defined(SOLARIS) && defined(__sparc)
|
||||
#include <stddef.h>
|
||||
#include <strings.h>
|
||||
#include <sys/systeminfo.h>
|
||||
|
||||
|
||||
#if defined(NSS_USE_64)
|
||||
|
||||
const static char fpu_hybrid_shared_lib[] = "libfreebl_64fpu_3.so";
|
||||
const static char int_hybrid_shared_lib[] = "libfreebl_64int_3.so";
|
||||
const static char non_hybrid_shared_lib[] = "libfreebl_64fpu_3.so";
|
||||
|
||||
const static char int_hybrid_isa[] = "sparcv9";
|
||||
const static char fpu_hybrid_isa[] = "sparcv9+vis";
|
||||
|
||||
#else
|
||||
|
||||
const static char fpu_hybrid_shared_lib[] = "libfreebl_32fpu_3.so";
|
||||
const static char int_hybrid_shared_lib[] = "libfreebl_32int64_3.so";
|
||||
/* This was for SPARC V8, now obsolete. */
|
||||
const static char *const non_hybrid_shared_lib = NULL;
|
||||
|
||||
const static char int_hybrid_isa[] = "sparcv8plus";
|
||||
const static char fpu_hybrid_isa[] = "sparcv8plus+vis";
|
||||
|
||||
#endif
|
||||
|
||||
static const char *
|
||||
getLibName(void)
|
||||
{
|
||||
char * found_int_hybrid;
|
||||
char * found_fpu_hybrid;
|
||||
long buflen;
|
||||
char buf[256];
|
||||
|
||||
buflen = sysinfo(SI_ISALIST, buf, sizeof buf);
|
||||
if (buflen <= 0)
|
||||
return NULL;
|
||||
/* sysinfo output is always supposed to be NUL terminated, but ... */
|
||||
if (buflen < sizeof buf)
|
||||
buf[buflen] = '\0';
|
||||
else
|
||||
buf[(sizeof buf) - 1] = '\0';
|
||||
/* The ISA list is a space separated string of names of ISAs and
|
||||
* ISA extensions, in order of decreasing performance.
|
||||
* There are two different ISAs with which NSS's crypto code can be
|
||||
* accelerated. If both are in the list, we take the first one.
|
||||
* If one is in the list, we use it, and if neither then we use
|
||||
* the base unaccelerated code.
|
||||
*/
|
||||
found_int_hybrid = strstr(buf, int_hybrid_isa);
|
||||
found_fpu_hybrid = strstr(buf, fpu_hybrid_isa);
|
||||
if (found_fpu_hybrid &&
|
||||
(!found_int_hybrid ||
|
||||
(found_int_hybrid - found_fpu_hybrid) >= 0)) {
|
||||
return fpu_hybrid_shared_lib;
|
||||
}
|
||||
if (found_int_hybrid) {
|
||||
return int_hybrid_shared_lib;
|
||||
}
|
||||
return non_hybrid_shared_lib;
|
||||
}
|
||||
|
||||
#elif defined(HPUX) && !defined(NSS_USE_64) && !defined(__ia64)
|
||||
#include <unistd.h>
|
||||
|
||||
/* This code tests to see if we're running on a PA2.x CPU.
|
||||
** It returns true (1) if so, and false (0) otherwise.
|
||||
*/
|
||||
static const char *
|
||||
getLibName(void)
|
||||
{
|
||||
long cpu = sysconf(_SC_CPU_VERSION);
|
||||
return (cpu == CPU_PA_RISC2_0)
|
||||
? "libfreebl_32fpu_3.sl"
|
||||
: "libfreebl_32int_3.sl" ;
|
||||
}
|
||||
#else
|
||||
/* default case, for platforms/ABIs that have only one freebl shared lib. */
|
||||
static const char * getLibName(void) { return default_name; }
|
||||
#endif
|
||||
#include "blname.c"
|
||||
|
||||
#include "prio.h"
|
||||
#include "prprf.h"
|
||||
@ -106,7 +20,7 @@ static const char * getLibName(void) { return default_name; }
|
||||
static const char *NameOfThisSharedLib =
|
||||
SHLIB_PREFIX"softokn"SOFTOKEN_SHLIB_VERSION"."SHLIB_SUFFIX;
|
||||
|
||||
static PRLibrary* blLib;
|
||||
static PRLibrary* blLib = NULL;
|
||||
|
||||
#define LSB(x) ((x)&0xff)
|
||||
#define MSB(x) ((x)>>8)
|
||||
@ -149,12 +63,12 @@ freebl_LoadDSO( void )
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
{
|
||||
if (blLib) {
|
||||
PRStatus status = PR_UnloadLibrary(blLib);
|
||||
PORT_Assert(PR_SUCCESS == status);
|
||||
}
|
||||
#else
|
||||
PR_UnloadLibrary(blLib);
|
||||
if (blLib) PR_UnloadLibrary(blLib);
|
||||
#endif
|
||||
}
|
||||
return PR_FAILURE;
|
||||
@ -2184,3 +2098,4 @@ ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx,
|
||||
ctx, output, outputLen, maxOutputLen, input, inputLen,
|
||||
nonce, nonceLen, ad, adLen);
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "blapi.h"
|
||||
|
||||
|
||||
#define FREEBL_VERSION 0x0312
|
||||
|
||||
struct FREEBLVectorStr {
|
||||
@ -740,8 +741,43 @@ struct FREEBLVectorStr {
|
||||
|
||||
typedef struct FREEBLVectorStr FREEBLVector;
|
||||
|
||||
#ifdef FREEBL_LOWHASH
|
||||
#include "nsslowhash.h"
|
||||
|
||||
#define NSSLOW_VERSION 0x0300
|
||||
|
||||
struct NSSLOWVectorStr {
|
||||
unsigned short length; /* of this struct in bytes */
|
||||
unsigned short version; /* of this struct. */
|
||||
const FREEBLVector *(*p_FREEBL_GetVector)(void);
|
||||
NSSLOWInitContext *(*p_NSSLOW_Init)(void);
|
||||
void (*p_NSSLOW_Shutdown)(NSSLOWInitContext *context);
|
||||
void (*p_NSSLOW_Reset)(NSSLOWInitContext *context);
|
||||
NSSLOWHASHContext *(*p_NSSLOWHASH_NewContext)(
|
||||
NSSLOWInitContext *initContext,
|
||||
HASH_HashType hashType);
|
||||
void (*p_NSSLOWHASH_Begin)(NSSLOWHASHContext *context);
|
||||
void (*p_NSSLOWHASH_Update)(NSSLOWHASHContext *context,
|
||||
const unsigned char *buf,
|
||||
unsigned int len);
|
||||
void (*p_NSSLOWHASH_End)(NSSLOWHASHContext *context,
|
||||
unsigned char *buf,
|
||||
unsigned int *ret, unsigned int len);
|
||||
void (*p_NSSLOWHASH_Destroy)(NSSLOWHASHContext *context);
|
||||
unsigned int (*p_NSSLOWHASH_Length)(NSSLOWHASHContext *context);
|
||||
};
|
||||
|
||||
typedef struct NSSLOWVectorStr NSSLOWVector;
|
||||
#endif
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
#ifdef FREEBL_LOWHASH
|
||||
typedef const NSSLOWVector * NSSLOWGetVectorFn(void);
|
||||
|
||||
extern NSSLOWGetVectorFn NSSLOW_GetVector;
|
||||
#endif
|
||||
|
||||
typedef const FREEBLVector * FREEBLGetVectorFn(void);
|
||||
|
||||
extern FREEBLGetVectorFn FREEBL_GetVector;
|
||||
|
206
security/nss/lib/freebl/lowhash_vector.c
Normal file
206
security/nss/lib/freebl/lowhash_vector.c
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* loader.c - load platform dependent DSO containing freebl implementation.
|
||||
*
|
||||
* 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/. */
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
#include "loader.h"
|
||||
#include "prmem.h"
|
||||
#include "prerror.h"
|
||||
#include "prinit.h"
|
||||
#include "prenv.h"
|
||||
#include "blname.c"
|
||||
|
||||
#include "prio.h"
|
||||
#include "prprf.h"
|
||||
#include <stdio.h>
|
||||
#include "prsystem.h"
|
||||
#include "nsslowhash.h"
|
||||
#include <dlfcn.h>
|
||||
#include "pratom.h"
|
||||
|
||||
|
||||
static PRLibrary* blLib;
|
||||
|
||||
#define LSB(x) ((x)&0xff)
|
||||
#define MSB(x) ((x)>>8)
|
||||
|
||||
static const NSSLOWVector *vector;
|
||||
static const char *libraryName = NULL;
|
||||
|
||||
/* pretty much only glibc uses this, make sure we don't have any depenencies
|
||||
* on nspr.. */
|
||||
#undef PORT_Alloc
|
||||
#undef PORT_Free
|
||||
#define PORT_Alloc malloc
|
||||
#define PR_Malloc malloc
|
||||
#define PORT_Free free
|
||||
#define PR_Free free
|
||||
#define PR_GetDirectorySeparator() '/'
|
||||
#define PR_LoadLibraryWithFlags(libspec,flags) \
|
||||
(PRLibrary*)dlopen(libSpec.value.pathname,RTLD_NOW|RTLD_LOCAL)
|
||||
#define PR_GetLibraryFilePathname(name,addr) \
|
||||
freebl_lowhash_getLibraryFilePath(addr)
|
||||
|
||||
static char *
|
||||
freebl_lowhash_getLibraryFilePath(void *addr)
|
||||
{
|
||||
Dl_info dli;
|
||||
if (dladdr(addr, &dli) == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return strdup(dli.dli_fname);
|
||||
}
|
||||
|
||||
/*
|
||||
* The PR_LoadLibraryWithFlags call above defines this variable away, so we
|
||||
* don't need it..
|
||||
*/
|
||||
#ifdef nodef
|
||||
static const char *NameOfThisSharedLib =
|
||||
SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX;
|
||||
#endif
|
||||
|
||||
#include "genload.c"
|
||||
|
||||
|
||||
/* This function must be run only once. */
|
||||
/* determine if hybrid platform, then actually load the DSO. */
|
||||
static PRStatus
|
||||
freebl_LoadDSO( void )
|
||||
{
|
||||
PRLibrary * handle;
|
||||
const char * name = getLibName();
|
||||
|
||||
if (!name) {
|
||||
/*PR_SetError(PR_LOAD_LIBRARY_ERROR,0); */
|
||||
return PR_FAILURE;
|
||||
}
|
||||
handle = loader_LoadLibrary(name);
|
||||
if (handle) {
|
||||
void *address = dlsym(handle, "NSSLOW_GetVector");
|
||||
if (address) {
|
||||
NSSLOWGetVectorFn * getVector = (NSSLOWGetVectorFn *)address;
|
||||
const NSSLOWVector * dsoVector = getVector();
|
||||
if (dsoVector) {
|
||||
unsigned short dsoVersion = dsoVector->version;
|
||||
unsigned short myVersion = NSSLOW_VERSION;
|
||||
if (MSB(dsoVersion) == MSB(myVersion) &&
|
||||
LSB(dsoVersion) >= LSB(myVersion) &&
|
||||
dsoVector->length >= sizeof(NSSLOWVector)) {
|
||||
vector = dsoVector;
|
||||
libraryName = name;
|
||||
blLib = handle;
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
(void)dlclose(handle);
|
||||
}
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
static PRCallOnceType loadFreeBLOnce;
|
||||
|
||||
static PRStatus
|
||||
freebl_RunLoaderOnce( void )
|
||||
{
|
||||
/* Don't have NSPR, so can use the real PR_CallOnce, implement a stripped
|
||||
* down version. */
|
||||
if (loadFreeBLOnce.initialized) {
|
||||
return loadFreeBLOnce.status;
|
||||
}
|
||||
if (__sync_lock_test_and_set(&loadFreeBLOnce.inProgress,1) == 0) {
|
||||
loadFreeBLOnce.status = freebl_LoadDSO();
|
||||
loadFreeBLOnce.initialized = 1;
|
||||
} else {
|
||||
/* shouldn't have a lot of takers on the else clause, which is good
|
||||
* since we don't have condition variables yet.
|
||||
* 'initialized' only ever gets set (not cleared) so we don't
|
||||
* need the traditional locks. */
|
||||
while (!loadFreeBLOnce.initialized) {
|
||||
sleep(1); /* don't have condition variables, just give up the CPU */
|
||||
}
|
||||
}
|
||||
|
||||
return loadFreeBLOnce.status;
|
||||
}
|
||||
|
||||
const FREEBLVector *FREEBL_GetVector(void)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return NULL;
|
||||
return (vector->p_FREEBL_GetVector)();
|
||||
}
|
||||
|
||||
NSSLOWInitContext *NSSLOW_Init(void)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return NULL;
|
||||
return (vector->p_NSSLOW_Init)();
|
||||
}
|
||||
|
||||
void NSSLOW_Shutdown(NSSLOWInitContext *context)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return;
|
||||
(vector->p_NSSLOW_Shutdown)(context);
|
||||
}
|
||||
|
||||
void NSSLOW_Reset(NSSLOWInitContext *context)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return;
|
||||
(vector->p_NSSLOW_Reset)(context);
|
||||
}
|
||||
|
||||
NSSLOWHASHContext *NSSLOWHASH_NewContext(
|
||||
NSSLOWInitContext *initContext,
|
||||
HASH_HashType hashType)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return NULL;
|
||||
return (vector->p_NSSLOWHASH_NewContext)(initContext, hashType);
|
||||
}
|
||||
|
||||
void NSSLOWHASH_Begin(NSSLOWHASHContext *context)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return;
|
||||
(vector->p_NSSLOWHASH_Begin)(context);
|
||||
}
|
||||
|
||||
void NSSLOWHASH_Update(NSSLOWHASHContext *context,
|
||||
const unsigned char *buf,
|
||||
unsigned int len)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return;
|
||||
(vector->p_NSSLOWHASH_Update)(context, buf, len);
|
||||
}
|
||||
|
||||
void NSSLOWHASH_End(NSSLOWHASHContext *context,
|
||||
unsigned char *buf,
|
||||
unsigned int *ret, unsigned int len)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return;
|
||||
(vector->p_NSSLOWHASH_End)(context, buf, ret, len);
|
||||
}
|
||||
|
||||
void NSSLOWHASH_Destroy(NSSLOWHASHContext *context)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return;
|
||||
(vector->p_NSSLOWHASH_Destroy)(context);
|
||||
}
|
||||
|
||||
unsigned int NSSLOWHASH_Length(NSSLOWHASHContext *context)
|
||||
{
|
||||
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
|
||||
return -1;
|
||||
return (vector->p_NSSLOWHASH_Length)(context);
|
||||
}
|
||||
|
@ -10,6 +10,30 @@ CORE_DEPTH = ../..
|
||||
|
||||
MODULE = nss
|
||||
|
||||
# copied from Linux.mk. We have a chicken and egg issue here. We need to set
|
||||
# Library name before we call the platform code in coreconf, but we need to
|
||||
# Pick up the automatic setting of FREEBL_LOWHASH before we can set the
|
||||
# Library name... so for now we mimic the code in Linux.mk to get the
|
||||
# automatic setting early...
|
||||
#
|
||||
# On Linux 2.6 or later, build libfreebl3.so with no NSPR and libnssutil3.so
|
||||
# dependencies by default. Set FREEBL_NO_DEPEND to 0 in the environment to
|
||||
# override this.
|
||||
#
|
||||
#
|
||||
include $(CORE_DEPTH)/coreconf/arch.mk
|
||||
ifeq ($(OS_ARCH),Linux)
|
||||
ifneq ($(OS_TARGET),Android)
|
||||
ifeq (2.6,$(firstword $(sort 2.6 $(OS_RELEASE))))
|
||||
ifndef FREEBL_NO_DEPEND
|
||||
FREEBL_NO_DEPEND = 1
|
||||
FREEBL_LOWHASH = 1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
LIBRARY_NAME = freebl
|
||||
LIBRARY_VERSION = 3
|
||||
|
||||
@ -29,6 +53,13 @@ ifdef FREEBL_CHILD_BUILD
|
||||
ifdef USE_ABI64_FPU
|
||||
LIBRARY_NAME = freebl_64fpu
|
||||
endif
|
||||
ifdef FREEBL_LOWHASH
|
||||
LIBRARY_NAME = freeblpriv
|
||||
endif
|
||||
ifdef USE_STUB_BUILD
|
||||
# for the stub build, reset name to the default (from freeblpriv)
|
||||
LIBRARY_NAME = freebl
|
||||
endif
|
||||
endif
|
||||
|
||||
# if the library name contains _, we prefix the version with _
|
||||
@ -105,6 +136,7 @@ CSRCS = \
|
||||
chacha20poly1305.c \
|
||||
cts.c \
|
||||
ctr.c \
|
||||
fipsfreebl.c \
|
||||
gcm.c \
|
||||
hmacct.c \
|
||||
rijndael.c \
|
||||
|
@ -545,7 +545,9 @@ mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
|
||||
rem = DIGIT(a, 0) & mask;
|
||||
|
||||
if(q) {
|
||||
mp_copy(a, q);
|
||||
if((res = mp_copy(a, q)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
s_mp_div_2d(q, pow);
|
||||
}
|
||||
|
||||
@ -1314,8 +1316,8 @@ mp_err mp_sqrt(const mp_int *a, mp_int *b)
|
||||
|
||||
for(;;) {
|
||||
/* t = (x * x) - a */
|
||||
mp_copy(&x, &t); /* can't fail, t is big enough for original x */
|
||||
if((res = mp_sqr(&t, &t)) != MP_OKAY ||
|
||||
if((res = mp_copy(&x, &t)) != MP_OKAY ||
|
||||
(res = mp_sqr(&t, &t)) != MP_OKAY ||
|
||||
(res = mp_sub(&t, a, &t)) != MP_OKAY)
|
||||
goto CLEANUP;
|
||||
|
||||
@ -1488,8 +1490,10 @@ mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c
|
||||
mp_set(&s, 1);
|
||||
|
||||
/* mu = b^2k / m */
|
||||
s_mp_add_d(&mu, 1);
|
||||
s_mp_lshd(&mu, 2 * USED(m));
|
||||
if((res = s_mp_add_d(&mu, 1)) != MP_OKAY)
|
||||
goto CLEANUP;
|
||||
if((res = s_mp_lshd(&mu, 2 * USED(m))) != MP_OKAY)
|
||||
goto CLEANUP;
|
||||
if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY)
|
||||
goto CLEANUP;
|
||||
|
||||
@ -1675,7 +1679,7 @@ int mp_cmp(const mp_int *a, const mp_int *b)
|
||||
Compares |a| <=> |b|, and returns an appropriate comparison result
|
||||
*/
|
||||
|
||||
int mp_cmp_mag(mp_int *a, mp_int *b)
|
||||
int mp_cmp_mag(const mp_int *a, const mp_int *b)
|
||||
{
|
||||
ARGCHK(a != NULL && b != NULL, MP_EQ);
|
||||
|
||||
@ -1700,7 +1704,8 @@ int mp_cmp_int(const mp_int *a, long z)
|
||||
|
||||
ARGCHK(a != NULL, MP_EQ);
|
||||
|
||||
mp_init(&tmp); mp_set_int(&tmp, z);
|
||||
mp_init(&tmp);
|
||||
mp_set_int(&tmp, z);
|
||||
out = mp_cmp(a, &tmp);
|
||||
mp_clear(&tmp);
|
||||
|
||||
@ -1937,8 +1942,8 @@ mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y
|
||||
MP_CHECKOK( s_mp_mul_2d(&gx,n) );
|
||||
}
|
||||
|
||||
mp_copy(&xc, &u);
|
||||
mp_copy(&yc, &v);
|
||||
MP_CHECKOK(mp_copy(&xc, &u));
|
||||
MP_CHECKOK(mp_copy(&yc, &v));
|
||||
mp_set(&A, 1); mp_set(&D, 1);
|
||||
|
||||
/* Loop through binary GCD algorithm */
|
||||
@ -4275,7 +4280,7 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
|
||||
*/
|
||||
for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) {
|
||||
--q_msd;
|
||||
s_mp_sub(&t, div); /* t -= div */
|
||||
MP_CHECKOK(s_mp_sub(&t, div)); /* t -= div */
|
||||
}
|
||||
if (i < 0) {
|
||||
res = MP_RANGE;
|
||||
|
@ -219,7 +219,7 @@ mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c);
|
||||
int mp_cmp_z(const mp_int *a);
|
||||
int mp_cmp_d(const mp_int *a, mp_digit d);
|
||||
int mp_cmp(const mp_int *a, const mp_int *b);
|
||||
int mp_cmp_mag(mp_int *a, mp_int *b);
|
||||
int mp_cmp_mag(const mp_int *a, const mp_int *b);
|
||||
int mp_cmp_int(const mp_int *a, long z);
|
||||
int mp_isodd(const mp_int *a);
|
||||
int mp_iseven(const mp_int *a);
|
||||
|
@ -21,15 +21,6 @@
|
||||
#endif
|
||||
#include <stddef.h> /* ptrdiff_t */
|
||||
|
||||
/* if MP_CHAR_STORE_SLOW is defined, we */
|
||||
/* need to know endianness of this platform. */
|
||||
#ifdef MP_CHAR_STORE_SLOW
|
||||
#if !defined(MP_IS_BIG_ENDIAN) && !defined(MP_IS_LITTLE_ENDIAN)
|
||||
#error "You must define MP_IS_BIG_ENDIAN or MP_IS_LITTLE_ENDIAN\n" \
|
||||
" if you define MP_CHAR_STORE_SLOW."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define STATIC
|
||||
|
||||
#define MAX_ODD_INTS 32 /* 2 ** (WINDOW_BITS - 1) */
|
||||
@ -506,17 +497,16 @@ mp_err mp_set_safe_modexp(int value)
|
||||
#ifdef MP_USING_CACHE_SAFE_MOD_EXP
|
||||
#define WEAVE_WORD_SIZE 4
|
||||
|
||||
#ifndef MP_CHAR_STORE_SLOW
|
||||
/*
|
||||
* mpi_to_weave takes an array of bignums, a matrix in which each bignum
|
||||
* occupies all the columns of a row, and transposes it into a matrix in
|
||||
* mpi_to_weave takes an array of bignums, a matrix in which each bignum
|
||||
* occupies all the columns of a row, and transposes it into a matrix in
|
||||
* which each bignum occupies a column of every row. The first row of the
|
||||
* input matrix becomes the first column of the output matrix. The n'th
|
||||
* row of input becomes the n'th column of output. The input data is said
|
||||
* to be "interleaved" or "woven" into the output matrix.
|
||||
*
|
||||
* The array of bignums is left in this woven form. Each time a single
|
||||
* bignum value is needed, it is recreated by fetching the n'th column,
|
||||
* bignum value is needed, it is recreated by fetching the n'th column,
|
||||
* forming a single row which is the new bignum.
|
||||
*
|
||||
* The purpose of this interleaving is make it impossible to determine which
|
||||
@ -526,46 +516,37 @@ mp_err mp_set_safe_modexp(int value)
|
||||
* The weaving function does not transpose the entire input matrix in one call.
|
||||
* It transposes 4 rows of mp_ints into their respective columns of output.
|
||||
*
|
||||
* There are two different implementations of the weaving and unweaving code
|
||||
* in this file. One uses byte loads and stores. The second uses loads and
|
||||
* stores of mp_weave_word size values. The weaved forms of these two
|
||||
* implementations differ. Consequently, each one has its own explanation.
|
||||
*
|
||||
* Here is the explanation for the byte-at-a-time implementation.
|
||||
*
|
||||
* This implementation treats each mp_int bignum as an array of bytes,
|
||||
* rather than as an array of mp_digits. It stores those bytes as a
|
||||
* column of bytes in the output matrix. It doesn't care if the machine
|
||||
* uses big-endian or little-endian byte ordering within mp_digits.
|
||||
* The first byte of the mp_digit array becomes the first byte in the output
|
||||
* column, regardless of whether that byte is the MSB or LSB of the mp_digit.
|
||||
* This implementation treats each mp_int bignum as an array of mp_digits,
|
||||
* It stores those bytes as a column of mp_digits in the output matrix. It
|
||||
* doesn't care if the machine uses big-endian or little-endian byte ordering
|
||||
* within mp_digits.
|
||||
*
|
||||
* "bignums" is an array of mp_ints.
|
||||
* It points to four rows, four mp_ints, a subset of a larger array of mp_ints.
|
||||
*
|
||||
* "weaved" is the weaved output matrix.
|
||||
* "weaved" is the weaved output matrix.
|
||||
* The first byte of bignums[0] is stored in weaved[0].
|
||||
*
|
||||
* "nBignums" is the total number of bignums in the array of which "bignums"
|
||||
* is a part.
|
||||
*
|
||||
* "nDigits" is the size in mp_digits of each mp_int in the "bignums" array.
|
||||
* mp_ints that use less than nDigits digits are logically padded with zeros
|
||||
* "nBignums" is the total number of bignums in the array of which "bignums"
|
||||
* is a part.
|
||||
*
|
||||
* "nDigits" is the size in mp_digits of each mp_int in the "bignums" array.
|
||||
* mp_ints that use less than nDigits digits are logically padded with zeros
|
||||
* while being stored in the weaved array.
|
||||
*/
|
||||
mp_err mpi_to_weave(const mp_int *bignums,
|
||||
unsigned char *weaved,
|
||||
mp_size nDigits, /* in each mp_int of input */
|
||||
mp_size nBignums) /* in the entire source array */
|
||||
mp_err mpi_to_weave(const mp_int *bignums,
|
||||
mp_digit *weaved,
|
||||
mp_size nDigits, /* in each mp_int of input */
|
||||
mp_size nBignums) /* in the entire source array */
|
||||
{
|
||||
mp_size i;
|
||||
unsigned char * endDest = weaved + (nDigits * nBignums * sizeof(mp_digit));
|
||||
mp_digit *endDest = weaved + (nDigits * nBignums);
|
||||
|
||||
for (i=0; i < WEAVE_WORD_SIZE; i++) {
|
||||
mp_size used = MP_USED(&bignums[i]);
|
||||
unsigned char *pSrc = (unsigned char *)MP_DIGITS(&bignums[i]);
|
||||
unsigned char *endSrc = pSrc + (used * sizeof(mp_digit));
|
||||
unsigned char *pDest = weaved + i;
|
||||
mp_digit *pSrc = MP_DIGITS(&bignums[i]);
|
||||
mp_digit *endSrc = pSrc + used;
|
||||
mp_digit *pDest = weaved + i;
|
||||
|
||||
ARGCHK(MP_SIGN(&bignums[i]) == MP_ZPOS, MP_BADARG);
|
||||
ARGCHK(used <= nDigits, MP_BADARG);
|
||||
@ -583,267 +564,45 @@ mp_err mpi_to_weave(const mp_int *bignums,
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
/*
|
||||
* These functions return 0xffffffff if the output is true, and 0 otherwise.
|
||||
*/
|
||||
#define CONST_TIME_MSB(x) (0L - ((x) >> (8*sizeof(x) - 1)))
|
||||
#define CONST_TIME_EQ_Z(x) CONST_TIME_MSB(~(x) & ((x)-1))
|
||||
#define CONST_TIME_EQ(a, b) CONST_TIME_EQ_Z((a) ^ (b))
|
||||
|
||||
/* Reverse the operation above for one mp_int.
|
||||
* Reconstruct one mp_int from its column in the weaved array.
|
||||
* "pSrc" points to the offset into the weave array of the bignum we
|
||||
* are going to reconstruct.
|
||||
* Every read accesses every element of the weaved array, in order to
|
||||
* avoid timing attacks based on patterns of memory accesses.
|
||||
*/
|
||||
mp_err weave_to_mpi(mp_int *a, /* output, result */
|
||||
const unsigned char *pSrc, /* input, byte matrix */
|
||||
mp_size nDigits, /* per mp_int output */
|
||||
mp_size nBignums) /* bignums in weaved matrix */
|
||||
mp_err weave_to_mpi(mp_int *a, /* out, result */
|
||||
const mp_digit *weaved, /* in, byte matrix */
|
||||
mp_size index, /* which column to read */
|
||||
mp_size nDigits, /* number of mp_digits in each bignum */
|
||||
mp_size nBignums) /* width of the matrix */
|
||||
{
|
||||
unsigned char *pDest = (unsigned char *)MP_DIGITS(a);
|
||||
unsigned char *endDest = pDest + (nDigits * sizeof(mp_digit));
|
||||
/* these are indices, but need to be the same size as mp_digit
|
||||
* because of the CONST_TIME operations */
|
||||
mp_digit i, j;
|
||||
mp_digit d;
|
||||
mp_digit *pDest = MP_DIGITS(a);
|
||||
|
||||
MP_SIGN(a) = MP_ZPOS;
|
||||
MP_USED(a) = nDigits;
|
||||
|
||||
for (; pDest < endDest; pSrc += nBignums, pDest++) {
|
||||
*pDest = *pSrc;
|
||||
}
|
||||
s_mp_clamp(a);
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Need a primitive that we know is 32 bits long... */
|
||||
/* this is true on all modern processors we know of today*/
|
||||
typedef unsigned int mp_weave_word;
|
||||
|
||||
/*
|
||||
* on some platforms character stores into memory is very expensive since they
|
||||
* generate a read/modify/write operation on the bus. On those platforms
|
||||
* we need to do integer writes to the bus. Because of some unrolled code,
|
||||
* in this current code the size of mp_weave_word must be four. The code that
|
||||
* makes this assumption explicity is called out. (on some platforms a write
|
||||
* of 4 bytes still requires a single read-modify-write operation.
|
||||
*
|
||||
* This function is takes the identical parameters as the function above,
|
||||
* however it lays out the final array differently. Where the previous function
|
||||
* treats the mpi_int as an byte array, this function treats it as an array of
|
||||
* mp_digits where each digit is stored in big endian order.
|
||||
*
|
||||
* since we need to interleave on a byte by byte basis, we need to collect
|
||||
* several mpi structures together into a single PRUint32 before we write. We
|
||||
* also need to make sure the PRUint32 is arranged so that the first value of
|
||||
* the first array winds up in b[0]. This means construction of that PRUint32
|
||||
* is endian specific (even though the layout of the mp_digits in the array
|
||||
* is always big endian).
|
||||
*
|
||||
* The final data is stored as follows :
|
||||
*
|
||||
* Our same logical array p array, m is sizeof(mp_digit),
|
||||
* N is still count and n is now b_size. If we define p[i].digit[j]0 as the
|
||||
* most significant byte of the word p[i].digit[j], p[i].digit[j]1 as
|
||||
* the next most significant byte of p[i].digit[j], ... and p[i].digit[j]m-1
|
||||
* is the least significant byte.
|
||||
* Our array would look like:
|
||||
* p[0].digit[0]0 p[1].digit[0]0 ... p[N-2].digit[0]0 p[N-1].digit[0]0
|
||||
* p[0].digit[0]1 p[1].digit[0]1 ... p[N-2].digit[0]1 p[N-1].digit[0]1
|
||||
* . .
|
||||
* p[0].digit[0]m-1 p[1].digit[0]m-1 ... p[N-2].digit[0]m-1 p[N-1].digit[0]m-1
|
||||
* p[0].digit[1]0 p[1].digit[1]0 ... p[N-2].digit[1]0 p[N-1].digit[1]0
|
||||
* . .
|
||||
* . .
|
||||
* p[0].digit[n-1]m-2 p[1].digit[n-1]m-2 ... p[N-2].digit[n-1]m-2 p[N-1].digit[n-1]m-2
|
||||
* p[0].digit[n-1]m-1 p[1].digit[n-1]m-1 ... p[N-2].digit[n-1]m-1 p[N-1].digit[n-1]m-1
|
||||
*
|
||||
*/
|
||||
mp_err mpi_to_weave(const mp_int *a, unsigned char *b,
|
||||
mp_size b_size, mp_size count)
|
||||
{
|
||||
mp_size i;
|
||||
mp_digit *digitsa0;
|
||||
mp_digit *digitsa1;
|
||||
mp_digit *digitsa2;
|
||||
mp_digit *digitsa3;
|
||||
mp_size useda0;
|
||||
mp_size useda1;
|
||||
mp_size useda2;
|
||||
mp_size useda3;
|
||||
mp_weave_word *weaved = (mp_weave_word *)b;
|
||||
|
||||
count = count/sizeof(mp_weave_word);
|
||||
|
||||
/* this code pretty much depends on this ! */
|
||||
#if MP_ARGCHK == 2
|
||||
assert(WEAVE_WORD_SIZE == 4);
|
||||
assert(sizeof(mp_weave_word) == 4);
|
||||
#endif
|
||||
|
||||
digitsa0 = MP_DIGITS(&a[0]);
|
||||
digitsa1 = MP_DIGITS(&a[1]);
|
||||
digitsa2 = MP_DIGITS(&a[2]);
|
||||
digitsa3 = MP_DIGITS(&a[3]);
|
||||
useda0 = MP_USED(&a[0]);
|
||||
useda1 = MP_USED(&a[1]);
|
||||
useda2 = MP_USED(&a[2]);
|
||||
useda3 = MP_USED(&a[3]);
|
||||
|
||||
ARGCHK(MP_SIGN(&a[0]) == MP_ZPOS, MP_BADARG);
|
||||
ARGCHK(MP_SIGN(&a[1]) == MP_ZPOS, MP_BADARG);
|
||||
ARGCHK(MP_SIGN(&a[2]) == MP_ZPOS, MP_BADARG);
|
||||
ARGCHK(MP_SIGN(&a[3]) == MP_ZPOS, MP_BADARG);
|
||||
ARGCHK(useda0 <= b_size, MP_BADARG);
|
||||
ARGCHK(useda1 <= b_size, MP_BADARG);
|
||||
ARGCHK(useda2 <= b_size, MP_BADARG);
|
||||
ARGCHK(useda3 <= b_size, MP_BADARG);
|
||||
|
||||
#define SAFE_FETCH(digit, used, word) ((word) < (used) ? (digit[word]) : 0)
|
||||
|
||||
for (i=0; i < b_size; i++) {
|
||||
mp_digit d0 = SAFE_FETCH(digitsa0,useda0,i);
|
||||
mp_digit d1 = SAFE_FETCH(digitsa1,useda1,i);
|
||||
mp_digit d2 = SAFE_FETCH(digitsa2,useda2,i);
|
||||
mp_digit d3 = SAFE_FETCH(digitsa3,useda3,i);
|
||||
register mp_weave_word acc;
|
||||
|
||||
/*
|
||||
* ONE_STEP takes the MSB of each of our current digits and places that
|
||||
* byte in the appropriate position for writing to the weaved array.
|
||||
* On little endian:
|
||||
* b3 b2 b1 b0
|
||||
* On big endian:
|
||||
* b0 b1 b2 b3
|
||||
* When the data is written it would always wind up:
|
||||
* b[0] = b0
|
||||
* b[1] = b1
|
||||
* b[2] = b2
|
||||
* b[3] = b3
|
||||
*
|
||||
* Once we've written the MSB, we shift the whole digit up left one
|
||||
* byte, putting the Next Most Significant Byte in the MSB position,
|
||||
* so we we repeat the next one step that byte will be written.
|
||||
* NOTE: This code assumes sizeof(mp_weave_word) and MP_WEAVE_WORD_SIZE
|
||||
* is 4.
|
||||
*/
|
||||
#ifdef MP_IS_LITTLE_ENDIAN
|
||||
#define MPI_WEAVE_ONE_STEP \
|
||||
acc = (d0 >> (MP_DIGIT_BIT-8)) & 0x000000ff; d0 <<= 8; /*b0*/ \
|
||||
acc |= (d1 >> (MP_DIGIT_BIT-16)) & 0x0000ff00; d1 <<= 8; /*b1*/ \
|
||||
acc |= (d2 >> (MP_DIGIT_BIT-24)) & 0x00ff0000; d2 <<= 8; /*b2*/ \
|
||||
acc |= (d3 >> (MP_DIGIT_BIT-32)) & 0xff000000; d3 <<= 8; /*b3*/ \
|
||||
*weaved = acc; weaved += count;
|
||||
#else
|
||||
#define MPI_WEAVE_ONE_STEP \
|
||||
acc = (d0 >> (MP_DIGIT_BIT-32)) & 0xff000000; d0 <<= 8; /*b0*/ \
|
||||
acc |= (d1 >> (MP_DIGIT_BIT-24)) & 0x00ff0000; d1 <<= 8; /*b1*/ \
|
||||
acc |= (d2 >> (MP_DIGIT_BIT-16)) & 0x0000ff00; d2 <<= 8; /*b2*/ \
|
||||
acc |= (d3 >> (MP_DIGIT_BIT-8)) & 0x000000ff; d3 <<= 8; /*b3*/ \
|
||||
*weaved = acc; weaved += count;
|
||||
#endif
|
||||
switch (sizeof(mp_digit)) {
|
||||
case 32:
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
case 16:
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
case 8:
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
case 4:
|
||||
MPI_WEAVE_ONE_STEP
|
||||
MPI_WEAVE_ONE_STEP
|
||||
case 2:
|
||||
MPI_WEAVE_ONE_STEP
|
||||
case 1:
|
||||
MPI_WEAVE_ONE_STEP
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
/* reverse the operation above for one entry.
|
||||
* b points to the offset into the weave array of the power we are
|
||||
* calculating */
|
||||
mp_err weave_to_mpi(mp_int *a, const unsigned char *b,
|
||||
mp_size b_size, mp_size count)
|
||||
{
|
||||
mp_digit *pb = MP_DIGITS(a);
|
||||
mp_digit *end = &pb[b_size];
|
||||
|
||||
MP_SIGN(a) = MP_ZPOS;
|
||||
MP_USED(a) = b_size;
|
||||
|
||||
for (; pb < end; pb++) {
|
||||
register mp_digit digit;
|
||||
|
||||
digit = *b << 8; b += count;
|
||||
#define MPI_UNWEAVE_ONE_STEP digit |= *b; b += count; digit = digit << 8;
|
||||
switch (sizeof(mp_digit)) {
|
||||
case 32:
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
case 16:
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
case 8:
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
case 4:
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
MPI_UNWEAVE_ONE_STEP
|
||||
case 2:
|
||||
break;
|
||||
/* Fetch the proper column in constant time, indexing over the whole array */
|
||||
for (i=0; i<nDigits; ++i) {
|
||||
d = 0;
|
||||
for (j=0; j<nBignums; ++j) {
|
||||
d |= weaved[i*nBignums + j] & CONST_TIME_EQ(j, index);
|
||||
}
|
||||
digit |= *b; b += count;
|
||||
|
||||
*pb = digit;
|
||||
pDest[i] = d;
|
||||
}
|
||||
|
||||
s_mp_clamp(a);
|
||||
return MP_OKAY;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define SQR(a,b) \
|
||||
MP_CHECKOK( mp_sqr(a, b) );\
|
||||
@ -859,7 +618,7 @@ mp_err weave_to_mpi(mp_int *a, const unsigned char *b,
|
||||
#endif
|
||||
|
||||
#define MUL(x,a,b) \
|
||||
MP_CHECKOK( weave_to_mpi(&tmp, powers + (x), nLen, num_powers) ); \
|
||||
MP_CHECKOK( weave_to_mpi(&tmp, powers, (x), nLen, num_powers) ); \
|
||||
MUL_NOWEAVE(&tmp,a,b)
|
||||
|
||||
#define SWAPPA ptmp = pa1; pa1 = pa2; pa2 = ptmp
|
||||
@ -883,8 +642,8 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase,
|
||||
int expOff;
|
||||
mp_int accum1, accum2, accum[WEAVE_WORD_SIZE];
|
||||
mp_int tmp;
|
||||
unsigned char *powersArray = NULL;
|
||||
unsigned char *powers = NULL;
|
||||
mp_digit *powersArray = NULL;
|
||||
mp_digit *powers = NULL;
|
||||
|
||||
MP_DIGITS(&accum1) = 0;
|
||||
MP_DIGITS(&accum2) = 0;
|
||||
@ -915,13 +674,13 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase,
|
||||
MP_CHECKOK( mp_copy(montBase, &accum[1]) );
|
||||
SQR(montBase, &accum[2]);
|
||||
MUL_NOWEAVE(montBase, &accum[2], &accum[3]);
|
||||
powersArray = (unsigned char *)malloc(num_powers*(nLen*sizeof(mp_digit)+1));
|
||||
powersArray = (mp_digit *)malloc(num_powers*(nLen*sizeof(mp_digit)+1));
|
||||
if (!powersArray) {
|
||||
res = MP_MEM;
|
||||
goto CLEANUP;
|
||||
}
|
||||
/* powers[i] = base ** (i); */ \
|
||||
powers = (unsigned char *)MP_ALIGN(powersArray,num_powers); \
|
||||
powers = (mp_digit *)MP_ALIGN(powersArray,num_powers); \
|
||||
MP_CHECKOK( mpi_to_weave(accum, powers, nLen, num_powers) );
|
||||
if (first_window < 4) {
|
||||
MP_CHECKOK( mp_copy(&accum[first_window], &accum1) );
|
||||
@ -968,7 +727,7 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase,
|
||||
* value is overwritten, so we need to fetch it from the stored
|
||||
* weave array */
|
||||
if (i > 2* WEAVE_WORD_SIZE) {
|
||||
MP_CHECKOK(weave_to_mpi(&accum2, powers+i/2, nLen, num_powers));
|
||||
MP_CHECKOK(weave_to_mpi(&accum2, powers, i/2, nLen, num_powers));
|
||||
SQR(&accum2, &accum[acc_index]);
|
||||
} else {
|
||||
int half_power_index = (i/2) & (WEAVE_WORD_SIZE-1);
|
||||
|
@ -410,31 +410,32 @@ mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong,
|
||||
MP_DIGITS(&q) = 0;
|
||||
MP_CHECKOK( mp_init(&trial) );
|
||||
MP_CHECKOK( mp_init(&q) );
|
||||
/* values taken from table 4.4, HandBook of Applied Cryptography */
|
||||
if (nBits >= 1300) {
|
||||
num_tests = 2;
|
||||
} else if (nBits >= 850) {
|
||||
/* values originally taken from table 4.4,
|
||||
* HandBook of Applied Cryptography, augmented by FIPS-186
|
||||
* requirements, Table C.2 and C.3 */
|
||||
if (nBits >= 2000) {
|
||||
num_tests = 3;
|
||||
} else if (nBits >= 650) {
|
||||
} else if (nBits >= 1536) {
|
||||
num_tests = 4;
|
||||
} else if (nBits >= 550) {
|
||||
} else if (nBits >= 1024) {
|
||||
num_tests = 5;
|
||||
} else if (nBits >= 450) {
|
||||
} else if (nBits >= 550) {
|
||||
num_tests = 6;
|
||||
} else if (nBits >= 400) {
|
||||
} else if (nBits >= 450) {
|
||||
num_tests = 7;
|
||||
} else if (nBits >= 350) {
|
||||
} else if (nBits >= 400) {
|
||||
num_tests = 8;
|
||||
} else if (nBits >= 300) {
|
||||
} else if (nBits >= 350) {
|
||||
num_tests = 9;
|
||||
} else if (nBits >= 300) {
|
||||
num_tests = 10;
|
||||
} else if (nBits >= 250) {
|
||||
num_tests = 12;
|
||||
num_tests = 20;
|
||||
} else if (nBits >= 200) {
|
||||
num_tests = 15;
|
||||
} else if (nBits >= 150) {
|
||||
num_tests = 18;
|
||||
num_tests = 41;
|
||||
} else if (nBits >= 100) {
|
||||
num_tests = 27;
|
||||
num_tests = 38; /* funny anomaly in the FIPS tables, for aux primes, the
|
||||
* required more iterations for larger aux primes */
|
||||
} else
|
||||
num_tests = 50;
|
||||
|
||||
|
@ -171,7 +171,7 @@ ifeq ($(TARGET),x86LINUX)
|
||||
#Linux
|
||||
AS_OBJS = mpi_x86.o
|
||||
MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D
|
||||
MPICMN += -DMP_MONT_USE_MP_MUL -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
|
||||
MPICMN += -DMP_MONT_USE_MP_MUL -DMP_IS_LITTLE_ENDIAN
|
||||
CFLAGS= -O2 -fPIC -DLINUX1_2 -Di386 -D_XOPEN_SOURCE -DLINUX2_1 -ansi -Wall \
|
||||
-pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR \
|
||||
-DXP_UNIX -UDEBUG -DNDEBUG -D_REENTRANT $(MPICMN)
|
||||
@ -193,7 +193,7 @@ ifeq ($(TARGET),AMD64SOLARIS)
|
||||
ASFLAGS += -xarch=generic64
|
||||
AS_OBJS = mpi_amd64.o mpi_amd64_sun.o
|
||||
MP_CONFIG = -DMP_ASSEMBLY_MULTIPLY -DMPI_AMD64
|
||||
MP_CONFIG += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
|
||||
MP_CONFIG += -DMP_IS_LITTLE_ENDIAN
|
||||
CFLAGS = -xarch=generic64 -xO4 -I. -DMP_API_COMPATIBLE -DMP_IOFUNC $(MP_CONFIG)
|
||||
MPICMN += $(MP_CONFIG)
|
||||
|
||||
|
@ -7,244 +7,11 @@
|
||||
#endif
|
||||
#include "prtypes.h"
|
||||
#include "secerr.h"
|
||||
#include "pkcs11t.h"
|
||||
#include "blapi.h"
|
||||
#include "hasht.h"
|
||||
#include "plhash.h"
|
||||
#include "nsslowhash.h"
|
||||
|
||||
/* FIPS preprocessor directives for message digests */
|
||||
#define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */
|
||||
|
||||
/* Known Hash Message (512-bits). Used for all hashes (incl. SHA-N [N>1]). */
|
||||
static const PRUint8 known_hash_message[] = {
|
||||
"The test message for the MD2, MD5, and SHA-1 hashing algorithms." };
|
||||
|
||||
static CK_RV
|
||||
freebl_fips_MD2_PowerUpSelfTest( void )
|
||||
{
|
||||
/* MD2 Known Digest Message (128-bits). */
|
||||
static const PRUint8 md2_known_digest[] = {
|
||||
0x41,0x5a,0x12,0xb2,0x3f,0x28,0x97,0x17,
|
||||
0x0c,0x71,0x4e,0xcc,0x40,0xc8,0x1d,0x1b};
|
||||
|
||||
/* MD2 variables. */
|
||||
MD2Context * md2_context;
|
||||
unsigned int md2_bytes_hashed;
|
||||
PRUint8 md2_computed_digest[MD2_LENGTH];
|
||||
|
||||
|
||||
/***********************************************/
|
||||
/* MD2 Single-Round Known Answer Hashing Test. */
|
||||
/***********************************************/
|
||||
|
||||
md2_context = MD2_NewContext();
|
||||
|
||||
if( md2_context == NULL )
|
||||
return( CKR_HOST_MEMORY );
|
||||
|
||||
MD2_Begin( md2_context );
|
||||
|
||||
MD2_Update( md2_context, known_hash_message,
|
||||
FIPS_KNOWN_HASH_MESSAGE_LENGTH );
|
||||
|
||||
MD2_End( md2_context, md2_computed_digest, &md2_bytes_hashed, MD2_LENGTH );
|
||||
|
||||
MD2_DestroyContext( md2_context , PR_TRUE );
|
||||
|
||||
if( ( md2_bytes_hashed != MD2_LENGTH ) ||
|
||||
( PORT_Memcmp( md2_computed_digest, md2_known_digest,
|
||||
MD2_LENGTH ) != 0 ) )
|
||||
return( CKR_DEVICE_ERROR );
|
||||
|
||||
return( CKR_OK );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static CK_RV
|
||||
freebl_fips_MD5_PowerUpSelfTest( void )
|
||||
{
|
||||
/* MD5 Known Digest Message (128-bits). */
|
||||
static const PRUint8 md5_known_digest[] = {
|
||||
0x25,0xc8,0xc0,0x10,0xc5,0x6e,0x68,0x28,
|
||||
0x28,0xa4,0xa5,0xd2,0x98,0x9a,0xea,0x2d};
|
||||
|
||||
/* MD5 variables. */
|
||||
PRUint8 md5_computed_digest[MD5_LENGTH];
|
||||
SECStatus md5_status;
|
||||
|
||||
|
||||
/***********************************************/
|
||||
/* MD5 Single-Round Known Answer Hashing Test. */
|
||||
/***********************************************/
|
||||
|
||||
md5_status = MD5_HashBuf( md5_computed_digest, known_hash_message,
|
||||
FIPS_KNOWN_HASH_MESSAGE_LENGTH );
|
||||
|
||||
if( ( md5_status != SECSuccess ) ||
|
||||
( PORT_Memcmp( md5_computed_digest, md5_known_digest,
|
||||
MD5_LENGTH ) != 0 ) )
|
||||
return( CKR_DEVICE_ERROR );
|
||||
|
||||
return( CKR_OK );
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
freebl_fips_SHA_PowerUpSelfTest( void )
|
||||
{
|
||||
/* SHA-1 Known Digest Message (160-bits). */
|
||||
static const PRUint8 sha1_known_digest[] = {
|
||||
0x0a,0x6d,0x07,0xba,0x1e,0xbd,0x8a,0x1b,
|
||||
0x72,0xf6,0xc7,0x22,0xf1,0x27,0x9f,0xf0,
|
||||
0xe0,0x68,0x47,0x7a};
|
||||
|
||||
/* SHA-224 Known Digest Message (224-bits). */
|
||||
static const PRUint8 sha224_known_digest[] = {
|
||||
0x89,0x5e,0x7f,0xfd,0x0e,0xd8,0x35,0x6f,
|
||||
0x64,0x6d,0xf2,0xde,0x5e,0xed,0xa6,0x7f,
|
||||
0x29,0xd1,0x12,0x73,0x42,0x84,0x95,0x4f,
|
||||
0x8e,0x08,0xe5,0xcb};
|
||||
|
||||
/* SHA-256 Known Digest Message (256-bits). */
|
||||
static const PRUint8 sha256_known_digest[] = {
|
||||
0x38,0xa9,0xc1,0xf0,0x35,0xf6,0x5d,0x61,
|
||||
0x11,0xd4,0x0b,0xdc,0xce,0x35,0x14,0x8d,
|
||||
0xf2,0xdd,0xaf,0xaf,0xcf,0xb7,0x87,0xe9,
|
||||
0x96,0xa5,0xd2,0x83,0x62,0x46,0x56,0x79};
|
||||
|
||||
/* SHA-384 Known Digest Message (384-bits). */
|
||||
static const PRUint8 sha384_known_digest[] = {
|
||||
0x11,0xfe,0x1c,0x00,0x89,0x48,0xde,0xb3,
|
||||
0x99,0xee,0x1c,0x18,0xb4,0x10,0xfb,0xfe,
|
||||
0xe3,0xa8,0x2c,0xf3,0x04,0xb0,0x2f,0xc8,
|
||||
0xa3,0xc4,0x5e,0xea,0x7e,0x60,0x48,0x7b,
|
||||
0xce,0x2c,0x62,0xf7,0xbc,0xa7,0xe8,0xa3,
|
||||
0xcf,0x24,0xce,0x9c,0xe2,0x8b,0x09,0x72};
|
||||
|
||||
/* SHA-512 Known Digest Message (512-bits). */
|
||||
static const PRUint8 sha512_known_digest[] = {
|
||||
0xc8,0xb3,0x27,0xf9,0x0b,0x24,0xc8,0xbf,
|
||||
0x4c,0xba,0x33,0x54,0xf2,0x31,0xbf,0xdb,
|
||||
0xab,0xfd,0xb3,0x15,0xd7,0xfa,0x48,0x99,
|
||||
0x07,0x60,0x0f,0x57,0x41,0x1a,0xdd,0x28,
|
||||
0x12,0x55,0x25,0xac,0xba,0x3a,0x99,0x12,
|
||||
0x2c,0x7a,0x8f,0x75,0x3a,0xe1,0x06,0x6f,
|
||||
0x30,0x31,0xc9,0x33,0xc6,0x1b,0x90,0x1a,
|
||||
0x6c,0x98,0x9a,0x87,0xd0,0xb2,0xf8,0x07};
|
||||
|
||||
/* SHA-X variables. */
|
||||
PRUint8 sha_computed_digest[HASH_LENGTH_MAX];
|
||||
SECStatus sha_status;
|
||||
|
||||
/*************************************************/
|
||||
/* SHA-1 Single-Round Known Answer Hashing Test. */
|
||||
/*************************************************/
|
||||
|
||||
sha_status = SHA1_HashBuf( sha_computed_digest, known_hash_message,
|
||||
FIPS_KNOWN_HASH_MESSAGE_LENGTH );
|
||||
|
||||
if( ( sha_status != SECSuccess ) ||
|
||||
( PORT_Memcmp( sha_computed_digest, sha1_known_digest,
|
||||
SHA1_LENGTH ) != 0 ) )
|
||||
return( CKR_DEVICE_ERROR );
|
||||
|
||||
/***************************************************/
|
||||
/* SHA-224 Single-Round Known Answer Hashing Test. */
|
||||
/***************************************************/
|
||||
|
||||
sha_status = SHA224_HashBuf( sha_computed_digest, known_hash_message,
|
||||
FIPS_KNOWN_HASH_MESSAGE_LENGTH );
|
||||
|
||||
if( ( sha_status != SECSuccess ) ||
|
||||
( PORT_Memcmp( sha_computed_digest, sha224_known_digest,
|
||||
SHA224_LENGTH ) != 0 ) )
|
||||
return( CKR_DEVICE_ERROR );
|
||||
|
||||
/***************************************************/
|
||||
/* SHA-256 Single-Round Known Answer Hashing Test. */
|
||||
/***************************************************/
|
||||
|
||||
sha_status = SHA256_HashBuf( sha_computed_digest, known_hash_message,
|
||||
FIPS_KNOWN_HASH_MESSAGE_LENGTH );
|
||||
|
||||
if( ( sha_status != SECSuccess ) ||
|
||||
( PORT_Memcmp( sha_computed_digest, sha256_known_digest,
|
||||
SHA256_LENGTH ) != 0 ) )
|
||||
return( CKR_DEVICE_ERROR );
|
||||
|
||||
/***************************************************/
|
||||
/* SHA-384 Single-Round Known Answer Hashing Test. */
|
||||
/***************************************************/
|
||||
|
||||
sha_status = SHA384_HashBuf( sha_computed_digest, known_hash_message,
|
||||
FIPS_KNOWN_HASH_MESSAGE_LENGTH );
|
||||
|
||||
if( ( sha_status != SECSuccess ) ||
|
||||
( PORT_Memcmp( sha_computed_digest, sha384_known_digest,
|
||||
SHA384_LENGTH ) != 0 ) )
|
||||
return( CKR_DEVICE_ERROR );
|
||||
|
||||
/***************************************************/
|
||||
/* SHA-512 Single-Round Known Answer Hashing Test. */
|
||||
/***************************************************/
|
||||
|
||||
sha_status = SHA512_HashBuf( sha_computed_digest, known_hash_message,
|
||||
FIPS_KNOWN_HASH_MESSAGE_LENGTH );
|
||||
|
||||
if( ( sha_status != SECSuccess ) ||
|
||||
( PORT_Memcmp( sha_computed_digest, sha512_known_digest,
|
||||
SHA512_LENGTH ) != 0 ) )
|
||||
return( CKR_DEVICE_ERROR );
|
||||
|
||||
return( CKR_OK );
|
||||
}
|
||||
|
||||
|
||||
static CK_RV
|
||||
freebl_fipsSoftwareIntegrityTest(void)
|
||||
{
|
||||
CK_RV crv = CKR_OK;
|
||||
|
||||
/* make sure that our check file signatures are OK */
|
||||
if (!BLAPI_VerifySelf(SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX)) {
|
||||
crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */
|
||||
}
|
||||
return crv;
|
||||
}
|
||||
|
||||
CK_RV
|
||||
freebl_fipsPowerUpSelfTest( void )
|
||||
{
|
||||
CK_RV rv;
|
||||
|
||||
/* MD2 Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_MD2_PowerUpSelfTest();
|
||||
|
||||
if( rv != CKR_OK )
|
||||
return rv;
|
||||
|
||||
/* MD5 Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_MD5_PowerUpSelfTest();
|
||||
|
||||
if( rv != CKR_OK )
|
||||
return rv;
|
||||
|
||||
/* SHA-X Power-Up SelfTest(s). */
|
||||
rv = freebl_fips_SHA_PowerUpSelfTest();
|
||||
|
||||
if( rv != CKR_OK )
|
||||
return rv;
|
||||
|
||||
/* Software/Firmware Integrity Test. */
|
||||
rv = freebl_fipsSoftwareIntegrityTest();
|
||||
|
||||
if( rv != CKR_OK )
|
||||
return rv;
|
||||
|
||||
/* Passed Power-Up SelfTest(s). */
|
||||
return( CKR_OK );
|
||||
}
|
||||
#include "blapii.h"
|
||||
|
||||
struct NSSLOWInitContextStr {
|
||||
int count;
|
||||
@ -276,36 +43,28 @@ static int nsslow_GetFIPSEnabled(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int post = 0;
|
||||
static int post_failed = 0;
|
||||
|
||||
static NSSLOWInitContext dummyContext = { 0 };
|
||||
static PRBool post_failed = PR_TRUE;
|
||||
|
||||
NSSLOWInitContext *
|
||||
NSSLOW_Init(void)
|
||||
{
|
||||
CK_RV crv;
|
||||
#ifdef FREEBL_NO_DEPEND
|
||||
(void)FREEBL_InitStubs();
|
||||
(void) FREEBL_InitStubs();
|
||||
#endif
|
||||
|
||||
if (post_failed) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (!post && nsslow_GetFIPSEnabled()) {
|
||||
crv = freebl_fipsPowerUpSelfTest();
|
||||
if (crv != CKR_OK) {
|
||||
post_failed = 1;
|
||||
/* make sure the FIPS product is installed if we are trying to
|
||||
* go into FIPS mode */
|
||||
if (nsslow_GetFIPSEnabled()) {
|
||||
if (BL_FIPSEntryOK(PR_TRUE) != SECSuccess) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
post_failed = PR_TRUE;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
post = 1;
|
||||
|
||||
}
|
||||
post_failed = PR_FALSE;
|
||||
|
||||
return &dummyContext;
|
||||
return &dummyContext;
|
||||
}
|
||||
|
||||
void
|
||||
@ -319,8 +78,6 @@ void
|
||||
NSSLOW_Reset(NSSLOWInitContext *context)
|
||||
{
|
||||
PORT_Assert(context == &dummyContext);
|
||||
post_failed = 0;
|
||||
post = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,8 @@ typedef enum {
|
||||
* implement Lucas and adjust these two functions. See FIPS 186-3 Appendix C
|
||||
* and F for more information.
|
||||
*/
|
||||
int prime_testcount_p(int L, int N)
|
||||
static int
|
||||
prime_testcount_p(int L, int N)
|
||||
{
|
||||
switch (L) {
|
||||
case 1024:
|
||||
@ -61,7 +62,8 @@ int prime_testcount_p(int L, int N)
|
||||
/* The q numbers are different if you run M-R followd by Lucas. I created
|
||||
* a separate function so if someone wanted to add the Lucas check, they
|
||||
* could do so fairly easily */
|
||||
int prime_testcount_q(int L, int N)
|
||||
static int
|
||||
prime_testcount_q(int L, int N)
|
||||
{
|
||||
return prime_testcount_p(L,N);
|
||||
}
|
||||
@ -486,7 +488,7 @@ cleanup:
|
||||
** steps 16 through 34 of FIPS 186-2 C.6
|
||||
*/
|
||||
#define MAX_ST_SEED_BITS (HASH_LENGTH_MAX*PR_BITS_PER_BYTE)
|
||||
SECStatus
|
||||
static SECStatus
|
||||
makePrimefromPrimesShaweTaylor(
|
||||
HASH_HashType hashtype, /* selected Hashing algorithm */
|
||||
unsigned int length, /* input. Length of prime in bits. */
|
||||
@ -701,6 +703,7 @@ cleanup:
|
||||
mp_clear(&a);
|
||||
mp_clear(&z);
|
||||
mp_clear(&two_length_minus_1);
|
||||
PORT_Memset(x, 0, sizeof(x));
|
||||
if (err) {
|
||||
MP_TO_SEC_ERROR(err);
|
||||
rv = SECFailure;
|
||||
@ -720,7 +723,7 @@ cleanup:
|
||||
**
|
||||
** This generates a provable prime from a seed
|
||||
*/
|
||||
SECStatus
|
||||
static SECStatus
|
||||
makePrimefromSeedShaweTaylor(
|
||||
HASH_HashType hashtype, /* selected Hashing algorithm */
|
||||
unsigned int length, /* input. Length of prime in bits. */
|
||||
@ -856,6 +859,7 @@ cleanup:
|
||||
mp_clear(&c);
|
||||
mp_clear(&c0);
|
||||
mp_clear(&one);
|
||||
PORT_Memset(x, 0, sizeof(x));
|
||||
if (err) {
|
||||
MP_TO_SEC_ERROR(err);
|
||||
rv = SECFailure;
|
||||
@ -1256,6 +1260,42 @@ pqg_ParamGen(unsigned int L, unsigned int N, pqgGenType type,
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Initialize bignums */
|
||||
MP_DIGITS(&P) = 0;
|
||||
MP_DIGITS(&Q) = 0;
|
||||
MP_DIGITS(&G) = 0;
|
||||
MP_DIGITS(&H) = 0;
|
||||
MP_DIGITS(&l) = 0;
|
||||
MP_DIGITS(&p0) = 0;
|
||||
CHECK_MPI_OK( mp_init(&P) );
|
||||
CHECK_MPI_OK( mp_init(&Q) );
|
||||
CHECK_MPI_OK( mp_init(&G) );
|
||||
CHECK_MPI_OK( mp_init(&H) );
|
||||
CHECK_MPI_OK( mp_init(&l) );
|
||||
CHECK_MPI_OK( mp_init(&p0) );
|
||||
|
||||
/* parameters have been passed in, only generate G */
|
||||
if (*pParams != NULL) {
|
||||
/* we only support G index generation if generating separate from PQ */
|
||||
if ((*pVfy == NULL) || (type == FIPS186_1_TYPE) ||
|
||||
((*pVfy)->h.len != 1) || ((*pVfy)->h.data == NULL) ||
|
||||
((*pVfy)->seed.data == NULL) || ((*pVfy)->seed.len == 0)) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
params = *pParams;
|
||||
verify = *pVfy;
|
||||
|
||||
/* fill in P Q, */
|
||||
SECITEM_TO_MPINT((*pParams)->prime, &P);
|
||||
SECITEM_TO_MPINT((*pParams)->subPrime, &Q);
|
||||
hashtype = getFirstHash(L,N);
|
||||
CHECK_SEC_OK(makeGfromIndex(hashtype, &P, &Q, &(*pVfy)->seed,
|
||||
(*pVfy)->h.data[0], &G) );
|
||||
MPINT_TO_SECITEM(&G, &(*pParams)->base, (*pParams)->arena);
|
||||
goto cleanup;
|
||||
}
|
||||
/* Initialize an arena for the params. */
|
||||
arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
|
||||
if (!arena) {
|
||||
@ -1513,8 +1553,12 @@ cleanup:
|
||||
rv = SECFailure;
|
||||
}
|
||||
if (rv) {
|
||||
PORT_FreeArena(params->arena, PR_TRUE);
|
||||
PORT_FreeArena(verify->arena, PR_TRUE);
|
||||
if (params) {
|
||||
PORT_FreeArena(params->arena, PR_TRUE);
|
||||
}
|
||||
if (verify) {
|
||||
PORT_FreeArena(verify->arena, PR_TRUE);
|
||||
}
|
||||
}
|
||||
if (hit.data) {
|
||||
SECITEM_FreeItem(&hit, PR_FALSE);
|
||||
|
@ -21,8 +21,11 @@
|
||||
|
||||
#ifdef USE_HW_AES
|
||||
#include "intel-aes.h"
|
||||
#endif
|
||||
|
||||
#include "mpi.h"
|
||||
|
||||
#ifdef USE_HW_AES
|
||||
static int has_intel_aes = 0;
|
||||
static PRBool use_hw_aes = PR_FALSE;
|
||||
|
||||
@ -1168,6 +1171,7 @@ AES_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
|
||||
AES_DestroyContext(cx, PR_FALSE);
|
||||
return rv;
|
||||
}
|
||||
cx->mode = mode;
|
||||
|
||||
/* finally, set up any mode specific contexts */
|
||||
switch (mode) {
|
||||
@ -1291,6 +1295,23 @@ AES_Encrypt(AESContext *cx, unsigned char *output,
|
||||
return SECFailure;
|
||||
}
|
||||
*outputLen = inputLen;
|
||||
#if UINT_MAX > MP_32BIT_MAX
|
||||
/*
|
||||
* we can guarentee that GSM won't overlfow if we limit the input to
|
||||
* 2^36 bytes. For simplicity, we are limiting it to 2^32 for now.
|
||||
*
|
||||
* We do it here to cover both hardware and software GCM operations.
|
||||
*/
|
||||
{PR_STATIC_ASSERT(sizeof(unsigned int) > 4);}
|
||||
if ((cx->mode == NSS_AES_GCM) && (inputLen > MP_32BIT_MAX)) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
#else
|
||||
/* if we can't pass in a 32_bit number, then no such check needed */
|
||||
{PR_STATIC_ASSERT(sizeof(unsigned int) <= 4);}
|
||||
#endif
|
||||
|
||||
return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
|
||||
input, inputLen, blocksize);
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ struct AESContextStr
|
||||
freeblDestroyFunc destroy;
|
||||
void *worker_cx;
|
||||
PRBool isBlock;
|
||||
int mode;
|
||||
};
|
||||
|
||||
#endif /* _RIJNDAEL_H_ */
|
||||
|
@ -138,7 +138,7 @@ rsa_build_from_primes(const mp_int *p, const mp_int *q,
|
||||
CHECK_MPI_OK( mp_sub_d(p, 1, &psub1) );
|
||||
CHECK_MPI_OK( mp_sub_d(q, 1, &qsub1) );
|
||||
if (needPublicExponent || needPrivateExponent) {
|
||||
CHECK_MPI_OK( mp_mul(&psub1, &qsub1, &phi) );
|
||||
CHECK_MPI_OK( mp_lcm(&psub1, &qsub1, &phi) );
|
||||
/* 3. Compute d = e**-1 mod(phi) */
|
||||
/* or e = d**-1 mod(phi) as necessary */
|
||||
if (needPublicExponent) {
|
||||
@ -225,6 +225,45 @@ cleanup:
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure the key components meet fips186 requirements.
|
||||
*/
|
||||
static PRBool
|
||||
rsa_fips186_verify(mp_int *p, mp_int *q, mp_int *d, int keySizeInBits)
|
||||
{
|
||||
mp_int pq_diff;
|
||||
mp_err err = MP_OKAY;
|
||||
PRBool ret=PR_FALSE;
|
||||
|
||||
if (keySizeInBits < 250) {
|
||||
/* not a valid FIPS length, no point in our other tests */
|
||||
/* if you are here, and in FIPS mode, you are outside the security
|
||||
* policy */
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/* p & q are already known to be greater then sqrt(2)*2^(keySize/2-1) */
|
||||
/* we also know that gcd(p-1,e) = 1 and gcd(q-1,e) = 1 because the
|
||||
* mp_invmod() function will fail. */
|
||||
/* now check p-q > 2^(keysize/2-100) */
|
||||
MP_DIGITS(&pq_diff) = 0;
|
||||
CHECK_MPI_OK( mp_init(&pq_diff) );
|
||||
/* NSS always has p > q, so we know pq_diff is positive */
|
||||
CHECK_MPI_OK( mp_sub(p,q,&pq_diff) );
|
||||
if ((unsigned)mpl_significant_bits(&pq_diff) < (keySizeInBits/2 - 100)) {
|
||||
goto cleanup;
|
||||
}
|
||||
/* now verify d is large enough*/
|
||||
if ((unsigned)mpl_significant_bits(d) < (keySizeInBits/2)) {
|
||||
goto cleanup;
|
||||
}
|
||||
ret = PR_TRUE;
|
||||
|
||||
cleanup:
|
||||
mp_clear(&pq_diff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
** Generate and return a new RSA public and private key.
|
||||
** Both keys are encoded in a single RSAPrivateKey structure.
|
||||
@ -241,6 +280,7 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
|
||||
unsigned int primeLen;
|
||||
mp_int p, q, e, d;
|
||||
int kiter;
|
||||
int max_attempts;
|
||||
mp_err err = MP_OKAY;
|
||||
SECStatus rv = SECSuccess;
|
||||
int prerr = 0;
|
||||
@ -281,6 +321,7 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
|
||||
/* 3. Set the public exponent */
|
||||
SECITEM_TO_MPINT(*publicExponent, &e);
|
||||
kiter = 0;
|
||||
max_attempts = 5*(keySizeInBits/2); /* FIPS 186-4 B.3.3 steps 4.7 and 5.8 */
|
||||
do {
|
||||
prerr = 0;
|
||||
PORT_SetError(0);
|
||||
@ -298,12 +339,17 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
|
||||
&e, PR_FALSE, /* needPublicExponent=false */
|
||||
&d, PR_TRUE, /* needPrivateExponent=true */
|
||||
key, keySizeInBits);
|
||||
if (rv == SECSuccess)
|
||||
break; /* generated two good primes */
|
||||
prerr = PORT_GetError();
|
||||
if (rv == SECSuccess) {
|
||||
if (rsa_fips186_verify(&p, &q, &d, keySizeInBits) ){
|
||||
break;
|
||||
}
|
||||
prerr = SEC_ERROR_NEED_RANDOM; /* retry with different values */
|
||||
} else {
|
||||
prerr = PORT_GetError();
|
||||
}
|
||||
kiter++;
|
||||
/* loop until have primes */
|
||||
} while (prerr == SEC_ERROR_NEED_RANDOM && kiter < MAX_KEY_GEN_ATTEMPTS);
|
||||
} while (prerr == SEC_ERROR_NEED_RANDOM && kiter < max_attempts);
|
||||
if (prerr)
|
||||
goto cleanup;
|
||||
cleanup:
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user