summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2018-08-14 07:52:35 +0200
committerwolfbeast <mcwerewolf@gmail.com>2018-08-14 16:42:52 +0200
commitab1060037931158d3a8bf4c8f9f6cb4dbfe916e9 (patch)
tree5e4677e52b9a349602f04135a44b3000c8baa97b
parentf44e99950fc25d16a3cdaffe26dadf7b58a9d38c (diff)
downloaduxp-ab1060037931158d3a8bf4c8f9f6cb4dbfe916e9.tar.gz
Update NSS to 3.38
- Added HACL*Poly1305 32-bit (INRIA/Microsoft) - Updated to final TLS 1.3 draft version (28) - Removed TLS 1.3 prerelease draft limit check - Removed NPN code - Enabled dev/urandom-only RNG on Linux with NSS_SEED_ONLY_DEV_URANDOM for non-standard environments - Fixed several bugs with TLS 1.3 negotiation - Updated internal certificate store - Added support for the TLS Record Size Limit Extension. - Fixed CVE-2018-0495 - Various security fixes in the ASN.1 code.
-rw-r--r--CLOBBER2
-rw-r--r--config/external/nss/nss.symbols16
-rw-r--r--security/nss/TAG-INFO2
-rw-r--r--security/nss/automation/abi-check/expected-report-libnssutil3.so.txt4
-rw-r--r--security/nss/automation/abi-check/expected-report-libssl3.so.txt28
-rw-r--r--security/nss/automation/abi-check/previous-nss-release2
-rw-r--r--security/nss/automation/taskcluster/docker-hacl/Dockerfile6
-rw-r--r--security/nss/automation/taskcluster/docker-hacl/setup-user.sh1
-rw-r--r--security/nss/automation/taskcluster/docker-saw/Dockerfile2
-rw-r--r--security/nss/automation/taskcluster/docker/Dockerfile3
-rw-r--r--security/nss/automation/taskcluster/graph/src/extend.js22
-rw-r--r--security/nss/automation/taskcluster/graph/src/try_syntax.js2
-rw-r--r--security/nss/automation/taskcluster/scripts/gen_coverage_report.sh12
-rw-r--r--security/nss/automation/taskcluster/scripts/run_hacl.sh4
-rw-r--r--security/nss/automation/taskcluster/scripts/tools.sh5
-rw-r--r--security/nss/cmd/bltest/blapitest.c6
-rw-r--r--security/nss/cmd/certutil/certutil.c156
-rw-r--r--security/nss/cmd/crlutil/crlutil.c14
-rw-r--r--security/nss/cmd/crmftest/testcrmf.c1
-rw-r--r--security/nss/cmd/dbtest/dbtest.c7
-rw-r--r--security/nss/cmd/httpserv/httpserv.c10
-rw-r--r--security/nss/cmd/lib/secutil.c8
-rw-r--r--security/nss/cmd/listsuites/listsuites.c2
-rw-r--r--security/nss/cmd/lowhashtest/lowhashtest.c4
-rw-r--r--security/nss/cmd/modutil/install-ds.c10
-rw-r--r--security/nss/cmd/mpitests/mpi-test.c16
-rw-r--r--security/nss/cmd/ocspclnt/ocspclnt.c24
-rw-r--r--security/nss/cmd/ocspresp/ocspresp.c6
-rw-r--r--security/nss/cmd/pk12util/pk12util.c12
-rw-r--r--security/nss/cmd/pk1sign/pk1sign.c2
-rw-r--r--security/nss/cmd/rsaperf/rsaperf.c32
-rw-r--r--security/nss/cmd/selfserv/selfserv.c59
-rw-r--r--security/nss/cmd/shlibsign/shlibsign.c2
-rw-r--r--security/nss/cmd/signtool/javascript.c8
-rw-r--r--security/nss/cmd/signtool/sign.c68
-rw-r--r--security/nss/cmd/signtool/zip.c4
-rw-r--r--security/nss/cmd/smimetools/cmsutil.c37
-rw-r--r--security/nss/cmd/strsclnt/strsclnt.c16
-rw-r--r--security/nss/cmd/symkeyutil/symkeyutil.c5
-rw-r--r--security/nss/cmd/tstclnt/tstclnt.c225
-rw-r--r--security/nss/cmd/vfyserv/vfyserv.c6
-rw-r--r--security/nss/cmd/vfyserv/vfyutil.c4
-rw-r--r--security/nss/coreconf/Werror.mk6
-rw-r--r--security/nss/coreconf/config.mk4
-rw-r--r--security/nss/coreconf/coreconf.dep1
-rw-r--r--security/nss/coreconf/nsinstall/pathsub.c2
-rw-r--r--security/nss/coreconf/werror.py2
-rw-r--r--security/nss/cpputil/databuffer.cc10
-rw-r--r--security/nss/cpputil/databuffer.h14
-rw-r--r--security/nss/cpputil/scoped_ptrs.h2
-rw-r--r--security/nss/cpputil/tls_parser.cc15
-rw-r--r--security/nss/cpputil/tls_parser.h1
-rw-r--r--security/nss/fuzz/fuzz.gyp3
-rw-r--r--security/nss/fuzz/tls_client_target.cc8
-rw-r--r--security/nss/gtests/freebl_gtest/blake2b_unittest.cc4
-rw-r--r--security/nss/gtests/freebl_gtest/kat/blake2b_kat.h2
-rw-r--r--security/nss/gtests/nss_bogo_shim/config.cc35
-rw-r--r--security/nss/gtests/nss_bogo_shim/config.h17
-rw-r--r--security/nss/gtests/nss_bogo_shim/config.json74
-rw-r--r--security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc59
-rw-r--r--security/nss/gtests/pk11_gtest/pk11_signature_test.h4
-rw-r--r--security/nss/gtests/ssl_gtest/libssl_internals.c13
-rw-r--r--security/nss/gtests/ssl_gtest/manifest.mn1
-rw-r--r--security/nss/gtests/ssl_gtest/rsa8193.h209
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc4
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_agent_unittest.cc78
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc48
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc11
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_custext_unittest.cc1
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_dhe_unittest.cc73
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_drop_unittest.cc126
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_ecdh_unittest.cc111
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_extension_unittest.cc35
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_fragment_unittest.cc28
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc4
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_gtest.gyp1
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_hrr_unittest.cc136
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc71
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_record_unittest.cc57
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_recordsize_unittest.cc431
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc6
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_skip_unittest.cc6
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_staticrsa_unittest.cc36
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_tls13compat_unittest.cc92
-rw-r--r--security/nss/gtests/ssl_gtest/ssl_versionpolicy_unittest.cc12
-rw-r--r--security/nss/gtests/ssl_gtest/test_io.cc8
-rw-r--r--security/nss/gtests/ssl_gtest/test_io.h6
-rw-r--r--security/nss/gtests/ssl_gtest/tls_agent.cc131
-rw-r--r--security/nss/gtests/ssl_gtest/tls_agent.h24
-rw-r--r--security/nss/gtests/ssl_gtest/tls_connect.cc49
-rw-r--r--security/nss/gtests/ssl_gtest/tls_connect.h4
-rw-r--r--security/nss/gtests/ssl_gtest/tls_filter.cc234
-rw-r--r--security/nss/gtests/ssl_gtest/tls_filter.h149
-rw-r--r--security/nss/gtests/ssl_gtest/tls_protect.cc35
-rw-r--r--security/nss/gtests/ssl_gtest/tls_protect.h15
-rw-r--r--security/nss/lib/certdb/crl.c8
-rw-r--r--security/nss/lib/ckfw/Makefile4
-rw-r--r--security/nss/lib/ckfw/builtins/certdata.txt467
-rw-r--r--security/nss/lib/ckfw/builtins/nssckbi.h6
-rw-r--r--security/nss/lib/ckfw/nssmkey/Makefile72
-rw-r--r--security/nss/lib/ckfw/nssmkey/README21
-rw-r--r--security/nss/lib/ckfw/nssmkey/ckmk.h182
-rw-r--r--security/nss/lib/ckfw/nssmkey/ckmkver.c17
-rw-r--r--security/nss/lib/ckfw/nssmkey/config.mk24
-rw-r--r--security/nss/lib/ckfw/nssmkey/manchor.c17
-rw-r--r--security/nss/lib/ckfw/nssmkey/manifest.mn33
-rw-r--r--security/nss/lib/ckfw/nssmkey/mconstants.c61
-rw-r--r--security/nss/lib/ckfw/nssmkey/mfind.c352
-rw-r--r--security/nss/lib/ckfw/nssmkey/minst.c97
-rw-r--r--security/nss/lib/ckfw/nssmkey/mobject.c1861
-rw-r--r--security/nss/lib/ckfw/nssmkey/mrsa.c479
-rw-r--r--security/nss/lib/ckfw/nssmkey/msession.c87
-rw-r--r--security/nss/lib/ckfw/nssmkey/mslot.c81
-rw-r--r--security/nss/lib/ckfw/nssmkey/mtoken.c184
-rw-r--r--security/nss/lib/ckfw/nssmkey/nssmkey.def26
-rw-r--r--security/nss/lib/ckfw/nssmkey/nssmkey.h41
-rw-r--r--security/nss/lib/ckfw/nssmkey/staticobj.c36
-rw-r--r--security/nss/lib/ckfw/session.c3
-rw-r--r--security/nss/lib/dev/devtoken.c4
-rw-r--r--security/nss/lib/freebl/Makefile10
-rw-r--r--security/nss/lib/freebl/blake2b.c2
-rw-r--r--security/nss/lib/freebl/chacha20poly1305.c88
-rw-r--r--security/nss/lib/freebl/dsa.c37
-rw-r--r--security/nss/lib/freebl/ec.c29
-rw-r--r--security/nss/lib/freebl/freebl.gyp36
-rw-r--r--security/nss/lib/freebl/freebl_base.gypi15
-rw-r--r--security/nss/lib/freebl/loader.c4
-rw-r--r--security/nss/lib/freebl/mpi/mpi.c13
-rw-r--r--security/nss/lib/freebl/poly1305-donna-x64-sse2-incremental-source.c881
-rw-r--r--security/nss/lib/freebl/poly1305.c314
-rw-r--r--security/nss/lib/freebl/poly1305.h30
-rw-r--r--security/nss/lib/freebl/unix_urandom.c33
-rw-r--r--security/nss/lib/freebl/verified/Hacl_Poly1305_32.c578
-rw-r--r--security/nss/lib/freebl/verified/Hacl_Poly1305_32.h103
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c130
-rw-r--r--security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c20
-rw-r--r--security/nss/lib/nss/nss.h6
-rw-r--r--security/nss/lib/pk11wrap/pk11akey.c18
-rw-r--r--security/nss/lib/pk11wrap/pk11pars.c8
-rw-r--r--security/nss/lib/pkcs12/p12e.c5
-rw-r--r--security/nss/lib/pkcs7/p7decode.c1
-rw-r--r--security/nss/lib/pki/pki3hack.c4
-rw-r--r--security/nss/lib/smime/cmsrecinfo.c2
-rw-r--r--security/nss/lib/softoken/legacydb/pcertdb.c3
-rw-r--r--security/nss/lib/softoken/lowkey.c24
-rw-r--r--security/nss/lib/softoken/lowkeyi.h1
-rw-r--r--security/nss/lib/softoken/lowkeyti.h9
-rw-r--r--security/nss/lib/softoken/lowpbe.c10
-rw-r--r--security/nss/lib/softoken/pkcs11.c72
-rw-r--r--security/nss/lib/softoken/pkcs11c.c116
-rw-r--r--security/nss/lib/softoken/pkcs11u.c4
-rw-r--r--security/nss/lib/softoken/sdb.c69
-rw-r--r--security/nss/lib/softoken/sftkdb.c3
-rw-r--r--security/nss/lib/softoken/sftkpars.c34
-rw-r--r--security/nss/lib/softoken/sftkpwd.c6
-rw-r--r--security/nss/lib/softoken/softkver.h6
-rw-r--r--security/nss/lib/ssl/SSLerrs.h11
-rw-r--r--security/nss/lib/ssl/dtls13con.c59
-rw-r--r--security/nss/lib/ssl/dtls13con.h4
-rw-r--r--security/nss/lib/ssl/dtlscon.c116
-rw-r--r--security/nss/lib/ssl/dtlscon.h2
-rw-r--r--security/nss/lib/ssl/ssl.h81
-rw-r--r--security/nss/lib/ssl/ssl3con.c430
-rw-r--r--security/nss/lib/ssl/ssl3ecc.c6
-rw-r--r--security/nss/lib/ssl/ssl3ext.c13
-rw-r--r--security/nss/lib/ssl/ssl3ext.h3
-rw-r--r--security/nss/lib/ssl/ssl3exthandle.c181
-rw-r--r--security/nss/lib/ssl/ssl3exthandle.h7
-rw-r--r--security/nss/lib/ssl/ssl3gthr.c109
-rw-r--r--security/nss/lib/ssl/ssl3prot.h2
-rw-r--r--security/nss/lib/ssl/sslcert.c3
-rw-r--r--security/nss/lib/ssl/sslerr.h2
-rw-r--r--security/nss/lib/ssl/sslimpl.h39
-rw-r--r--security/nss/lib/ssl/sslsecur.c19
-rw-r--r--security/nss/lib/ssl/sslsock.c123
-rw-r--r--security/nss/lib/ssl/sslspec.c1
-rw-r--r--security/nss/lib/ssl/sslspec.h8
-rw-r--r--security/nss/lib/ssl/sslt.h3
-rw-r--r--security/nss/lib/ssl/tls13con.c262
-rw-r--r--security/nss/lib/ssl/tls13con.h2
-rw-r--r--security/nss/lib/ssl/tls13exthandle.c4
-rw-r--r--security/nss/lib/util/nssutil.def7
-rw-r--r--security/nss/lib/util/nssutil.h6
-rw-r--r--security/nss/lib/util/pkcs11t.h2
-rw-r--r--security/nss/lib/util/secasn1d.c4
-rw-r--r--security/nss/lib/util/secitem.c9
-rw-r--r--security/nss/lib/util/secitem.h8
-rw-r--r--security/nss/nss-tool/enc/enctool.cc1
-rwxr-xr-xsecurity/nss/tests/all.sh2
-rwxr-xr-xsecurity/nss/tests/bogo/bogo.sh9
-rwxr-xr-xsecurity/nss/tests/cert/cert.sh76
-rw-r--r--security/nss/tests/common/init.sh7
-rw-r--r--security/nss/tests/interop/interop.sh2
-rwxr-xr-xsecurity/nss/tests/ssl/ssl.sh122
-rwxr-xr-xsecurity/nss/tests/ssl_gtests/ssl_gtests.sh2
-rw-r--r--security/nss/tests/tools/TestRSAPSS.p12bin0 -> 2554 bytes
-rw-r--r--security/nss/tests/tools/tools.sh21
197 files changed, 4873 insertions, 7145 deletions
diff --git a/CLOBBER b/CLOBBER
index fd0b259671..76ebbb54bf 100644
--- a/CLOBBER
+++ b/CLOBBER
@@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
-Clobber for updating NSPR+NSS
+Clobber required for updating NSS to 3.38 (poly1305 symbol changes)
diff --git a/config/external/nss/nss.symbols b/config/external/nss/nss.symbols
index ba5492c37a..3239d3119c 100644
--- a/config/external/nss/nss.symbols
+++ b/config/external/nss/nss.symbols
@@ -271,7 +271,6 @@ NSS_IsInitialized
NSS_OptionSet
NSS_NoDB_Init
NSS_SecureMemcmp
-NSS_SecureMemcmpZero
NSS_SetAlgorithmPolicy
NSS_SetDomesticPolicy
NSS_Shutdown
@@ -490,7 +489,6 @@ PORT_UCS2_ASCIIConversion_Util
PORT_UCS2_UTF8Conversion
PORT_UCS2_UTF8Conversion_Util
PORT_ZAlloc
-PORT_ZAllocAlignedOffset_Util
PORT_ZAlloc_Util
PORT_ZFree_Util
SEC_AnyTemplate_Util @DATA@
@@ -725,9 +723,17 @@ VFY_VerifyDataWithAlgorithmID
VFY_VerifyDigestDirect
_SGN_VerifyPKCS1DigestInfo
__PK11_SetCertificateNickname
-# These symbols are not used by Firefox itself, but are used by Java's security
-# libraries, which in turn are used by Java applets/plugins/etc. Provide them
-# to make Java code happy.
+# These symbols are not used by applications but are possibly used across
+# NSS library boundaries.
+NSS_SecureMemcmpZero
+PORT_ZAllocAlignedOffset_Util
+CERT_FindCertByNicknameOrEmailAddrCX
+SECKEY_GetPrivateKeyType
+SEC_DerSignDataWithAlgorithmID
+SEC_CreateSignatureAlgorithmParameters
+# These symbols are not used by applicatons themselves, but are used by
+# Java's security libraries, which in turn are used by Java
+# applets/plugins/etc. Provide them to make Java code happy.
NSS_VersionCheck
NSS_Initialize
#ifdef NSS_EXTRA_SYMBOLS_FILE
diff --git a/security/nss/TAG-INFO b/security/nss/TAG-INFO
index 1d96321b3c..a004fa449d 100644
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1 +1 @@
-NSS_3_36_4_RTM
+NSS_3_38_RTM
diff --git a/security/nss/automation/abi-check/expected-report-libnssutil3.so.txt b/security/nss/automation/abi-check/expected-report-libnssutil3.so.txt
index e69de29bb2..efc7d6d677 100644
--- a/security/nss/automation/abi-check/expected-report-libnssutil3.so.txt
+++ b/security/nss/automation/abi-check/expected-report-libnssutil3.so.txt
@@ -0,0 +1,4 @@
+
+1 Added function:
+
+ 'function SECStatus SECITEM_MakeItem(PLArenaPool*, SECItem*, unsigned char*, unsigned int)' {SECITEM_MakeItem@@NSSUTIL_3.38}
diff --git a/security/nss/automation/abi-check/expected-report-libssl3.so.txt b/security/nss/automation/abi-check/expected-report-libssl3.so.txt
index ad818d0aaa..e69de29bb2 100644
--- a/security/nss/automation/abi-check/expected-report-libssl3.so.txt
+++ b/security/nss/automation/abi-check/expected-report-libssl3.so.txt
@@ -1,28 +0,0 @@
-
-1 function with some indirect sub-type change:
-
- [C]'function SECStatus SSL_GetChannelInfo(PRFileDesc*, SSLChannelInfo*, PRUintn)' at sslinfo.c:12:1 has some indirect sub-type changes:
- parameter 2 of type 'SSLChannelInfo*' has sub-type changes:
- in pointed to type 'typedef SSLChannelInfo' at sslt.h:318:1:
- underlying type 'struct SSLChannelInfoStr' at sslt.h:251:1 changed:
- type size hasn't changed
- 1 data member change:
- type of 'SSLSignatureScheme SSLChannelInfoStr::signatureScheme' changed:
- underlying type 'enum __anonymous_enum__' at sslt.h:115:1 changed:
- type size hasn't changed
- 3 enumerator deletions:
- '__anonymous_enum__::ssl_sig_rsa_pss_sha256' value '2052'
- '__anonymous_enum__::ssl_sig_rsa_pss_sha384' value '2053'
- '__anonymous_enum__::ssl_sig_rsa_pss_sha512' value '2054'
-
- 6 enumerator insertions:
- '__anonymous_enum__::ssl_sig_rsa_pss_rsae_sha256' value '2052'
- '__anonymous_enum__::ssl_sig_rsa_pss_rsae_sha384' value '2053'
- '__anonymous_enum__::ssl_sig_rsa_pss_rsae_sha512' value '2054'
- '__anonymous_enum__::ssl_sig_rsa_pss_pss_sha256' value '2057'
- '__anonymous_enum__::ssl_sig_rsa_pss_pss_sha384' value '2058'
- '__anonymous_enum__::ssl_sig_rsa_pss_pss_sha512' value '2059'
-
-
-
-
diff --git a/security/nss/automation/abi-check/previous-nss-release b/security/nss/automation/abi-check/previous-nss-release
index c213ca3f88..c52061e7e2 100644
--- a/security/nss/automation/abi-check/previous-nss-release
+++ b/security/nss/automation/abi-check/previous-nss-release
@@ -1 +1 @@
-NSS_3_35_BRANCH
+NSS_3_37_BRANCH
diff --git a/security/nss/automation/taskcluster/docker-hacl/Dockerfile b/security/nss/automation/taskcluster/docker-hacl/Dockerfile
index 63f9a24e25..50f2be239c 100644
--- a/security/nss/automation/taskcluster/docker-hacl/Dockerfile
+++ b/security/nss/automation/taskcluster/docker-hacl/Dockerfile
@@ -5,11 +5,11 @@ MAINTAINER Franziskus Kiefer <franziskuskiefer@gmail.com>
# the original F* formula with Daniel Fabian
# Pinned versions of HACL* (F* and KreMLin are pinned as submodules)
-ENV haclrepo https://github.com/franziskuskiefer/hacl-star.git
+ENV haclrepo https://github.com/mitls/hacl-star.git
# Define versions of dependencies
-ENV opamv 4.04.2
-ENV haclversion 668d6cf274c33bbe2e951e3a84b73f2b6442a51f
+ENV opamv 4.05.0
+ENV haclversion 1da331f9ef30e13269e45ae73bbe4a4bca679ae6
# Install required packages and set versions
ADD setup.sh /tmp/setup.sh
diff --git a/security/nss/automation/taskcluster/docker-hacl/setup-user.sh b/security/nss/automation/taskcluster/docker-hacl/setup-user.sh
index b8accaf584..e2c0b857bc 100644
--- a/security/nss/automation/taskcluster/docker-hacl/setup-user.sh
+++ b/security/nss/automation/taskcluster/docker-hacl/setup-user.sh
@@ -16,7 +16,6 @@ git -C hacl-star checkout ${haclversion}
# This caches the extracted c code (pins the HACL* version). All we need to do
# on CI now is comparing the code in this docker image with the one in NSS.
opam config exec -- make -C hacl-star prepare -j$(nproc)
-make -C hacl-star verify-nss -j$(nproc)
make -C hacl-star -f Makefile.build snapshots/nss -j$(nproc)
KOPTS="-funroll-loops 5" make -C hacl-star/code/curve25519 test -j$(nproc)
make -C hacl-star/code/salsa-family test -j$(nproc)
diff --git a/security/nss/automation/taskcluster/docker-saw/Dockerfile b/security/nss/automation/taskcluster/docker-saw/Dockerfile
index a481ba0486..d677870109 100644
--- a/security/nss/automation/taskcluster/docker-saw/Dockerfile
+++ b/security/nss/automation/taskcluster/docker-saw/Dockerfile
@@ -1,4 +1,4 @@
-FROM ubuntu:latest
+FROM ubuntu:16.04
MAINTAINER Tim Taubert <ttaubert@mozilla.com>
RUN useradd -d /home/worker -s /bin/bash -m worker
diff --git a/security/nss/automation/taskcluster/docker/Dockerfile b/security/nss/automation/taskcluster/docker/Dockerfile
index 8a2256d12c..b3c2516baa 100644
--- a/security/nss/automation/taskcluster/docker/Dockerfile
+++ b/security/nss/automation/taskcluster/docker/Dockerfile
@@ -12,9 +12,6 @@ RUN chmod +x /home/worker/bin/*
ADD setup.sh /tmp/setup.sh
RUN bash /tmp/setup.sh
-# Change user.
-USER worker
-
# Env variables.
ENV HOME /home/worker
ENV SHELL /bin/bash
diff --git a/security/nss/automation/taskcluster/graph/src/extend.js b/security/nss/automation/taskcluster/graph/src/extend.js
index ee9ac9b742..5305325c52 100644
--- a/security/nss/automation/taskcluster/graph/src/extend.js
+++ b/security/nss/automation/taskcluster/graph/src/extend.js
@@ -995,13 +995,13 @@ async function scheduleTools() {
}));
queue.scheduleTask(merge(base, {
- symbol: "scan-build-5.0",
- name: "scan-build-5.0",
- image: LINUX_IMAGE,
+ symbol: "scan-build",
+ name: "scan-build",
+ image: FUZZ_IMAGE,
env: {
USE_64: "1",
- CC: "clang-5.0",
- CCC: "clang++-5.0",
+ CC: "clang",
+ CCC: "clang++",
},
artifacts: {
public: {
@@ -1092,5 +1092,17 @@ async function scheduleTools() {
]
}));
+ queue.scheduleTask(merge(base, {
+ symbol: "Coverage",
+ name: "Coverage",
+ image: FUZZ_IMAGE,
+ features: ["allowPtrace"],
+ command: [
+ "/bin/bash",
+ "-c",
+ "bin/checkout.sh && nss/automation/taskcluster/scripts/gen_coverage_report.sh"
+ ]
+ }));
+
return queue.submit();
}
diff --git a/security/nss/automation/taskcluster/graph/src/try_syntax.js b/security/nss/automation/taskcluster/graph/src/try_syntax.js
index 1c06dde133..214793bd5d 100644
--- a/security/nss/automation/taskcluster/graph/src/try_syntax.js
+++ b/security/nss/automation/taskcluster/graph/src/try_syntax.js
@@ -51,7 +51,7 @@ function parseOptions(opts) {
}
// Parse tools.
- let allTools = ["clang-format", "scan-build", "hacl", "saw", "abi"];
+ let allTools = ["clang-format", "scan-build", "hacl", "saw", "abi", "coverage"];
let tools = intersect(opts.tools.split(/\s*,\s*/), allTools);
// If the given value is "all" run all tools.
diff --git a/security/nss/automation/taskcluster/scripts/gen_coverage_report.sh b/security/nss/automation/taskcluster/scripts/gen_coverage_report.sh
new file mode 100644
index 0000000000..3907c72e89
--- /dev/null
+++ b/security/nss/automation/taskcluster/scripts/gen_coverage_report.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+source $(dirname "$0")/tools.sh
+
+# Clone NSPR.
+hg_clone https://hg.mozilla.org/projects/nspr ./nspr default
+
+out=/home/worker/artifacts
+mkdir -p $out
+
+# Generate coverage report.
+cd nss && ./mach coverage --outdir=$out ssl_gtests
diff --git a/security/nss/automation/taskcluster/scripts/run_hacl.sh b/security/nss/automation/taskcluster/scripts/run_hacl.sh
index 281075eef4..6cbda49b4b 100644
--- a/security/nss/automation/taskcluster/scripts/run_hacl.sh
+++ b/security/nss/automation/taskcluster/scripts/run_hacl.sh
@@ -12,8 +12,8 @@ set -e -x -v
# The extracted C code from HACL* is already generated and the HACL* tests were
# successfully executed.
-# Verify Poly1305 (doesn't work in docker image build)
-make verify -C ~/hacl-star/code/poly1305 -j$(nproc)
+# Verify HACL*. Taskcluster fails when we do this in the image build.
+make -C hacl-star verify-nss -j$(nproc)
# Add license header to specs
spec_files=($(find ~/hacl-star/specs -type f -name '*.fst'))
diff --git a/security/nss/automation/taskcluster/scripts/tools.sh b/security/nss/automation/taskcluster/scripts/tools.sh
index 46d567e3a2..534cb32ce6 100644
--- a/security/nss/automation/taskcluster/scripts/tools.sh
+++ b/security/nss/automation/taskcluster/scripts/tools.sh
@@ -3,11 +3,16 @@
set -v -e -x
if [[ $(id -u) -eq 0 ]]; then
+ # Stupid Docker. It works without sometimes... But not always.
+ echo "127.0.0.1 localhost.localdomain" >> /etc/hosts
+
# Drop privileges by re-running this script.
# Note: this mangles arguments, better to avoid running scripts as root.
exec su worker -c "$0 $*"
fi
+export PATH="${PATH}:/home/worker/.cargo/bin/:/usr/lib/go-1.6/bin"
+
# Usage: hg_clone repo dir [revision=@]
hg_clone() {
repo=$1
diff --git a/security/nss/cmd/bltest/blapitest.c b/security/nss/cmd/bltest/blapitest.c
index ca3d6f3144..ef8fdd8021 100644
--- a/security/nss/cmd/bltest/blapitest.c
+++ b/security/nss/cmd/bltest/blapitest.c
@@ -3724,7 +3724,7 @@ main(int argc, char **argv)
/* test the RSA_PopulatePrivateKey function */
if (bltest.commands[cmd_RSAPopulate].activated) {
unsigned int keySize = 1024;
- unsigned long exponent = 65537;
+ unsigned long keyExponent = 65537;
int rounds = 1;
int ret = -1;
@@ -3735,12 +3735,12 @@ main(int argc, char **argv)
rounds = PORT_Atoi(bltest.options[opt_Rounds].arg);
}
if (bltest.options[opt_Exponent].activated) {
- exponent = PORT_Atoi(bltest.options[opt_Exponent].arg);
+ keyExponent = PORT_Atoi(bltest.options[opt_Exponent].arg);
}
for (i = 0; i < rounds; i++) {
printf("Running RSA Populate test round %d\n", i);
- ret = doRSAPopulateTest(keySize, exponent);
+ ret = doRSAPopulateTest(keySize, keyExponent);
if (ret != 0) {
break;
}
diff --git a/security/nss/cmd/certutil/certutil.c b/security/nss/cmd/certutil/certutil.c
index 20722ae782..dbb93c9220 100644
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -36,9 +36,11 @@
#include "certdb.h"
#include "nss.h"
#include "certutil.h"
+#include "basicutil.h"
+#include "ssl.h"
#define MIN_KEY_BITS 512
-/* MAX_KEY_BITS should agree with MAX_RSA_MODULUS in freebl */
+/* MAX_KEY_BITS should agree with RSA_MAX_MODULUS_BITS in freebl */
#define MAX_KEY_BITS 8192
#define DEFAULT_KEY_BITS 2048
@@ -447,7 +449,8 @@ ChangeTrustAttributes(CERTCertDBHandle *handle, PK11SlotInfo *slot,
}
static SECStatus
-DumpChain(CERTCertDBHandle *handle, char *name, PRBool ascii)
+DumpChain(CERTCertDBHandle *handle, char *name, PRBool ascii,
+ PRBool simpleSelfSigned)
{
CERTCertificate *the_cert;
CERTCertificateList *chain;
@@ -458,6 +461,14 @@ DumpChain(CERTCertDBHandle *handle, char *name, PRBool ascii)
SECU_PrintError(progName, "Could not find: %s\n", name);
return SECFailure;
}
+ if (simpleSelfSigned &&
+ SECEqual == SECITEM_CompareItem(&the_cert->derIssuer,
+ &the_cert->derSubject)) {
+ printf("\"%s\" [%s]\n\n", the_cert->nickname, the_cert->subjectName);
+ CERT_DestroyCertificate(the_cert);
+ return SECSuccess;
+ }
+
chain = CERT_CertChainFromCert(the_cert, 0, PR_TRUE);
CERT_DestroyCertificate(the_cert);
if (!chain) {
@@ -782,17 +793,17 @@ ValidateCert(CERTCertDBHandle *handle, char *name, char *date,
fprintf(stdout, "%s: certificate is valid\n", progName);
GEN_BREAK(SECSuccess)
} else {
- char *name;
+ char *nick;
CERTVerifyLogNode *node;
node = log->head;
while (node) {
if (node->cert->nickname != NULL) {
- name = node->cert->nickname;
+ nick = node->cert->nickname;
} else {
- name = node->cert->subjectName;
+ nick = node->cert->subjectName;
}
- fprintf(stderr, "%s : %s\n", name,
+ fprintf(stderr, "%s : %s\n", nick,
SECU_Strerror(node->error));
CERT_DestroyCertificate(node->cert);
node = node->next;
@@ -845,7 +856,7 @@ SECItemToHex(const SECItem *item, char *dst)
}
static const char *const keyTypeName[] = {
- "null", "rsa", "dsa", "fortezza", "dh", "kea", "ec"
+ "null", "rsa", "dsa", "fortezza", "dh", "kea", "ec", "rsaPss"
};
#define MAX_CKA_ID_BIN_LEN 20
@@ -999,7 +1010,7 @@ DeleteKey(char *nickname, secuPWData *pwdata)
slot = PK11_GetInternalKeySlot();
if (PK11_NeedLogin(slot)) {
- SECStatus rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
+ rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
if (rv != SECSuccess) {
SECU_PrintError(progName, "could not authenticate to token %s.",
PK11_GetTokenName(slot));
@@ -1066,7 +1077,7 @@ PrintBuildFlags()
}
static void
-PrintSyntax(char *progName)
+PrintSyntax()
{
#define FPS fprintf(stderr,
FPS "Type %s -H for more detailed descriptions\n", progName);
@@ -1115,7 +1126,9 @@ PrintSyntax(char *progName)
FPS "\t%s --build-flags\n", progName);
FPS "\t%s -M -n cert-name -t trustargs [-d certdir] [-P dbprefix]\n",
progName);
- FPS "\t%s -O -n cert-name [-X] [-d certdir] [-a] [-P dbprefix]\n", progName);
+ FPS "\t%s -O -n cert-name [-X] [-d certdir] [-a] [-P dbprefix]\n"
+ "\t\t [--simple-self-signed]\n",
+ progName);
FPS "\t%s -R -s subj -o cert-request-file [-d certdir] [-P dbprefix] [-p phone] [-a]\n"
"\t\t [-7 emailAddrs] [-k key-type-or-id] [-h token-name] [-f pwfile]\n"
"\t\t [-g key-size] [-Z hashAlg]\n",
@@ -1542,6 +1555,8 @@ luO(enum usage_level ul, const char *command)
" -P dbprefix");
FPS "%-20s force the database to open R/W\n",
" -X");
+ FPS "%-20s don't search for a chain if issuer name equals subject name\n",
+ " --simple-self-signed");
FPS "\n");
}
@@ -1560,7 +1575,7 @@ luR(enum usage_level ul, const char *command)
" -o output-req");
FPS "%-20s Type of key pair to generate (\"dsa\", \"ec\", \"rsa\" (default))\n",
" -k key-type-or-id");
- FPS "%-20s or nickname of the cert key to use \n",
+ FPS "%-20s or nickname of the cert key to use, or key id obtained using -K\n",
"");
FPS "%-20s Name of token in which to generate key (default is internal)\n",
" -h token-name");
@@ -1838,7 +1853,7 @@ luBuildFlags(enum usage_level ul, const char *command)
}
static void
-LongUsage(char *progName, enum usage_level ul, const char *command)
+LongUsage(enum usage_level ul, const char *command)
{
luA(ul, command);
luB(ul, command);
@@ -1866,14 +1881,14 @@ LongUsage(char *progName, enum usage_level ul, const char *command)
}
static void
-Usage(char *progName)
+Usage()
{
PR_fprintf(PR_STDERR,
"%s - Utility to manipulate NSS certificate databases\n\n"
"Usage: %s <command> -d <database-directory> <options>\n\n"
"Valid commands:\n",
progName, progName);
- LongUsage(progName, usage_selected, NULL);
+ LongUsage(usage_selected, NULL);
PR_fprintf(PR_STDERR, "\n"
"%s -H <command> : Print available options for the given command\n"
"%s -H : Print complete help output of all commands and options\n"
@@ -2269,10 +2284,10 @@ flagArray opFlagsArray[] =
{ NAME_SIZE(verify_recover), CKF_VERIFY_RECOVER },
{ NAME_SIZE(wrap), CKF_WRAP },
{ NAME_SIZE(unwrap), CKF_UNWRAP },
- { NAME_SIZE(derive), CKF_DERIVE },
+ { NAME_SIZE(derive), CKF_DERIVE }
};
-int opFlagsCount = sizeof(opFlagsArray) / sizeof(flagArray);
+int opFlagsCount = PR_ARRAY_SIZE(opFlagsArray);
flagArray attrFlagsArray[] =
{
@@ -2286,14 +2301,13 @@ flagArray attrFlagsArray[] =
{ NAME_SIZE(insensitive), PK11_ATTR_INSENSITIVE },
{ NAME_SIZE(extractable), PK11_ATTR_EXTRACTABLE },
{ NAME_SIZE(unextractable), PK11_ATTR_UNEXTRACTABLE }
-
};
-int attrFlagsCount = sizeof(attrFlagsArray) / sizeof(flagArray);
+int attrFlagsCount = PR_ARRAY_SIZE(attrFlagsArray);
#define MAX_STRING 30
CK_ULONG
-GetFlags(char *flagsString, flagArray *flagArray, int count)
+GetFlags(char *flagsString, flagArray *flags, int count)
{
CK_ULONG flagsValue = strtol(flagsString, NULL, 0);
int i;
@@ -2303,10 +2317,10 @@ GetFlags(char *flagsString, flagArray *flagArray, int count)
}
while (*flagsString) {
for (i = 0; i < count; i++) {
- if (strncmp(flagsString, flagArray[i].name, flagArray[i].nameSize) ==
+ if (strncmp(flagsString, flags[i].name, flags[i].nameSize) ==
0) {
- flagsValue |= flagArray[i].value;
- flagsString += flagArray[i].nameSize;
+ flagsValue |= flags[i].value;
+ flagsString += flags[i].nameSize;
if (*flagsString != 0) {
flagsString++;
}
@@ -2499,6 +2513,7 @@ enum certutilOpts {
opt_NewNickname,
opt_Pss,
opt_PssSign,
+ opt_SimpleSelfSigned,
opt_Help
};
@@ -2623,6 +2638,8 @@ static const secuCommandFlag options_init[] =
"pss" },
{ /* opt_PssSign */ 0, PR_FALSE, 0, PR_FALSE,
"pss-sign" },
+ { /* opt_SimpleSelfSigned */ 0, PR_FALSE, 0, PR_FALSE,
+ "simple-self-signed" },
};
#define NUM_OPTIONS ((sizeof options_init) / (sizeof options_init[0]))
@@ -2691,14 +2708,13 @@ certutil_main(int argc, char **argv, PRBool initialize)
rv = SECU_ParseCommandLine(argc, argv, progName, &certutil);
if (rv != SECSuccess)
- Usage(progName);
+ Usage();
if (certutil.commands[cmd_PrintSyntax].activated) {
- PrintSyntax(progName);
+ PrintSyntax();
}
if (certutil.commands[cmd_PrintHelp].activated) {
- int i;
char buf[2];
const char *command = NULL;
for (i = 0; i < max_cmd; i++) {
@@ -2715,7 +2731,7 @@ certutil_main(int argc, char **argv, PRBool initialize)
break;
}
}
- LongUsage(progName, (command ? usage_selected : usage_all), command);
+ LongUsage((command ? usage_selected : usage_all), command);
exit(1);
}
@@ -2823,7 +2839,7 @@ certutil_main(int argc, char **argv, PRBool initialize)
if (certutil.options[opt_DBPrefix].arg) {
certPrefix = certutil.options[opt_DBPrefix].arg;
} else {
- Usage(progName);
+ Usage();
}
}
@@ -2832,7 +2848,7 @@ certutil_main(int argc, char **argv, PRBool initialize)
if (certutil.options[opt_SourcePrefix].arg) {
srcCertPrefix = certutil.options[opt_SourcePrefix].arg;
} else {
- Usage(progName);
+ Usage();
}
}
@@ -2916,7 +2932,7 @@ certutil_main(int argc, char **argv, PRBool initialize)
return 255;
}
if (commandsEntered == 0) {
- Usage(progName);
+ Usage();
}
if (certutil.commands[cmd_ListCerts].activated ||
@@ -3124,6 +3140,8 @@ certutil_main(int argc, char **argv, PRBool initialize)
}
initialized = PR_TRUE;
SECU_RegisterDynamicOids();
+ /* Ensure the SSL error code table has been registered. Bug 1460284. */
+ SSL_OptionSetDefault(-1, 0);
}
certHandle = CERT_GetDefaultCertDB();
@@ -3350,7 +3368,8 @@ certutil_main(int argc, char **argv, PRBool initialize)
}
if (certutil.commands[cmd_DumpChain].activated) {
rv = DumpChain(certHandle, name,
- certutil.options[opt_ASCIIForIO].activated);
+ certutil.options[opt_ASCIIForIO].activated,
+ certutil.options[opt_SimpleSelfSigned].activated);
goto shutdown;
}
/* XXX needs work */
@@ -3444,37 +3463,80 @@ certutil_main(int argc, char **argv, PRBool initialize)
keycert = CERT_FindCertByNicknameOrEmailAddr(certHandle, keysource);
if (!keycert) {
keycert = PK11_FindCertFromNickname(keysource, NULL);
- if (!keycert) {
- SECU_PrintError(progName,
- "%s is neither a key-type nor a nickname", keysource);
+ }
+
+ if (keycert) {
+ privkey = PK11_FindKeyByDERCert(slot, keycert, &pwdata);
+ } else {
+ PLArenaPool *arena = NULL;
+ SECItem keyidItem = { 0 };
+ char *keysourcePtr = keysource;
+ /* Interpret keysource as CKA_ID */
+ if (PK11_NeedLogin(slot)) {
+ rv = PK11_Authenticate(slot, PR_TRUE, &pwdata);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "could not authenticate to token %s.",
+ PK11_GetTokenName(slot));
+ return SECFailure;
+ }
+ }
+ if (0 == PL_strncasecmp("0x", keysource, 2)) {
+ keysourcePtr = keysource + 2; // skip leading "0x"
+ }
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ SECU_PrintError(progName, "unable to allocate arena");
return SECFailure;
}
+ if (SECU_HexString2SECItem(arena, &keyidItem, keysourcePtr)) {
+ privkey = PK11_FindKeyByKeyID(slot, &keyidItem, &pwdata);
+ }
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+
+ if (!privkey) {
+ SECU_PrintError(
+ progName,
+ "%s is neither a key-type nor a nickname nor a key-id", keysource);
+ return SECFailure;
}
- privkey = PK11_FindKeyByDERCert(slot, keycert, &pwdata);
- if (privkey)
- pubkey = CERT_ExtractPublicKey(keycert);
+
+ pubkey = SECKEY_ConvertToPublicKey(privkey);
if (!pubkey) {
SECU_PrintError(progName,
"Could not get keys from cert %s", keysource);
+ if (keycert) {
+ CERT_DestroyCertificate(keycert);
+ }
rv = SECFailure;
- CERT_DestroyCertificate(keycert);
goto shutdown;
}
keytype = privkey->keyType;
+
/* On CertReq for renewal if no subject has been
* specified obtain it from the certificate.
*/
if (certutil.commands[cmd_CertReq].activated && !subject) {
- subject = CERT_AsciiToName(keycert->subjectName);
- if (!subject) {
- SECU_PrintError(progName,
- "Could not get subject from certificate %s", keysource);
- CERT_DestroyCertificate(keycert);
+ if (keycert) {
+ subject = CERT_AsciiToName(keycert->subjectName);
+ if (!subject) {
+ SECU_PrintError(
+ progName,
+ "Could not get subject from certificate %s",
+ keysource);
+ CERT_DestroyCertificate(keycert);
+ rv = SECFailure;
+ goto shutdown;
+ }
+ } else {
+ SECU_PrintError(progName, "Subject name not provided");
rv = SECFailure;
goto shutdown;
}
}
- CERT_DestroyCertificate(keycert);
+ if (keycert) {
+ CERT_DestroyCertificate(keycert);
+ }
} else {
privkey =
CERTUTIL_GeneratePrivateKey(keytype, slot, keysize,
@@ -3537,6 +3599,14 @@ certutil_main(int argc, char **argv, PRBool initialize)
}
}
+ if (certutil.options[opt_SimpleSelfSigned].activated &&
+ !certutil.commands[cmd_DumpChain].activated) {
+ PR_fprintf(PR_STDERR,
+ "%s -%c: --simple-self-signed only works with -O.\n",
+ progName, commandToRun);
+ return 255;
+ }
+
/* If we need a list of extensions convert the flags into list format */
if (certutil.commands[cmd_CertReq].activated ||
certutil.commands[cmd_CreateAndAddCert].activated ||
diff --git a/security/nss/cmd/crlutil/crlutil.c b/security/nss/cmd/crlutil/crlutil.c
index c008ecc01a..c5527fc932 100644
--- a/security/nss/cmd/crlutil/crlutil.c
+++ b/security/nss/cmd/crlutil/crlutil.c
@@ -770,7 +770,7 @@ loser:
}
static void
-Usage(char *progName)
+Usage()
{
fprintf(stderr,
"Usage: %s -L [-n nickname] [-d keydir] [-P dbprefix] [-t crlType]\n"
@@ -908,7 +908,7 @@ main(int argc, char **argv)
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
case '?':
- Usage(progName);
+ Usage();
break;
case 'T':
@@ -1038,17 +1038,17 @@ main(int argc, char **argv)
}
if (deleteCRL && !nickName)
- Usage(progName);
+ Usage();
if (importCRL && !inFile)
- Usage(progName);
+ Usage();
if (showFileCRL && !inFile)
- Usage(progName);
+ Usage();
if ((generateCRL && !nickName) ||
(modifyCRL && !inFile && !nickName))
- Usage(progName);
+ Usage();
if (!(listCRL || deleteCRL || importCRL || showFileCRL || generateCRL ||
modifyCRL || test || erase))
- Usage(progName);
+ Usage();
if (listCRL || showFileCRL) {
readonly = PR_TRUE;
diff --git a/security/nss/cmd/crmftest/testcrmf.c b/security/nss/cmd/crmftest/testcrmf.c
index cbc680b08f..1c1359b1bc 100644
--- a/security/nss/cmd/crmftest/testcrmf.c
+++ b/security/nss/cmd/crmftest/testcrmf.c
@@ -577,7 +577,6 @@ Decode(void)
printf("WARNING: The DER contained %d messages.\n", numMsgs);
}
for (i = 0; i < numMsgs; i++) {
- SECStatus rv;
printf("crmftest: Processing cert request %d\n", i);
certReqMsg = CRMF_CertReqMessagesGetCertReqMsgAtIndex(certReqMsgs, i);
if (certReqMsg == NULL) {
diff --git a/security/nss/cmd/dbtest/dbtest.c b/security/nss/cmd/dbtest/dbtest.c
index 9a6a034a69..11713c23fb 100644
--- a/security/nss/cmd/dbtest/dbtest.c
+++ b/security/nss/cmd/dbtest/dbtest.c
@@ -58,7 +58,7 @@ getPassword(PK11SlotInfo *slot, PRBool retry, void *arg)
}
static void
-Usage(const char *progName)
+Usage()
{
printf("Usage: %s [-r] [-f] [-i] [-d dbdir ] \n",
progName);
@@ -96,7 +96,7 @@ main(int argc, char **argv)
switch (optstate->option) {
case 'h':
default:
- Usage(progName);
+ Usage();
break;
case 'r':
@@ -122,7 +122,7 @@ main(int argc, char **argv)
}
PL_DestroyOptState(optstate);
if (optstatus == PL_OPT_BAD)
- Usage(progName);
+ Usage();
if (dbDir) {
char *tmp = dbDir;
@@ -181,7 +181,6 @@ main(int argc, char **argv)
ret = SUCCESS;
if (doInitTest) {
PK11SlotInfo *slot = PK11_GetInternalKeySlot();
- SECStatus rv;
int passwordSuccess = 0;
int type = CKM_DES3_CBC;
SECItem keyid = { 0, NULL, 0 };
diff --git a/security/nss/cmd/httpserv/httpserv.c b/security/nss/cmd/httpserv/httpserv.c
index 7cf28c65a0..71e2ab88d9 100644
--- a/security/nss/cmd/httpserv/httpserv.c
+++ b/security/nss/cmd/httpserv/httpserv.c
@@ -682,6 +682,7 @@ handle_connection(
}
if (arena) {
PORT_FreeArena(arena, PR_FALSE);
+ arena = NULL;
}
if (!request || !request->tbsRequest ||
!request->tbsRequest->requestList ||
@@ -753,11 +754,11 @@ handle_connection(
{
PRTime now = PR_Now();
- PLArenaPool *arena = NULL;
CERTOCSPSingleResponse *sr;
CERTOCSPSingleResponse **singleResponses;
SECItem *ocspResponse;
+ PORT_Assert(!arena);
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (unknown) {
@@ -787,8 +788,8 @@ handle_connection(
} else {
PR_Write(ssl_sock, outOcspHeader, strlen(outOcspHeader));
PR_Write(ssl_sock, ocspResponse->data, ocspResponse->len);
- PORT_FreeArena(arena, PR_FALSE);
}
+ PORT_FreeArena(arena, PR_FALSE);
}
CERT_DestroyOCSPRequest(request);
break;
@@ -1357,7 +1358,6 @@ main(int argc, char **argv)
caRevoIter = &caRevoInfos->link;
do {
PRFileDesc *inFile;
- int rv = SECFailure;
SECItem crlDER;
crlDER.data = NULL;
@@ -1413,11 +1413,9 @@ main(int argc, char **argv)
if (provideOcsp) {
if (caRevoInfos) {
- PRCList *caRevoIter;
-
caRevoIter = &caRevoInfos->link;
do {
- caRevoInfo *revoInfo = (caRevoInfo *)caRevoIter;
+ revoInfo = (caRevoInfo *)caRevoIter;
if (revoInfo->nickname)
PORT_Free(revoInfo->nickname);
if (revoInfo->crlFilename)
diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c
index 2b33f89633..6be2df432a 100644
--- a/security/nss/cmd/lib/secutil.c
+++ b/security/nss/cmd/lib/secutil.c
@@ -1528,9 +1528,9 @@ SECU_PrintDumpDerIssuerAndSerial(FILE *out, SECItem *der, char *m,
unsigned int i;
for (i = 0; i < c->serialNumber.len; ++i) {
unsigned char *chardata = (unsigned char *)(c->serialNumber.data);
- unsigned char c = *(chardata + i);
+ unsigned char ch = *(chardata + i);
- fprintf(out, "\\x%02x", c);
+ fprintf(out, "\\x%02x", ch);
}
fprintf(out, "\" }\n");
}
@@ -3137,7 +3137,7 @@ typedef enum {
static int
secu_PrintSignedDataSigOpt(FILE *out, SECItem *der, const char *m,
int level, SECU_PPFunc inner,
- SignatureOptionType withSignature)
+ SignatureOptionType signatureOption)
{
PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
CERTSignedData *sd;
@@ -3164,7 +3164,7 @@ secu_PrintSignedDataSigOpt(FILE *out, SECItem *der, const char *m,
}
rv = (*inner)(out, &sd->data, "Data", level + 1);
- if (withSignature) {
+ if (signatureOption == withSignature) {
SECU_PrintAlgorithmID(out, &sd->signatureAlgorithm, "Signature Algorithm",
level + 1);
DER_ConvertBitString(&sd->signature);
diff --git a/security/nss/cmd/listsuites/listsuites.c b/security/nss/cmd/listsuites/listsuites.c
index 8eb2c3553e..b49f2d8cf4 100644
--- a/security/nss/cmd/listsuites/listsuites.c
+++ b/security/nss/cmd/listsuites/listsuites.c
@@ -64,9 +64,7 @@ main(int argc, char **argv)
/* disable all the SSL3 cipher suites */
for (i = 0; i < SSL_NumImplementedCiphers; i++) {
PRUint16 suite = cipherSuites[i];
- SECStatus rv;
PRBool enabled;
- PRErrorCode err;
SSLCipherSuiteInfo info;
rv = SSL_CipherPrefGetDefault(suite, &enabled);
diff --git a/security/nss/cmd/lowhashtest/lowhashtest.c b/security/nss/cmd/lowhashtest/lowhashtest.c
index 29d6ff4fd1..fcc06a86ee 100644
--- a/security/nss/cmd/lowhashtest/lowhashtest.c
+++ b/security/nss/cmd/lowhashtest/lowhashtest.c
@@ -390,7 +390,7 @@ testSHA512(NSSLOWInitContext *initCtx)
}
static void
-Usage(char *progName)
+Usage()
{
fprintf(stderr, "Usage: %s [algorithm]\n",
progName);
@@ -436,7 +436,7 @@ main(int argc, char **argv)
rv += testSHA512(initCtx);
} else {
SECU_PrintError(progName, "Unsupported hash type %s\n", argv[0]);
- Usage(progName);
+ Usage();
}
NSSLOW_Shutdown(initCtx);
diff --git a/security/nss/cmd/modutil/install-ds.c b/security/nss/cmd/modutil/install-ds.c
index 0305687626..576839f8f5 100644
--- a/security/nss/cmd/modutil/install-ds.c
+++ b/security/nss/cmd/modutil/install-ds.c
@@ -88,11 +88,11 @@ static const char* errString[] = {
static char* PR_Strdup(const char* str);
-#define PAD(x) \
- { \
- int i; \
- for (i = 0; i < x; i++) \
- printf(" "); \
+#define PAD(x) \
+ { \
+ int pad_i; \
+ for (pad_i = 0; pad_i < (x); pad_i++) \
+ printf(" "); \
}
#define PADINC 4
diff --git a/security/nss/cmd/mpitests/mpi-test.c b/security/nss/cmd/mpitests/mpi-test.c
index 3a1f5d6c2e..b7953b6f66 100644
--- a/security/nss/cmd/mpitests/mpi-test.c
+++ b/security/nss/cmd/mpitests/mpi-test.c
@@ -375,14 +375,14 @@ void reason(char *fmt, ...);
char g_intbuf[4096]; /* buffer for integer comparison */
char a_intbuf[4096]; /* buffer for integer comparison */
int g_verbose = 1; /* print out reasons for failure? */
-int res;
-
-#define IFOK(x) \
- { \
- if (MP_OKAY > (res = (x))) { \
- reason("test %s failed: error %d\n", #x, res); \
- return 1; \
- } \
+
+#define IFOK(x) \
+ { \
+ int ifok_res = (x); \
+ if (MP_OKAY > ifok_res) { \
+ reason("test %s failed: error %d\n", #x, ifok_res); \
+ return 1; \
+ } \
}
int
diff --git a/security/nss/cmd/ocspclnt/ocspclnt.c b/security/nss/cmd/ocspclnt/ocspclnt.c
index afcb7e13fb..0927f8ef63 100644
--- a/security/nss/cmd/ocspclnt/ocspclnt.c
+++ b/security/nss/cmd/ocspclnt/ocspclnt.c
@@ -38,7 +38,7 @@
char *program_name;
static void
-synopsis(char *program_name)
+synopsis(char *progname)
{
PRFileDesc *pr_stderr;
@@ -46,44 +46,44 @@ synopsis(char *program_name)
PR_fprintf(pr_stderr, "Usage:");
PR_fprintf(pr_stderr,
"\t%s -p [-d <dir>]\n",
- program_name);
+ progname);
PR_fprintf(pr_stderr,
"\t%s -P [-d <dir>]\n",
- program_name);
+ progname);
PR_fprintf(pr_stderr,
"\t%s -r <name> [-a] [-L] [-s <name>] [-d <dir>]\n",
- program_name);
+ progname);
PR_fprintf(pr_stderr,
"\t%s -R <name> [-a] [-l <location>] [-s <name>] [-d <dir>]\n",
- program_name);
+ progname);
PR_fprintf(pr_stderr,
"\t%s -S <name> [-a] [-l <location> -t <name>]\n",
- program_name);
+ progname);
PR_fprintf(pr_stderr,
"\t\t [-s <name>] [-w <time>] [-d <dir>]\n");
PR_fprintf(pr_stderr,
"\t%s -V <name> [-a] -u <usage> [-l <location> -t <name>]\n",
- program_name);
+ progname);
PR_fprintf(pr_stderr,
"\t\t [-s <name>] [-w <time>] [-d <dir>]\n");
}
static void
-short_usage(char *program_name)
+short_usage(char *progname)
{
PR_fprintf(PR_STDERR,
"Type %s -H for more detailed descriptions\n",
- program_name);
- synopsis(program_name);
+ progname);
+ synopsis(progname);
}
static void
-long_usage(char *program_name)
+long_usage(char *progname)
{
PRFileDesc *pr_stderr;
pr_stderr = PR_STDERR;
- synopsis(program_name);
+ synopsis(progname);
PR_fprintf(pr_stderr, "\nCommands (must specify exactly one):\n");
PR_fprintf(pr_stderr,
" %-13s Pretty-print a binary request read from stdin\n",
diff --git a/security/nss/cmd/ocspresp/ocspresp.c b/security/nss/cmd/ocspresp/ocspresp.c
index 632623c97c..d18d32e18e 100644
--- a/security/nss/cmd/ocspresp/ocspresp.c
+++ b/security/nss/cmd/ocspresp/ocspresp.c
@@ -194,8 +194,8 @@ main(int argc, char **argv)
&obtainedSignerCert, caCert));
#ifdef DEBUG
{
- SECStatus rv = CERT_GetOCSPStatusForCertID(certHandle, decodedRev, cid,
- obtainedSignerCert, now);
+ rv = CERT_GetOCSPStatusForCertID(certHandle, decodedRev, cid,
+ obtainedSignerCert, now);
PORT_Assert(rv == SECFailure);
PORT_Assert(PORT_GetError() == SEC_ERROR_REVOKED_CERTIFICATE);
}
@@ -211,7 +211,7 @@ main(int argc, char **argv)
decodedFail = CERT_DecodeOCSPResponse(encodedFail);
#ifdef DEBUG
{
- SECStatus rv = CERT_GetOCSPResponseStatus(decodedFail);
+ rv = CERT_GetOCSPResponseStatus(decodedFail);
PORT_Assert(rv == SECFailure);
PORT_Assert(PORT_GetError() == SEC_ERROR_OCSP_TRY_SERVER_LATER);
}
diff --git a/security/nss/cmd/pk12util/pk12util.c b/security/nss/cmd/pk12util/pk12util.c
index 70454a0d8f..5884713e3c 100644
--- a/security/nss/cmd/pk12util/pk12util.c
+++ b/security/nss/cmd/pk12util/pk12util.c
@@ -28,7 +28,7 @@ static PRBool pk12uForceUnicode;
PRIntn pk12uErrno = 0;
static void
-Usage(char *progName)
+Usage()
{
#define FPS PR_fprintf(PR_STDERR,
FPS "Usage: %s -i importfile [-d certdir] [-P dbprefix] [-h tokenname]\n",
@@ -1020,26 +1020,26 @@ main(int argc, char **argv)
rv = SECU_ParseCommandLine(argc, argv, progName, &pk12util);
if (rv != SECSuccess)
- Usage(progName);
+ Usage();
pk12_debugging = pk12util.options[opt_Debug].activated;
if ((pk12util.options[opt_Import].activated +
pk12util.options[opt_Export].activated +
pk12util.options[opt_List].activated) != 1) {
- Usage(progName);
+ Usage();
}
if (pk12util.options[opt_Export].activated &&
!pk12util.options[opt_Nickname].activated) {
- Usage(progName);
+ Usage();
}
rv = NSS_OptionGet(__NSS_PKCS12_DECODE_FORCE_UNICODE, &forceUnicode);
if (rv != SECSuccess) {
SECU_PrintError(progName,
"Failed to get NSS_PKCS12_DECODE_FORCE_UNICODE option");
- Usage(progName);
+ Usage();
}
pk12uForceUnicode = forceUnicode;
@@ -1144,7 +1144,7 @@ main(int argc, char **argv)
P12U_ListPKCS12File(import_file, slot, &slotPw, &p12FilePw);
} else {
- Usage(progName);
+ Usage();
pk12uErrno = PK12UERR_USAGE;
}
diff --git a/security/nss/cmd/pk1sign/pk1sign.c b/security/nss/cmd/pk1sign/pk1sign.c
index 085aa16598..d5524c149b 100644
--- a/security/nss/cmd/pk1sign/pk1sign.c
+++ b/security/nss/cmd/pk1sign/pk1sign.c
@@ -178,7 +178,7 @@ loser:
SECKEY_DestroyPrivateKey(privKey);
}
if (data) {
- PORT_Free(data);
+ PR_Free(data);
}
PORT_FreeArena(arena, PR_FALSE);
diff --git a/security/nss/cmd/rsaperf/rsaperf.c b/security/nss/cmd/rsaperf/rsaperf.c
index 2bb23856e7..7762a465b8 100644
--- a/security/nss/cmd/rsaperf/rsaperf.c
+++ b/security/nss/cmd/rsaperf/rsaperf.c
@@ -313,7 +313,7 @@ main(int argc, char **argv)
char *slotname = NULL;
long keybits = 0;
RSAOp fn;
- void *rsaKey = NULL;
+ void *rsaKeyPtr = NULL;
PLOptState *optstate;
PLOptStatus optstatus;
long iters = DEFAULT_ITERS;
@@ -464,7 +464,7 @@ main(int argc, char **argv)
if (doPub) {
/* do public key ops */
fn = (RSAOp)PK11_PublicKeyOp;
- rsaKey = (void *)pubHighKey;
+ rsaKeyPtr = (void *)pubHighKey;
kh = PK11_ImportPublicKey(cert->slot, pubHighKey, PR_FALSE);
if (CK_INVALID_HANDLE == kh) {
@@ -489,7 +489,7 @@ main(int argc, char **argv)
fn = (RSAOp)PK11_PrivateKeyOp;
keys.privKey = privHighKey;
keys.pubKey = pubHighKey;
- rsaKey = (void *)&keys;
+ rsaKeyPtr = (void *)&keys;
printf("Using PKCS#11 for RSA decryption with token %s.\n",
PK11_GetTokenName(privHighKey->pkcs11Slot));
}
@@ -537,13 +537,13 @@ main(int argc, char **argv)
if (doPub) {
/* do public key operations */
fn = (RSAOp)PK11_PublicKeyOp;
- rsaKey = (void *)pubHighKey;
+ rsaKeyPtr = (void *)pubHighKey;
} else {
/* do private key operations */
fn = (RSAOp)PK11_PrivateKeyOp;
keys.privKey = privHighKey;
keys.pubKey = pubHighKey;
- rsaKey = (void *)&keys;
+ rsaKeyPtr = (void *)&keys;
}
} else
@@ -574,7 +574,7 @@ main(int argc, char **argv)
pe.data = &pubEx[0];
pe.type = siBuffer;
- rsaKey = RSA_NewKey(keybits, &pe);
+ rsaKeyPtr = RSA_NewKey(keybits, &pe);
fprintf(stderr, "Keygen completed.\n");
} else {
/* use a hardcoded key */
@@ -589,31 +589,31 @@ main(int argc, char **argv)
if (doPub) {
/* do public key operations */
fn = (RSAOp)RSA_PublicKeyOp;
- if (rsaKey) {
+ if (rsaKeyPtr) {
/* convert the RSAPrivateKey to RSAPublicKey */
pubKeyStr.arena = NULL;
- pubKeyStr.modulus = ((RSAPrivateKey *)rsaKey)->modulus;
+ pubKeyStr.modulus = ((RSAPrivateKey *)rsaKeyPtr)->modulus;
pubKeyStr.publicExponent =
- ((RSAPrivateKey *)rsaKey)->publicExponent;
- rsaKey = &pubKeyStr;
+ ((RSAPrivateKey *)rsaKeyPtr)->publicExponent;
+ rsaKeyPtr = &pubKeyStr;
} else {
/* convert NSSLOWKeyPublicKey to RSAPublicKey */
- rsaKey = (void *)(&pubKey->u.rsa);
+ rsaKeyPtr = (void *)(&pubKey->u.rsa);
}
- PORT_Assert(rsaKey);
+ PORT_Assert(rsaKeyPtr);
} else {
/* do private key operations */
fn = (RSAOp)RSA_PrivateKeyOp;
if (privKey) {
/* convert NSSLOWKeyPrivateKey to RSAPrivateKey */
- rsaKey = (void *)(&privKey->u.rsa);
+ rsaKeyPtr = (void *)(&privKey->u.rsa);
}
- PORT_Assert(rsaKey);
+ PORT_Assert(rsaKeyPtr);
}
}
memset(buf, 1, sizeof buf);
- rv = fn(rsaKey, buf2, buf);
+ rv = fn(rsaKeyPtr, buf2, buf);
if (rv != SECSuccess) {
PRErrorCode errNum;
const char *errStr = NULL;
@@ -638,7 +638,7 @@ main(int argc, char **argv)
runDataArr[i]->fn = fn;
runDataArr[i]->buf = buf;
runDataArr[i]->doIters = &doIters;
- runDataArr[i]->rsaKey = rsaKey;
+ runDataArr[i]->rsaKey = rsaKeyPtr;
runDataArr[i]->seconds = seconds;
runDataArr[i]->iters = iters;
threadsArr[i] =
diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c
index fac428e101..c372ec9b83 100644
--- a/security/nss/cmd/selfserv/selfserv.c
+++ b/security/nss/cmd/selfserv/selfserv.c
@@ -57,7 +57,7 @@
int NumSidCacheEntries = 1024;
-static int handle_connection(PRFileDesc *, PRFileDesc *, int);
+static int handle_connection(PRFileDesc *, PRFileDesc *);
static const char envVarName[] = { SSL_ENV_VAR_NAME };
static const char inheritableSockName[] = { "SELFSERV_LISTEN_SOCKET" };
@@ -509,7 +509,6 @@ typedef struct jobStr {
PRCList link;
PRFileDesc *tcp_sock;
PRFileDesc *model_sock;
- int requestCert;
} JOB;
static PZLock *qLock; /* this lock protects all data immediately below */
@@ -541,7 +540,7 @@ setupJobs(int maxJobs)
return SECSuccess;
}
-typedef int startFn(PRFileDesc *a, PRFileDesc *b, int c);
+typedef int startFn(PRFileDesc *a, PRFileDesc *b);
typedef enum { rs_idle = 0,
rs_running = 1,
@@ -550,7 +549,6 @@ typedef enum { rs_idle = 0,
typedef struct perThreadStr {
PRFileDesc *a;
PRFileDesc *b;
- int c;
int rv;
startFn *startFunc;
PRThread *prThread;
@@ -564,7 +562,7 @@ thread_wrapper(void *arg)
{
perThread *slot = (perThread *)arg;
- slot->rv = (*slot->startFunc)(slot->a, slot->b, slot->c);
+ slot->rv = (*slot->startFunc)(slot->a, slot->b);
/* notify the thread exit handler. */
PZ_Lock(qLock);
@@ -575,7 +573,7 @@ thread_wrapper(void *arg)
}
int
-jobLoop(PRFileDesc *a, PRFileDesc *b, int c)
+jobLoop(PRFileDesc *a, PRFileDesc *b)
{
PRCList *myLink = 0;
JOB *myJob;
@@ -595,8 +593,7 @@ jobLoop(PRFileDesc *a, PRFileDesc *b, int c)
/* myJob will be null when stopping is true and jobQ is empty */
if (!myJob)
break;
- handle_connection(myJob->tcp_sock, myJob->model_sock,
- myJob->requestCert);
+ handle_connection(myJob->tcp_sock, myJob->model_sock);
PZ_Lock(qLock);
PR_APPEND_LINK(myLink, &freeJobs);
PZ_NotifyCondVar(freeListNotEmptyCv);
@@ -609,7 +606,6 @@ launch_threads(
startFn *startFunc,
PRFileDesc *a,
PRFileDesc *b,
- int c,
PRBool local)
{
int i;
@@ -645,7 +641,6 @@ launch_threads(
slot->state = rs_running;
slot->a = a;
slot->b = b;
- slot->c = c;
slot->startFunc = startFunc;
slot->prThread = PR_CreateThread(PR_USER_THREAD,
thread_wrapper, slot, PR_PRIORITY_NORMAL,
@@ -893,8 +888,7 @@ int /* returns count */
int
do_writes(
PRFileDesc *ssl_sock,
- PRFileDesc *model_sock,
- int requestCert)
+ PRFileDesc *model_sock)
{
int sent = 0;
int count = 0;
@@ -925,8 +919,7 @@ do_writes(
static int
handle_fdx_connection(
PRFileDesc *tcp_sock,
- PRFileDesc *model_sock,
- int requestCert)
+ PRFileDesc *model_sock)
{
PRFileDesc *ssl_sock = NULL;
SECStatus result;
@@ -960,8 +953,7 @@ handle_fdx_connection(
lockedVars_AddToCount(&lv, 1);
/* Attempt to launch the writer thread. */
- result = launch_thread(do_writes, ssl_sock, (PRFileDesc *)&lv,
- requestCert);
+ result = launch_thread(do_writes, ssl_sock, (PRFileDesc *)&lv);
if (result == SECSuccess)
do {
@@ -1093,7 +1085,7 @@ makeCorruptedOCSPResponse(PLArenaPool *arena)
}
SECItemArray *
-makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm,
+makeSignedOCSPResponse(PLArenaPool *arena,
CERTCertificate *cert, secuPWData *pwdata)
{
SECItemArray *result = NULL;
@@ -1117,7 +1109,7 @@ makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm,
nextUpdate = now + (PRTime)60 * 60 * 24 * PR_USEC_PER_SEC; /* plus 1 day */
- switch (osm) {
+ switch (ocspStaplingMode) {
case osm_good:
case osm_badsig:
sr = CERT_CreateOCSPSingleResponseGood(arena, cid, now,
@@ -1150,7 +1142,7 @@ makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm,
singleResponses[1] = NULL;
ocspResponse = CERT_CreateEncodedOCSPSuccessResponse(arena,
- (osm == osm_badsig)
+ (ocspStaplingMode == osm_badsig)
? NULL
: ca,
ocspResponderID_byName, now, singleResponses,
@@ -1175,7 +1167,7 @@ makeSignedOCSPResponse(PLArenaPool *arena, ocspStaplingModeType osm,
}
void
-setupCertStatus(PLArenaPool *arena, enum ocspStaplingModeEnum ocspStaplingMode,
+setupCertStatus(PLArenaPool *arena,
CERTCertificate *cert, int index, secuPWData *pwdata)
{
if (ocspStaplingMode == osm_random) {
@@ -1213,7 +1205,7 @@ setupCertStatus(PLArenaPool *arena, enum ocspStaplingModeEnum ocspStaplingMode,
case osm_unknown:
case osm_badsig:
multiOcspResponses =
- makeSignedOCSPResponse(arena, ocspStaplingMode, cert,
+ makeSignedOCSPResponse(arena, cert,
pwdata);
break;
case osm_corrupted:
@@ -1236,10 +1228,7 @@ setupCertStatus(PLArenaPool *arena, enum ocspStaplingModeEnum ocspStaplingMode,
}
int
-handle_connection(
- PRFileDesc *tcp_sock,
- PRFileDesc *model_sock,
- int requestCert)
+handle_connection(PRFileDesc *tcp_sock, PRFileDesc *model_sock)
{
PRFileDesc *ssl_sock = NULL;
PRFileDesc *local_file_fd = NULL;
@@ -1272,7 +1261,6 @@ handle_connection(
VLOG(("selfserv: handle_connection: starting\n"));
if (useModelSocket && model_sock) {
- SECStatus rv;
ssl_sock = SSL_ImportFD(model_sock, tcp_sock);
if (!ssl_sock) {
errWarn("SSL_ImportFD with model");
@@ -1588,8 +1576,7 @@ sigusr1_handler(int sig)
SECStatus
do_accepts(
PRFileDesc *listen_sock,
- PRFileDesc *model_sock,
- int requestCert)
+ PRFileDesc *model_sock)
{
PRNetAddr addr;
PRErrorCode perr;
@@ -1659,7 +1646,6 @@ do_accepts(
JOB *myJob = (JOB *)myLink;
myJob->tcp_sock = tcp_sock;
myJob->model_sock = model_sock;
- myJob->requestCert = requestCert;
}
PR_APPEND_LINK(myLink, &jobQ);
@@ -1818,7 +1804,6 @@ handshakeCallback(PRFileDesc *fd, void *client_data)
void
server_main(
PRFileDesc *listen_sock,
- int requestCert,
SECKEYPrivateKey **privKey,
CERTCertificate **cert,
const char *expectedHostNameVal)
@@ -2021,7 +2006,7 @@ server_main(
/* end of ssl configuration. */
/* Now, do the accepting, here in the main thread. */
- rv = do_accepts(listen_sock, model_sock, requestCert);
+ rv = do_accepts(listen_sock, model_sock);
terminateWorkerThreads();
@@ -2654,9 +2639,8 @@ main(int argc, char **argv)
}
}
if (cipher > 0) {
- SECStatus status;
- status = SSL_CipherPrefSetDefault(cipher, SSL_ALLOWED);
- if (status != SECSuccess)
+ rv = SSL_CipherPrefSetDefault(cipher, SSL_ALLOWED);
+ if (rv != SECSuccess)
SECU_PrintError(progName, "SSL_CipherPrefSet()");
} else {
fprintf(stderr,
@@ -2684,7 +2668,7 @@ main(int argc, char **argv)
exit(11);
}
if (privKey[i]->keyType != ecKey)
- setupCertStatus(certStatusArena, ocspStaplingMode, cert[i], i, &pwdata);
+ setupCertStatus(certStatusArena, cert[i], i, &pwdata);
}
if (configureWeakDHE > 0) {
@@ -2697,7 +2681,7 @@ main(int argc, char **argv)
}
/* allocate the array of thread slots, and launch the worker threads. */
- rv = launch_threads(&jobLoop, 0, 0, requestCert, useLocalThreads);
+ rv = launch_threads(&jobLoop, 0, 0, useLocalThreads);
if (rv == SECSuccess && logStats) {
loggerThread = PR_CreateThread(PR_SYSTEM_THREAD,
@@ -2712,7 +2696,7 @@ main(int argc, char **argv)
}
if (rv == SECSuccess) {
- server_main(listen_sock, requestCert, privKey, cert,
+ server_main(listen_sock, privKey, cert,
expectedHostNameVal);
}
@@ -2731,7 +2715,6 @@ cleanup:
}
{
- int i;
for (i = 0; i < certNicknameIndex; i++) {
if (cert[i]) {
CERT_DestroyCertificate(cert[i]);
diff --git a/security/nss/cmd/shlibsign/shlibsign.c b/security/nss/cmd/shlibsign/shlibsign.c
index d93fc422d5..221d1e67ed 100644
--- a/security/nss/cmd/shlibsign/shlibsign.c
+++ b/security/nss/cmd/shlibsign/shlibsign.c
@@ -148,7 +148,7 @@ writeItem(PRFileDesc *fd, CK_VOID_PTR pValue,
return PR_FAILURE;
}
bytesWritten = PR_Write(fd, pValue, ulValueLen);
- if (bytesWritten != ulValueLen) {
+ if (bytesWritten < 0 || (CK_ULONG)bytesWritten != ulValueLen) {
lperror(file);
return PR_FAILURE;
}
diff --git a/security/nss/cmd/signtool/javascript.c b/security/nss/cmd/signtool/javascript.c
index ffff2db592..58869aa619 100644
--- a/security/nss/cmd/signtool/javascript.c
+++ b/security/nss/cmd/signtool/javascript.c
@@ -1300,7 +1300,6 @@ extract_js(char *filename)
* Now we have a stream of tags and text. Go through and deal with each.
*/
for (curitem = head; curitem; curitem = curitem->next) {
- TagItem *tagp = NULL;
AVPair *pairp = NULL;
char *src = NULL, *id = NULL, *codebase = NULL;
PRBool hasEventHandler = PR_FALSE;
@@ -1669,11 +1668,14 @@ loser:
* Returns PR_SUCCESS if the directory is present, PR_FAILURE otherwise.
*/
static PRStatus
-ensureExists(char *base, char *path)
+ensureExists(char *basepath, char *path)
{
char fn[FNSIZE];
PRDir *dir;
- sprintf(fn, "%s/%s", base, path);
+ int c = snprintf(fn, sizeof(fn), "%s/%s", basepath, path);
+ if (c >= sizeof(fn)) {
+ return PR_FAILURE;
+ }
/*PR_fprintf(outputFD, "Trying to open directory %s.\n", fn);*/
diff --git a/security/nss/cmd/signtool/sign.c b/security/nss/cmd/signtool/sign.c
index 6f8e439467..5345309472 100644
--- a/security/nss/cmd/signtool/sign.c
+++ b/security/nss/cmd/signtool/sign.c
@@ -175,16 +175,16 @@ typedef struct {
*
*/
int
-SignAllArc(char *jartree, char *keyName, int javascript, char *metafile,
- char *install_script, int optimize, PRBool recurse)
+SignAllArc(char *jartree, char *keyName, int javascript, char *metafilename,
+ char *install_script, int optimize_level, PRBool recurse)
{
SignArcInfo info;
info.keyName = keyName;
info.javascript = javascript;
- info.metafile = metafile;
+ info.metafile = metafilename;
info.install_script = install_script;
- info.optimize = optimize;
+ info.optimize = optimize_level;
return foreach (jartree, "", sign_all_arc_fn, recurse,
PR_TRUE /*include dirs*/, (void *)&info);
@@ -194,7 +194,7 @@ static int
sign_all_arc_fn(char *relpath, char *basedir, char *reldir, char *filename,
void *arg)
{
- char *zipfile = NULL;
+ char *zipfilename = NULL;
char *arc = NULL, *archive = NULL;
int retval = 0;
SignArcInfo *infop = (SignArcInfo *)arg;
@@ -212,8 +212,8 @@ sign_all_arc_fn(char *relpath, char *basedir, char *reldir, char *filename,
}
archive = PR_smprintf("%s/%s", basedir, relpath);
- zipfile = PL_strdup(archive);
- arc = PORT_Strrchr(zipfile, '.');
+ zipfilename = PL_strdup(archive);
+ arc = PORT_Strrchr(zipfilename, '.');
if (arc == NULL) {
PR_fprintf(errorFD, "%s: Internal failure\n", PROGRAM_NAME);
@@ -225,17 +225,17 @@ sign_all_arc_fn(char *relpath, char *basedir, char *reldir, char *filename,
PL_strcpy(arc, ".jar");
if (verbosity >= 0) {
- PR_fprintf(outputFD, "\nsigning: %s\n", zipfile);
+ PR_fprintf(outputFD, "\nsigning: %s\n", zipfilename);
}
- retval = SignArchive(archive, infop->keyName, zipfile,
+ retval = SignArchive(archive, infop->keyName, zipfilename,
infop->javascript, infop->metafile, infop->install_script,
infop->optimize, PR_TRUE /* recurse */);
}
finish:
if (archive)
PR_Free(archive);
- if (zipfile)
- PR_Free(zipfile);
+ if (zipfilename)
+ PR_Free(zipfilename);
return retval;
}
@@ -707,8 +707,8 @@ SignFile(FILE *outFile, FILE *inFile, CERTCertificate *cert)
static int
generate_SF_file(char *manifile, char *who)
{
- FILE *sf;
- FILE *mf;
+ FILE *sfFile;
+ FILE *mfFile;
long r1, r2, r3;
char whofile[FNSIZE];
char *buf, *name = NULL;
@@ -718,12 +718,12 @@ generate_SF_file(char *manifile, char *who)
strcpy(whofile, who);
- if ((mf = fopen(manifile, "rb")) == NULL) {
+ if ((mfFile = fopen(manifile, "rb")) == NULL) {
perror(manifile);
exit(ERRX);
}
- if ((sf = fopen(whofile, "wb")) == NULL) {
+ if ((sfFile = fopen(whofile, "wb")) == NULL) {
perror(who);
exit(ERRX);
}
@@ -736,11 +736,11 @@ generate_SF_file(char *manifile, char *who)
if (buf == NULL || name == NULL)
out_of_memory();
- fprintf(sf, "Signature-Version: 1.0\n");
- fprintf(sf, "Created-By: %s\n", CREATOR);
- fprintf(sf, "Comments: %s\n", BREAKAGE);
+ fprintf(sfFile, "Signature-Version: 1.0\n");
+ fprintf(sfFile, "Created-By: %s\n", CREATOR);
+ fprintf(sfFile, "Comments: %s\n", BREAKAGE);
- if (fgets(buf, BUFSIZ, mf) == NULL) {
+ if (fgets(buf, BUFSIZ, mfFile) == NULL) {
PR_fprintf(errorFD, "%s: empty manifest file!\n", PROGRAM_NAME);
errorCount++;
exit(ERRX);
@@ -752,15 +752,15 @@ generate_SF_file(char *manifile, char *who)
exit(ERRX);
}
- fseek(mf, 0L, SEEK_SET);
+ fseek(mfFile, 0L, SEEK_SET);
/* Process blocks of headers, and calculate their hashen */
while (1) {
/* Beginning range */
- r1 = ftell(mf);
+ r1 = ftell(mfFile);
- if (fgets(name, BUFSIZ, mf) == NULL)
+ if (fgets(name, BUFSIZ, mfFile) == NULL)
break;
line++;
@@ -774,46 +774,46 @@ generate_SF_file(char *manifile, char *who)
}
r2 = r1;
- while (fgets(buf, BUFSIZ, mf)) {
+ while (fgets(buf, BUFSIZ, mfFile)) {
if (*buf == 0 || *buf == '\n' || *buf == '\r')
break;
line++;
/* Ending range for hashing */
- r2 = ftell(mf);
+ r2 = ftell(mfFile);
}
- r3 = ftell(mf);
+ r3 = ftell(mfFile);
if (r1) {
- fprintf(sf, "\n");
- fprintf(sf, "%s", name);
+ fprintf(sfFile, "\n");
+ fprintf(sfFile, "%s", name);
}
- calculate_MD5_range(mf, r1, r2, &dig);
+ calculate_MD5_range(mfFile, r1, r2, &dig);
if (optimize == 0) {
- fprintf(sf, "Digest-Algorithms: MD5 SHA1\n");
+ fprintf(sfFile, "Digest-Algorithms: MD5 SHA1\n");
md5 = BTOA_DataToAscii(dig.md5, MD5_LENGTH);
- fprintf(sf, "MD5-Digest: %s\n", md5);
+ fprintf(sfFile, "MD5-Digest: %s\n", md5);
PORT_Free(md5);
}
sha1 = BTOA_DataToAscii(dig.sha1, SHA1_LENGTH);
- fprintf(sf, "SHA1-Digest: %s\n", sha1);
+ fprintf(sfFile, "SHA1-Digest: %s\n", sha1);
PORT_Free(sha1);
/* restore normalcy after changing offset position */
- fseek(mf, r3, SEEK_SET);
+ fseek(mfFile, r3, SEEK_SET);
}
PORT_Free(buf);
PORT_Free(name);
- fclose(sf);
- fclose(mf);
+ fclose(sfFile);
+ fclose(mfFile);
return 0;
}
diff --git a/security/nss/cmd/signtool/zip.c b/security/nss/cmd/signtool/zip.c
index 35d5f5733f..aeb5d6c541 100644
--- a/security/nss/cmd/signtool/zip.c
+++ b/security/nss/cmd/signtool/zip.c
@@ -129,7 +129,7 @@ handle_zerror(int err, char *msg)
* been opened with JzipOpen.
*/
int
-JzipAdd(char *fullname, char *filename, ZIPfile *zipfile, int compression_level)
+JzipAdd(char *fullname, char *filename, ZIPfile *zipfile, int lvl)
{
ZIPentry *entry;
PRFileDesc *readfp;
@@ -319,7 +319,7 @@ JzipAdd(char *fullname, char *filename, ZIPfile *zipfile, int compression_level)
* It causes zlib to leave out its headers and footers, which don't
* work in PKZIP files.
*/
- err = deflateInit2(&zstream, compression_level, Z_DEFLATED,
+ err = deflateInit2(&zstream, lvl, Z_DEFLATED,
-MAX_WBITS, 8 /*default*/, Z_DEFAULT_STRATEGY);
if (err != Z_OK) {
handle_zerror(err, zstream.msg);
diff --git a/security/nss/cmd/smimetools/cmsutil.c b/security/nss/cmd/smimetools/cmsutil.c
index fe17f26a48..7106521c12 100644
--- a/security/nss/cmd/smimetools/cmsutil.c
+++ b/security/nss/cmd/smimetools/cmsutil.c
@@ -68,7 +68,7 @@ DigestFile(PLArenaPool *poolp, SECItem ***digests, SECItem *input,
}
static void
-Usage(char *progName)
+Usage(void)
{
fprintf(stderr,
"Usage: %s [-C|-D|-E|-O|-S] [<options>] [-d dbdir] [-u certusage]\n"
@@ -280,7 +280,6 @@ decode(FILE *out, SECItem *input, const struct decodeOptionsStr *decodeOptions)
** or might be an invalid message, such as a QA test message
** or a message from an attacker.
*/
- SECStatus rv;
rv = NSS_CMSSignedData_VerifyCertsOnly(sigd,
decodeOptions->options->certHandle,
decodeOptions->options->certUsage);
@@ -1127,7 +1126,7 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: option -G only supported with option -S.\n",
progName);
- Usage(progName);
+ Usage();
exit(1);
}
signOptions.signingTime = PR_TRUE;
@@ -1137,7 +1136,7 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: option -H only supported with option -S.\n",
progName);
- Usage(progName);
+ Usage();
exit(1);
}
decodeOptions.suppressContent = PR_TRUE;
@@ -1167,7 +1166,7 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: option -N only supported with option -S.\n",
progName);
- Usage(progName);
+ Usage();
exit(1);
}
signOptions.nickname = PORT_Strdup(optstate->value);
@@ -1180,7 +1179,7 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: option -P only supported with option -S.\n",
progName);
- Usage(progName);
+ Usage();
exit(1);
}
signOptions.smimeProfile = PR_TRUE;
@@ -1193,7 +1192,7 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: option -T only supported with option -S.\n",
progName);
- Usage(progName);
+ Usage();
exit(1);
}
signOptions.detached = PR_TRUE;
@@ -1203,7 +1202,7 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: option -Y only supported with option -S.\n",
progName);
- Usage(progName);
+ Usage();
exit(1);
}
signOptions.encryptionKeyPreferenceNick = strdup(optstate->value);
@@ -1214,7 +1213,7 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: option -b only supported with option -D.\n",
progName);
- Usage(progName);
+ Usage();
exit(1);
}
batch = PR_TRUE;
@@ -1225,7 +1224,7 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: option -c only supported with option -D.\n",
progName);
- Usage(progName);
+ Usage();
exit(1);
}
contentFile = PR_Open(optstate->value, PR_RDONLY, 006600);
@@ -1261,7 +1260,7 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: option -h only supported with option -D.\n",
progName);
- Usage(progName);
+ Usage();
exit(1);
}
decodeOptions.headerLevel = atoi(optstate->value);
@@ -1288,7 +1287,7 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: option -k only supported with option -D.\n",
progName);
- Usage(progName);
+ Usage();
exit(1);
}
decodeOptions.keepCerts = PR_TRUE;
@@ -1299,7 +1298,7 @@ main(int argc, char **argv)
fprintf(stderr,
"%s: option -n only supported with option -D.\n",
progName);
- Usage(progName);
+ Usage();
exit(1);
}
decodeOptions.suppressContent = PR_TRUE;
@@ -1315,7 +1314,7 @@ main(int argc, char **argv)
case 'p':
if (!optstate->value) {
fprintf(stderr, "%s: option -p must have a value.\n", progName);
- Usage(progName);
+ Usage();
exit(1);
}
@@ -1325,7 +1324,7 @@ main(int argc, char **argv)
case 'f':
if (!optstate->value) {
fprintf(stderr, "%s: option -f must have a value.\n", progName);
- Usage(progName);
+ Usage();
exit(1);
}
@@ -1335,7 +1334,7 @@ main(int argc, char **argv)
case 'r':
if (!optstate->value) {
fprintf(stderr, "%s: option -r must have a value.\n", progName);
- Usage(progName);
+ Usage();
exit(1);
}
envelopeOptions.recipients = ptrarray;
@@ -1368,11 +1367,11 @@ main(int argc, char **argv)
}
}
if (status == PL_OPT_BAD)
- Usage(progName);
+ Usage();
PL_DestroyOptState(optstate);
if (mode == UNKNOWN)
- Usage(progName);
+ Usage();
if (mode != CERTSONLY && !batch) {
rv = SECU_FileToItem(&input, inFile);
@@ -1529,7 +1528,7 @@ main(int argc, char **argv)
break;
default:
fprintf(stderr, "One of options -D, -S or -E must be set.\n");
- Usage(progName);
+ Usage();
exitstatus = 1;
}
diff --git a/security/nss/cmd/strsclnt/strsclnt.c b/security/nss/cmd/strsclnt/strsclnt.c
index 7d259bd0aa..bba53efac6 100644
--- a/security/nss/cmd/strsclnt/strsclnt.c
+++ b/security/nss/cmd/strsclnt/strsclnt.c
@@ -137,7 +137,7 @@ SECItem bigBuf;
fprintf
static void
-Usage(const char *progName)
+Usage(void)
{
fprintf(stderr,
"Usage: %s [-n nickname] [-p port] [-d dbdir] [-c connections]\n"
@@ -260,7 +260,6 @@ void
printSecurityInfo(PRFileDesc *fd)
{
CERTCertificate *cert = NULL;
- SSL3Statistics *ssl3stats = SSL_GetStatistics();
SECStatus result;
SSLChannelInfo channel;
SSLCipherSuiteInfo suite;
@@ -1095,7 +1094,6 @@ client_main(
while (0 != (ndx = *cipherString)) {
const char *startCipher = cipherString++;
int cipher = 0;
- SECStatus rv;
if (ndx == ':') {
cipher = hexchar_to_int(*cipherString++);
@@ -1353,7 +1351,7 @@ main(int argc, char **argv)
enabledVersions, &enabledVersions) !=
SECSuccess) {
fprintf(stderr, "Bad version specified.\n");
- Usage(progName);
+ Usage();
}
break;
@@ -1431,27 +1429,27 @@ main(int argc, char **argv)
case 0: /* positional parameter */
if (hostName) {
- Usage(progName);
+ Usage();
}
hostName = PL_strdup(optstate->value);
break;
default:
case '?':
- Usage(progName);
+ Usage();
break;
}
}
PL_DestroyOptState(optstate);
if (!hostName || status == PL_OPT_BAD)
- Usage(progName);
+ Usage();
if (fullhs != NO_FULLHS_PERCENTAGE && (fullhs < 0 || fullhs > 100 || NoReuse))
- Usage(progName);
+ Usage();
if (port == 0)
- Usage(progName);
+ Usage();
if (fileName)
readBigFile(fileName);
diff --git a/security/nss/cmd/symkeyutil/symkeyutil.c b/security/nss/cmd/symkeyutil/symkeyutil.c
index 4444568083..31ab4dda4c 100644
--- a/security/nss/cmd/symkeyutil/symkeyutil.c
+++ b/security/nss/cmd/symkeyutil/symkeyutil.c
@@ -1034,10 +1034,10 @@ main(int argc, char **argv)
char *targetName = symKeyUtil.options[opt_TargetToken].arg;
PK11SymKey *newKey;
PK11SymKey *symKey = FindKey(slot, name, &keyID, &pwdata);
- char *keyName = PK11_GetSymKeyNickname(symKey);
+ char *keyName;
if (!symKey) {
- char *keyName = keyID.data ? BufToHex(&keyID) : PORT_Strdup(name);
+ keyName = keyID.data ? BufToHex(&keyID) : PORT_Strdup(name);
PR_fprintf(PR_STDERR, "%s: Couldn't find key %s on %s\n",
progName, keyName, PK11_GetTokenName(slot));
PORT_Free(keyName);
@@ -1061,6 +1061,7 @@ main(int argc, char **argv)
PR_fprintf(PR_STDERR, "%s: Couldn't move the key \n", progName);
goto shutdown;
}
+ keyName = PK11_GetSymKeyNickname(symKey);
if (keyName) {
rv = PK11_SetSymKeyNickname(newKey, keyName);
if (rv != SECSuccess) {
diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c
index 1ad99502bb..6f5a43146a 100644
--- a/security/nss/cmd/tstclnt/tstclnt.c
+++ b/security/nss/cmd/tstclnt/tstclnt.c
@@ -51,6 +51,7 @@
#define MAX_WAIT_FOR_SERVER 600
#define WAIT_INTERVAL 100
+#define ZERO_RTT_MAX (2 << 16)
#define EXIT_CODE_HANDSHAKE_FAILED 254
@@ -99,6 +100,7 @@ int renegotiationsDone = 0;
PRBool initializedServerSessionCache = PR_FALSE;
static char *progName;
+static const char *requestFile;
secuPWData pwdata = { PW_NONE, 0 };
@@ -172,7 +174,7 @@ printSecurityInfo(PRFileDesc *fd)
}
static void
-PrintUsageHeader(const char *progName)
+PrintUsageHeader()
{
fprintf(stderr,
"Usage: %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n"
@@ -186,7 +188,7 @@ PrintUsageHeader(const char *progName)
}
static void
-PrintParameterUsage(void)
+PrintParameterUsage()
{
fprintf(stderr, "%-20s Send different SNI name. 1st_hs_name - at first\n"
"%-20s handshake, 2nd_hs_name - at second handshake.\n"
@@ -259,17 +261,17 @@ PrintParameterUsage(void)
}
static void
-Usage(const char *progName)
+Usage()
{
- PrintUsageHeader(progName);
+ PrintUsageHeader();
PrintParameterUsage();
exit(1);
}
static void
-PrintCipherUsage(const char *progName)
+PrintCipherUsage()
{
- PrintUsageHeader(progName);
+ PrintUsageHeader();
fprintf(stderr, "%-20s Letter(s) chosen from the following list\n",
"-c ciphers");
fprintf(stderr,
@@ -303,7 +305,7 @@ milliPause(PRUint32 milli)
}
void
-disableAllSSLCiphers(void)
+disableAllSSLCiphers()
{
const PRUint16 *cipherSuites = SSL_GetImplementedCiphers();
int i = SSL_GetNumImplementedCiphers();
@@ -711,12 +713,18 @@ void
thread_main(void *arg)
{
PRFileDesc *ps = (PRFileDesc *)arg;
- PRFileDesc *std_in = PR_GetSpecialFD(PR_StandardInput);
+ PRFileDesc *std_in;
int wc, rc;
char buf[256];
+ if (requestFile) {
+ std_in = PR_Open(requestFile, PR_RDONLY, 0);
+ } else {
+ std_in = PR_GetSpecialFD(PR_StandardInput);
+ }
+
#ifdef WIN32
- {
+ if (!requestFile) {
/* Put stdin into O_BINARY mode
** or else incoming \r\n's will become \n's.
*/
@@ -737,6 +745,9 @@ thread_main(void *arg)
wc = PR_Send(ps, buf, rc, 0, maxInterval);
} while (wc == rc);
PR_Close(ps);
+ if (requestFile) {
+ PR_Close(std_in);
+ }
}
#endif
@@ -844,7 +855,7 @@ separateReqHeader(const PRFileDesc *outFd, const char *buf, const int nb,
} else if (((c) >= 'A') && ((c) <= 'F')) { \
i = (c) - 'A' + 10; \
} else { \
- Usage(progName); \
+ Usage(); \
}
static SECStatus
@@ -915,22 +926,22 @@ char *hs1SniHostName = NULL;
char *hs2SniHostName = NULL;
PRUint16 portno = 443;
int override = 0;
-char *requestString = NULL;
-PRInt32 requestStringLen = 0;
-PRBool requestSent = PR_FALSE;
PRBool enableZeroRtt = PR_FALSE;
+PRUint8 *zeroRttData;
+unsigned int zeroRttLen = 0;
PRBool enableAltServerHello = PR_FALSE;
PRBool useDTLS = PR_FALSE;
PRBool actAsServer = PR_FALSE;
PRBool stopAfterHandshake = PR_FALSE;
PRBool requestToExit = PR_FALSE;
char *versionString = NULL;
+PRBool handshakeComplete = PR_FALSE;
static int
-writeBytesToServer(PRFileDesc *s, const char *buf, int nb)
+writeBytesToServer(PRFileDesc *s, const PRUint8 *buf, int nb)
{
SECStatus rv;
- const char *bufp = buf;
+ const PRUint8 *bufp = buf;
PRPollDesc pollDesc;
pollDesc.in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
@@ -944,12 +955,20 @@ writeBytesToServer(PRFileDesc *s, const char *buf, int nb)
if (cc < 0) {
PRErrorCode err = PR_GetError();
if (err != PR_WOULD_BLOCK_ERROR) {
- SECU_PrintError(progName,
- "write to SSL socket failed");
+ SECU_PrintError(progName, "write to SSL socket failed");
return 254;
}
cc = 0;
}
+ FPRINTF(stderr, "%s: %d bytes written\n", progName, cc);
+ if (enableZeroRtt && !handshakeComplete) {
+ if (zeroRttLen + cc > ZERO_RTT_MAX) {
+ SECU_PrintError(progName, "too much early data to save");
+ return -1;
+ }
+ PORT_Memcpy(zeroRttData + zeroRttLen, bufp, cc);
+ zeroRttLen += cc;
+ }
bufp += cc;
nb -= cc;
if (nb <= 0)
@@ -969,8 +988,7 @@ writeBytesToServer(PRFileDesc *s, const char *buf, int nb)
progName);
cc = PR_Poll(&pollDesc, 1, PR_INTERVAL_NO_TIMEOUT);
if (cc < 0) {
- SECU_PrintError(progName,
- "PR_Poll failed");
+ SECU_PrintError(progName, "PR_Poll failed");
return -1;
}
FPRINTF(stderr,
@@ -993,7 +1011,7 @@ handshakeCallback(PRFileDesc *fd, void *client_data)
SSL_ReHandshake(fd, (renegotiationsToDo < 2));
++renegotiationsDone;
}
- if (requestString && requestSent) {
+ if (zeroRttLen) {
/* This data was sent in 0-RTT. */
SSLChannelInfo info;
SECStatus rv;
@@ -1003,29 +1021,30 @@ handshakeCallback(PRFileDesc *fd, void *client_data)
return;
if (!info.earlyDataAccepted) {
- FPRINTF(stderr, "Early data rejected. Re-sending\n");
- writeBytesToServer(fd, requestString, requestStringLen);
+ FPRINTF(stderr, "Early data rejected. Re-sending %d bytes\n",
+ zeroRttLen);
+ writeBytesToServer(fd, zeroRttData, zeroRttLen);
+ zeroRttLen = 0;
}
}
if (stopAfterHandshake) {
requestToExit = PR_TRUE;
}
+ handshakeComplete = PR_TRUE;
}
-#define REQUEST_WAITING (requestString && !requestSent)
-
static SECStatus
-installServerCertificate(PRFileDesc *s, char *nickname)
+installServerCertificate(PRFileDesc *s, char *nick)
{
CERTCertificate *cert;
SECKEYPrivateKey *privKey = NULL;
- if (!nickname) {
+ if (!nick) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- cert = PK11_FindCertFromNickname(nickname, &pwdata);
+ cert = PK11_FindCertFromNickname(nick, &pwdata);
if (cert == NULL) {
return SECFailure;
}
@@ -1129,20 +1148,19 @@ connectToServer(PRFileDesc *s, PRPollDesc *pollset)
}
static int
-run(void)
+run()
{
int headerSeparatorPtrnId = 0;
int error = 0;
SECStatus rv;
PRStatus status;
PRInt32 filesReady;
- int npds;
PRFileDesc *s = NULL;
PRFileDesc *std_out;
- PRPollDesc pollset[2];
+ PRPollDesc pollset[2] = { { 0 }, { 0 } };
PRBool wrStarted = PR_FALSE;
- requestSent = PR_FALSE;
+ handshakeComplete = PR_FALSE;
/* Create socket */
if (useDTLS) {
@@ -1225,19 +1243,18 @@ run(void)
cipherString++;
} else {
if (!isalpha(ndx))
- Usage(progName);
+ Usage();
ndx = tolower(ndx) - 'a';
if (ndx < PR_ARRAY_SIZE(ssl3CipherSuites)) {
cipher = ssl3CipherSuites[ndx];
}
}
if (cipher > 0) {
- SECStatus status;
- status = SSL_CipherPrefSet(s, cipher, SSL_ALLOWED);
- if (status != SECSuccess)
+ rv = SSL_CipherPrefSet(s, cipher, SSL_ALLOWED);
+ if (rv != SECSuccess)
SECU_PrintError(progName, "SSL_CipherPrefSet()");
} else {
- Usage(progName);
+ Usage();
}
}
PORT_Free(cstringSaved);
@@ -1394,7 +1411,6 @@ run(void)
/* Try to connect to the server */
rv = connectToServer(s, pollset);
if (rv != SECSuccess) {
- ;
error = 1;
goto done;
}
@@ -1406,13 +1422,18 @@ run(void)
pollset[SSOCK_FD].in_flags |= (clientSpeaksFirst ? 0 : PR_POLL_READ);
else
pollset[SSOCK_FD].in_flags |= PR_POLL_READ;
- pollset[STDIN_FD].fd = PR_GetSpecialFD(PR_StandardInput);
- if (!REQUEST_WAITING) {
- pollset[STDIN_FD].in_flags = PR_POLL_READ;
- npds = 2;
+ if (requestFile) {
+ pollset[STDIN_FD].fd = PR_Open(requestFile, PR_RDONLY, 0);
+ if (!pollset[STDIN_FD].fd) {
+ fprintf(stderr, "%s: unable to open input file: %s\n",
+ progName, requestFile);
+ error = 1;
+ goto done;
+ }
} else {
- npds = 1;
+ pollset[STDIN_FD].fd = PR_GetSpecialFD(PR_StandardInput);
}
+ pollset[STDIN_FD].in_flags = PR_POLL_READ;
std_out = PR_GetSpecialFD(PR_StandardOutput);
#if defined(WIN32) || defined(OS2)
@@ -1458,10 +1479,9 @@ run(void)
requestToExit = PR_FALSE;
FPRINTF(stderr, "%s: ready...\n", progName);
while (!requestToExit &&
- ((pollset[SSOCK_FD].in_flags | pollset[STDIN_FD].in_flags) ||
- REQUEST_WAITING)) {
- char buf[4000]; /* buffer for stdin */
- int nb; /* num bytes read from stdin. */
+ (pollset[SSOCK_FD].in_flags || pollset[STDIN_FD].in_flags)) {
+ PRUint8 buf[4000]; /* buffer for stdin */
+ int nb; /* num bytes read from stdin. */
rv = restartHandshakeAfterServerCertIfNeeded(s, &serverCertAuth,
override);
@@ -1475,7 +1495,8 @@ run(void)
pollset[STDIN_FD].out_flags = 0;
FPRINTF(stderr, "%s: about to call PR_Poll !\n", progName);
- filesReady = PR_Poll(pollset, npds, PR_INTERVAL_NO_TIMEOUT);
+ filesReady = PR_Poll(pollset, PR_ARRAY_SIZE(pollset),
+ PR_INTERVAL_NO_TIMEOUT);
if (filesReady < 0) {
SECU_PrintError(progName, "select failed");
error = 1;
@@ -1497,14 +1518,6 @@ run(void)
"%s: PR_Poll returned 0x%02x for socket out_flags.\n",
progName, pollset[SSOCK_FD].out_flags);
}
- if (REQUEST_WAITING) {
- error = writeBytesToServer(s, requestString, requestStringLen);
- if (error) {
- goto done;
- }
- requestSent = PR_TRUE;
- pollset[SSOCK_FD].in_flags = PR_POLL_READ;
- }
if (pollset[STDIN_FD].out_flags & PR_POLL_READ) {
/* Read from stdin and write to socket */
nb = PR_Read(pollset[STDIN_FD].fd, buf, sizeof(buf));
@@ -1518,6 +1531,8 @@ run(void)
} else if (nb == 0) {
/* EOF on stdin, stop polling stdin for read. */
pollset[STDIN_FD].in_flags = 0;
+ if (actAsServer)
+ requestToExit = PR_TRUE;
} else {
error = writeBytesToServer(s, buf, nb);
if (error) {
@@ -1532,12 +1547,12 @@ run(void)
"%s: PR_Poll returned 0x%02x for socket out_flags.\n",
progName, pollset[SSOCK_FD].out_flags);
}
- if ((pollset[SSOCK_FD].out_flags & PR_POLL_READ) ||
- (pollset[SSOCK_FD].out_flags & PR_POLL_ERR)
#ifdef PR_POLL_HUP
- || (pollset[SSOCK_FD].out_flags & PR_POLL_HUP)
+#define POLL_RECV_FLAGS (PR_POLL_READ | PR_POLL_ERR | PR_POLL_HUP)
+#else
+#define POLL_RECV_FLAGS (PR_POLL_READ | PR_POLL_ERR)
#endif
- ) {
+ if (pollset[SSOCK_FD].out_flags & POLL_RECV_FLAGS) {
/* Read from socket and write to stdout */
nb = PR_Recv(pollset[SSOCK_FD].fd, buf, sizeof buf, 0, maxInterval);
FPRINTF(stderr, "%s: Read from server %d bytes\n", progName, nb);
@@ -1554,7 +1569,7 @@ run(void)
if (skipProtoHeader != PR_TRUE || wrStarted == PR_TRUE) {
PR_Write(std_out, buf, nb);
} else {
- separateReqHeader(std_out, buf, nb, &wrStarted,
+ separateReqHeader(std_out, (char *)buf, nb, &wrStarted,
&headerSeparatorPtrnId);
}
if (verbose)
@@ -1568,42 +1583,10 @@ done:
if (s) {
PR_Close(s);
}
-
- return error;
-}
-
-PRInt32
-ReadFile(const char *filename, char **data)
-{
- char *ret = NULL;
- char buf[8192];
- unsigned int len = 0;
- PRStatus rv;
-
- PRFileDesc *fd = PR_Open(filename, PR_RDONLY, 0);
- if (!fd)
- return -1;
-
- for (;;) {
- rv = PR_Read(fd, buf, sizeof(buf));
- if (rv < 0) {
- PR_Free(ret);
- return rv;
- }
-
- if (!rv)
- break;
-
- ret = PR_Realloc(ret, len + rv);
- if (!ret) {
- return -1;
- }
- PORT_Memcpy(ret + len, buf, rv);
- len += rv;
+ if (requestFile && pollset[STDIN_FD].fd) {
+ PR_Close(pollset[STDIN_FD].fd);
}
-
- *data = ret;
- return len;
+ return error;
}
int
@@ -1653,26 +1636,22 @@ main(int argc, char **argv)
switch (optstate->option) {
case '?':
default:
- Usage(progName);
+ Usage();
break;
case '4':
allowIPv6 = PR_FALSE;
if (!allowIPv4)
- Usage(progName);
+ Usage();
break;
case '6':
allowIPv4 = PR_FALSE;
if (!allowIPv6)
- Usage(progName);
+ Usage();
break;
case 'A':
- requestStringLen = ReadFile(optstate->value, &requestString);
- if (requestStringLen < 0) {
- fprintf(stderr, "Couldn't read file %s\n", optstate->value);
- exit(1);
- }
+ requestFile = PORT_Strdup(optstate->value);
break;
case 'C':
@@ -1735,7 +1714,7 @@ main(int argc, char **argv)
actAsServer = 1;
} else {
if (strcmp(optstate->value, "client")) {
- Usage(progName);
+ Usage();
}
}
break;
@@ -1768,16 +1747,21 @@ main(int argc, char **argv)
if (!strcmp(optstate->value, "alt-server-hello")) {
enableAltServerHello = PR_TRUE;
} else {
- Usage(progName);
+ Usage();
}
break;
case 'Y':
- PrintCipherUsage(progName);
+ PrintCipherUsage();
exit(0);
break;
case 'Z':
enableZeroRtt = PR_TRUE;
+ zeroRttData = PORT_ZAlloc(ZERO_RTT_MAX);
+ if (!zeroRttData) {
+ fprintf(stderr, "Unable to allocate buffer for 0-RTT\n");
+ exit(1);
+ }
break;
case 'a':
@@ -1786,7 +1770,7 @@ main(int argc, char **argv)
} else if (!hs2SniHostName) {
hs2SniHostName = PORT_Strdup(optstate->value);
} else {
- Usage(progName);
+ Usage();
}
break;
@@ -1875,7 +1859,7 @@ main(int argc, char **argv)
if (rv != SECSuccess) {
PL_DestroyOptState(optstate);
fprintf(stderr, "Bad group specified.\n");
- Usage(progName);
+ Usage();
}
break;
}
@@ -1889,18 +1873,18 @@ main(int argc, char **argv)
enabledVersions, &enabledVersions) !=
SECSuccess) {
fprintf(stderr, "Bad version specified.\n");
- Usage(progName);
+ Usage();
}
PORT_Free(versionString);
}
if (optstatus == PL_OPT_BAD) {
- Usage(progName);
+ Usage();
}
if (!host || !portno) {
fprintf(stderr, "%s: parameters -h and -p are mandatory\n", progName);
- Usage(progName);
+ Usage();
}
if (serverCertAuth.testFreshStatusFromSideChannel &&
@@ -2060,20 +2044,13 @@ done:
PR_Close(s);
}
- if (hs1SniHostName) {
- PORT_Free(hs1SniHostName);
- }
- if (hs2SniHostName) {
- PORT_Free(hs2SniHostName);
- }
- if (nickname) {
- PORT_Free(nickname);
- }
- if (pwdata.data) {
- PORT_Free(pwdata.data);
- }
+ PORT_Free((void *)requestFile);
+ PORT_Free(hs1SniHostName);
+ PORT_Free(hs2SniHostName);
+ PORT_Free(nickname);
+ PORT_Free(pwdata.data);
PORT_Free(host);
- PORT_Free(requestString);
+ PORT_Free(zeroRttData);
if (enabledGroups) {
PORT_Free(enabledGroups);
diff --git a/security/nss/cmd/vfyserv/vfyserv.c b/security/nss/cmd/vfyserv/vfyserv.c
index aa648ad8c2..4234ecd09d 100644
--- a/security/nss/cmd/vfyserv/vfyserv.c
+++ b/security/nss/cmd/vfyserv/vfyserv.c
@@ -327,9 +327,7 @@ do_connects(void *a, int connection)
}
void
-client_main(unsigned short port,
- int connections,
- const char *hostName)
+client_main(int connections)
{
int i;
SECStatus secStatus;
@@ -553,7 +551,7 @@ main(int argc, char **argv)
}
}
- client_main(port, connections, hostName);
+ client_main(connections);
cleanup:
if (doOcspCheck) {
diff --git a/security/nss/cmd/vfyserv/vfyutil.c b/security/nss/cmd/vfyserv/vfyutil.c
index 2f1b532620..d3d8a206e7 100644
--- a/security/nss/cmd/vfyserv/vfyutil.c
+++ b/security/nss/cmd/vfyserv/vfyutil.c
@@ -310,13 +310,13 @@ myHandshakeCallback(PRFileDesc *socket, void *arg)
void
disableAllSSLCiphers(void)
{
- const PRUint16 *cipherSuites = SSL_ImplementedCiphers;
+ const PRUint16 *allSuites = SSL_ImplementedCiphers;
int i = SSL_NumImplementedCiphers;
SECStatus rv;
/* disable all the SSL3 cipher suites */
while (--i >= 0) {
- PRUint16 suite = cipherSuites[i];
+ PRUint16 suite = allSuites[i];
rv = SSL_CipherPrefSetDefault(suite, PR_FALSE);
if (rv != SECSuccess) {
fprintf(stderr,
diff --git a/security/nss/coreconf/Werror.mk b/security/nss/coreconf/Werror.mk
index 69155eb145..a569a497ce 100644
--- a/security/nss/coreconf/Werror.mk
+++ b/security/nss/coreconf/Werror.mk
@@ -48,9 +48,11 @@ ifndef WARNING_CFLAGS
else
# This tests to see if enabling the warning is possible before
# setting an option to disable it.
- disable_warning = $(shell $(CC) -x c -E -Werror -W$(1) /dev/null >/dev/null 2>&1 && echo -Wno-$(1))
+ set_warning = $(shell $(CC) -x c -E -Werror -W$(1) /dev/null >/dev/null 2>&1 && echo -W$(2)$(1))
+ enable_warning = $(call set_warning,$(1),)
+ disable_warning = $(call set_warning,$(1),no-)
- WARNING_CFLAGS = -Wall
+ WARNING_CFLAGS = -Wall $(call enable_warning,shadow)
ifdef CC_IS_CLANG
# -Qunused-arguments : clang objects to arguments that it doesn't understand
# and fixing this would require rearchitecture
diff --git a/security/nss/coreconf/config.mk b/security/nss/coreconf/config.mk
index 55d95c30ea..b62f6cef42 100644
--- a/security/nss/coreconf/config.mk
+++ b/security/nss/coreconf/config.mk
@@ -181,6 +181,10 @@ ifndef NSS_FORCE_FIPS
DEFINES += -DNSS_NO_INIT_SUPPORT
endif
+ifdef NSS_SEED_ONLY_DEV_URANDOM
+DEFINES += -DSEED_ONLY_DEV_URANDOM
+endif
+
# Avoid building object leak test code for optimized library
ifndef BUILD_OPT
ifdef PKIX_OBJECT_LEAK_TEST
diff --git a/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep
index 5182f75552..590d1bfaee 100644
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -10,3 +10,4 @@
*/
#error "Do not include this header file."
+
diff --git a/security/nss/coreconf/nsinstall/pathsub.c b/security/nss/coreconf/nsinstall/pathsub.c
index a42a9f30a5..c31a946f0d 100644
--- a/security/nss/coreconf/nsinstall/pathsub.c
+++ b/security/nss/coreconf/nsinstall/pathsub.c
@@ -212,7 +212,7 @@ reversepath(char *inpath, char *name, int len, char *outpath)
xchdir("..");
} else {
cp -= 3;
- strncpy(cp, "../", 3);
+ memcpy(cp, "../", 3);
xchdir(buf);
}
}
diff --git a/security/nss/coreconf/werror.py b/security/nss/coreconf/werror.py
index c469c40029..0e2d41c63c 100644
--- a/security/nss/coreconf/werror.py
+++ b/security/nss/coreconf/werror.py
@@ -54,7 +54,7 @@ def main():
set_warning(w, 'no-')
print('-Qunused-arguments')
- # set_warning('shadow') # Bug 1309068
+ set_warning('shadow')
if __name__ == '__main__':
main()
diff --git a/security/nss/cpputil/databuffer.cc b/security/nss/cpputil/databuffer.cc
index d60ebccb34..1420d76b45 100644
--- a/security/nss/cpputil/databuffer.cc
+++ b/security/nss/cpputil/databuffer.cc
@@ -18,12 +18,12 @@
namespace nss_test {
-void DataBuffer::Assign(const uint8_t* data, size_t len) {
- if (data) {
- Allocate(len);
- memcpy(static_cast<void*>(data_), static_cast<const void*>(data), len);
+void DataBuffer::Assign(const uint8_t* d, size_t l) {
+ if (d) {
+ Allocate(l);
+ memcpy(static_cast<void*>(data_), static_cast<const void*>(d), l);
} else {
- assert(len == 0);
+ assert(l == 0);
data_ = nullptr;
len_ = 0;
}
diff --git a/security/nss/cpputil/databuffer.h b/security/nss/cpputil/databuffer.h
index 58e07efe19..5ec0350986 100644
--- a/security/nss/cpputil/databuffer.h
+++ b/security/nss/cpputil/databuffer.h
@@ -17,8 +17,8 @@ namespace nss_test {
class DataBuffer {
public:
DataBuffer() : data_(nullptr), len_(0) {}
- DataBuffer(const uint8_t* data, size_t len) : data_(nullptr), len_(0) {
- Assign(data, len);
+ DataBuffer(const uint8_t* d, size_t l) : data_(nullptr), len_(0) {
+ Assign(d, l);
}
DataBuffer(const DataBuffer& other) : data_(nullptr), len_(0) {
Assign(other);
@@ -32,17 +32,17 @@ class DataBuffer {
return *this;
}
- void Allocate(size_t len) {
+ void Allocate(size_t l) {
delete[] data_;
- data_ = new uint8_t[len ? len : 1]; // Don't depend on new [0].
- len_ = len;
+ data_ = new uint8_t[l ? l : 1]; // Don't depend on new [0].
+ len_ = l;
}
- void Truncate(size_t len) { len_ = (std::min)(len_, len); }
+ void Truncate(size_t l) { len_ = (std::min)(len_, l); }
void Assign(const DataBuffer& other) { Assign(other.data(), other.len()); }
- void Assign(const uint8_t* data, size_t len);
+ void Assign(const uint8_t* d, size_t l);
// Write will do a new allocation and expand the size of the buffer if needed.
// Returns the offset of the end of the write.
diff --git a/security/nss/cpputil/scoped_ptrs.h b/security/nss/cpputil/scoped_ptrs.h
index 8a0b4f5abe..6ffef4dd3f 100644
--- a/security/nss/cpputil/scoped_ptrs.h
+++ b/security/nss/cpputil/scoped_ptrs.h
@@ -45,6 +45,7 @@ struct ScopedDelete {
void operator()(SEC_PKCS12DecoderContext* dcx) {
SEC_PKCS12DecoderFinish(dcx);
}
+ void operator()(CERTDistNames* names) { CERT_FreeDistNames(names); }
};
template <class T>
@@ -78,6 +79,7 @@ SCOPED(PK11Context);
SCOPED(PK11GenericObject);
SCOPED(SSLResumptionTokenInfo);
SCOPED(SEC_PKCS12DecoderContext);
+SCOPED(CERTDistNames);
#undef SCOPED
diff --git a/security/nss/cpputil/tls_parser.cc b/security/nss/cpputil/tls_parser.cc
index e4c06aa910..efedd7a658 100644
--- a/security/nss/cpputil/tls_parser.cc
+++ b/security/nss/cpputil/tls_parser.cc
@@ -46,6 +46,21 @@ bool TlsParser::Read(DataBuffer* val, size_t len) {
return true;
}
+bool TlsParser::ReadFromMark(DataBuffer* val, size_t len, size_t mark) {
+ auto saved = offset_;
+ offset_ = mark;
+
+ if (remaining() < len) {
+ offset_ = saved;
+ return false;
+ }
+
+ val->Assign(ptr(), len);
+
+ offset_ = saved;
+ return true;
+}
+
bool TlsParser::ReadVariable(DataBuffer* val, size_t len_size) {
uint32_t len;
if (!Read(&len, len_size)) {
diff --git a/security/nss/cpputil/tls_parser.h b/security/nss/cpputil/tls_parser.h
index 436c11e765..56f562e073 100644
--- a/security/nss/cpputil/tls_parser.h
+++ b/security/nss/cpputil/tls_parser.h
@@ -123,6 +123,7 @@ class TlsParser {
bool Read(uint32_t* val, size_t size);
// Reads len bytes into dest buffer, overwriting it.
bool Read(DataBuffer* dest, size_t len);
+ bool ReadFromMark(DataBuffer* val, size_t len, size_t mark);
// Reads bytes into dest buffer, overwriting it. The number of bytes is
// determined by reading from len_size bytes from the stream first.
bool ReadVariable(DataBuffer* dest, size_t len_size);
diff --git a/security/nss/fuzz/fuzz.gyp b/security/nss/fuzz/fuzz.gyp
index ed1f53d585..69e1783190 100644
--- a/security/nss/fuzz/fuzz.gyp
+++ b/security/nss/fuzz/fuzz.gyp
@@ -44,6 +44,9 @@
# This is a static build of pk11wrap, softoken, and freebl.
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
],
+ 'cflags_cc': [
+ '-Wno-error=shadow',
+ ],
'conditions': [
['fuzz_oss==0', {
'sources': [
diff --git a/security/nss/fuzz/tls_client_target.cc b/security/nss/fuzz/tls_client_target.cc
index e595509845..a5b2a2c5ff 100644
--- a/security/nss/fuzz/tls_client_target.cc
+++ b/security/nss/fuzz/tls_client_target.cc
@@ -87,15 +87,12 @@ static void SetupCallbacks(PRFileDesc* fd, ClientConfig* config) {
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
- static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
+ std::unique_ptr<NSSDatabase> db(new NSSDatabase());
assert(db != nullptr);
EnableAllProtocolVersions();
std::unique_ptr<ClientConfig> config(new ClientConfig(data, len));
- // Clear the cache. We never want to resume as we couldn't reproduce that.
- SSL_ClearSessionCache();
-
// Reset the RNG state.
assert(RNG_RandomUpdate(NULL, 0) == SECSuccess);
@@ -114,6 +111,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
SetupCallbacks(ssl_fd, config.get());
DoHandshake(ssl_fd, false);
+ // Release all SIDs.
+ SSL_ClearSessionCache();
+
return 0;
}
diff --git a/security/nss/gtests/freebl_gtest/blake2b_unittest.cc b/security/nss/gtests/freebl_gtest/blake2b_unittest.cc
index e6b0c11576..ac9cca83fd 100644
--- a/security/nss/gtests/freebl_gtest/blake2b_unittest.cc
+++ b/security/nss/gtests/freebl_gtest/blake2b_unittest.cc
@@ -50,7 +50,7 @@ TEST_P(Blake2BKATUnkeyed, Unkeyed) {
TEST_P(Blake2BKATKeyed, Keyed) {
std::vector<uint8_t> values(BLAKE2B512_LENGTH);
SECStatus rv = BLAKE2B_MAC_HashBuf(values.data(), kat_data.data(),
- std::get<0>(GetParam()), key.data(),
+ std::get<0>(GetParam()), kat_key.data(),
BLAKE2B_KEY_SIZE);
ASSERT_EQ(SECSuccess, rv);
EXPECT_EQ(values, std::get<1>(GetParam()));
@@ -139,7 +139,7 @@ TEST_F(Blake2BTests, NullTest) {
EXPECT_EQ(std::get<1>(TestcasesUnkeyed[0]), digest);
digest = std::vector<uint8_t>(BLAKE2B512_LENGTH);
- rv = BLAKE2B_MAC_HashBuf(digest.data(), nullptr, 0, key.data(),
+ rv = BLAKE2B_MAC_HashBuf(digest.data(), nullptr, 0, kat_key.data(),
BLAKE2B_KEY_SIZE);
ASSERT_EQ(SECSuccess, rv);
EXPECT_EQ(std::get<1>(TestcasesKeyed[0]), digest);
diff --git a/security/nss/gtests/freebl_gtest/kat/blake2b_kat.h b/security/nss/gtests/freebl_gtest/kat/blake2b_kat.h
index 28921cc945..2d73a4ab55 100644
--- a/security/nss/gtests/freebl_gtest/kat/blake2b_kat.h
+++ b/security/nss/gtests/freebl_gtest/kat/blake2b_kat.h
@@ -7,7 +7,7 @@
#include <vector>
#include <stdint.h>
-const std::vector<uint8_t> key = {
+const std::vector<uint8_t> kat_key = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
diff --git a/security/nss/gtests/nss_bogo_shim/config.cc b/security/nss/gtests/nss_bogo_shim/config.cc
index 2e6f7f7752..603bb60296 100644
--- a/security/nss/gtests/nss_bogo_shim/config.cc
+++ b/security/nss/gtests/nss_bogo_shim/config.cc
@@ -9,26 +9,37 @@
#include <queue>
#include <string>
-bool ConfigEntryBase::ParseInternal(std::queue<const char *> *args,
- std::string *out) {
- if (args->empty()) return false;
- *out = args->front();
- args->pop();
+bool ConfigEntryBase::ParseInternal(std::queue<const char *> &args,
+ std::vector<int> &out) {
+ if (args.empty()) return false;
+
+ char *endptr;
+ out.push_back(strtol(args.front(), &endptr, 10));
+ args.pop();
+
+ return !*endptr;
+}
+
+bool ConfigEntryBase::ParseInternal(std::queue<const char *> &args,
+ std::string &out) {
+ if (args.empty()) return false;
+ out = args.front();
+ args.pop();
return true;
}
-bool ConfigEntryBase::ParseInternal(std::queue<const char *> *args, int *out) {
- if (args->empty()) return false;
+bool ConfigEntryBase::ParseInternal(std::queue<const char *> &args, int &out) {
+ if (args.empty()) return false;
char *endptr;
- *out = strtol(args->front(), &endptr, 10);
- args->pop();
+ out = strtol(args.front(), &endptr, 10);
+ args.pop();
return !*endptr;
}
-bool ConfigEntryBase::ParseInternal(std::queue<const char *> *args, bool *out) {
- *out = true;
+bool ConfigEntryBase::ParseInternal(std::queue<const char *> &args, bool &out) {
+ out = true;
return true;
}
@@ -51,7 +62,7 @@ Config::Status Config::ParseArgs(int argc, char **argv) {
if (e == entries_.end()) {
return kUnknownFlag;
}
- if (!e->second->Parse(&args)) return kMalformedArgument;
+ if (!e->second->Parse(args)) return kMalformedArgument;
}
return kOK;
diff --git a/security/nss/gtests/nss_bogo_shim/config.h b/security/nss/gtests/nss_bogo_shim/config.h
index 822df65b3a..0e7fb5ed58 100644
--- a/security/nss/gtests/nss_bogo_shim/config.h
+++ b/security/nss/gtests/nss_bogo_shim/config.h
@@ -23,18 +23,19 @@
// Abstract base class for a given config flag.
class ConfigEntryBase {
public:
- ConfigEntryBase(const std::string& name, const std::string& type)
- : name_(name), type_(type) {}
+ ConfigEntryBase(const std::string& nm, const std::string& typ)
+ : name_(nm), type_(typ) {}
virtual ~ConfigEntryBase() {}
const std::string& type() const { return type_; }
- virtual bool Parse(std::queue<const char*>* args) = 0;
+ virtual bool Parse(std::queue<const char*>& args) = 0;
protected:
- bool ParseInternal(std::queue<const char*>* args, std::string* out);
- bool ParseInternal(std::queue<const char*>* args, int* out);
- bool ParseInternal(std::queue<const char*>* args, bool* out);
+ bool ParseInternal(std::queue<const char*>& args, std::vector<int>& out);
+ bool ParseInternal(std::queue<const char*>& args, std::string& out);
+ bool ParseInternal(std::queue<const char*>& args, int& out);
+ bool ParseInternal(std::queue<const char*>& args, bool& out);
const std::string name_;
const std::string type_;
@@ -48,8 +49,8 @@ class ConfigEntry : public ConfigEntryBase {
: ConfigEntryBase(name, typeid(T).name()), value_(init) {}
T get() const { return value_; }
- bool Parse(std::queue<const char*>* args) {
- return ParseInternal(args, &value_);
+ bool Parse(std::queue<const char*>& args) {
+ return ParseInternal(args, value_);
}
private:
diff --git a/security/nss/gtests/nss_bogo_shim/config.json b/security/nss/gtests/nss_bogo_shim/config.json
index 03f8754662..6dc155befa 100644
--- a/security/nss/gtests/nss_bogo_shim/config.json
+++ b/security/nss/gtests/nss_bogo_shim/config.json
@@ -1,69 +1,16 @@
{
"DisabledTests": {
"### These tests break whenever we rev versions, so just leave them here for easy uncommenting":"",
- "SendWarningAlerts-Pass":"BoringSSL updated",
- "SendBogusAlertType":"BoringSSL updated",
- "SendEmptyRecords-Pass":"BoringSSL updated",
- "ExtraCompressionMethods-TLS12":"BoringSSL updated",
- "SendSNIWarningAlert":"BoringSSL updated",
- "NoNullCompression-TLS12":"BoringSSL updated",
- "InvalidCompressionMethod":"BoringSSL updated",
- "SupportTicketsWithSessionID":"BoringSSL updated",
- "NoSharedCipher":"BoringSSL updated",
- "ServerHelloBogusCipher":"BoringSSL updated",
- "ClientHelloVersionTooHigh":"BoringSSL updated",
- "ServerAuth-SignatureType":"BoringSSL updated",
- "ECDSACurveMismatch-Verify-TLS12":"BoringSSL updated",
- "UnknownExtension-Client":"BoringSSL updated",
- "UnofferedExtension-Client":"BoringSSL updated",
- "SendClientVersion-RSA":"BoringSSL updated",
- "SupportedCurves-ServerHello-TLS12":"BoringSSL updated",
- "Basic-Client*Sync":"BoringSSL updated",
- "Resume-Client-CipherMismatch":"BoringSSL updated",
- "ClientAuth-SignatureType":"BoringSSL updated",
- "Agree-Digest-Default":"BoringSSL updated",
- "Basic-Server*Sync":"BoringSSL updated",
- "ClientAuth-*-Sync":"BoringSSL updated",
- "RSA-PSS-Default*":"BoringSSL updated",
- "Renegotiate-Server-NoExt*":"BoringSSL updated",
- "Downgrade-TLS12*":"BoringSSL updated",
- "MaxCBCPadding":"BoringSSL updated",
- "UnknownCipher":"BoringSSL updated",
- "LargeMessage":"BoringSSL updated",
- "NoCommonCurves":"BoringSSL updated",
- "UnknownCurve":"BoringSSL updated",
- "SessionTicketsDisabled*":"BoringSSL updated",
- "BadFinished-*":"BoringSSL updated",
- "ServerSkipCertificateVerify":"BoringSSL updated",
- "*VersionTolerance":"BoringSSL updated",
- "ConflictingVersionNegotiation*":"BoringSSL updated",
- "Ed25519DefaultDisable*":"BoringSSL updated",
- "*SHA1-Fallback*":"BoringSSL updated",
- "ExtendedMasterSecret-NoToNo*":"BoringSSL updated",
- "ServerNameExtensionClientMissing*":"BoringSSL updated",
- "NoClientCertificate*":"BoringSSL updated",
- "ServerCipherFilter*":"BoringSSL updated",
- "*FallbackSCSV*":"BoringSSL updated",
- "LooseInitialRecordVersion*":"BoringSSL updated",
- "ALPNClient*":"BoringSSL updated",
- "MinimumVersion*":"BoringSSL updated",
- "VersionNegotiation*":"BoringSSL updated",
- "*Client-ClientAuth*":"BoringSSL updated",
- "*Server-ClientAuth*":"BoringSSL updated",
- "NoExtendedMasterSecret*":"BoringSSL updated",
- "PointFormat*":"BoringSSL updated",
- "*Sync-SplitHandshakeRecords*":"BoringSSL updated",
- "*Sync-PackHandshakeFlight*":"BoringSSL updated",
- "TicketSessionIDLength*":"BoringSSL updated",
- "*LargeRecord*":"BoringSSL updated",
- "WrongMessageType-NewSessionTicket":"BoringSSL updated",
- "WrongMessageType*Certificate*":"BoringSSL updated",
- "WrongMessageType*Client*":"BoringSSL updated",
- "WrongMessageType*Server*":"BoringSSL updated",
- "WrongMessageType*DTLS":"BoringSSL updated",
- "GarbageCertificate*":"BoringSSL updated",
- "EmptyExtensions*":"BoringSSL updated",
- "*OmitExtensions*":"BoringSSL updated",
+ "ServerBogusVersion":"Check that SH.legacy_version=TLS12 when the server picks TLS 1.3 (Bug 1443761)",
+ "DummyPQPadding-Server*":"Boring is testing a dummy PQ padding extension",
+ "VerifyPreferences-Enforced":"NSS sends alerts in response to errors in protected handshake messages in the clear",
+ "Draft-Downgrade-Server":"Boring implements a draft downgrade sentinel used for measurements.",
+ "FilterExtraAlgorithms":"NSS doesn't allow sending unsupported signature algorithms",
+ "SendBogusAlertType":"Unexpected TLS alerts should abort connections (Bug 1438263)",
+ "VerifyPreferences-Ed25519":"Add Ed25519 support (Bug 1325335)",
+ "Ed25519DefaultDisable*":"Add Ed25519 support (Bug 1325335)",
+ "ServerCipherFilter*":"Add Ed25519 support (Bug 1325335)",
+ "GarbageCertificate*":"Send bad_certificate alert when certificate parsing fails (Bug 1441565)",
"SupportedVersionSelection-TLS12":"Should maybe reject TLS 1.2 in SH.supported_versions (Bug 1438266)",
"*TLS13*":"(NSS=19, BoGo=18)",
"*HelloRetryRequest*":"(NSS=19, BoGo=18)",
@@ -108,7 +55,6 @@
"WrongMessageType-TLS13-ServerCertificateVerify":"nss updated/broken",
"WrongMessageType-TLS13-ServerCertificate":"nss updated/broken",
"WrongMessageType-TLS13-ServerFinished":"nss updated/broken",
- "EncryptedExtensionsWithKeyShare":"nss updated/broken",
"EmptyEncryptedExtensions":"nss updated/broken",
"TrailingMessageData-*": "Bug 1304575",
"DuplicateKeyShares":"Bug 1304578",
diff --git a/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc b/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc
index e12714e8d1..72dbd57711 100644
--- a/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc
+++ b/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc
@@ -5,6 +5,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "config.h"
+#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <memory>
@@ -90,9 +91,14 @@ class TestAgent {
PRStatus prv;
PRNetAddr addr;
- prv = PR_StringToNetAddr("127.0.0.1", &addr);
+ // Try IPv6 first.
+ prv = PR_StringToNetAddr("::1", &addr);
if (prv != PR_SUCCESS) {
- return false;
+ // If that fails, try IPv4.
+ prv = PR_StringToNetAddr("127.0.0.1", &addr);
+ if (prv != PR_SUCCESS) {
+ return false;
+ }
}
addr.inet.port = PR_htons(cfg_.get<int>("port"));
@@ -256,7 +262,11 @@ class TestAgent {
}
bool SetupOptions() {
- SECStatus rv = SSL_OptionSet(ssl_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE);
+ SECStatus rv =
+ SSL_OptionSet(ssl_fd_, SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE);
+ if (rv != SECSuccess) return false;
+
+ rv = SSL_OptionSet(ssl_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE);
if (rv != SECSuccess) return false;
SSLVersionRange vrange;
@@ -287,6 +297,26 @@ class TestAgent {
if (rv != SECSuccess) return false;
}
+ // Set supported signature schemes.
+ auto sign_prefs = cfg_.get<std::vector<int>>("signing-prefs");
+ auto verify_prefs = cfg_.get<std::vector<int>>("verify-prefs");
+ if (sign_prefs.empty()) {
+ sign_prefs = verify_prefs;
+ } else if (!verify_prefs.empty()) {
+ return false; // Both shouldn't be set.
+ }
+ if (!sign_prefs.empty()) {
+ std::vector<SSLSignatureScheme> sig_schemes;
+ std::transform(
+ sign_prefs.begin(), sign_prefs.end(), std::back_inserter(sig_schemes),
+ [](int scheme) { return static_cast<SSLSignatureScheme>(scheme); });
+
+ rv = SSL_SignatureSchemePrefSet(
+ ssl_fd_, sig_schemes.data(),
+ static_cast<unsigned int>(sig_schemes.size()));
+ if (rv != SECSuccess) return false;
+ }
+
if (cfg_.get<bool>("fallback-scsv")) {
rv = SSL_OptionSet(ssl_fd_, SSL_ENABLE_FALLBACK_SCSV, PR_TRUE);
if (rv != SECSuccess) return false;
@@ -410,7 +440,7 @@ class TestAgent {
size_t left = sizeof(block);
while (left) {
- int32_t rv = PR_Read(ssl_fd_, block, left);
+ rv = PR_Read(ssl_fd_, block, left);
if (rv < 0) {
std::cerr << "Failure reading\n";
return SECFailure;
@@ -481,6 +511,24 @@ class TestAgent {
}
}
+ auto sig_alg = cfg_.get<int>("expect-peer-signature-algorithm");
+ if (sig_alg) {
+ SSLChannelInfo info;
+ rv = SSL_GetChannelInfo(ssl_fd_, &info, sizeof(info));
+ if (rv != SECSuccess) {
+ PRErrorCode err = PR_GetError();
+ std::cerr << "SSL_GetChannelInfo failed with error=" << FormatError(err)
+ << std::endl;
+ return SECFailure;
+ }
+
+ auto expected = static_cast<SSLSignatureScheme>(sig_alg);
+ if (info.signatureScheme != expected) {
+ std::cerr << "Unexpected signature scheme" << std::endl;
+ return SECFailure;
+ }
+ }
+
return SECSuccess;
}
@@ -513,6 +561,9 @@ std::unique_ptr<const Config> ReadConfig(int argc, char** argv) {
cfg->AddEntry<bool>("verify-peer", false);
cfg->AddEntry<std::string>("advertise-alpn", "");
cfg->AddEntry<std::string>("expect-alpn", "");
+ cfg->AddEntry<std::vector<int>>("signing-prefs", std::vector<int>());
+ cfg->AddEntry<std::vector<int>>("verify-prefs", std::vector<int>());
+ cfg->AddEntry<int>("expect-peer-signature-algorithm", 0);
auto rv = cfg->ParseArgs(argc, argv);
switch (rv) {
diff --git a/security/nss/gtests/pk11_gtest/pk11_signature_test.h b/security/nss/gtests/pk11_gtest/pk11_signature_test.h
index b141043716..8a12171a0a 100644
--- a/security/nss/gtests/pk11_gtest/pk11_signature_test.h
+++ b/security/nss/gtests/pk11_gtest/pk11_signature_test.h
@@ -25,8 +25,8 @@ struct Pkcs11SignatureTestParams {
class Pk11SignatureTest : public ::testing::Test {
protected:
- Pk11SignatureTest(CK_MECHANISM_TYPE mechanism, SECOidTag hash_oid)
- : mechanism_(mechanism), hash_oid_(hash_oid) {}
+ Pk11SignatureTest(CK_MECHANISM_TYPE mech, SECOidTag hash_oid)
+ : mechanism_(mech), hash_oid_(hash_oid) {}
virtual const SECItem* parameters() const { return nullptr; }
CK_MECHANISM_TYPE mechanism() const { return mechanism_; }
diff --git a/security/nss/gtests/ssl_gtest/libssl_internals.c b/security/nss/gtests/ssl_gtest/libssl_internals.c
index 17b4ffe49a..e43113de42 100644
--- a/security/nss/gtests/ssl_gtest/libssl_internals.c
+++ b/security/nss/gtests/ssl_gtest/libssl_internals.c
@@ -237,22 +237,23 @@ SECStatus SSLInt_AdvanceReadSeqNum(PRFileDesc *fd, PRUint64 to) {
if (!ss) {
return SECFailure;
}
- if (to >= RECORD_SEQ_MAX) {
+ if (to > RECORD_SEQ_MAX) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
ssl_GetSpecWriteLock(ss);
spec = ss->ssl3.crSpec;
- spec->seqNum = to;
+ spec->nextSeqNum = to;
/* For DTLS, we need to fix the record sequence number. For this, we can just
* scrub the entire structure on the assumption that the new sequence number
* is far enough past the last received sequence number. */
- if (spec->seqNum <= spec->recvdRecords.right + DTLS_RECVD_RECORDS_WINDOW) {
+ if (spec->nextSeqNum <=
+ spec->recvdRecords.right + DTLS_RECVD_RECORDS_WINDOW) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
- dtls_RecordSetRecvd(&spec->recvdRecords, spec->seqNum);
+ dtls_RecordSetRecvd(&spec->recvdRecords, spec->nextSeqNum - 1);
ssl_ReleaseSpecWriteLock(ss);
return SECSuccess;
@@ -270,7 +271,7 @@ SECStatus SSLInt_AdvanceWriteSeqNum(PRFileDesc *fd, PRUint64 to) {
return SECFailure;
}
ssl_GetSpecWriteLock(ss);
- ss->ssl3.cwSpec->seqNum = to;
+ ss->ssl3.cwSpec->nextSeqNum = to;
ssl_ReleaseSpecWriteLock(ss);
return SECSuccess;
}
@@ -284,7 +285,7 @@ SECStatus SSLInt_AdvanceWriteSeqByAWindow(PRFileDesc *fd, PRInt32 extra) {
return SECFailure;
}
ssl_GetSpecReadLock(ss);
- to = ss->ssl3.cwSpec->seqNum + DTLS_RECVD_RECORDS_WINDOW + extra;
+ to = ss->ssl3.cwSpec->nextSeqNum + DTLS_RECVD_RECORDS_WINDOW + extra;
ssl_ReleaseSpecReadLock(ss);
return SSLInt_AdvanceWriteSeqNum(fd, to);
}
diff --git a/security/nss/gtests/ssl_gtest/manifest.mn b/security/nss/gtests/ssl_gtest/manifest.mn
index 5d893bab35..8547e56d1d 100644
--- a/security/nss/gtests/ssl_gtest/manifest.mn
+++ b/security/nss/gtests/ssl_gtest/manifest.mn
@@ -36,6 +36,7 @@ CPPSRCS = \
ssl_loopback_unittest.cc \
ssl_misc_unittest.cc \
ssl_record_unittest.cc \
+ ssl_recordsize_unittest.cc \
ssl_resumption_unittest.cc \
ssl_renegotiation_unittest.cc \
ssl_skip_unittest.cc \
diff --git a/security/nss/gtests/ssl_gtest/rsa8193.h b/security/nss/gtests/ssl_gtest/rsa8193.h
new file mode 100644
index 0000000000..6265163896
--- /dev/null
+++ b/security/nss/gtests/ssl_gtest/rsa8193.h
@@ -0,0 +1,209 @@
+/* -*- 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/. */
+
+// openssl req -nodes -x509 -newkey rsa:8193 -out cert.pem -days 365
+static const uint8_t rsa8193[] = {
+ 0x30, 0x82, 0x09, 0x61, 0x30, 0x82, 0x05, 0x48, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x09, 0x00, 0xaf, 0xff, 0x37, 0x91, 0x3e, 0x44, 0xae, 0x57,
+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x0b, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+ 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
+ 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a,
+ 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
+ 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c,
+ 0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x35, 0x31, 0x37,
+ 0x30, 0x39, 0x34, 0x32, 0x32, 0x39, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x30,
+ 0x35, 0x31, 0x37, 0x30, 0x39, 0x34, 0x32, 0x32, 0x39, 0x5a, 0x30, 0x45,
+ 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41,
+ 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a,
+ 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21,
+ 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49, 0x6e, 0x74,
+ 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74,
+ 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x82, 0x04,
+ 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+ 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x04, 0x0f, 0x00, 0x30, 0x82, 0x04,
+ 0x0a, 0x02, 0x82, 0x04, 0x01, 0x01, 0x77, 0xd6, 0xa9, 0x93, 0x4e, 0x15,
+ 0xb5, 0x67, 0x70, 0x8e, 0xc3, 0x77, 0x4f, 0xc9, 0x8a, 0x06, 0xd9, 0xb9,
+ 0xa6, 0x41, 0xb8, 0xfa, 0x4a, 0x13, 0x26, 0xdc, 0x2b, 0xc5, 0x82, 0xa0,
+ 0x74, 0x8c, 0x1e, 0xe9, 0xc0, 0x70, 0x15, 0x56, 0xec, 0x1f, 0x7e, 0x91,
+ 0x6e, 0x31, 0x42, 0x8b, 0xd5, 0xe2, 0x0e, 0x9c, 0xeb, 0xff, 0xbc, 0xf9,
+ 0x42, 0xd3, 0xb9, 0x1c, 0x5e, 0x46, 0x80, 0x90, 0x5f, 0xe1, 0x59, 0x22,
+ 0x13, 0x71, 0xd3, 0xd6, 0x66, 0x7a, 0xe0, 0x56, 0x04, 0x10, 0x59, 0x01,
+ 0xb3, 0xb6, 0xd2, 0xc7, 0xa7, 0x3b, 0xbc, 0xe6, 0x38, 0x44, 0xd5, 0x71,
+ 0x66, 0x1d, 0xb2, 0x63, 0x2f, 0xa9, 0x5e, 0x80, 0x92, 0x3c, 0x21, 0x0e,
+ 0xe1, 0xda, 0xd6, 0x1d, 0xcb, 0xce, 0xac, 0xe1, 0x5f, 0x97, 0x45, 0x8f,
+ 0xc1, 0x64, 0x16, 0xa6, 0x88, 0x2a, 0x36, 0x4a, 0x76, 0x64, 0x8f, 0x83,
+ 0x7a, 0x1d, 0xd8, 0x91, 0x90, 0x7b, 0x58, 0xb8, 0x1c, 0x7f, 0x56, 0x57,
+ 0x35, 0xfb, 0xf3, 0x1a, 0xcb, 0x7c, 0x66, 0x66, 0x04, 0x95, 0xee, 0x3a,
+ 0x80, 0xf0, 0xd4, 0x12, 0x3a, 0x7e, 0x7e, 0x5e, 0xb8, 0x55, 0x29, 0x23,
+ 0x06, 0xd3, 0x85, 0x0c, 0x99, 0x91, 0x42, 0xee, 0x5a, 0x30, 0x7f, 0x52,
+ 0x20, 0xb3, 0xe2, 0xe7, 0x39, 0x69, 0xb6, 0xfc, 0x42, 0x1e, 0x98, 0xd3,
+ 0x31, 0xa2, 0xfa, 0x81, 0x52, 0x69, 0x6d, 0x23, 0xf8, 0xc4, 0xc3, 0x3c,
+ 0x9b, 0x48, 0x75, 0xa8, 0xc7, 0xe7, 0x61, 0x81, 0x1f, 0xf7, 0xce, 0x10,
+ 0xaa, 0x13, 0xcb, 0x6e, 0x19, 0xc0, 0x4f, 0x6f, 0x90, 0xa8, 0x41, 0xea,
+ 0x49, 0xdf, 0xe4, 0xef, 0x84, 0x54, 0xb5, 0x37, 0xaf, 0x12, 0x75, 0x1a,
+ 0x11, 0x4b, 0x58, 0x7f, 0x63, 0x22, 0x33, 0xb1, 0xc8, 0x4d, 0xf2, 0x41,
+ 0x10, 0xbc, 0x37, 0xb5, 0xd5, 0xb2, 0x21, 0x32, 0x35, 0x9d, 0xf3, 0x8d,
+ 0xab, 0x66, 0x9d, 0x19, 0x12, 0x71, 0x45, 0xb3, 0x82, 0x5a, 0x5c, 0xff,
+ 0x2d, 0xcf, 0xf4, 0x5b, 0x56, 0xb8, 0x08, 0xb3, 0xd2, 0x43, 0x8c, 0xac,
+ 0xd2, 0xf8, 0xcc, 0x6d, 0x90, 0x97, 0xff, 0x12, 0x74, 0x97, 0xf8, 0xa4,
+ 0xe3, 0x95, 0xae, 0x92, 0xdc, 0x7e, 0x9d, 0x2b, 0xb4, 0x94, 0xc3, 0x8d,
+ 0x80, 0xe7, 0x77, 0x5c, 0x5b, 0xbb, 0x43, 0xdc, 0xa6, 0xe9, 0xbe, 0x20,
+ 0xcc, 0x9d, 0x8e, 0xa4, 0x2b, 0xf2, 0x72, 0xdc, 0x44, 0x61, 0x0f, 0xad,
+ 0x1a, 0x5e, 0xa5, 0x48, 0xe4, 0x42, 0xc5, 0xe4, 0xf1, 0x6d, 0x33, 0xdb,
+ 0xb2, 0x1b, 0x9f, 0xb2, 0xff, 0x18, 0x0e, 0x62, 0x35, 0x99, 0xed, 0x22,
+ 0x19, 0x4a, 0x5e, 0xb3, 0x3c, 0x07, 0x8f, 0x6e, 0x22, 0x5b, 0x16, 0x4a,
+ 0x9f, 0xef, 0xf3, 0xe7, 0xd6, 0x48, 0xe1, 0xb4, 0x3b, 0xab, 0x1b, 0x9e,
+ 0x53, 0xd7, 0x1b, 0xd9, 0x2d, 0x51, 0x8f, 0xe4, 0x1c, 0xab, 0xdd, 0xb9,
+ 0xe2, 0xee, 0xe4, 0xdd, 0x60, 0x04, 0x86, 0x6b, 0x4e, 0x7a, 0xc8, 0x09,
+ 0x51, 0xd1, 0x9b, 0x36, 0x9a, 0x36, 0x7f, 0xe8, 0x6b, 0x09, 0x6c, 0xee,
+ 0xad, 0x3a, 0x2f, 0xa8, 0x63, 0x92, 0x23, 0x2f, 0x7e, 0x00, 0xe2, 0xd1,
+ 0xbb, 0xd9, 0x5b, 0x5b, 0xfa, 0x4b, 0x83, 0x00, 0x19, 0x28, 0xfb, 0x7e,
+ 0xfe, 0x58, 0xab, 0xb7, 0x33, 0x45, 0x8f, 0x75, 0x9a, 0x54, 0x3d, 0x77,
+ 0x06, 0x75, 0x61, 0x4f, 0x5c, 0x93, 0xa0, 0xf9, 0xe8, 0xcf, 0xf6, 0x04,
+ 0x14, 0xda, 0x1b, 0x2e, 0x79, 0x35, 0xb8, 0xb4, 0xfa, 0x08, 0x27, 0x9a,
+ 0x03, 0x70, 0x78, 0x97, 0x8f, 0xae, 0x2e, 0xd5, 0x1c, 0xe0, 0x4d, 0x91,
+ 0x3a, 0xfe, 0x1a, 0x64, 0xd8, 0x49, 0xdf, 0x6c, 0x66, 0xac, 0xc9, 0x57,
+ 0x06, 0x72, 0xc0, 0xc0, 0x09, 0x71, 0x6a, 0xd0, 0xb0, 0x7d, 0x35, 0x3f,
+ 0x53, 0x17, 0x49, 0x38, 0x92, 0x22, 0x55, 0xf6, 0x58, 0x56, 0xa2, 0x42,
+ 0x77, 0x94, 0xb7, 0x28, 0x0a, 0xa0, 0xd2, 0xda, 0x25, 0xc1, 0xcc, 0x52,
+ 0x51, 0xd6, 0xba, 0x18, 0x0f, 0x0d, 0xe3, 0x7d, 0xd1, 0xda, 0xd9, 0x0c,
+ 0x5e, 0x3a, 0xca, 0xe9, 0xf1, 0xf5, 0x65, 0xfc, 0xc3, 0x99, 0x72, 0x25,
+ 0xf2, 0xc0, 0xa1, 0x8c, 0x43, 0x9d, 0xb2, 0xc9, 0xb1, 0x1a, 0x24, 0x34,
+ 0x57, 0xd8, 0xa7, 0x52, 0xa3, 0x39, 0x6e, 0x0b, 0xec, 0xbd, 0x5e, 0xc9,
+ 0x1f, 0x74, 0xed, 0xae, 0xe6, 0x4e, 0x49, 0xe8, 0x87, 0x3e, 0x46, 0x0d,
+ 0x40, 0x30, 0xda, 0x9d, 0xcf, 0xf5, 0x03, 0x1f, 0x38, 0x29, 0x3b, 0x66,
+ 0xe5, 0xc0, 0x89, 0x4c, 0xfc, 0x09, 0x62, 0x37, 0x01, 0xf9, 0x01, 0xab,
+ 0x8d, 0x53, 0x9c, 0x36, 0x5d, 0x36, 0x66, 0x8d, 0x87, 0xf4, 0xab, 0x37,
+ 0xb7, 0xf7, 0xe3, 0xdf, 0xc1, 0x52, 0xc0, 0x1d, 0x09, 0x92, 0x21, 0x47,
+ 0x49, 0x9a, 0x19, 0x38, 0x05, 0x62, 0xf3, 0x47, 0x80, 0x89, 0x1e, 0x70,
+ 0xa1, 0x57, 0xb7, 0x72, 0xd0, 0x41, 0x7a, 0x5c, 0x6a, 0x13, 0x8b, 0x6c,
+ 0xda, 0xdf, 0x6b, 0x01, 0x15, 0x20, 0xfa, 0xc8, 0x67, 0xee, 0xb2, 0x13,
+ 0xd8, 0x5f, 0x84, 0x30, 0x44, 0x8e, 0xf9, 0x2a, 0xae, 0x17, 0x53, 0x49,
+ 0xaa, 0x34, 0x31, 0x12, 0x31, 0xec, 0xf3, 0x25, 0x27, 0x53, 0x6b, 0xb5,
+ 0x63, 0xa6, 0xbc, 0xf1, 0x77, 0xd4, 0xb4, 0x77, 0xd1, 0xee, 0xad, 0x62,
+ 0x9d, 0x2c, 0x2e, 0x11, 0x0a, 0xd1, 0x87, 0xfe, 0xef, 0x77, 0x0e, 0xd1,
+ 0x38, 0xfe, 0xcc, 0x88, 0xaa, 0x1c, 0x06, 0x93, 0x25, 0x56, 0xfe, 0x0c,
+ 0x52, 0xe9, 0x7f, 0x4c, 0x3b, 0x2a, 0xfb, 0x40, 0x62, 0x29, 0x0a, 0x1d,
+ 0x58, 0x78, 0x8b, 0x09, 0x25, 0xaa, 0xc6, 0x8f, 0x66, 0x8f, 0xd1, 0x93,
+ 0x5a, 0xd6, 0x68, 0x35, 0x69, 0x13, 0x5d, 0x42, 0x35, 0x95, 0xcb, 0xc4,
+ 0xec, 0x17, 0x92, 0x96, 0xcb, 0x4a, 0xb9, 0x8f, 0xe5, 0xc4, 0x4a, 0xe7,
+ 0x54, 0x52, 0x4c, 0x64, 0x06, 0xac, 0x2f, 0x13, 0x32, 0x02, 0x47, 0x13,
+ 0x5c, 0xa2, 0x66, 0xdc, 0x36, 0x0c, 0x4f, 0xbb, 0x89, 0x58, 0x85, 0x16,
+ 0xf1, 0xf1, 0xff, 0xd2, 0x86, 0x54, 0x29, 0xb3, 0x7e, 0x2a, 0xbd, 0xf9,
+ 0x53, 0x8c, 0xa0, 0x60, 0x60, 0xb2, 0x90, 0x7f, 0x3a, 0x11, 0x5f, 0x2a,
+ 0x50, 0x74, 0x2a, 0xd1, 0x68, 0x78, 0xdb, 0x31, 0x1b, 0x8b, 0xee, 0xee,
+ 0x18, 0x97, 0xf3, 0x50, 0x84, 0xc1, 0x8f, 0xe1, 0xc6, 0x01, 0xb4, 0x16,
+ 0x65, 0x25, 0x0c, 0x03, 0xab, 0xed, 0x4f, 0xd6, 0xe6, 0x16, 0x23, 0xcc,
+ 0x42, 0x93, 0xff, 0xfa, 0x92, 0x63, 0x33, 0x9e, 0x36, 0xb0, 0xdc, 0x9a,
+ 0xb6, 0xaa, 0xd7, 0x48, 0xfe, 0x27, 0x01, 0xcf, 0x67, 0xc0, 0x75, 0xa0,
+ 0x86, 0x9a, 0xec, 0xa7, 0x2e, 0xb8, 0x7b, 0x00, 0x7f, 0xd4, 0xe3, 0xb3,
+ 0xfc, 0x48, 0xab, 0x50, 0x20, 0xd4, 0x0d, 0x58, 0x26, 0xc0, 0x3c, 0x09,
+ 0x0b, 0x80, 0x9e, 0xaf, 0x14, 0x3c, 0x0c, 0x6e, 0x69, 0xbc, 0x6c, 0x4e,
+ 0x50, 0x33, 0xb0, 0x07, 0x64, 0x6e, 0x77, 0x96, 0xc2, 0xe6, 0x3b, 0xd7,
+ 0xfe, 0xdc, 0xa4, 0x2f, 0x18, 0x5b, 0x53, 0xe5, 0xdd, 0xb6, 0xce, 0xeb,
+ 0x16, 0xb4, 0x25, 0xc6, 0xcb, 0xf2, 0x65, 0x3c, 0x4f, 0x94, 0xa5, 0x11,
+ 0x18, 0xeb, 0x7b, 0x62, 0x1d, 0xd5, 0x02, 0x35, 0x76, 0xf6, 0xb5, 0x20,
+ 0x27, 0x21, 0x9b, 0xab, 0xf4, 0xb6, 0x8f, 0x1a, 0x70, 0x1d, 0x12, 0xe3,
+ 0xb9, 0x8e, 0x29, 0x52, 0x25, 0xf4, 0xba, 0xb4, 0x25, 0x2c, 0x91, 0x11,
+ 0xf2, 0xae, 0x7b, 0xbe, 0xb6, 0x67, 0xd6, 0x08, 0xf8, 0x6f, 0xe7, 0xb0,
+ 0x16, 0xc5, 0xf6, 0xd5, 0xfb, 0x07, 0x71, 0x5b, 0x0e, 0xe1, 0x02, 0x03,
+ 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55,
+ 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xaa, 0xe7, 0x7f, 0xcf, 0xf8, 0xb4,
+ 0xe0, 0x8d, 0x39, 0x9a, 0x1d, 0x4f, 0x86, 0xa2, 0xac, 0x56, 0x32, 0xd9,
+ 0x58, 0xe3, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
+ 0x16, 0x80, 0x14, 0xaa, 0xe7, 0x7f, 0xcf, 0xf8, 0xb4, 0xe0, 0x8d, 0x39,
+ 0x9a, 0x1d, 0x4f, 0x86, 0xa2, 0xac, 0x56, 0x32, 0xd9, 0x58, 0xe3, 0x30,
+ 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30,
+ 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x04, 0x02, 0x00,
+ 0x00, 0x0a, 0x0a, 0x81, 0xb5, 0x2e, 0xac, 0x52, 0xab, 0x0f, 0xeb, 0xad,
+ 0x96, 0xd6, 0xd6, 0x59, 0x8f, 0x55, 0x15, 0x56, 0x70, 0xda, 0xd5, 0x75,
+ 0x47, 0x12, 0x9a, 0x0e, 0xd1, 0x65, 0x68, 0xe0, 0x51, 0x89, 0x59, 0xcc,
+ 0xe3, 0x5a, 0x1b, 0x85, 0x14, 0xa3, 0x1d, 0x9b, 0x3f, 0xd1, 0xa4, 0x42,
+ 0xb0, 0x89, 0x12, 0x93, 0xd3, 0x54, 0x19, 0x04, 0xa2, 0xaf, 0xaa, 0x60,
+ 0xca, 0x03, 0xc2, 0xae, 0x62, 0x8c, 0xb6, 0x31, 0x03, 0xd6, 0xa5, 0xf3,
+ 0x5e, 0x8d, 0x5c, 0x69, 0x4c, 0x7d, 0x81, 0x49, 0x20, 0x25, 0x41, 0xa4,
+ 0x2a, 0x95, 0x87, 0x36, 0xa3, 0x9b, 0x9e, 0x9f, 0xed, 0x85, 0xf3, 0xb1,
+ 0xf1, 0xe9, 0x1b, 0xbb, 0xe3, 0xbc, 0x3b, 0x11, 0x36, 0xca, 0xb9, 0x5f,
+ 0xee, 0x64, 0xde, 0x2a, 0x99, 0x27, 0x91, 0xc0, 0x54, 0x9e, 0x7a, 0xd4,
+ 0x89, 0x8c, 0xa0, 0xe3, 0xfd, 0x44, 0x6f, 0x02, 0x38, 0x3c, 0xee, 0x52,
+ 0x48, 0x1b, 0xd4, 0x25, 0x2b, 0xcb, 0x8e, 0xa8, 0x1b, 0x09, 0xd6, 0x30,
+ 0x51, 0x15, 0x6c, 0x5c, 0x03, 0x76, 0xad, 0x64, 0x45, 0x50, 0xa2, 0xe1,
+ 0x3c, 0x5a, 0x67, 0x87, 0xff, 0x8c, 0xed, 0x9a, 0x8d, 0x04, 0xc1, 0xac,
+ 0xf9, 0xca, 0xf5, 0x2a, 0x05, 0x9c, 0xdd, 0x78, 0xce, 0x99, 0x78, 0x7b,
+ 0xcd, 0x43, 0x10, 0x40, 0xf7, 0xb5, 0x27, 0x12, 0xec, 0xe9, 0xb2, 0x3f,
+ 0xf4, 0x5d, 0xd9, 0xbb, 0xf8, 0xc4, 0xc9, 0xa4, 0x46, 0x20, 0x41, 0x7f,
+ 0xeb, 0x79, 0xb0, 0x51, 0x8c, 0xf7, 0xc3, 0x2c, 0x16, 0xfe, 0x42, 0x59,
+ 0x77, 0xfe, 0x53, 0xfe, 0x19, 0x57, 0x58, 0x44, 0x6d, 0x12, 0xe2, 0x95,
+ 0xd0, 0xd3, 0x5a, 0xb5, 0x2d, 0xe5, 0x7e, 0xb4, 0xb3, 0xa9, 0xcc, 0x7d,
+ 0x53, 0x77, 0x81, 0x01, 0x0f, 0x0a, 0xf6, 0x86, 0x3c, 0x7d, 0xb5, 0x2c,
+ 0xbf, 0x62, 0xc3, 0xf5, 0x38, 0x89, 0x13, 0x84, 0x1f, 0x44, 0x2d, 0x87,
+ 0x5c, 0x23, 0x9e, 0x05, 0x62, 0x56, 0x3d, 0x71, 0x4d, 0xd0, 0xe3, 0x15,
+ 0xe9, 0x09, 0x9c, 0x1a, 0xc0, 0x9a, 0x19, 0x8b, 0x9c, 0xe9, 0xae, 0xde,
+ 0x62, 0x05, 0x23, 0xe2, 0xd0, 0x3f, 0xf5, 0xef, 0x04, 0x96, 0x4c, 0x87,
+ 0x34, 0x2f, 0xd5, 0x90, 0xde, 0xbf, 0x4b, 0x56, 0x12, 0x5f, 0xc6, 0xdc,
+ 0xa4, 0x1c, 0xc4, 0x53, 0x0c, 0xf9, 0xb4, 0xe4, 0x2c, 0xe7, 0x48, 0xbd,
+ 0xb1, 0xac, 0xf1, 0xc1, 0x8d, 0x53, 0x47, 0x84, 0xc0, 0x78, 0x0a, 0x5e,
+ 0xc2, 0x16, 0xff, 0xef, 0x97, 0x5b, 0x33, 0x85, 0x92, 0xcd, 0xd4, 0xbb,
+ 0x64, 0xee, 0xed, 0x17, 0x18, 0x43, 0x32, 0x99, 0x32, 0x36, 0x25, 0xf4,
+ 0x21, 0x3c, 0x2f, 0x55, 0xdc, 0x16, 0x06, 0x4d, 0x86, 0xa3, 0xa9, 0x34,
+ 0x22, 0xd5, 0xc3, 0xc8, 0x64, 0x3c, 0x4e, 0x3a, 0x69, 0xbd, 0xcf, 0xd7,
+ 0xee, 0x3f, 0x0d, 0x15, 0xeb, 0xfb, 0xbd, 0x91, 0x7f, 0xef, 0x48, 0xec,
+ 0x86, 0xb2, 0x78, 0xf7, 0x53, 0x90, 0x38, 0xb5, 0x04, 0x9c, 0xb7, 0xd7,
+ 0x9e, 0xaa, 0x15, 0xf7, 0xcd, 0xc2, 0x17, 0xd5, 0x8f, 0x82, 0x98, 0xa3,
+ 0xaf, 0x59, 0xf1, 0x71, 0xda, 0x6e, 0xaf, 0x97, 0x6d, 0x77, 0x72, 0xfd,
+ 0xa8, 0x80, 0x25, 0xce, 0x46, 0x04, 0x6e, 0x40, 0x15, 0x24, 0xc0, 0xf9,
+ 0xbf, 0x13, 0x16, 0x72, 0xcb, 0xb7, 0x10, 0xc7, 0x0a, 0xd6, 0x66, 0x96,
+ 0x5b, 0x27, 0x4d, 0x66, 0xc4, 0x2f, 0x21, 0x90, 0x9f, 0x8c, 0x24, 0xa0,
+ 0x0e, 0xa2, 0x89, 0x92, 0xd2, 0x44, 0x63, 0x06, 0xb2, 0xab, 0x07, 0x26,
+ 0xde, 0x03, 0x1d, 0xdb, 0x2a, 0x42, 0x5b, 0x4c, 0xf6, 0xfe, 0x53, 0xfa,
+ 0x80, 0x45, 0x8d, 0x75, 0xf6, 0x0e, 0x1d, 0xcc, 0x4c, 0x3b, 0xb0, 0x80,
+ 0x6d, 0x4c, 0xed, 0x7c, 0xe0, 0xd2, 0xe7, 0x62, 0x59, 0xb1, 0x5a, 0x5d,
+ 0x3a, 0xec, 0x86, 0x04, 0xfe, 0x26, 0xd1, 0x18, 0xed, 0x56, 0x7d, 0x67,
+ 0x56, 0x24, 0x6d, 0x7c, 0x6e, 0x8f, 0xc8, 0xa0, 0xba, 0x42, 0x0a, 0x33,
+ 0x38, 0x7a, 0x09, 0x03, 0xc2, 0xbf, 0x9b, 0x01, 0xdd, 0x03, 0x5a, 0xba,
+ 0x76, 0x04, 0xb1, 0xc3, 0x40, 0x23, 0x53, 0xbd, 0x64, 0x4e, 0x0f, 0xe7,
+ 0xc3, 0x4e, 0x48, 0xea, 0x19, 0x2b, 0x1c, 0xe4, 0x3d, 0x93, 0xd8, 0xf6,
+ 0xfb, 0xda, 0x3d, 0xeb, 0xed, 0xc2, 0xbd, 0x14, 0x57, 0x40, 0xde, 0xd1,
+ 0x74, 0x54, 0x1b, 0xa8, 0x39, 0xda, 0x73, 0x56, 0xd4, 0xbe, 0xab, 0xec,
+ 0xc7, 0x17, 0x4f, 0x91, 0xb6, 0xf6, 0xcb, 0x24, 0xc6, 0x1c, 0x07, 0xc4,
+ 0xf3, 0xd0, 0x5e, 0x8d, 0xfa, 0x44, 0x98, 0x5c, 0x87, 0x36, 0x75, 0xb6,
+ 0xa5, 0x31, 0xaa, 0xab, 0x7d, 0x38, 0x66, 0xb3, 0x18, 0x58, 0x65, 0x97,
+ 0x06, 0xfd, 0x61, 0x81, 0x71, 0xc5, 0x17, 0x8b, 0x19, 0x03, 0xc8, 0x58,
+ 0xec, 0x05, 0xca, 0x7b, 0x0f, 0xec, 0x9d, 0xb4, 0xbc, 0xa3, 0x20, 0x2e,
+ 0xf8, 0xe4, 0xb1, 0x82, 0xdc, 0x5a, 0xd2, 0x92, 0x9c, 0x43, 0x5d, 0x16,
+ 0x5b, 0x90, 0x80, 0xe4, 0xfb, 0x6e, 0x24, 0x6b, 0x8c, 0x1a, 0x35, 0xab,
+ 0xbd, 0x77, 0x7f, 0xf9, 0x61, 0x80, 0xa5, 0xab, 0xa3, 0x39, 0xc2, 0xc9,
+ 0x69, 0x3c, 0xfc, 0xb3, 0x9a, 0x05, 0x45, 0x03, 0x88, 0x8f, 0x8e, 0x23,
+ 0xf2, 0x0c, 0x4c, 0x54, 0xb9, 0x40, 0x3a, 0x31, 0x1a, 0x22, 0x67, 0x43,
+ 0x4a, 0x3e, 0xa0, 0x8c, 0x2d, 0x4d, 0x4f, 0xfc, 0xb5, 0x9b, 0x1f, 0xe1,
+ 0xef, 0x02, 0x54, 0xab, 0x8d, 0x75, 0x4d, 0x93, 0xba, 0x76, 0xe1, 0xbc,
+ 0x42, 0x7f, 0x6c, 0xcb, 0xf5, 0x47, 0xd6, 0x8a, 0xac, 0x5d, 0xe9, 0xbb,
+ 0x3a, 0x65, 0x2c, 0x81, 0xe5, 0xff, 0x27, 0x7e, 0x60, 0x64, 0x80, 0x42,
+ 0x8d, 0x36, 0x6b, 0x07, 0x76, 0x6a, 0xf1, 0xdf, 0x96, 0x17, 0x93, 0x21,
+ 0x5d, 0xe4, 0x6c, 0xce, 0x1c, 0xb9, 0x82, 0x45, 0x05, 0x61, 0xe2, 0x41,
+ 0x96, 0x03, 0x7d, 0x10, 0x8b, 0x3e, 0xc7, 0xe5, 0xcf, 0x08, 0xeb, 0x81,
+ 0xd3, 0x82, 0x1b, 0x04, 0x96, 0x93, 0x5a, 0xe2, 0x8c, 0x8e, 0x50, 0x33,
+ 0xf6, 0xf9, 0xf0, 0xfb, 0xb1, 0xd7, 0xc6, 0x97, 0xaa, 0xef, 0x0b, 0x87,
+ 0xe1, 0x34, 0x97, 0x78, 0x2e, 0x7c, 0x46, 0x11, 0xd5, 0x3c, 0xec, 0x38,
+ 0x70, 0x59, 0x14, 0x65, 0x4d, 0x0e, 0xd1, 0xeb, 0x49, 0xb3, 0x99, 0x6f,
+ 0x87, 0xf1, 0x79, 0x21, 0xd9, 0x5c, 0x37, 0xb2, 0xfe, 0xc4, 0x7a, 0xc1,
+ 0x67, 0xbd, 0x02, 0xfc, 0x02, 0xab, 0x2f, 0xf5, 0x0f, 0xa7, 0xae, 0x90,
+ 0xc2, 0xaf, 0xdb, 0xd1, 0x96, 0xb2, 0x92, 0x5a, 0xfb, 0xca, 0x28, 0x74,
+ 0x17, 0xed, 0xda, 0x2c, 0x9f, 0xb4, 0x2d, 0xf5, 0x71, 0x20, 0x64, 0x2d,
+ 0x44, 0xe5, 0xa3, 0xa0, 0x94, 0x6f, 0x20, 0xb3, 0x73, 0x96, 0x40, 0x06,
+ 0x9b, 0x25, 0x47, 0x4b, 0xe0, 0x63, 0x91, 0xd9, 0xda, 0xf3, 0xc3, 0xe5,
+ 0x3a, 0x3c, 0xb7, 0x5f, 0xab, 0x1e, 0x51, 0x17, 0x4f, 0xec, 0xc1, 0x6d,
+ 0x82, 0x79, 0x8e, 0xba, 0x7c, 0x47, 0x8e, 0x99, 0x00, 0x17, 0x9e, 0xda,
+ 0x10, 0x42, 0x70, 0x25, 0x42, 0x84, 0xc8, 0xb1, 0x95, 0x56, 0xb2, 0x08,
+ 0xa0, 0x4f, 0xdc, 0xcd, 0x9e, 0x31, 0x4b, 0x0c, 0x0b, 0x03, 0x5d, 0x2c,
+ 0x26, 0xbc, 0xa9, 0x4b, 0x19, 0xdf, 0x90, 0x01, 0x9a, 0xe0, 0x06, 0x05,
+ 0x13, 0x34, 0x9d, 0x34, 0xb8, 0xef, 0x13, 0x3a, 0x20, 0xf5, 0x74, 0x02,
+ 0x70, 0x3b, 0x41, 0x60, 0x1f, 0x5e, 0x76, 0x0a, 0xb1, 0x17, 0xd5, 0xcf,
+ 0x79, 0xef, 0xf7, 0xab, 0xe7, 0xd6, 0x0f, 0xad, 0x85, 0x2c, 0x52, 0x67,
+ 0xb5, 0xa0, 0x4a, 0xfd, 0xaf}; \ No newline at end of file
diff --git a/security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc
index 08781af711..28fdc66318 100644
--- a/security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_0rtt_unittest.cc
@@ -345,8 +345,8 @@ TEST_P(TlsConnectTls13, TestTls13ZeroRttNoAlpnClient) {
TEST_P(TlsConnectTls13, TestTls13ZeroRttAlpnChangeBoth) {
EnableAlpn();
SetupForZeroRtt();
- static const uint8_t alpn[] = {0x01, 0x62}; // "b"
- EnableAlpn(alpn, sizeof(alpn));
+ static const std::vector<uint8_t> alpn({0x01, 0x62}); // "b"
+ EnableAlpn(alpn);
client_->Set0RttEnabled(true);
server_->Set0RttEnabled(true);
ExpectResumption(RESUME_TICKET);
diff --git a/security/nss/gtests/ssl_gtest/ssl_agent_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_agent_unittest.cc
index f0c57e8b10..6be3b61f8d 100644
--- a/security/nss/gtests/ssl_gtest/ssl_agent_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_agent_unittest.cc
@@ -8,9 +8,6 @@
#include "sslerr.h"
#include "sslproto.h"
-// This is an internal header, used to get TLS_1_3_DRAFT_VERSION.
-#include "ssl3prot.h"
-
#include <memory>
#include "databuffer.h"
@@ -21,7 +18,6 @@
namespace nss_test {
-static const uint8_t kD13 = TLS_1_3_DRAFT_VERSION;
// This is a 1-RTT ClientHello with ECDHE.
const static uint8_t kCannedTls13ClientHello[] = {
0x01, 0x00, 0x00, 0xcf, 0x03, 0x03, 0x6c, 0xb3, 0x46, 0x81, 0xc8, 0x1a,
@@ -42,16 +38,7 @@ const static uint8_t kCannedTls13ClientHello[] = {
0x1e, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08,
0x05, 0x08, 0x06, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x02, 0x01, 0x04,
0x02, 0x05, 0x02, 0x06, 0x02, 0x02, 0x02};
-
-const static uint8_t kCannedTls13ServerHello[] = {
- 0x03, 0x03, 0x9c, 0xbc, 0x14, 0x9b, 0x0e, 0x2e, 0xfa, 0x0d, 0xf3,
- 0xf0, 0x5c, 0x70, 0x7a, 0xe0, 0xd1, 0x9b, 0x3e, 0x5a, 0x44, 0x6b,
- 0xdf, 0xe5, 0xc2, 0x28, 0x64, 0xf7, 0x00, 0xc1, 0x9c, 0x08, 0x76,
- 0x08, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33, 0x00, 0x24,
- 0x00, 0x1d, 0x00, 0x20, 0xc2, 0xcf, 0x23, 0x17, 0x64, 0x23, 0x03,
- 0xf0, 0xfb, 0x45, 0x98, 0x26, 0xd1, 0x65, 0x24, 0xa1, 0x6c, 0xa9,
- 0x80, 0x8f, 0x2c, 0xac, 0x0a, 0xea, 0x53, 0x3a, 0xcb, 0xe3, 0x08,
- 0x84, 0xae, 0x19, 0x00, 0x2b, 0x00, 0x02, 0x7f, kD13};
+static const size_t kFirstFragmentSize = 20;
static const char *k0RttData = "ABCDEF";
TEST_P(TlsAgentTest, EarlyFinished) {
@@ -74,8 +61,9 @@ TEST_P(TlsAgentTestClient13, CannedHello) {
DataBuffer buffer;
EnsureInit();
DataBuffer server_hello;
- MakeHandshakeMessage(kTlsHandshakeServerHello, kCannedTls13ServerHello,
- sizeof(kCannedTls13ServerHello), &server_hello);
+ auto sh = MakeCannedTls13ServerHello();
+ MakeHandshakeMessage(kTlsHandshakeServerHello, sh.data(), sh.len(),
+ &server_hello);
MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3,
server_hello.data(), server_hello.len(), &buffer);
ProcessMessage(buffer, TlsAgent::STATE_CONNECTING);
@@ -83,8 +71,9 @@ TEST_P(TlsAgentTestClient13, CannedHello) {
TEST_P(TlsAgentTestClient13, EncryptedExtensionsInClear) {
DataBuffer server_hello;
- MakeHandshakeMessage(kTlsHandshakeServerHello, kCannedTls13ServerHello,
- sizeof(kCannedTls13ServerHello), &server_hello);
+ auto sh = MakeCannedTls13ServerHello();
+ MakeHandshakeMessage(kTlsHandshakeServerHello, sh.data(), sh.len(),
+ &server_hello);
DataBuffer encrypted_extensions;
MakeHandshakeMessage(kTlsHandshakeEncryptedExtensions, nullptr, 0,
&encrypted_extensions, 1);
@@ -100,19 +89,21 @@ TEST_P(TlsAgentTestClient13, EncryptedExtensionsInClear) {
TEST_F(TlsAgentStreamTestClient, EncryptedExtensionsInClearTwoPieces) {
DataBuffer server_hello;
- MakeHandshakeMessage(kTlsHandshakeServerHello, kCannedTls13ServerHello,
- sizeof(kCannedTls13ServerHello), &server_hello);
+ auto sh = MakeCannedTls13ServerHello();
+ MakeHandshakeMessage(kTlsHandshakeServerHello, sh.data(), sh.len(),
+ &server_hello);
DataBuffer encrypted_extensions;
MakeHandshakeMessage(kTlsHandshakeEncryptedExtensions, nullptr, 0,
&encrypted_extensions, 1);
server_hello.Append(encrypted_extensions);
DataBuffer buffer;
MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3,
- server_hello.data(), 20, &buffer);
+ server_hello.data(), kFirstFragmentSize, &buffer);
DataBuffer buffer2;
MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3,
- server_hello.data() + 20, server_hello.len() - 20, &buffer2);
+ server_hello.data() + kFirstFragmentSize,
+ server_hello.len() - kFirstFragmentSize, &buffer2);
EnsureInit();
agent_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_3,
@@ -124,15 +115,15 @@ TEST_F(TlsAgentStreamTestClient, EncryptedExtensionsInClearTwoPieces) {
}
TEST_F(TlsAgentDgramTestClient, EncryptedExtensionsInClearTwoPieces) {
+ auto sh = MakeCannedTls13ServerHello();
DataBuffer server_hello_frag1;
- MakeHandshakeMessageFragment(
- kTlsHandshakeServerHello, kCannedTls13ServerHello,
- sizeof(kCannedTls13ServerHello), &server_hello_frag1, 0, 0, 20);
+ MakeHandshakeMessageFragment(kTlsHandshakeServerHello, sh.data(), sh.len(),
+ &server_hello_frag1, 0, 0, kFirstFragmentSize);
DataBuffer server_hello_frag2;
- MakeHandshakeMessageFragment(
- kTlsHandshakeServerHello, kCannedTls13ServerHello + 20,
- sizeof(kCannedTls13ServerHello), &server_hello_frag2, 0, 20,
- sizeof(kCannedTls13ServerHello) - 20);
+ MakeHandshakeMessageFragment(kTlsHandshakeServerHello,
+ sh.data() + kFirstFragmentSize, sh.len(),
+ &server_hello_frag2, 0, kFirstFragmentSize,
+ sh.len() - kFirstFragmentSize);
DataBuffer encrypted_extensions;
MakeHandshakeMessage(kTlsHandshakeEncryptedExtensions, nullptr, 0,
&encrypted_extensions, 1);
@@ -154,6 +145,35 @@ TEST_F(TlsAgentDgramTestClient, EncryptedExtensionsInClearTwoPieces) {
SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
}
+TEST_F(TlsAgentDgramTestClient, AckWithBogusLengthField) {
+ EnsureInit();
+ // Length doesn't match
+ const uint8_t ackBuf[] = {0x00, 0x08, 0x00};
+ DataBuffer record;
+ MakeRecord(variant_, kTlsAckType, SSL_LIBRARY_VERSION_TLS_1_2, ackBuf,
+ sizeof(ackBuf), &record, 0);
+ agent_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_3,
+ SSL_LIBRARY_VERSION_TLS_1_3);
+ ExpectAlert(kTlsAlertDecodeError);
+ ProcessMessage(record, TlsAgent::STATE_ERROR,
+ SSL_ERROR_RX_MALFORMED_DTLS_ACK);
+}
+
+TEST_F(TlsAgentDgramTestClient, AckWithNonEvenLength) {
+ EnsureInit();
+ // Length isn't a multiple of 8
+ const uint8_t ackBuf[] = {0x00, 0x01, 0x00};
+ DataBuffer record;
+ MakeRecord(variant_, kTlsAckType, SSL_LIBRARY_VERSION_TLS_1_2, ackBuf,
+ sizeof(ackBuf), &record, 0);
+ agent_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_3,
+ SSL_LIBRARY_VERSION_TLS_1_3);
+ // Because we haven't negotiated the version,
+ // ssl3_DecodeError() sends an older (pre-TLS error).
+ ExpectAlert(kTlsAlertIllegalParameter);
+ ProcessMessage(record, TlsAgent::STATE_ERROR, SSL_ERROR_BAD_SERVER);
+}
+
TEST_F(TlsAgentStreamTestClient, Set0RttOptionThenWrite) {
EnsureInit();
agent_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
diff --git a/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc
index 7f2b2840d5..e2a30e6bcb 100644
--- a/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc
@@ -155,8 +155,8 @@ TEST_P(TlsConnectTls12, ClientAuthBigRsaCheckSigAlg) {
class TlsZeroCertificateRequestSigAlgsFilter : public TlsHandshakeFilter {
public:
- TlsZeroCertificateRequestSigAlgsFilter(const std::shared_ptr<TlsAgent>& agent)
- : TlsHandshakeFilter(agent, {kTlsHandshakeCertificateRequest}) {}
+ TlsZeroCertificateRequestSigAlgsFilter(const std::shared_ptr<TlsAgent>& a)
+ : TlsHandshakeFilter(a, {kTlsHandshakeCertificateRequest}) {}
virtual PacketFilter::Action FilterHandshake(
const TlsHandshakeFilter::HandshakeHeader& header,
const DataBuffer& input, DataBuffer* output) {
@@ -366,6 +366,50 @@ TEST_P(TlsConnectTls12, SignatureAlgorithmDrop) {
server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
}
+// Replaces the signature scheme in a TLS 1.3 CertificateVerify message.
+class TlsReplaceSignatureSchemeFilter : public TlsHandshakeFilter {
+ public:
+ TlsReplaceSignatureSchemeFilter(const std::shared_ptr<TlsAgent>& a,
+ SSLSignatureScheme scheme)
+ : TlsHandshakeFilter(a, {kTlsHandshakeCertificateVerify}),
+ scheme_(scheme) {
+ EnableDecryption();
+ }
+
+ protected:
+ virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
+ const DataBuffer& input,
+ DataBuffer* output) {
+ *output = input;
+ output->Write(0, scheme_, 2);
+ return CHANGE;
+ }
+
+ private:
+ SSLSignatureScheme scheme_;
+};
+
+TEST_P(TlsConnectTls13, UnsupportedSignatureSchemeAlert) {
+ EnsureTlsSetup();
+ MakeTlsFilter<TlsReplaceSignatureSchemeFilter>(server_, ssl_sig_none);
+
+ ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
+ server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
+ client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CERT_VERIFY);
+}
+
+TEST_P(TlsConnectTls13, InconsistentSignatureSchemeAlert) {
+ EnsureTlsSetup();
+
+ // This won't work because we use an RSA cert by default.
+ MakeTlsFilter<TlsReplaceSignatureSchemeFilter>(
+ server_, ssl_sig_ecdsa_secp256r1_sha256);
+
+ ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
+ server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
+ client_->CheckErrorCode(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
+}
+
TEST_P(TlsConnectTls12Plus, RequestClientAuthWithSha384) {
server_->SetSignatureSchemes(SignatureSchemeRsaSha384,
PR_ARRAY_SIZE(SignatureSchemeRsaSha384));
diff --git a/security/nss/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc
index fa2238be7d..ec289bdd69 100644
--- a/security/nss/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc
@@ -166,8 +166,8 @@ class TlsCipherSuiteTestBase : public TlsConnectTestBase {
case ssl_calg_seed:
break;
}
- EXPECT_TRUE(false) << "No limit for " << csinfo_.cipherSuiteName;
- return 1ULL < 48;
+ ADD_FAILURE() << "No limit for " << csinfo_.cipherSuiteName;
+ return 0;
}
uint64_t last_safe_write() const {
@@ -246,12 +246,13 @@ TEST_P(TlsCipherSuiteTest, ReadLimit) {
client_->SendData(10, 10);
server_->ReadBytes(); // This should be OK.
+ server_->ReadBytes(); // Read twice to flush any 1,N-1 record splitting.
} else {
// In TLS 1.3, reading or writing triggers a KeyUpdate. That would mean
// that the sequence numbers would reset and we wouldn't hit the limit. So
- // we move the sequence number to one less than the limit directly and don't
- // test sending and receiving just before the limit.
- uint64_t last = record_limit() - 1;
+ // move the sequence number to the limit directly and don't test sending and
+ // receiving just before the limit.
+ uint64_t last = record_limit();
EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), last));
}
diff --git a/security/nss/gtests/ssl_gtest/ssl_custext_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_custext_unittest.cc
index c2f582a93a..5be62e5065 100644
--- a/security/nss/gtests/ssl_gtest/ssl_custext_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_custext_unittest.cc
@@ -68,6 +68,7 @@ static const uint16_t kManyExtensions[] = {
ssl_next_proto_nego_xtn,
ssl_renegotiation_info_xtn,
ssl_tls13_short_header_xtn,
+ ssl_record_size_limit_xtn,
1,
0xffff};
// The list here includes all extensions we expect to use (SSL_MAX_EXTENSIONS),
diff --git a/security/nss/gtests/ssl_gtest/ssl_dhe_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_dhe_unittest.cc
index cdafa7a84f..b99461632c 100644
--- a/security/nss/gtests/ssl_gtest/ssl_dhe_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_dhe_unittest.cc
@@ -103,8 +103,8 @@ TEST_P(TlsConnectGenericPre13, ConnectFfdheServer) {
class TlsDheServerKeyExchangeDamager : public TlsHandshakeFilter {
public:
- TlsDheServerKeyExchangeDamager(const std::shared_ptr<TlsAgent>& agent)
- : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}) {}
+ TlsDheServerKeyExchangeDamager(const std::shared_ptr<TlsAgent>& a)
+ : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}) {}
virtual PacketFilter::Action FilterHandshake(
const TlsHandshakeFilter::HandshakeHeader& header,
const DataBuffer& input, DataBuffer* output) {
@@ -141,9 +141,9 @@ class TlsDheSkeChangeY : public TlsHandshakeFilter {
kYZeroPad
};
- TlsDheSkeChangeY(const std::shared_ptr<TlsAgent>& agent,
- uint8_t handshake_type, ChangeYTo change)
- : TlsHandshakeFilter(agent, {handshake_type}), change_Y_(change) {}
+ TlsDheSkeChangeY(const std::shared_ptr<TlsAgent>& a, uint8_t handshake_type,
+ ChangeYTo change)
+ : TlsHandshakeFilter(a, {handshake_type}), change_Y_(change) {}
protected:
void ChangeY(const DataBuffer& input, DataBuffer* output, size_t offset,
@@ -208,9 +208,9 @@ class TlsDheSkeChangeY : public TlsHandshakeFilter {
class TlsDheSkeChangeYServer : public TlsDheSkeChangeY {
public:
- TlsDheSkeChangeYServer(const std::shared_ptr<TlsAgent>& agent,
- ChangeYTo change, bool modify)
- : TlsDheSkeChangeY(agent, kTlsHandshakeServerKeyExchange, change),
+ TlsDheSkeChangeYServer(const std::shared_ptr<TlsAgent>& a, ChangeYTo change,
+ bool modify)
+ : TlsDheSkeChangeY(a, kTlsHandshakeServerKeyExchange, change),
modify_(modify),
p_() {}
@@ -247,9 +247,9 @@ class TlsDheSkeChangeYServer : public TlsDheSkeChangeY {
class TlsDheSkeChangeYClient : public TlsDheSkeChangeY {
public:
TlsDheSkeChangeYClient(
- const std::shared_ptr<TlsAgent>& agent, ChangeYTo change,
+ const std::shared_ptr<TlsAgent>& a, ChangeYTo change,
std::shared_ptr<const TlsDheSkeChangeYServer> server_filter)
- : TlsDheSkeChangeY(agent, kTlsHandshakeClientKeyExchange, change),
+ : TlsDheSkeChangeY(a, kTlsHandshakeClientKeyExchange, change),
server_filter_(server_filter) {}
protected:
@@ -357,8 +357,8 @@ INSTANTIATE_TEST_CASE_P(
class TlsDheSkeMakePEven : public TlsHandshakeFilter {
public:
- TlsDheSkeMakePEven(const std::shared_ptr<TlsAgent>& agent)
- : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}) {}
+ TlsDheSkeMakePEven(const std::shared_ptr<TlsAgent>& a)
+ : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}) {}
virtual PacketFilter::Action FilterHandshake(
const TlsHandshakeFilter::HandshakeHeader& header,
@@ -390,8 +390,8 @@ TEST_P(TlsConnectGenericPre13, MakeDhePEven) {
class TlsDheSkeZeroPadP : public TlsHandshakeFilter {
public:
- TlsDheSkeZeroPadP(const std::shared_ptr<TlsAgent>& agent)
- : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}) {}
+ TlsDheSkeZeroPadP(const std::shared_ptr<TlsAgent>& a)
+ : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}) {}
virtual PacketFilter::Action FilterHandshake(
const TlsHandshakeFilter::HandshakeHeader& header,
@@ -475,6 +475,45 @@ TEST_P(TlsConnectTls13, NamedGroupMismatch13) {
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
}
+// Replace the key share in the server key exchange message with one that's
+// larger than 8192 bits.
+class TooLongDHEServerKEXFilter : public TlsHandshakeFilter {
+ public:
+ TooLongDHEServerKEXFilter(const std::shared_ptr<TlsAgent>& server)
+ : TlsHandshakeFilter(server, {kTlsHandshakeServerKeyExchange}) {}
+
+ protected:
+ virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
+ const DataBuffer& input,
+ DataBuffer* output) {
+ // Replace the server key exchange message very large DH shares that are
+ // not supported by NSS.
+ const uint32_t share_len = 0x401;
+ const uint8_t zero_share[share_len] = {0x80};
+ size_t offset = 0;
+ // Write dh_p.
+ offset = output->Write(offset, share_len, 2);
+ offset = output->Write(offset, zero_share, share_len);
+ // Write dh_g.
+ offset = output->Write(offset, share_len, 2);
+ offset = output->Write(offset, zero_share, share_len);
+ // Write dh_Y.
+ offset = output->Write(offset, share_len, 2);
+ offset = output->Write(offset, zero_share, share_len);
+
+ return CHANGE;
+ }
+};
+
+TEST_P(TlsConnectGenericPre13, TooBigDHGroup) {
+ EnableOnlyDheCiphers();
+ MakeTlsFilter<TooLongDHEServerKEXFilter>(server_);
+ client_->SetOption(SSL_REQUIRE_DH_NAMED_GROUPS, PR_FALSE);
+ ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
+ server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
+ client_->CheckErrorCode(SSL_ERROR_DH_KEY_TOO_LONG);
+}
+
// Even though the client doesn't have DHE groups enabled the server assumes it
// does. The client requires named groups and thus does not accept FF3072 as
// custom group in contrast to the previous test.
@@ -546,9 +585,9 @@ TEST_P(TlsConnectTls13, ResumeFfdhe) {
class TlsDheSkeChangeSignature : public TlsHandshakeFilter {
public:
- TlsDheSkeChangeSignature(const std::shared_ptr<TlsAgent>& agent,
- uint16_t version, const uint8_t* data, size_t len)
- : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}),
+ TlsDheSkeChangeSignature(const std::shared_ptr<TlsAgent>& a, uint16_t version,
+ const uint8_t* data, size_t len)
+ : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}),
version_(version),
data_(data),
len_(len) {}
diff --git a/security/nss/gtests/ssl_gtest/ssl_drop_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_drop_unittest.cc
index ee8906deb5..e5b52ff06b 100644
--- a/security/nss/gtests/ssl_gtest/ssl_drop_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_drop_unittest.cc
@@ -66,7 +66,8 @@ TEST_P(TlsConnectDatagramPre13, DropServerSecondFlightThrice) {
Connect();
}
-class TlsDropDatagram13 : public TlsConnectDatagram13 {
+class TlsDropDatagram13 : public TlsConnectDatagram13,
+ public ::testing::WithParamInterface<bool> {
public:
TlsDropDatagram13()
: client_filters_(),
@@ -77,6 +78,9 @@ class TlsDropDatagram13 : public TlsConnectDatagram13 {
void SetUp() override {
TlsConnectDatagram13::SetUp();
ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
+ int short_header = GetParam() ? PR_TRUE : PR_FALSE;
+ client_->SetOption(SSL_ENABLE_DTLS_SHORT_HEADER, short_header);
+ server_->SetOption(SSL_ENABLE_DTLS_SHORT_HEADER, short_header);
SetFilters();
}
@@ -138,10 +142,13 @@ class TlsDropDatagram13 : public TlsConnectDatagram13 {
void CheckAcks(const DropAckChain& chain, size_t index,
std::vector<uint64_t> acks) {
const DataBuffer& buf = chain.ack_->record(index).buffer;
- size_t offset = 0;
+ size_t offset = 2;
+ uint64_t len;
- EXPECT_EQ(acks.size() * 8, buf.len());
- if ((acks.size() * 8) != buf.len()) {
+ EXPECT_EQ(2 + acks.size() * 8, buf.len());
+ ASSERT_TRUE(buf.Read(0, 2, &len));
+ ASSERT_EQ(static_cast<size_t>(len + 2), buf.len());
+ if ((2 + acks.size() * 8) != buf.len()) {
while (offset < buf.len()) {
uint64_t ack;
ASSERT_TRUE(buf.Read(offset, 8, &ack));
@@ -186,7 +193,7 @@ class TlsDropDatagram13 : public TlsConnectDatagram13 {
// to the client upon receiving the client Finished.
// Dropping complete first and second flights does not produce
// ACKs
-TEST_F(TlsDropDatagram13, DropClientFirstFlightOnce) {
+TEST_P(TlsDropDatagram13, DropClientFirstFlightOnce) {
client_filters_.drop_->Reset({0});
StartConnect();
client_->Handshake();
@@ -195,7 +202,7 @@ TEST_F(TlsDropDatagram13, DropClientFirstFlightOnce) {
CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
}
-TEST_F(TlsDropDatagram13, DropServerFirstFlightOnce) {
+TEST_P(TlsDropDatagram13, DropServerFirstFlightOnce) {
server_filters_.drop_->Reset(0xff);
StartConnect();
client_->Handshake();
@@ -209,7 +216,7 @@ TEST_F(TlsDropDatagram13, DropServerFirstFlightOnce) {
// Dropping the server's first record also does not produce
// an ACK because the next record is ignored.
// TODO(ekr@rtfm.com): We should generate an empty ACK.
-TEST_F(TlsDropDatagram13, DropServerFirstRecordOnce) {
+TEST_P(TlsDropDatagram13, DropServerFirstRecordOnce) {
server_filters_.drop_->Reset({0});
StartConnect();
client_->Handshake();
@@ -221,7 +228,7 @@ TEST_F(TlsDropDatagram13, DropServerFirstRecordOnce) {
// Dropping the second packet of the server's flight should
// produce an ACK.
-TEST_F(TlsDropDatagram13, DropServerSecondRecordOnce) {
+TEST_P(TlsDropDatagram13, DropServerSecondRecordOnce) {
server_filters_.drop_->Reset({1});
StartConnect();
client_->Handshake();
@@ -235,7 +242,7 @@ TEST_F(TlsDropDatagram13, DropServerSecondRecordOnce) {
// Drop the server ACK and verify that the client retransmits
// the ClientHello.
-TEST_F(TlsDropDatagram13, DropServerAckOnce) {
+TEST_P(TlsDropDatagram13, DropServerAckOnce) {
StartConnect();
client_->Handshake();
server_->Handshake();
@@ -263,7 +270,7 @@ TEST_F(TlsDropDatagram13, DropServerAckOnce) {
}
// Drop the client certificate verify.
-TEST_F(TlsDropDatagram13, DropClientCertVerify) {
+TEST_P(TlsDropDatagram13, DropClientCertVerify) {
StartConnect();
client_->SetupClientAuth();
server_->RequestClientAuth(true);
@@ -284,7 +291,7 @@ TEST_F(TlsDropDatagram13, DropClientCertVerify) {
}
// Shrink the MTU down so that certs get split and drop the first piece.
-TEST_F(TlsDropDatagram13, DropFirstHalfOfServerCertificate) {
+TEST_P(TlsDropDatagram13, DropFirstHalfOfServerCertificate) {
server_filters_.drop_->Reset({2});
StartConnect();
ShrinkPostServerHelloMtu();
@@ -311,7 +318,7 @@ TEST_F(TlsDropDatagram13, DropFirstHalfOfServerCertificate) {
}
// Shrink the MTU down so that certs get split and drop the second piece.
-TEST_F(TlsDropDatagram13, DropSecondHalfOfServerCertificate) {
+TEST_P(TlsDropDatagram13, DropSecondHalfOfServerCertificate) {
server_filters_.drop_->Reset({3});
StartConnect();
ShrinkPostServerHelloMtu();
@@ -524,11 +531,11 @@ class TlsFragmentationAndRecoveryTest : public TlsDropDatagram13 {
size_t cert_len_;
};
-TEST_F(TlsFragmentationAndRecoveryTest, DropFirstHalf) { RunTest(0); }
+TEST_P(TlsFragmentationAndRecoveryTest, DropFirstHalf) { RunTest(0); }
-TEST_F(TlsFragmentationAndRecoveryTest, DropSecondHalf) { RunTest(1); }
+TEST_P(TlsFragmentationAndRecoveryTest, DropSecondHalf) { RunTest(1); }
-TEST_F(TlsDropDatagram13, NoDropsDuringZeroRtt) {
+TEST_P(TlsDropDatagram13, NoDropsDuringZeroRtt) {
SetupForZeroRtt();
SetFilters();
std::cerr << "Starting second handshake" << std::endl;
@@ -546,7 +553,7 @@ TEST_F(TlsDropDatagram13, NoDropsDuringZeroRtt) {
0x0002000000000000ULL}); // Finished
}
-TEST_F(TlsDropDatagram13, DropEEDuringZeroRtt) {
+TEST_P(TlsDropDatagram13, DropEEDuringZeroRtt) {
SetupForZeroRtt();
SetFilters();
std::cerr << "Starting second handshake" << std::endl;
@@ -591,7 +598,7 @@ class TlsReorderDatagram13 : public TlsDropDatagram13 {
// Reorder the server records so that EE comes at the end
// of the flight and will still produce an ACK.
-TEST_F(TlsDropDatagram13, ReorderServerEE) {
+TEST_P(TlsDropDatagram13, ReorderServerEE) {
server_filters_.drop_->Reset({1});
StartConnect();
client_->Handshake();
@@ -647,7 +654,7 @@ class TlsSendCipherSpecCapturer {
std::vector<std::shared_ptr<TlsCipherSpec>> send_cipher_specs_;
};
-TEST_F(TlsDropDatagram13, SendOutOfOrderAppWithHandshakeKey) {
+TEST_P(TlsDropDatagram13, SendOutOfOrderAppWithHandshakeKey) {
StartConnect();
TlsSendCipherSpecCapturer capturer(client_);
client_->Handshake();
@@ -662,9 +669,9 @@ TEST_F(TlsDropDatagram13, SendOutOfOrderAppWithHandshakeKey) {
auto spec = capturer.spec(0);
ASSERT_NE(nullptr, spec.get());
ASSERT_EQ(2, spec->epoch());
- ASSERT_TRUE(client_->SendEncryptedRecord(
- spec, SSL_LIBRARY_VERSION_DTLS_1_2_WIRE, 0x0002000000000002,
- kTlsApplicationDataType, DataBuffer(buf, sizeof(buf))));
+ ASSERT_TRUE(client_->SendEncryptedRecord(spec, 0x0002000000000002,
+ kTlsApplicationDataType,
+ DataBuffer(buf, sizeof(buf))));
// Now have the server consume the bogus message.
server_->ExpectSendAlert(illegal_parameter, kTlsAlertFatal);
@@ -673,7 +680,7 @@ TEST_F(TlsDropDatagram13, SendOutOfOrderAppWithHandshakeKey) {
EXPECT_EQ(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE, PORT_GetError());
}
-TEST_F(TlsDropDatagram13, SendOutOfOrderHsNonsenseWithHandshakeKey) {
+TEST_P(TlsDropDatagram13, SendOutOfOrderHsNonsenseWithHandshakeKey) {
StartConnect();
TlsSendCipherSpecCapturer capturer(client_);
client_->Handshake();
@@ -688,9 +695,9 @@ TEST_F(TlsDropDatagram13, SendOutOfOrderHsNonsenseWithHandshakeKey) {
auto spec = capturer.spec(0);
ASSERT_NE(nullptr, spec.get());
ASSERT_EQ(2, spec->epoch());
- ASSERT_TRUE(client_->SendEncryptedRecord(
- spec, SSL_LIBRARY_VERSION_DTLS_1_2_WIRE, 0x0002000000000002,
- kTlsHandshakeType, DataBuffer(buf, sizeof(buf))));
+ ASSERT_TRUE(client_->SendEncryptedRecord(spec, 0x0002000000000002,
+ kTlsHandshakeType,
+ DataBuffer(buf, sizeof(buf))));
server_->Handshake();
EXPECT_EQ(2UL, server_filters_.ack_->count());
// The server acknowledges client Finished twice.
@@ -700,7 +707,7 @@ TEST_F(TlsDropDatagram13, SendOutOfOrderHsNonsenseWithHandshakeKey) {
// Shrink the MTU down so that certs get split and then swap the first and
// second pieces of the server certificate.
-TEST_F(TlsReorderDatagram13, ReorderServerCertificate) {
+TEST_P(TlsReorderDatagram13, ReorderServerCertificate) {
StartConnect();
ShrinkPostServerHelloMtu();
client_->Handshake();
@@ -722,7 +729,7 @@ TEST_F(TlsReorderDatagram13, ReorderServerCertificate) {
CheckAcks(server_filters_, 0, {0x0002000000000000ULL});
}
-TEST_F(TlsReorderDatagram13, DataAfterEOEDDuringZeroRtt) {
+TEST_P(TlsReorderDatagram13, DataAfterEOEDDuringZeroRtt) {
SetupForZeroRtt();
SetFilters();
std::cerr << "Starting second handshake" << std::endl;
@@ -761,7 +768,7 @@ TEST_F(TlsReorderDatagram13, DataAfterEOEDDuringZeroRtt) {
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
}
-TEST_F(TlsReorderDatagram13, DataAfterFinDuringZeroRtt) {
+TEST_P(TlsReorderDatagram13, DataAfterFinDuringZeroRtt) {
SetupForZeroRtt();
SetFilters();
std::cerr << "Starting second handshake" << std::endl;
@@ -812,12 +819,17 @@ static void GetCipherAndLimit(uint16_t version, uint16_t* cipher,
*cipher = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
*limit = (1ULL << 48) - 1;
} else {
+ // This test probably isn't especially useful for TLS 1.3, which has a much
+ // shorter sequence number encoding. That space can probably be searched in
+ // a reasonable amount of time.
*cipher = TLS_CHACHA20_POLY1305_SHA256;
- *limit = (1ULL << 48) - 1;
+ // Assume that we are starting with an expected sequence number of 0.
+ *limit = (1ULL << 29) - 1;
}
}
// This simulates a huge number of drops on one side.
+// See Bug 12965514 where a large gap was handled very inefficiently.
TEST_P(TlsConnectDatagram, MissLotsOfPackets) {
uint16_t cipher;
uint64_t limit;
@@ -834,6 +846,17 @@ TEST_P(TlsConnectDatagram, MissLotsOfPackets) {
SendReceive();
}
+// Send a sequence number of 0xfffffffd and it should be interpreted as that
+// (and not -3 or UINT64_MAX - 2).
+TEST_F(TlsConnectDatagram13, UnderflowSequenceNumber) {
+ Connect();
+ // This is only valid if short headers are disabled.
+ client_->SetOption(SSL_ENABLE_DTLS_SHORT_HEADER, PR_FALSE);
+ EXPECT_EQ(SECSuccess,
+ SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), (1ULL << 30) - 3));
+ SendReceive();
+}
+
class TlsConnectDatagram12Plus : public TlsConnectDatagram {
public:
TlsConnectDatagram12Plus() : TlsConnectDatagram() {}
@@ -861,9 +884,54 @@ TEST_P(TlsConnectDatagram12Plus, MissAWindowAndOne) {
SendReceive();
}
+// This filter replaces the first record it sees with junk application data.
+class TlsReplaceFirstRecordWithJunk : public TlsRecordFilter {
+ public:
+ TlsReplaceFirstRecordWithJunk(const std::shared_ptr<TlsAgent>& a)
+ : TlsRecordFilter(a), replaced_(false) {}
+
+ protected:
+ PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
+ const DataBuffer& record, size_t* offset,
+ DataBuffer* output) override {
+ if (replaced_) {
+ return KEEP;
+ }
+ replaced_ = true;
+ TlsRecordHeader out_header(header.variant(), header.version(),
+ kTlsApplicationDataType,
+ header.sequence_number());
+
+ static const uint8_t junk[] = {1, 2, 3, 4};
+ *offset = out_header.Write(output, *offset, DataBuffer(junk, sizeof(junk)));
+ return CHANGE;
+ }
+
+ private:
+ bool replaced_;
+};
+
+// DTLS needs to discard application_data that it receives prior to handshake
+// completion, not generate an error.
+TEST_P(TlsConnectDatagram, ReplaceFirstServerRecordWithApplicationData) {
+ MakeTlsFilter<TlsReplaceFirstRecordWithJunk>(server_);
+ Connect();
+}
+
+TEST_P(TlsConnectDatagram, ReplaceFirstClientRecordWithApplicationData) {
+ MakeTlsFilter<TlsReplaceFirstRecordWithJunk>(client_);
+ Connect();
+}
+
INSTANTIATE_TEST_CASE_P(Datagram12Plus, TlsConnectDatagram12Plus,
TlsConnectTestBase::kTlsV12Plus);
INSTANTIATE_TEST_CASE_P(DatagramPre13, TlsConnectDatagramPre13,
TlsConnectTestBase::kTlsV11V12);
+INSTANTIATE_TEST_CASE_P(DatagramDrop13, TlsDropDatagram13,
+ ::testing::Values(true, false));
+INSTANTIATE_TEST_CASE_P(DatagramReorder13, TlsReorderDatagram13,
+ ::testing::Values(true, false));
+INSTANTIATE_TEST_CASE_P(DatagramFragment13, TlsFragmentationAndRecoveryTest,
+ ::testing::Values(true, false));
} // namespace nss_test
diff --git a/security/nss/gtests/ssl_gtest/ssl_ecdh_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_ecdh_unittest.cc
index 3c7cd2ecfa..12c6e8516c 100644
--- a/security/nss/gtests/ssl_gtest/ssl_ecdh_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_ecdh_unittest.cc
@@ -192,8 +192,8 @@ TEST_P(TlsConnectGenericPre13, P384PriorityFromModelSocket) {
class TlsKeyExchangeGroupCapture : public TlsHandshakeFilter {
public:
- TlsKeyExchangeGroupCapture(const std::shared_ptr<TlsAgent> &agent)
- : TlsHandshakeFilter(agent, {kTlsHandshakeServerKeyExchange}),
+ TlsKeyExchangeGroupCapture(const std::shared_ptr<TlsAgent> &a)
+ : TlsHandshakeFilter(a, {kTlsHandshakeServerKeyExchange}),
group_(ssl_grp_none) {}
SSLNamedGroup group() const { return group_; }
@@ -559,6 +559,113 @@ TEST_P(TlsConnectGenericPre13, ConnectECDHEmptyClientPoint) {
server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH);
}
+// Damage ECParams/ECPoint of a SKE.
+class ECCServerKEXDamager : public TlsHandshakeFilter {
+ public:
+ ECCServerKEXDamager(const std::shared_ptr<TlsAgent> &server, ECType ec_type,
+ SSLNamedGroup named_curve)
+ : TlsHandshakeFilter(server, {kTlsHandshakeServerKeyExchange}),
+ ec_type_(ec_type),
+ named_curve_(named_curve) {}
+
+ protected:
+ virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header,
+ const DataBuffer &input,
+ DataBuffer *output) {
+ size_t offset = 0;
+ output->Allocate(5);
+ offset = output->Write(offset, ec_type_, 1);
+ offset = output->Write(offset, named_curve_, 2);
+ // Write a point with fmt != EC_POINT_FORM_UNCOMPRESSED.
+ offset = output->Write(offset, 1U, 1);
+ (void)output->Write(offset, 0x02, 1); // EC_POINT_FORM_COMPRESSED_Y0
+ return CHANGE;
+ }
+
+ private:
+ ECType ec_type_;
+ SSLNamedGroup named_curve_;
+};
+
+TEST_P(TlsConnectGenericPre13, ConnectUnsupportedCurveType) {
+ EnsureTlsSetup();
+ client_->DisableAllCiphers();
+ client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
+
+ MakeTlsFilter<ECCServerKEXDamager>(server_, ec_type_explicitPrime,
+ ssl_grp_none);
+ ConnectExpectAlert(client_, kTlsAlertHandshakeFailure);
+ client_->CheckErrorCode(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+}
+
+TEST_P(TlsConnectGenericPre13, ConnectUnsupportedCurve) {
+ EnsureTlsSetup();
+ client_->DisableAllCiphers();
+ client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
+
+ MakeTlsFilter<ECCServerKEXDamager>(server_, ec_type_named,
+ ssl_grp_ffdhe_2048);
+ ConnectExpectAlert(client_, kTlsAlertHandshakeFailure);
+ client_->CheckErrorCode(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+}
+
+TEST_P(TlsConnectGenericPre13, ConnectUnsupportedPointFormat) {
+ EnsureTlsSetup();
+ client_->DisableAllCiphers();
+ client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
+
+ MakeTlsFilter<ECCServerKEXDamager>(server_, ec_type_named,
+ ssl_grp_ec_secp256r1);
+ ConnectExpectAlert(client_, kTlsAlertHandshakeFailure);
+ client_->CheckErrorCode(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
+}
+
+// Replace SignatureAndHashAlgorithm of a SKE.
+class ECCServerKEXSigAlgReplacer : public TlsHandshakeFilter {
+ public:
+ ECCServerKEXSigAlgReplacer(const std::shared_ptr<TlsAgent> &server,
+ SSLSignatureScheme sig_scheme)
+ : TlsHandshakeFilter(server, {kTlsHandshakeServerKeyExchange}),
+ sig_scheme_(sig_scheme) {}
+
+ protected:
+ virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header,
+ const DataBuffer &input,
+ DataBuffer *output) {
+ *output = input;
+
+ uint32_t point_len;
+ EXPECT_TRUE(output->Read(3, 1, &point_len));
+ output->Write(4 + point_len, sig_scheme_, 2);
+
+ return CHANGE;
+ }
+
+ private:
+ SSLSignatureScheme sig_scheme_;
+};
+
+TEST_P(TlsConnectTls12, ConnectUnsupportedSigAlg) {
+ EnsureTlsSetup();
+ client_->DisableAllCiphers();
+ client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
+
+ MakeTlsFilter<ECCServerKEXSigAlgReplacer>(server_, ssl_sig_none);
+ ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
+ client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
+}
+
+TEST_P(TlsConnectTls12, ConnectIncorrectSigAlg) {
+ EnsureTlsSetup();
+ client_->DisableAllCiphers();
+ client_->EnableCiphersByKeyExchange(ssl_kea_ecdh);
+
+ MakeTlsFilter<ECCServerKEXSigAlgReplacer>(server_,
+ ssl_sig_ecdsa_secp256r1_sha256);
+ ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
+ client_->CheckErrorCode(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
+}
+
INSTANTIATE_TEST_CASE_P(KeyExchangeTest, TlsKeyExchangeTest,
::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
TlsConnectTestBase::kTlsV11Plus));
diff --git a/security/nss/gtests/ssl_gtest/ssl_extension_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_extension_unittest.cc
index 0453dabdb6..6965e9ca75 100644
--- a/security/nss/gtests/ssl_gtest/ssl_extension_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_extension_unittest.cc
@@ -19,9 +19,9 @@ namespace nss_test {
class TlsExtensionTruncator : public TlsExtensionFilter {
public:
- TlsExtensionTruncator(const std::shared_ptr<TlsAgent>& agent,
- uint16_t extension, size_t length)
- : TlsExtensionFilter(agent), extension_(extension), length_(length) {}
+ TlsExtensionTruncator(const std::shared_ptr<TlsAgent>& a, uint16_t extension,
+ size_t length)
+ : TlsExtensionFilter(a), extension_(extension), length_(length) {}
virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
const DataBuffer& input,
DataBuffer* output) {
@@ -43,9 +43,9 @@ class TlsExtensionTruncator : public TlsExtensionFilter {
class TlsExtensionDamager : public TlsExtensionFilter {
public:
- TlsExtensionDamager(const std::shared_ptr<TlsAgent>& agent,
- uint16_t extension, size_t index)
- : TlsExtensionFilter(agent), extension_(extension), index_(index) {}
+ TlsExtensionDamager(const std::shared_ptr<TlsAgent>& a, uint16_t extension,
+ size_t index)
+ : TlsExtensionFilter(a), extension_(extension), index_(index) {}
virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
const DataBuffer& input,
DataBuffer* output) {
@@ -65,11 +65,9 @@ class TlsExtensionDamager : public TlsExtensionFilter {
class TlsExtensionAppender : public TlsHandshakeFilter {
public:
- TlsExtensionAppender(const std::shared_ptr<TlsAgent>& agent,
+ TlsExtensionAppender(const std::shared_ptr<TlsAgent>& a,
uint8_t handshake_type, uint16_t ext, DataBuffer& data)
- : TlsHandshakeFilter(agent, {handshake_type}),
- extension_(ext),
- data_(data) {}
+ : TlsHandshakeFilter(a, {handshake_type}), extension_(ext), data_(data) {}
virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
const DataBuffer& input,
@@ -323,7 +321,15 @@ TEST_P(TlsExtensionTestGeneric, AlpnMissingValue) {
TEST_P(TlsExtensionTestGeneric, AlpnZeroLength) {
EnableAlpn();
- const uint8_t val[] = {0x01, 0x61, 0x00};
+ const uint8_t val[] = {0x00, 0x03, 0x01, 0x61, 0x00};
+ DataBuffer extension(val, sizeof(val));
+ ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
+ client_, ssl_app_layer_protocol_xtn, extension));
+}
+
+TEST_P(TlsExtensionTestGeneric, AlpnLengthOverflow) {
+ EnableAlpn();
+ const uint8_t val[] = {0x00, 0x03, 0x01, 0x61, 0x01};
DataBuffer extension(val, sizeof(val));
ClientHelloErrorTest(std::make_shared<TlsExtensionReplacer>(
client_, ssl_app_layer_protocol_xtn, extension));
@@ -628,12 +634,9 @@ typedef std::function<void(TlsPreSharedKeyReplacer*)>
class TlsPreSharedKeyReplacer : public TlsExtensionFilter {
public:
- TlsPreSharedKeyReplacer(const std::shared_ptr<TlsAgent>& agent,
+ TlsPreSharedKeyReplacer(const std::shared_ptr<TlsAgent>& a,
TlsPreSharedKeyReplacerFunc function)
- : TlsExtensionFilter(agent),
- identities_(),
- binders_(),
- function_(function) {}
+ : TlsExtensionFilter(a), identities_(), binders_(), function_(function) {}
static size_t CopyAndMaybeReplace(TlsParser* parser, size_t size,
const std::unique_ptr<DataBuffer>& replace,
diff --git a/security/nss/gtests/ssl_gtest/ssl_fragment_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_fragment_unittest.cc
index f4940bf282..92947c2c70 100644
--- a/security/nss/gtests/ssl_gtest/ssl_fragment_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_fragment_unittest.cc
@@ -20,14 +20,16 @@ namespace nss_test {
// This class cuts every unencrypted handshake record into two parts.
class RecordFragmenter : public PacketFilter {
public:
- RecordFragmenter() : sequence_number_(0), splitting_(true) {}
+ RecordFragmenter(bool is_dtls13)
+ : is_dtls13_(is_dtls13), sequence_number_(0), splitting_(true) {}
private:
class HandshakeSplitter {
public:
- HandshakeSplitter(const DataBuffer& input, DataBuffer* output,
- uint64_t* sequence_number)
- : input_(input),
+ HandshakeSplitter(bool is_dtls13, const DataBuffer& input,
+ DataBuffer* output, uint64_t* sequence_number)
+ : is_dtls13_(is_dtls13),
+ input_(input),
output_(output),
cursor_(0),
sequence_number_(sequence_number) {}
@@ -35,9 +37,9 @@ class RecordFragmenter : public PacketFilter {
private:
void WriteRecord(TlsRecordHeader& record_header,
DataBuffer& record_fragment) {
- TlsRecordHeader fragment_header(record_header.version(),
- record_header.content_type(),
- *sequence_number_);
+ TlsRecordHeader fragment_header(
+ record_header.variant(), record_header.version(),
+ record_header.content_type(), *sequence_number_);
++*sequence_number_;
if (::g_ssl_gtest_verbose) {
std::cerr << "Fragment: " << fragment_header << ' ' << record_fragment
@@ -88,7 +90,7 @@ class RecordFragmenter : public PacketFilter {
while (parser.remaining()) {
TlsRecordHeader header;
DataBuffer record;
- if (!header.Parse(0, &parser, &record)) {
+ if (!header.Parse(is_dtls13_, 0, &parser, &record)) {
ADD_FAILURE() << "bad record header";
return false;
}
@@ -118,6 +120,7 @@ class RecordFragmenter : public PacketFilter {
}
private:
+ bool is_dtls13_;
const DataBuffer& input_;
DataBuffer* output_;
size_t cursor_;
@@ -132,7 +135,7 @@ class RecordFragmenter : public PacketFilter {
}
output->Allocate(input.len());
- HandshakeSplitter splitter(input, output, &sequence_number_);
+ HandshakeSplitter splitter(is_dtls13_, input, output, &sequence_number_);
if (!splitter.Split()) {
// If splitting fails, we obviously reached encrypted packets.
// Stop splitting from that point onward.
@@ -144,18 +147,21 @@ class RecordFragmenter : public PacketFilter {
}
private:
+ bool is_dtls13_;
uint64_t sequence_number_;
bool splitting_;
};
TEST_P(TlsConnectDatagram, FragmentClientPackets) {
- client_->SetFilter(std::make_shared<RecordFragmenter>());
+ bool is_dtls13 = version_ >= SSL_LIBRARY_VERSION_TLS_1_3;
+ client_->SetFilter(std::make_shared<RecordFragmenter>(is_dtls13));
Connect();
SendReceive();
}
TEST_P(TlsConnectDatagram, FragmentServerPackets) {
- server_->SetFilter(std::make_shared<RecordFragmenter>());
+ bool is_dtls13 = version_ >= SSL_LIBRARY_VERSION_TLS_1_3;
+ server_->SetFilter(std::make_shared<RecordFragmenter>(is_dtls13));
Connect();
SendReceive();
}
diff --git a/security/nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc
index 99448321c5..f0afc9118a 100644
--- a/security/nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_fuzz_unittest.cc
@@ -27,8 +27,8 @@ class TlsFuzzTest : public ::testing::Test {};
// Record the application data stream.
class TlsApplicationDataRecorder : public TlsRecordFilter {
public:
- TlsApplicationDataRecorder(const std::shared_ptr<TlsAgent>& agent)
- : TlsRecordFilter(agent), buffer_() {}
+ TlsApplicationDataRecorder(const std::shared_ptr<TlsAgent>& a)
+ : TlsRecordFilter(a), buffer_() {}
virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
const DataBuffer& input,
diff --git a/security/nss/gtests/ssl_gtest/ssl_gtest.gyp b/security/nss/gtests/ssl_gtest/ssl_gtest.gyp
index e2a8d830ac..17677713d6 100644
--- a/security/nss/gtests/ssl_gtest/ssl_gtest.gyp
+++ b/security/nss/gtests/ssl_gtest/ssl_gtest.gyp
@@ -37,6 +37,7 @@
'ssl_loopback_unittest.cc',
'ssl_misc_unittest.cc',
'ssl_record_unittest.cc',
+ 'ssl_recordsize_unittest.cc',
'ssl_resumption_unittest.cc',
'ssl_renegotiation_unittest.cc',
'ssl_skip_unittest.cc',
diff --git a/security/nss/gtests/ssl_gtest/ssl_hrr_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_hrr_unittest.cc
index 05ae870348..77b335e86b 100644
--- a/security/nss/gtests/ssl_gtest/ssl_hrr_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_hrr_unittest.cc
@@ -69,8 +69,8 @@ TEST_P(TlsConnectTls13, HelloRetryRequestAbortsZeroRtt) {
// handshake packets, this will break.
class CorrectMessageSeqAfterHrrFilter : public TlsRecordFilter {
public:
- CorrectMessageSeqAfterHrrFilter(const std::shared_ptr<TlsAgent>& agent)
- : TlsRecordFilter(agent) {}
+ CorrectMessageSeqAfterHrrFilter(const std::shared_ptr<TlsAgent>& a)
+ : TlsRecordFilter(a) {}
protected:
PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
@@ -81,8 +81,9 @@ class CorrectMessageSeqAfterHrrFilter : public TlsRecordFilter {
}
DataBuffer buffer(record);
- TlsRecordHeader new_header = {header.version(), header.content_type(),
- header.sequence_number() + 1};
+ TlsRecordHeader new_header(header.variant(), header.version(),
+ header.content_type(),
+ header.sequence_number() + 1);
// Correct message_seq.
buffer.Write(4, 1U, 2);
@@ -151,8 +152,8 @@ TEST_P(TlsConnectTls13, SecondClientHelloRejectEarlyDataXtn) {
class KeyShareReplayer : public TlsExtensionFilter {
public:
- KeyShareReplayer(const std::shared_ptr<TlsAgent>& agent)
- : TlsExtensionFilter(agent) {}
+ KeyShareReplayer(const std::shared_ptr<TlsAgent>& a)
+ : TlsExtensionFilter(a) {}
virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
const DataBuffer& input,
@@ -567,6 +568,28 @@ void TriggerHelloRetryRequest(std::shared_ptr<TlsAgent>& client,
client->Handshake();
server->Handshake();
EXPECT_EQ(1U, cb_called);
+ // Stop the callback from being called in future handshakes.
+ EXPECT_EQ(SECSuccess,
+ SSL_HelloRetryRequestCallback(server->ssl_fd(), nullptr, nullptr));
+}
+
+TEST_P(TlsConnectTls13, VersionNumbersAfterRetry) {
+ ConfigureSelfEncrypt();
+ EnsureTlsSetup();
+ auto r = MakeTlsFilter<TlsRecordRecorder>(client_);
+ TriggerHelloRetryRequest(client_, server_);
+ Handshake();
+ ASSERT_GT(r->count(), 1UL);
+ auto ch1 = r->record(0);
+ if (ch1.header.is_dtls()) {
+ ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, ch1.header.version());
+ } else {
+ ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, ch1.header.version());
+ }
+ auto ch2 = r->record(1);
+ ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, ch2.header.version());
+
+ CheckConnected();
}
TEST_P(TlsConnectTls13, RetryStateless) {
@@ -577,6 +600,7 @@ TEST_P(TlsConnectTls13, RetryStateless) {
MakeNewServer();
Handshake();
+ CheckConnected();
SendReceive();
}
@@ -593,6 +617,68 @@ TEST_P(TlsConnectTls13, RetryStatefulDropCookie) {
server_->CheckErrorCode(SSL_ERROR_MISSING_COOKIE_EXTENSION);
}
+class TruncateHrrCookie : public TlsExtensionFilter {
+ public:
+ TruncateHrrCookie(const std::shared_ptr<TlsAgent>& a)
+ : TlsExtensionFilter(a) {}
+ virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
+ const DataBuffer& input,
+ DataBuffer* output) {
+ if (extension_type != ssl_tls13_cookie_xtn) {
+ return KEEP;
+ }
+
+ // Claim a zero-length cookie.
+ output->Allocate(2);
+ output->Write(0, static_cast<uint32_t>(0), 2);
+ return CHANGE;
+ }
+};
+
+TEST_P(TlsConnectTls13, RetryCookieEmpty) {
+ ConfigureSelfEncrypt();
+ EnsureTlsSetup();
+
+ TriggerHelloRetryRequest(client_, server_);
+ MakeTlsFilter<TruncateHrrCookie>(client_);
+
+ ExpectAlert(server_, kTlsAlertHandshakeFailure);
+ Handshake();
+ client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
+ server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
+}
+
+class AddJunkToCookie : public TlsExtensionFilter {
+ public:
+ AddJunkToCookie(const std::shared_ptr<TlsAgent>& a) : TlsExtensionFilter(a) {}
+ virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
+ const DataBuffer& input,
+ DataBuffer* output) {
+ if (extension_type != ssl_tls13_cookie_xtn) {
+ return KEEP;
+ }
+
+ *output = input;
+ // Add junk after the cookie.
+ static const uint8_t junk[2] = {1, 2};
+ output->Append(DataBuffer(junk, sizeof(junk)));
+ return CHANGE;
+ }
+};
+
+TEST_P(TlsConnectTls13, RetryCookieWithExtras) {
+ ConfigureSelfEncrypt();
+ EnsureTlsSetup();
+
+ TriggerHelloRetryRequest(client_, server_);
+ MakeTlsFilter<AddJunkToCookie>(client_);
+
+ ExpectAlert(server_, kTlsAlertHandshakeFailure);
+ Handshake();
+ client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
+ server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
+}
+
// Stream only because DTLS drops bad packets.
TEST_F(TlsConnectStreamTls13, RetryStatelessDamageFirstClientHello) {
ConfigureSelfEncrypt();
@@ -907,7 +993,10 @@ class HelloRetryRequestAgentTest : public TlsAgentTestClient {
hrr_data.Allocate(len + 6);
size_t i = 0;
- i = hrr_data.Write(i, 0x0303, 2);
+ i = hrr_data.Write(i, variant_ == ssl_variant_datagram
+ ? SSL_LIBRARY_VERSION_DTLS_1_2_WIRE
+ : SSL_LIBRARY_VERSION_TLS_1_2,
+ 2);
i = hrr_data.Write(i, ssl_hello_retry_random,
sizeof(ssl_hello_retry_random));
i = hrr_data.Write(i, static_cast<uint32_t>(0), 1); // session_id
@@ -973,6 +1062,39 @@ TEST_P(HelloRetryRequestAgentTest, HandleNoopHelloRetryRequest) {
SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST);
}
+class ReplaceRandom : public TlsHandshakeFilter {
+ public:
+ ReplaceRandom(const std::shared_ptr<TlsAgent>& a, const DataBuffer& r)
+ : TlsHandshakeFilter(a, {kTlsHandshakeServerHello}), random_(r) {}
+
+ PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
+ const DataBuffer& input,
+ DataBuffer* output) override {
+ output->Assign(input);
+ output->Write(2, random_);
+ return CHANGE;
+ }
+
+ private:
+ DataBuffer random_;
+};
+
+// Make sure that the TLS 1.3 special value for the ServerHello.random
+// is rejected by earlier versions.
+TEST_P(TlsConnectStreamPre13, HrrRandomOnTls10) {
+ static const uint8_t hrr_random[] = {
+ 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, 0x1D, 0x8C,
+ 0x02, 0x1E, 0x65, 0xB8, 0x91, 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB,
+ 0x8C, 0x5E, 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C};
+
+ EnsureTlsSetup();
+ MakeTlsFilter<ReplaceRandom>(server_,
+ DataBuffer(hrr_random, sizeof(hrr_random)));
+ ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
+ client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
+ server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
+}
+
INSTANTIATE_TEST_CASE_P(HelloRetryRequestAgentTests, HelloRetryRequestAgentTest,
::testing::Combine(TlsConnectTestBase::kTlsVariantsAll,
TlsConnectTestBase::kTlsV13));
diff --git a/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc
index f1b78f52fd..5adbd9dc71 100644
--- a/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_loopback_unittest.cc
@@ -56,8 +56,8 @@ TEST_P(TlsConnectGeneric, CipherSuiteMismatch) {
class TlsAlertRecorder : public TlsRecordFilter {
public:
- TlsAlertRecorder(const std::shared_ptr<TlsAgent>& agent)
- : TlsRecordFilter(agent), level_(255), description_(255) {}
+ TlsAlertRecorder(const std::shared_ptr<TlsAgent>& a)
+ : TlsRecordFilter(a), level_(255), description_(255) {}
PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
const DataBuffer& input,
@@ -87,9 +87,9 @@ class TlsAlertRecorder : public TlsRecordFilter {
class HelloTruncator : public TlsHandshakeFilter {
public:
- HelloTruncator(const std::shared_ptr<TlsAgent>& agent)
+ HelloTruncator(const std::shared_ptr<TlsAgent>& a)
: TlsHandshakeFilter(
- agent, {kTlsHandshakeClientHello, kTlsHandshakeServerHello}) {}
+ a, {kTlsHandshakeClientHello, kTlsHandshakeServerHello}) {}
PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
const DataBuffer& input,
DataBuffer* output) override {
@@ -149,6 +149,27 @@ TEST_P(TlsConnectGeneric, ConnectAlpn) {
CheckAlpn("a");
}
+TEST_P(TlsConnectGeneric, ConnectAlpnPriorityA) {
+ // "alpn" "npn"
+ // alpn is the fallback here. npn has the highest priority and should be
+ // picked.
+ const std::vector<uint8_t> alpn = {0x04, 0x61, 0x6c, 0x70, 0x6e,
+ 0x03, 0x6e, 0x70, 0x6e};
+ EnableAlpn(alpn);
+ Connect();
+ CheckAlpn("npn");
+}
+
+TEST_P(TlsConnectGeneric, ConnectAlpnPriorityB) {
+ // "alpn" "npn" "http"
+ // npn has the highest priority and should be picked.
+ const std::vector<uint8_t> alpn = {0x04, 0x61, 0x6c, 0x70, 0x6e, 0x03, 0x6e,
+ 0x70, 0x6e, 0x04, 0x68, 0x74, 0x74, 0x70};
+ EnableAlpn(alpn);
+ Connect();
+ CheckAlpn("npn");
+}
+
TEST_P(TlsConnectGeneric, ConnectAlpnClone) {
EnsureModelSockets();
client_model_->EnableAlpn(alpn_dummy_val_, sizeof(alpn_dummy_val_));
@@ -157,6 +178,33 @@ TEST_P(TlsConnectGeneric, ConnectAlpnClone) {
CheckAlpn("a");
}
+TEST_P(TlsConnectGeneric, ConnectAlpnWithCustomCallbackA) {
+ // "ab" "alpn"
+ const std::vector<uint8_t> client_alpn = {0x02, 0x61, 0x62, 0x04,
+ 0x61, 0x6c, 0x70, 0x6e};
+ EnableAlpnWithCallback(client_alpn, "alpn");
+ Connect();
+ CheckAlpn("alpn");
+}
+
+TEST_P(TlsConnectGeneric, ConnectAlpnWithCustomCallbackB) {
+ // "ab" "alpn"
+ const std::vector<uint8_t> client_alpn = {0x02, 0x61, 0x62, 0x04,
+ 0x61, 0x6c, 0x70, 0x6e};
+ EnableAlpnWithCallback(client_alpn, "ab");
+ Connect();
+ CheckAlpn("ab");
+}
+
+TEST_P(TlsConnectGeneric, ConnectAlpnWithCustomCallbackC) {
+ // "cd" "npn" "alpn"
+ const std::vector<uint8_t> client_alpn = {0x02, 0x63, 0x64, 0x03, 0x6e, 0x70,
+ 0x6e, 0x04, 0x61, 0x6c, 0x70, 0x6e};
+ EnableAlpnWithCallback(client_alpn, "npn");
+ Connect();
+ CheckAlpn("npn");
+}
+
TEST_P(TlsConnectDatagram, ConnectSrtp) {
EnableSrtp();
Connect();
@@ -171,8 +219,8 @@ TEST_P(TlsConnectGeneric, ConnectSendReceive) {
class SaveTlsRecord : public TlsRecordFilter {
public:
- SaveTlsRecord(const std::shared_ptr<TlsAgent>& agent, size_t index)
- : TlsRecordFilter(agent), index_(index), count_(0), contents_() {}
+ SaveTlsRecord(const std::shared_ptr<TlsAgent>& a, size_t index)
+ : TlsRecordFilter(a), index_(index), count_(0), contents_() {}
const DataBuffer& contents() const { return contents_; }
@@ -227,8 +275,8 @@ TEST_F(TlsConnectStreamTls13, DecryptRecordServer) {
class DropTlsRecord : public TlsRecordFilter {
public:
- DropTlsRecord(const std::shared_ptr<TlsAgent>& agent, size_t index)
- : TlsRecordFilter(agent), index_(index), count_(0) {}
+ DropTlsRecord(const std::shared_ptr<TlsAgent>& a, size_t index)
+ : TlsRecordFilter(a), index_(index), count_(0) {}
protected:
PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
@@ -373,8 +421,8 @@ TEST_P(TlsHolddownTest, TestDtlsHolddownExpiryResumption) {
class TlsPreCCSHeaderInjector : public TlsRecordFilter {
public:
- TlsPreCCSHeaderInjector(const std::shared_ptr<TlsAgent>& agent)
- : TlsRecordFilter(agent) {}
+ TlsPreCCSHeaderInjector(const std::shared_ptr<TlsAgent>& a)
+ : TlsRecordFilter(a) {}
virtual PacketFilter::Action FilterRecord(
const TlsRecordHeader& record_header, const DataBuffer& input,
size_t* offset, DataBuffer* output) override {
@@ -383,7 +431,8 @@ class TlsPreCCSHeaderInjector : public TlsRecordFilter {
std::cerr << "Injecting Finished header before CCS\n";
const uint8_t hhdr[] = {kTlsHandshakeFinished, 0x00, 0x00, 0x0c};
DataBuffer hhdr_buf(hhdr, sizeof(hhdr));
- TlsRecordHeader nhdr(record_header.version(), kTlsHandshakeType, 0);
+ TlsRecordHeader nhdr(record_header.variant(), record_header.version(),
+ kTlsHandshakeType, 0);
*offset = nhdr.Write(output, *offset, hhdr_buf);
*offset = record_header.Write(output, *offset, input);
return CHANGE;
diff --git a/security/nss/gtests/ssl_gtest/ssl_record_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_record_unittest.cc
index 3b87278501..53b11c61a5 100644
--- a/security/nss/gtests/ssl_gtest/ssl_record_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_record_unittest.cc
@@ -103,16 +103,14 @@ TEST_P(TlsPaddingTest, LastByteOfPadWrong) {
class RecordReplacer : public TlsRecordFilter {
public:
- RecordReplacer(const std::shared_ptr<TlsAgent>& agent, size_t size)
- : TlsRecordFilter(agent), enabled_(false), size_(size) {}
+ RecordReplacer(const std::shared_ptr<TlsAgent>& a, size_t size)
+ : TlsRecordFilter(a), size_(size) {
+ Disable();
+ }
PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
const DataBuffer& data,
DataBuffer* changed) override {
- if (!enabled_) {
- return KEEP;
- }
-
EXPECT_EQ(kTlsApplicationDataType, header.content_type());
changed->Allocate(size_);
@@ -120,17 +118,33 @@ class RecordReplacer : public TlsRecordFilter {
changed->data()[i] = i & 0xff;
}
- enabled_ = false;
+ Disable();
return CHANGE;
}
- void Enable() { enabled_ = true; }
-
private:
- bool enabled_;
size_t size_;
};
+TEST_P(TlsConnectStream, BadRecordMac) {
+ EnsureTlsSetup();
+ Connect();
+ client_->SetFilter(std::make_shared<TlsRecordLastByteDamager>(client_));
+ ExpectAlert(server_, kTlsAlertBadRecordMac);
+ client_->SendData(10);
+
+ // Read from the client, get error.
+ uint8_t buf[10];
+ PRInt32 rv = PR_Read(server_->ssl_fd(), buf, sizeof(buf));
+ EXPECT_GT(0, rv);
+ EXPECT_EQ(SSL_ERROR_BAD_MAC_READ, PORT_GetError());
+
+ // Read the server alert.
+ rv = PR_Read(client_->ssl_fd(), buf, sizeof(buf));
+ EXPECT_GT(0, rv);
+ EXPECT_EQ(SSL_ERROR_BAD_MAC_ALERT, PORT_GetError());
+}
+
TEST_F(TlsConnectStreamTls13, LargeRecord) {
EnsureTlsSetup();
@@ -168,6 +182,29 @@ TEST_F(TlsConnectStreamTls13, TooLargeRecord) {
EXPECT_EQ(SSL_ERROR_RECORD_OVERFLOW_ALERT, PORT_GetError());
}
+class ShortHeaderChecker : public PacketFilter {
+ public:
+ PacketFilter::Action Filter(const DataBuffer& input, DataBuffer* output) {
+ // The first octet should be 0b001xxxxx.
+ EXPECT_EQ(1, input.data()[0] >> 5);
+ return KEEP;
+ }
+};
+
+TEST_F(TlsConnectDatagram13, ShortHeadersClient) {
+ Connect();
+ client_->SetOption(SSL_ENABLE_DTLS_SHORT_HEADER, PR_TRUE);
+ client_->SetFilter(std::make_shared<ShortHeaderChecker>());
+ SendReceive();
+}
+
+TEST_F(TlsConnectDatagram13, ShortHeadersServer) {
+ Connect();
+ server_->SetOption(SSL_ENABLE_DTLS_SHORT_HEADER, PR_TRUE);
+ server_->SetFilter(std::make_shared<ShortHeaderChecker>());
+ SendReceive();
+}
+
const static size_t kContentSizesArr[] = {
1, kMacSize - 1, kMacSize, 30, 31, 32, 36, 256, 257, 287, 288};
diff --git a/security/nss/gtests/ssl_gtest/ssl_recordsize_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_recordsize_unittest.cc
new file mode 100644
index 0000000000..00651aec5f
--- /dev/null
+++ b/security/nss/gtests/ssl_gtest/ssl_recordsize_unittest.cc
@@ -0,0 +1,431 @@
+/* -*- 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 "secerr.h"
+#include "ssl.h"
+#include "sslerr.h"
+#include "sslproto.h"
+
+#include "gtest_utils.h"
+#include "scoped_ptrs.h"
+#include "tls_connect.h"
+#include "tls_filter.h"
+#include "tls_parser.h"
+
+namespace nss_test {
+
+// This class tracks the maximum size of record that was sent, both cleartext
+// and plain. It only tracks records that have an outer type of
+// application_data. In TLS 1.3, this includes handshake messages.
+class TlsRecordMaximum : public TlsRecordFilter {
+ public:
+ TlsRecordMaximum(const std::shared_ptr<TlsAgent>& a)
+ : TlsRecordFilter(a), max_ciphertext_(0), max_plaintext_(0) {}
+
+ size_t max_ciphertext() const { return max_ciphertext_; }
+ size_t max_plaintext() const { return max_plaintext_; }
+
+ protected:
+ PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
+ const DataBuffer& record, size_t* offset,
+ DataBuffer* output) override {
+ std::cerr << "max: " << record << std::endl;
+ // Ignore unprotected packets.
+ if (header.content_type() != kTlsApplicationDataType) {
+ return KEEP;
+ }
+
+ max_ciphertext_ = (std::max)(max_ciphertext_, record.len());
+ return TlsRecordFilter::FilterRecord(header, record, offset, output);
+ }
+
+ PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
+ const DataBuffer& data,
+ DataBuffer* changed) override {
+ max_plaintext_ = (std::max)(max_plaintext_, data.len());
+ return KEEP;
+ }
+
+ private:
+ size_t max_ciphertext_;
+ size_t max_plaintext_;
+};
+
+void CheckRecordSizes(const std::shared_ptr<TlsAgent>& agent,
+ const std::shared_ptr<TlsRecordMaximum>& record_max,
+ size_t config) {
+ uint16_t cipher_suite;
+ ASSERT_TRUE(agent->cipher_suite(&cipher_suite));
+
+ size_t expansion;
+ size_t iv;
+ switch (cipher_suite) {
+ case TLS_AES_128_GCM_SHA256:
+ case TLS_AES_256_GCM_SHA384:
+ case TLS_CHACHA20_POLY1305_SHA256:
+ expansion = 16;
+ iv = 0;
+ break;
+
+ case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+ expansion = 16;
+ iv = 8;
+ break;
+
+ case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
+ // Expansion is 20 for the MAC. Maximum block padding is 16. Maximum
+ // padding is added when the input plus the MAC is an exact multiple of
+ // the block size.
+ expansion = 20 + 16 - ((config + 20) % 16);
+ iv = 16;
+ break;
+
+ default:
+ ADD_FAILURE() << "No expansion set for ciphersuite "
+ << agent->cipher_suite_name();
+ return;
+ }
+
+ switch (agent->version()) {
+ case SSL_LIBRARY_VERSION_TLS_1_3:
+ EXPECT_EQ(0U, iv) << "No IV for TLS 1.3";
+ // We only have decryption in TLS 1.3.
+ EXPECT_EQ(config - 1, record_max->max_plaintext())
+ << "bad plaintext length for " << agent->role_str();
+ break;
+
+ case SSL_LIBRARY_VERSION_TLS_1_2:
+ case SSL_LIBRARY_VERSION_TLS_1_1:
+ expansion += iv;
+ break;
+
+ case SSL_LIBRARY_VERSION_TLS_1_0:
+ break;
+
+ default:
+ ADD_FAILURE() << "Unexpected version " << agent->version();
+ return;
+ }
+
+ EXPECT_EQ(config + expansion, record_max->max_ciphertext())
+ << "bad ciphertext length for " << agent->role_str();
+}
+
+TEST_P(TlsConnectGeneric, RecordSizeMaximum) {
+ uint16_t max_record_size =
+ (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) ? 16385 : 16384;
+ size_t send_size = (version_ >= SSL_LIBRARY_VERSION_TLS_1_3)
+ ? max_record_size
+ : max_record_size + 1;
+
+ EnsureTlsSetup();
+ auto client_max = MakeTlsFilter<TlsRecordMaximum>(client_);
+ client_max->EnableDecryption();
+ auto server_max = MakeTlsFilter<TlsRecordMaximum>(server_);
+ server_max->EnableDecryption();
+
+ Connect();
+ client_->SendData(send_size, send_size);
+ server_->SendData(send_size, send_size);
+ server_->ReadBytes(send_size);
+ client_->ReadBytes(send_size);
+
+ CheckRecordSizes(client_, client_max, max_record_size);
+ CheckRecordSizes(server_, server_max, max_record_size);
+}
+
+TEST_P(TlsConnectGeneric, RecordSizeMinimumClient) {
+ EnsureTlsSetup();
+ auto server_max = MakeTlsFilter<TlsRecordMaximum>(server_);
+ server_max->EnableDecryption();
+
+ client_->SetOption(SSL_RECORD_SIZE_LIMIT, 64);
+ Connect();
+ SendReceive(127); // Big enough for one record, allowing for 1+N splitting.
+
+ CheckRecordSizes(server_, server_max, 64);
+}
+
+TEST_P(TlsConnectGeneric, RecordSizeMinimumServer) {
+ EnsureTlsSetup();
+ auto client_max = MakeTlsFilter<TlsRecordMaximum>(client_);
+ client_max->EnableDecryption();
+
+ server_->SetOption(SSL_RECORD_SIZE_LIMIT, 64);
+ Connect();
+ SendReceive(127);
+
+ CheckRecordSizes(client_, client_max, 64);
+}
+
+TEST_P(TlsConnectGeneric, RecordSizeAsymmetric) {
+ EnsureTlsSetup();
+ auto client_max = MakeTlsFilter<TlsRecordMaximum>(client_);
+ client_max->EnableDecryption();
+ auto server_max = MakeTlsFilter<TlsRecordMaximum>(server_);
+ server_max->EnableDecryption();
+
+ client_->SetOption(SSL_RECORD_SIZE_LIMIT, 64);
+ server_->SetOption(SSL_RECORD_SIZE_LIMIT, 100);
+ Connect();
+ SendReceive(127);
+
+ CheckRecordSizes(client_, client_max, 100);
+ CheckRecordSizes(server_, server_max, 64);
+}
+
+// This just modifies the encrypted payload so to include a few extra zeros.
+class TlsRecordExpander : public TlsRecordFilter {
+ public:
+ TlsRecordExpander(const std::shared_ptr<TlsAgent>& a, size_t expansion)
+ : TlsRecordFilter(a), expansion_(expansion) {}
+
+ protected:
+ virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
+ const DataBuffer& data,
+ DataBuffer* changed) {
+ if (header.content_type() != kTlsApplicationDataType) {
+ return KEEP;
+ }
+ changed->Allocate(data.len() + expansion_);
+ changed->Write(0, data.data(), data.len());
+ return CHANGE;
+ }
+
+ private:
+ size_t expansion_;
+};
+
+// Tweak the plaintext of server records so that they exceed the client's limit.
+TEST_P(TlsConnectTls13, RecordSizePlaintextExceed) {
+ EnsureTlsSetup();
+ auto server_expand = MakeTlsFilter<TlsRecordExpander>(server_, 1);
+ server_expand->EnableDecryption();
+
+ client_->SetOption(SSL_RECORD_SIZE_LIMIT, 64);
+ Connect();
+
+ server_->SendData(100);
+
+ client_->ExpectReadWriteError();
+ ExpectAlert(client_, kTlsAlertRecordOverflow);
+ client_->ReadBytes(100);
+ EXPECT_EQ(SSL_ERROR_RX_RECORD_TOO_LONG, client_->error_code());
+
+ // Consume the alert at the server.
+ server_->Handshake();
+ server_->CheckErrorCode(SSL_ERROR_RECORD_OVERFLOW_ALERT);
+}
+
+// Tweak the ciphertext of server records so that they greatly exceed the limit.
+// This requires a much larger expansion than for plaintext to trigger the
+// guard, which runs before decryption (current allowance is 304 octets).
+TEST_P(TlsConnectTls13, RecordSizeCiphertextExceed) {
+ EnsureTlsSetup();
+
+ client_->SetOption(SSL_RECORD_SIZE_LIMIT, 64);
+ Connect();
+
+ auto server_expand = MakeTlsFilter<TlsRecordExpander>(server_, 320);
+ server_->SendData(100);
+
+ client_->ExpectReadWriteError();
+ ExpectAlert(client_, kTlsAlertRecordOverflow);
+ client_->ReadBytes(100);
+ EXPECT_EQ(SSL_ERROR_RX_RECORD_TOO_LONG, client_->error_code());
+
+ // Consume the alert at the server.
+ server_->Handshake();
+ server_->CheckErrorCode(SSL_ERROR_RECORD_OVERFLOW_ALERT);
+}
+
+// This indiscriminately adds padding to application data records.
+class TlsRecordPadder : public TlsRecordFilter {
+ public:
+ TlsRecordPadder(const std::shared_ptr<TlsAgent>& a, size_t padding)
+ : TlsRecordFilter(a), padding_(padding) {}
+
+ protected:
+ PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
+ const DataBuffer& record, size_t* offset,
+ DataBuffer* output) override {
+ if (header.content_type() != kTlsApplicationDataType) {
+ return KEEP;
+ }
+
+ uint8_t inner_content_type;
+ DataBuffer plaintext;
+ if (!Unprotect(header, record, &inner_content_type, &plaintext)) {
+ return KEEP;
+ }
+
+ if (inner_content_type != kTlsApplicationDataType) {
+ return KEEP;
+ }
+
+ DataBuffer ciphertext;
+ bool ok =
+ Protect(header, inner_content_type, plaintext, &ciphertext, padding_);
+ EXPECT_TRUE(ok);
+ if (!ok) {
+ return KEEP;
+ }
+ *offset = header.Write(output, *offset, ciphertext);
+ return CHANGE;
+ }
+
+ private:
+ size_t padding_;
+};
+
+TEST_P(TlsConnectTls13, RecordSizeExceedPad) {
+ EnsureTlsSetup();
+ auto server_max = std::make_shared<TlsRecordMaximum>(server_);
+ auto server_expand = std::make_shared<TlsRecordPadder>(server_, 1);
+ server_->SetFilter(std::make_shared<ChainedPacketFilter>(
+ ChainedPacketFilterInit({server_max, server_expand})));
+ server_expand->EnableDecryption();
+
+ client_->SetOption(SSL_RECORD_SIZE_LIMIT, 64);
+ Connect();
+
+ server_->SendData(100);
+
+ client_->ExpectReadWriteError();
+ ExpectAlert(client_, kTlsAlertRecordOverflow);
+ client_->ReadBytes(100);
+ EXPECT_EQ(SSL_ERROR_RX_RECORD_TOO_LONG, client_->error_code());
+
+ // Consume the alert at the server.
+ server_->Handshake();
+ server_->CheckErrorCode(SSL_ERROR_RECORD_OVERFLOW_ALERT);
+}
+
+TEST_P(TlsConnectGeneric, RecordSizeBadValues) {
+ EnsureTlsSetup();
+ EXPECT_EQ(SECFailure,
+ SSL_OptionSet(client_->ssl_fd(), SSL_RECORD_SIZE_LIMIT, 63));
+ EXPECT_EQ(SECFailure,
+ SSL_OptionSet(client_->ssl_fd(), SSL_RECORD_SIZE_LIMIT, -1));
+ EXPECT_EQ(SECFailure,
+ SSL_OptionSet(server_->ssl_fd(), SSL_RECORD_SIZE_LIMIT, 16386));
+ Connect();
+}
+
+TEST_P(TlsConnectGeneric, RecordSizeGetValues) {
+ EnsureTlsSetup();
+ int v;
+ EXPECT_EQ(SECSuccess,
+ SSL_OptionGet(client_->ssl_fd(), SSL_RECORD_SIZE_LIMIT, &v));
+ EXPECT_EQ(16385, v);
+ client_->SetOption(SSL_RECORD_SIZE_LIMIT, 300);
+ EXPECT_EQ(SECSuccess,
+ SSL_OptionGet(client_->ssl_fd(), SSL_RECORD_SIZE_LIMIT, &v));
+ EXPECT_EQ(300, v);
+ Connect();
+}
+
+// The value of the extension is capped by the maximum version of the client.
+TEST_P(TlsConnectGeneric, RecordSizeCapExtensionClient) {
+ EnsureTlsSetup();
+ client_->SetOption(SSL_RECORD_SIZE_LIMIT, 16385);
+ auto capture =
+ MakeTlsFilter<TlsExtensionCapture>(client_, ssl_record_size_limit_xtn);
+ capture->EnableDecryption();
+ Connect();
+
+ uint64_t val = 0;
+ EXPECT_TRUE(capture->extension().Read(0, 2, &val));
+ if (version_ < SSL_LIBRARY_VERSION_TLS_1_3) {
+ EXPECT_EQ(16384U, val) << "Extension should be capped";
+ } else {
+ EXPECT_EQ(16385U, val);
+ }
+}
+
+// The value of the extension is capped by the maximum version of the server.
+TEST_P(TlsConnectGeneric, RecordSizeCapExtensionServer) {
+ EnsureTlsSetup();
+ server_->SetOption(SSL_RECORD_SIZE_LIMIT, 16385);
+ auto capture =
+ MakeTlsFilter<TlsExtensionCapture>(server_, ssl_record_size_limit_xtn);
+ capture->EnableDecryption();
+ Connect();
+
+ uint64_t val = 0;
+ EXPECT_TRUE(capture->extension().Read(0, 2, &val));
+ if (version_ < SSL_LIBRARY_VERSION_TLS_1_3) {
+ EXPECT_EQ(16384U, val) << "Extension should be capped";
+ } else {
+ EXPECT_EQ(16385U, val);
+ }
+}
+
+// Damage the client extension and the handshake fails, but the server
+// doesn't generate a validation error.
+TEST_P(TlsConnectGenericPre13, RecordSizeClientExtensionInvalid) {
+ EnsureTlsSetup();
+ client_->SetOption(SSL_RECORD_SIZE_LIMIT, 1000);
+ static const uint8_t v[] = {0xf4, 0x1f};
+ MakeTlsFilter<TlsExtensionReplacer>(client_, ssl_record_size_limit_xtn,
+ DataBuffer(v, sizeof(v)));
+ ConnectExpectAlert(server_, kTlsAlertDecryptError);
+}
+
+// Special handling for TLS 1.3, where the alert isn't read.
+TEST_F(TlsConnectStreamTls13, RecordSizeClientExtensionInvalid) {
+ EnsureTlsSetup();
+ client_->SetOption(SSL_RECORD_SIZE_LIMIT, 1000);
+ static const uint8_t v[] = {0xf4, 0x1f};
+ MakeTlsFilter<TlsExtensionReplacer>(client_, ssl_record_size_limit_xtn,
+ DataBuffer(v, sizeof(v)));
+ client_->ExpectSendAlert(kTlsAlertBadRecordMac);
+ server_->ExpectSendAlert(kTlsAlertBadRecordMac);
+ ConnectExpectFail();
+}
+
+TEST_P(TlsConnectGeneric, RecordSizeServerExtensionInvalid) {
+ EnsureTlsSetup();
+ server_->SetOption(SSL_RECORD_SIZE_LIMIT, 1000);
+ static const uint8_t v[] = {0xf4, 0x1f};
+ auto replace = MakeTlsFilter<TlsExtensionReplacer>(
+ server_, ssl_record_size_limit_xtn, DataBuffer(v, sizeof(v)));
+ replace->EnableDecryption();
+ ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
+}
+
+class RecordSizeDefaultsTest : public ::testing::Test {
+ public:
+ void SetUp() {
+ EXPECT_EQ(SECSuccess,
+ SSL_OptionGetDefault(SSL_RECORD_SIZE_LIMIT, &default_));
+ }
+ void TearDown() {
+ // Make sure to restore the default value at the end.
+ EXPECT_EQ(SECSuccess,
+ SSL_OptionSetDefault(SSL_RECORD_SIZE_LIMIT, default_));
+ }
+
+ private:
+ PRIntn default_ = 0;
+};
+
+TEST_F(RecordSizeDefaultsTest, RecordSizeBadValues) {
+ EXPECT_EQ(SECFailure, SSL_OptionSetDefault(SSL_RECORD_SIZE_LIMIT, 63));
+ EXPECT_EQ(SECFailure, SSL_OptionSetDefault(SSL_RECORD_SIZE_LIMIT, -1));
+ EXPECT_EQ(SECFailure, SSL_OptionSetDefault(SSL_RECORD_SIZE_LIMIT, 16386));
+}
+
+TEST_F(RecordSizeDefaultsTest, RecordSizeGetValue) {
+ int v;
+ EXPECT_EQ(SECSuccess, SSL_OptionGetDefault(SSL_RECORD_SIZE_LIMIT, &v));
+ EXPECT_EQ(16385, v);
+ EXPECT_EQ(SECSuccess, SSL_OptionSetDefault(SSL_RECORD_SIZE_LIMIT, 3000));
+ EXPECT_EQ(SECSuccess, SSL_OptionGetDefault(SSL_RECORD_SIZE_LIMIT, &v));
+ EXPECT_EQ(3000, v);
+}
+
+} // namespace nss_test
diff --git a/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc
index eb78c05851..2cc98a3278 100644
--- a/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_resumption_unittest.cc
@@ -484,10 +484,8 @@ TEST_P(TlsConnectStream, TestResumptionOverrideCipher) {
class SelectedVersionReplacer : public TlsHandshakeFilter {
public:
- SelectedVersionReplacer(const std::shared_ptr<TlsAgent>& agent,
- uint16_t version)
- : TlsHandshakeFilter(agent, {kTlsHandshakeServerHello}),
- version_(version) {}
+ SelectedVersionReplacer(const std::shared_ptr<TlsAgent>& a, uint16_t version)
+ : TlsHandshakeFilter(a, {kTlsHandshakeServerHello}), version_(version) {}
protected:
PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
diff --git a/security/nss/gtests/ssl_gtest/ssl_skip_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_skip_unittest.cc
index e4a9e5aed7..9ef19653bc 100644
--- a/security/nss/gtests/ssl_gtest/ssl_skip_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_skip_unittest.cc
@@ -22,11 +22,9 @@ namespace nss_test {
class TlsHandshakeSkipFilter : public TlsRecordFilter {
public:
// A TLS record filter that skips handshake messages of the identified type.
- TlsHandshakeSkipFilter(const std::shared_ptr<TlsAgent>& agent,
+ TlsHandshakeSkipFilter(const std::shared_ptr<TlsAgent>& a,
uint8_t handshake_type)
- : TlsRecordFilter(agent),
- handshake_type_(handshake_type),
- skipped_(false) {}
+ : TlsRecordFilter(a), handshake_type_(handshake_type), skipped_(false) {}
protected:
// Takes a record; if it is a handshake record, it removes the first handshake
diff --git a/security/nss/gtests/ssl_gtest/ssl_staticrsa_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_staticrsa_unittest.cc
index e5fccc12b6..ff4091b9a3 100644
--- a/security/nss/gtests/ssl_gtest/ssl_staticrsa_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_staticrsa_unittest.cc
@@ -21,6 +21,7 @@ extern "C" {
#include "tls_connect.h"
#include "tls_filter.h"
#include "tls_parser.h"
+#include "rsa8193.h"
namespace nss_test {
@@ -100,4 +101,39 @@ TEST_P(TlsConnectStreamPre13,
Connect();
}
+// Replace the server certificate with one that uses 8193-bit RSA.
+class TooLargeRSACertFilter : public TlsHandshakeFilter {
+ public:
+ TooLargeRSACertFilter(const std::shared_ptr<TlsAgent> &server)
+ : TlsHandshakeFilter(server, {kTlsHandshakeCertificate}) {}
+
+ protected:
+ virtual PacketFilter::Action FilterHandshake(const HandshakeHeader &header,
+ const DataBuffer &input,
+ DataBuffer *output) {
+ const uint32_t cert_len = sizeof(rsa8193);
+ const uint32_t outer_len = cert_len + 3;
+ size_t offset = 0;
+ offset = output->Write(offset, outer_len, 3);
+ offset = output->Write(offset, cert_len, 3);
+ offset = output->Write(offset, rsa8193, cert_len);
+
+ return CHANGE;
+ }
+};
+
+TEST_P(TlsConnectGenericPre13, TooLargeRSAKeyInCert) {
+ EnableOnlyStaticRsaCiphers();
+ MakeTlsFilter<TooLargeRSACertFilter>(server_);
+ ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
+ client_->CheckErrorCode(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
+}
+
+TEST_P(TlsConnectGeneric, ServerAuthBiggestRsa) {
+ Reset(TlsAgent::kRsa8192);
+ Connect();
+ CheckKeys();
+}
+
} // namespace nss_test
diff --git a/security/nss/gtests/ssl_gtest/ssl_tls13compat_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_tls13compat_unittest.cc
index f5ccf096b8..42f1065f6e 100644
--- a/security/nss/gtests/ssl_gtest/ssl_tls13compat_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_tls13compat_unittest.cc
@@ -214,6 +214,98 @@ TEST_F(Tls13CompatTest, EnabledHrrZeroRtt) {
CheckForCompatHandshake();
}
+class TlsSessionIDEchoFilter : public TlsHandshakeFilter {
+ public:
+ TlsSessionIDEchoFilter(const std::shared_ptr<TlsAgent>& a)
+ : TlsHandshakeFilter(
+ a, {kTlsHandshakeClientHello, kTlsHandshakeServerHello}) {}
+
+ protected:
+ virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
+ const DataBuffer& input,
+ DataBuffer* output) {
+ TlsParser parser(input);
+
+ // Skip version + random.
+ EXPECT_TRUE(parser.Skip(2 + 32));
+
+ // Capture CH.legacy_session_id.
+ if (header.handshake_type() == kTlsHandshakeClientHello) {
+ EXPECT_TRUE(parser.ReadVariable(&sid_, 1));
+ return KEEP;
+ }
+
+ // Check that server sends one too.
+ uint32_t sid_len = 0;
+ EXPECT_TRUE(parser.Read(&sid_len, 1));
+ EXPECT_EQ(sid_len, sid_.len());
+
+ // Echo the one we captured.
+ *output = input;
+ output->Write(parser.consumed(), sid_.data(), sid_.len());
+
+ return CHANGE;
+ }
+
+ private:
+ DataBuffer sid_;
+};
+
+TEST_F(TlsConnectTest, EchoTLS13CompatibilitySessionID) {
+ ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID);
+
+ client_->SetOption(SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE);
+
+ client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
+ SSL_LIBRARY_VERSION_TLS_1_3);
+
+ server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
+ SSL_LIBRARY_VERSION_TLS_1_2);
+
+ server_->SetFilter(MakeTlsFilter<TlsSessionIDEchoFilter>(client_));
+ ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
+
+ client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
+ server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
+}
+
+class TlsSessionIDInjectFilter : public TlsHandshakeFilter {
+ public:
+ TlsSessionIDInjectFilter(const std::shared_ptr<TlsAgent>& a)
+ : TlsHandshakeFilter(a, {kTlsHandshakeServerHello}) {}
+
+ protected:
+ virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
+ const DataBuffer& input,
+ DataBuffer* output) {
+ TlsParser parser(input);
+
+ // Skip version + random.
+ EXPECT_TRUE(parser.Skip(2 + 32));
+
+ *output = input;
+
+ // Inject a Session ID.
+ const uint8_t fake_sid[SSL3_SESSIONID_BYTES] = {0xff};
+ output->Write(parser.consumed(), sizeof(fake_sid), 1);
+ output->Splice(fake_sid, sizeof(fake_sid), parser.consumed() + 1, 0);
+
+ return CHANGE;
+ }
+};
+
+TEST_F(TlsConnectTest, TLS13NonCompatModeSessionID) {
+ ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
+
+ MakeTlsFilter<TlsSessionIDInjectFilter>(server_);
+ client_->ExpectSendAlert(kTlsAlertIllegalParameter);
+ server_->ExpectSendAlert(kTlsAlertBadRecordMac);
+ ConnectExpectFail();
+
+ client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
+ server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
+}
+
static const uint8_t kCannedCcs[] = {
kTlsChangeCipherSpecType,
SSL_LIBRARY_VERSION_TLS_1_2 >> 8,
diff --git a/security/nss/gtests/ssl_gtest/ssl_versionpolicy_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_versionpolicy_unittest.cc
index 7f3c4a8964..09d7801e9a 100644
--- a/security/nss/gtests/ssl_gtest/ssl_versionpolicy_unittest.cc
+++ b/security/nss/gtests/ssl_gtest/ssl_versionpolicy_unittest.cc
@@ -50,12 +50,12 @@ inline std::ostream& operator<<(std::ostream& stream,
class VersionRangeWithLabel {
public:
- VersionRangeWithLabel(const std::string& label, const SSLVersionRange& vr)
- : label_(label), vr_(vr) {}
- VersionRangeWithLabel(const std::string& label, uint16_t min, uint16_t max)
- : label_(label) {
- vr_.min = min;
- vr_.max = max;
+ VersionRangeWithLabel(const std::string& txt, const SSLVersionRange& vr)
+ : label_(txt), vr_(vr) {}
+ VersionRangeWithLabel(const std::string& txt, uint16_t start, uint16_t end)
+ : label_(txt) {
+ vr_.min = start;
+ vr_.max = end;
}
VersionRangeWithLabel(const std::string& label) : label_(label) {
vr_.min = vr_.max = SSL_LIBRARY_VERSION_NONE;
diff --git a/security/nss/gtests/ssl_gtest/test_io.cc b/security/nss/gtests/ssl_gtest/test_io.cc
index 7282178515..d76b3526c6 100644
--- a/security/nss/gtests/ssl_gtest/test_io.cc
+++ b/security/nss/gtests/ssl_gtest/test_io.cc
@@ -99,8 +99,8 @@ int32_t DummyPrSocket::Write(PRFileDesc *f, const void *buf, int32_t length) {
return -1;
}
- auto peer = peer_.lock();
- if (!peer) {
+ auto dst = peer_.lock();
+ if (!dst) {
PR_SetError(PR_IO_ERROR, 0);
return -1;
}
@@ -116,14 +116,14 @@ int32_t DummyPrSocket::Write(PRFileDesc *f, const void *buf, int32_t length) {
case PacketFilter::CHANGE:
LOG("Original packet: " << packet);
LOG("Filtered packet: " << filtered);
- peer->PacketReceived(filtered);
+ dst->PacketReceived(filtered);
break;
case PacketFilter::DROP:
LOG("Droppped packet: " << packet);
break;
case PacketFilter::KEEP:
LOGV("Packet: " << packet);
- peer->PacketReceived(packet);
+ dst->PacketReceived(packet);
break;
}
// libssl can't handle it if this reports something other than the length
diff --git a/security/nss/gtests/ssl_gtest/test_io.h b/security/nss/gtests/ssl_gtest/test_io.h
index dbeb6b9d4c..8327373ce5 100644
--- a/security/nss/gtests/ssl_gtest/test_io.h
+++ b/security/nss/gtests/ssl_gtest/test_io.h
@@ -59,9 +59,9 @@ class PacketFilter {
class DummyPrSocket : public DummyIOLayerMethods {
public:
- DummyPrSocket(const std::string& name, SSLProtocolVariant variant)
+ DummyPrSocket(const std::string& name, SSLProtocolVariant var)
: name_(name),
- variant_(variant),
+ variant_(var),
peer_(),
input_(),
filter_(nullptr),
@@ -73,7 +73,7 @@ class DummyPrSocket : public DummyIOLayerMethods {
ScopedPRFileDesc CreateFD();
std::weak_ptr<DummyPrSocket>& peer() { return peer_; }
- void SetPeer(const std::shared_ptr<DummyPrSocket>& peer) { peer_ = peer; }
+ void SetPeer(const std::shared_ptr<DummyPrSocket>& p) { peer_ = p; }
void SetPacketFilter(const std::shared_ptr<PacketFilter>& filter) {
filter_ = filter;
}
diff --git a/security/nss/gtests/ssl_gtest/tls_agent.cc b/security/nss/gtests/ssl_gtest/tls_agent.cc
index 2f71caedb0..9bed1ce1b7 100644
--- a/security/nss/gtests/ssl_gtest/tls_agent.cc
+++ b/security/nss/gtests/ssl_gtest/tls_agent.cc
@@ -33,6 +33,7 @@ const char* TlsAgent::states[] = {"INIT", "CONNECTING", "CONNECTED", "ERROR"};
const std::string TlsAgent::kClient = "client"; // both sign and encrypt
const std::string TlsAgent::kRsa2048 = "rsa2048"; // bigger
+const std::string TlsAgent::kRsa8192 = "rsa8192"; // biggest allowed
const std::string TlsAgent::kServerRsa = "rsa"; // both sign and encrypt
const std::string TlsAgent::kServerRsaSign = "rsa_sign";
const std::string TlsAgent::kServerRsaPss = "rsa_pss";
@@ -44,13 +45,22 @@ const std::string TlsAgent::kServerEcdhRsa = "ecdh_rsa";
const std::string TlsAgent::kServerEcdhEcdsa = "ecdh_ecdsa";
const std::string TlsAgent::kServerDsa = "dsa";
-TlsAgent::TlsAgent(const std::string& name, Role role,
- SSLProtocolVariant variant)
- : name_(name),
- variant_(variant),
- role_(role),
+static const uint8_t kCannedTls13ServerHello[] = {
+ 0x03, 0x03, 0x9c, 0xbc, 0x14, 0x9b, 0x0e, 0x2e, 0xfa, 0x0d, 0xf3,
+ 0xf0, 0x5c, 0x70, 0x7a, 0xe0, 0xd1, 0x9b, 0x3e, 0x5a, 0x44, 0x6b,
+ 0xdf, 0xe5, 0xc2, 0x28, 0x64, 0xf7, 0x00, 0xc1, 0x9c, 0x08, 0x76,
+ 0x08, 0x00, 0x13, 0x01, 0x00, 0x00, 0x2e, 0x00, 0x33, 0x00, 0x24,
+ 0x00, 0x1d, 0x00, 0x20, 0xc2, 0xcf, 0x23, 0x17, 0x64, 0x23, 0x03,
+ 0xf0, 0xfb, 0x45, 0x98, 0x26, 0xd1, 0x65, 0x24, 0xa1, 0x6c, 0xa9,
+ 0x80, 0x8f, 0x2c, 0xac, 0x0a, 0xea, 0x53, 0x3a, 0xcb, 0xe3, 0x08,
+ 0x84, 0xae, 0x19, 0x00, 0x2b, 0x00, 0x02, 0x7f, kD13};
+
+TlsAgent::TlsAgent(const std::string& nm, Role rl, SSLProtocolVariant var)
+ : name_(nm),
+ variant_(var),
+ role_(rl),
server_key_bits_(0),
- adapter_(new DummyPrSocket(role_str(), variant)),
+ adapter_(new DummyPrSocket(role_str(), var)),
ssl_fd_(nullptr),
state_(STATE_INIT),
timer_handle_(nullptr),
@@ -103,11 +113,11 @@ TlsAgent::~TlsAgent() {
}
}
-void TlsAgent::SetState(State state) {
- if (state_ == state) return;
+void TlsAgent::SetState(State s) {
+ if (state_ == s) return;
- LOG("Changing state from " << state_ << " to " << state);
- state_ = state;
+ LOG("Changing state from " << state_ << " to " << s);
+ state_ = s;
}
/*static*/ bool TlsAgent::LoadCertificate(const std::string& name,
@@ -124,11 +134,11 @@ void TlsAgent::SetState(State state) {
return true;
}
-bool TlsAgent::ConfigServerCert(const std::string& name, bool updateKeyBits,
+bool TlsAgent::ConfigServerCert(const std::string& id, bool updateKeyBits,
const SSLExtraServerCertData* serverCertData) {
ScopedCERTCertificate cert;
ScopedSECKEYPrivateKey priv;
- if (!TlsAgent::LoadCertificate(name, &cert, &priv)) {
+ if (!TlsAgent::LoadCertificate(id, &cert, &priv)) {
return false;
}
@@ -175,6 +185,10 @@ bool TlsAgent::EnsureTlsSetup(PRFileDesc* modelSocket) {
if (rv != SECSuccess) return false;
}
+ ScopedCERTCertList anchors(CERT_NewCertList());
+ rv = SSL_SetTrustAnchors(ssl_fd(), anchors.get());
+ if (rv != SECSuccess) return false;
+
if (role_ == SERVER) {
EXPECT_TRUE(ConfigServerCert(name_, true));
@@ -182,10 +196,6 @@ bool TlsAgent::EnsureTlsSetup(PRFileDesc* modelSocket) {
EXPECT_EQ(SECSuccess, rv);
if (rv != SECSuccess) return false;
- ScopedCERTCertList anchors(CERT_NewCertList());
- rv = SSL_SetTrustAnchors(ssl_fd(), anchors.get());
- if (rv != SECSuccess) return false;
-
rv = SSL_SetMaxEarlyDataSize(ssl_fd(), 1024);
EXPECT_EQ(SECSuccess, rv);
if (rv != SECSuccess) return false;
@@ -246,6 +256,17 @@ void TlsAgent::SetupClientAuth() {
reinterpret_cast<void*>(this)));
}
+void CheckCertReqAgainstDefaultCAs(const CERTDistNames* caNames) {
+ ScopedCERTDistNames expected(CERT_GetSSLCACerts(nullptr));
+
+ ASSERT_EQ(expected->nnames, caNames->nnames);
+
+ for (size_t i = 0; i < static_cast<size_t>(expected->nnames); ++i) {
+ EXPECT_EQ(SECEqual,
+ SECITEM_CompareItem(&(expected->names[i]), &(caNames->names[i])));
+ }
+}
+
SECStatus TlsAgent::GetClientAuthDataHook(void* self, PRFileDesc* fd,
CERTDistNames* caNames,
CERTCertificate** clientCert,
@@ -254,6 +275,9 @@ SECStatus TlsAgent::GetClientAuthDataHook(void* self, PRFileDesc* fd,
ScopedCERTCertificate peerCert(SSL_PeerCertificate(agent->ssl_fd()));
EXPECT_TRUE(peerCert) << "Client should be able to see the server cert";
+ // See bug 1457716
+ // CheckCertReqAgainstDefaultCAs(caNames);
+
ScopedCERTCertificate cert;
ScopedSECKEYPrivateKey priv;
if (!TlsAgent::LoadCertificate(agent->name(), &cert, &priv)) {
@@ -282,8 +306,8 @@ bool TlsAgent::GetPeerChainLength(size_t* count) {
return true;
}
-void TlsAgent::CheckCipherSuite(uint16_t cipher_suite) {
- EXPECT_EQ(csinfo_.cipherSuite, cipher_suite);
+void TlsAgent::CheckCipherSuite(uint16_t suite) {
+ EXPECT_EQ(csinfo_.cipherSuite, suite);
}
void TlsAgent::RequestClientAuth(bool requireAuth) {
@@ -442,9 +466,7 @@ void TlsAgent::GetVersionRange(uint16_t* minver, uint16_t* maxver) {
*maxver = vrange_.max;
}
-void TlsAgent::SetExpectedVersion(uint16_t version) {
- expected_version_ = version;
-}
+void TlsAgent::SetExpectedVersion(uint16_t ver) { expected_version_ = ver; }
void TlsAgent::SetServerKeyBits(uint16_t bits) { server_key_bits_ = bits; }
@@ -491,10 +513,10 @@ void TlsAgent::SetSignatureSchemes(const SSLSignatureScheme* schemes,
EXPECT_EQ(i, configuredCount) << "schemes in use were all set";
}
-void TlsAgent::CheckKEA(SSLKEAType kea_type, SSLNamedGroup kea_group,
+void TlsAgent::CheckKEA(SSLKEAType kea, SSLNamedGroup kea_group,
size_t kea_size) const {
EXPECT_EQ(STATE_CONNECTED, state_);
- EXPECT_EQ(kea_type, info_.keaType);
+ EXPECT_EQ(kea, info_.keaType);
if (kea_size == 0) {
switch (kea_group) {
case ssl_grp_ec_curve25519:
@@ -515,7 +537,7 @@ void TlsAgent::CheckKEA(SSLKEAType kea_type, SSLNamedGroup kea_group,
case ssl_grp_ffdhe_custom:
break;
default:
- if (kea_type == ssl_kea_rsa) {
+ if (kea == ssl_kea_rsa) {
kea_size = server_key_bits_;
} else {
EXPECT_TRUE(false) << "need to update group sizes";
@@ -534,13 +556,13 @@ void TlsAgent::CheckOriginalKEA(SSLNamedGroup kea_group) const {
}
}
-void TlsAgent::CheckAuthType(SSLAuthType auth_type,
+void TlsAgent::CheckAuthType(SSLAuthType auth,
SSLSignatureScheme sig_scheme) const {
EXPECT_EQ(STATE_CONNECTED, state_);
- EXPECT_EQ(auth_type, info_.authType);
+ EXPECT_EQ(auth, info_.authType);
EXPECT_EQ(server_key_bits_, info_.authKeyBits);
if (expected_version_ < SSL_LIBRARY_VERSION_TLS_1_2) {
- switch (auth_type) {
+ switch (auth) {
case ssl_auth_rsa_sign:
sig_scheme = ssl_sig_rsa_pkcs1_sha1md5;
break;
@@ -558,9 +580,8 @@ void TlsAgent::CheckAuthType(SSLAuthType auth_type,
}
// Check authAlgorithm, which is the old value for authType. This is a second
- // switch
- // statement because default label is different.
- switch (auth_type) {
+ // switch statement because default label is different.
+ switch (auth) {
case ssl_auth_rsa_sign:
EXPECT_EQ(ssl_auth_rsa_decrypt, csinfo_.authAlgorithm)
<< "authAlgorithm for RSA is always decrypt";
@@ -574,7 +595,7 @@ void TlsAgent::CheckAuthType(SSLAuthType auth_type,
<< "authAlgorithm for ECDH_ECDSA is ECDSA (i.e., wrong)";
break;
default:
- EXPECT_EQ(auth_type, csinfo_.authAlgorithm)
+ EXPECT_EQ(auth, csinfo_.authAlgorithm)
<< "authAlgorithm is (usually) the same as authType";
break;
}
@@ -593,22 +614,20 @@ void TlsAgent::ExpectResumption() { expect_resumption_ = true; }
void TlsAgent::EnableAlpn(const uint8_t* val, size_t len) {
EXPECT_TRUE(EnsureTlsSetup());
-
- SetOption(SSL_ENABLE_ALPN, PR_TRUE);
EXPECT_EQ(SECSuccess, SSL_SetNextProtoNego(ssl_fd(), val, len));
}
void TlsAgent::CheckAlpn(SSLNextProtoState expected_state,
const std::string& expected) const {
- SSLNextProtoState state;
+ SSLNextProtoState alpn_state;
char chosen[10];
unsigned int chosen_len;
- SECStatus rv = SSL_GetNextProto(ssl_fd(), &state,
+ SECStatus rv = SSL_GetNextProto(ssl_fd(), &alpn_state,
reinterpret_cast<unsigned char*>(chosen),
&chosen_len, sizeof(chosen));
EXPECT_EQ(SECSuccess, rv);
- EXPECT_EQ(expected_state, state);
- if (state == SSL_NEXT_PROTO_NO_SUPPORT) {
+ EXPECT_EQ(expected_state, alpn_state);
+ if (alpn_state == SSL_NEXT_PROTO_NO_SUPPORT) {
EXPECT_EQ("", expected);
} else {
EXPECT_NE("", expected);
@@ -840,10 +859,10 @@ void TlsAgent::CheckSecretsDestroyed() {
ASSERT_EQ(PR_TRUE, SSLInt_CheckSecretsDestroyed(ssl_fd()));
}
-void TlsAgent::SetDowngradeCheckVersion(uint16_t version) {
+void TlsAgent::SetDowngradeCheckVersion(uint16_t ver) {
ASSERT_TRUE(EnsureTlsSetup());
- SECStatus rv = SSL_SetDowngradeCheckVersion(ssl_fd(), version);
+ SECStatus rv = SSL_SetDowngradeCheckVersion(ssl_fd(), ver);
ASSERT_EQ(SECSuccess, rv);
}
@@ -920,9 +939,9 @@ static bool ErrorIsNonFatal(PRErrorCode code) {
}
void TlsAgent::SendData(size_t bytes, size_t blocksize) {
- uint8_t block[4096];
+ uint8_t block[16385]; // One larger than the maximum record size.
- ASSERT_LT(blocksize, sizeof(block));
+ ASSERT_LE(blocksize, sizeof(block));
while (bytes) {
size_t tosend = std::min(blocksize, bytes);
@@ -951,12 +970,13 @@ void TlsAgent::SendBuffer(const DataBuffer& buf) {
}
bool TlsAgent::SendEncryptedRecord(const std::shared_ptr<TlsCipherSpec>& spec,
- uint16_t wireVersion, uint64_t seq,
- uint8_t ct, const DataBuffer& buf) {
- LOGV("Writing " << buf.len() << " bytes");
- // Ensure we are a TLS 1.3 cipher agent.
+ uint64_t seq, uint8_t ct,
+ const DataBuffer& buf) {
+ LOGV("Encrypting " << buf.len() << " bytes");
+ // Ensure that we are doing TLS 1.3.
EXPECT_GE(expected_version_, SSL_LIBRARY_VERSION_TLS_1_3);
- TlsRecordHeader header(wireVersion, kTlsApplicationDataType, seq);
+ TlsRecordHeader header(variant_, expected_version_, kTlsApplicationDataType,
+ seq);
DataBuffer padded = buf;
padded.Write(padded.len(), ct, 1);
DataBuffer ciphertext;
@@ -1078,15 +1098,20 @@ void TlsAgentTestBase::ProcessMessage(const DataBuffer& buffer,
void TlsAgentTestBase::MakeRecord(SSLProtocolVariant variant, uint8_t type,
uint16_t version, const uint8_t* buf,
size_t len, DataBuffer* out,
- uint64_t seq_num) {
+ uint64_t sequence_number) {
size_t index = 0;
index = out->Write(index, type, 1);
if (variant == ssl_variant_stream) {
index = out->Write(index, version, 2);
+ } else if (version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
+ type == kTlsApplicationDataType) {
+ uint32_t epoch = (sequence_number >> 48) & 0x3;
+ uint32_t seqno = sequence_number & ((1ULL << 30) - 1);
+ index = out->Write(index, (epoch << 30) | seqno, 4);
} else {
index = out->Write(index, TlsVersionToDtlsVersion(version), 2);
- index = out->Write(index, seq_num >> 32, 4);
- index = out->Write(index, seq_num & PR_UINT32_MAX, 4);
+ index = out->Write(index, sequence_number >> 32, 4);
+ index = out->Write(index, sequence_number & PR_UINT32_MAX, 4);
}
index = out->Write(index, len, 2);
out->Write(index, buf, len);
@@ -1144,4 +1169,12 @@ void TlsAgentTestBase::MakeTrivialHandshakeRecord(uint8_t hs_type,
}
}
+DataBuffer TlsAgentTestBase::MakeCannedTls13ServerHello() {
+ DataBuffer sh(kCannedTls13ServerHello, sizeof(kCannedTls13ServerHello));
+ if (variant_ == ssl_variant_datagram) {
+ sh.Write(0, SSL_LIBRARY_VERSION_DTLS_1_2_WIRE, 2);
+ }
+ return sh;
+}
+
} // namespace nss_test
diff --git a/security/nss/gtests/ssl_gtest/tls_agent.h b/security/nss/gtests/ssl_gtest/tls_agent.h
index 6cd6d5073b..a93d0c6ee5 100644
--- a/security/nss/gtests/ssl_gtest/tls_agent.h
+++ b/security/nss/gtests/ssl_gtest/tls_agent.h
@@ -10,6 +10,9 @@
#include "prio.h"
#include "ssl.h"
+// This is an internal header, used to get TLS_1_3_DRAFT_VERSION.
+#include "ssl3prot.h"
+
#include <functional>
#include <iostream>
@@ -57,6 +60,8 @@ typedef std::function<int32_t(TlsAgent* agent, const SECItem* srvNameArr,
PRUint32 srvNameArrSize)>
SniCallbackFunction;
+static const uint8_t kD13 = TLS_1_3_DRAFT_VERSION;
+
class TlsAgent : public PollTarget {
public:
enum Role { CLIENT, SERVER };
@@ -64,6 +69,7 @@ class TlsAgent : public PollTarget {
static const std::string kClient; // the client key is sign only
static const std::string kRsa2048; // bigger sign and encrypt for either
+ static const std::string kRsa8192; // biggest sign and encrypt for either
static const std::string kServerRsa; // both sign and encrypt
static const std::string kServerRsaSign;
static const std::string kServerRsaPss;
@@ -143,8 +149,7 @@ class TlsAgent : public PollTarget {
void SendData(size_t bytes, size_t blocksize = 1024);
void SendBuffer(const DataBuffer& buf);
bool SendEncryptedRecord(const std::shared_ptr<TlsCipherSpec>& spec,
- uint16_t wireVersion, uint64_t seq, uint8_t ct,
- const DataBuffer& buf);
+ uint64_t seq, uint8_t ct, const DataBuffer& buf);
// Send data directly to the underlying socket, skipping the TLS layer.
void SendDirect(const DataBuffer& buf);
void SendRecordDirect(const TlsRecord& record);
@@ -209,10 +214,10 @@ class TlsAgent : public PollTarget {
return info_.protocolVersion;
}
- bool cipher_suite(uint16_t* cipher_suite) const {
+ bool cipher_suite(uint16_t* suite) const {
if (state_ != STATE_CONNECTED) return false;
- *cipher_suite = info_.cipherSuite;
+ *suite = info_.cipherSuite;
return true;
}
@@ -227,17 +232,17 @@ class TlsAgent : public PollTarget {
info_.sessionID + info_.sessionIDLength);
}
- bool auth_type(SSLAuthType* auth_type) const {
+ bool auth_type(SSLAuthType* a) const {
if (state_ != STATE_CONNECTED) return false;
- *auth_type = info_.authType;
+ *a = info_.authType;
return true;
}
- bool kea_type(SSLKEAType* kea_type) const {
+ bool kea_type(SSLKEAType* k) const {
if (state_ != STATE_CONNECTED) return false;
- *kea_type = info_.keaType;
+ *k = info_.keaType;
return true;
}
@@ -264,6 +269,8 @@ class TlsAgent : public PollTarget {
void ExpectReceiveAlert(uint8_t alert, uint8_t level = 0);
void ExpectSendAlert(uint8_t alert, uint8_t level = 0);
+ std::string alpn_value_to_use_ = "";
+
private:
const static char* states[];
@@ -443,6 +450,7 @@ class TlsAgentTestBase : public ::testing::Test {
size_t hs_len, DataBuffer* out,
uint64_t seq_num, uint32_t fragment_offset,
uint32_t fragment_length) const;
+ DataBuffer MakeCannedTls13ServerHello();
static void MakeTrivialHandshakeRecord(uint8_t hs_type, size_t hs_len,
DataBuffer* out);
static inline TlsAgent::Role ToRole(const std::string& str) {
diff --git a/security/nss/gtests/ssl_gtest/tls_connect.cc b/security/nss/gtests/ssl_gtest/tls_connect.cc
index 8567b392fd..68f6d21e9c 100644
--- a/security/nss/gtests/ssl_gtest/tls_connect.cc
+++ b/security/nss/gtests/ssl_gtest/tls_connect.cc
@@ -571,14 +571,57 @@ void TlsConnectTestBase::CheckResumption(SessionResumptionMode expected) {
}
}
+static SECStatus NextProtoCallbackServer(void* arg, PRFileDesc* fd,
+ const unsigned char* protos,
+ unsigned int protos_len,
+ unsigned char* protoOut,
+ unsigned int* protoOutLen,
+ unsigned int protoMaxLen) {
+ EXPECT_EQ(protoMaxLen, 255U);
+ TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
+ // Check that agent->alpn_value_to_use_ is in protos.
+ if (protos_len < 1) {
+ return SECFailure;
+ }
+ for (size_t i = 0; i < protos_len;) {
+ size_t l = protos[i];
+ EXPECT_LT(i + l, protos_len);
+ if (i + l >= protos_len) {
+ return SECFailure;
+ }
+ std::string protos_s(reinterpret_cast<const char*>(protos + i + 1), l);
+ if (protos_s == agent->alpn_value_to_use_) {
+ size_t s_len = agent->alpn_value_to_use_.size();
+ EXPECT_LE(s_len, 255U);
+ memcpy(protoOut, &agent->alpn_value_to_use_[0], s_len);
+ *protoOutLen = s_len;
+ return SECSuccess;
+ }
+ i += l + 1;
+ }
+ return SECFailure;
+}
+
void TlsConnectTestBase::EnableAlpn() {
client_->EnableAlpn(alpn_dummy_val_, sizeof(alpn_dummy_val_));
server_->EnableAlpn(alpn_dummy_val_, sizeof(alpn_dummy_val_));
}
-void TlsConnectTestBase::EnableAlpn(const uint8_t* val, size_t len) {
- client_->EnableAlpn(val, len);
- server_->EnableAlpn(val, len);
+void TlsConnectTestBase::EnableAlpnWithCallback(
+ const std::vector<uint8_t>& client_vals, std::string server_choice) {
+ EnsureTlsSetup();
+ server_->alpn_value_to_use_ = server_choice;
+ EXPECT_EQ(SECSuccess,
+ SSL_SetNextProtoNego(client_->ssl_fd(), client_vals.data(),
+ client_vals.size()));
+ SECStatus rv = SSL_SetNextProtoCallback(
+ server_->ssl_fd(), NextProtoCallbackServer, server_.get());
+ EXPECT_EQ(SECSuccess, rv);
+}
+
+void TlsConnectTestBase::EnableAlpn(const std::vector<uint8_t>& vals) {
+ client_->EnableAlpn(vals.data(), vals.size());
+ server_->EnableAlpn(vals.data(), vals.size());
}
void TlsConnectTestBase::EnsureModelSockets() {
diff --git a/security/nss/gtests/ssl_gtest/tls_connect.h b/security/nss/gtests/ssl_gtest/tls_connect.h
index 7dffe7f8aa..0004945011 100644
--- a/security/nss/gtests/ssl_gtest/tls_connect.h
+++ b/security/nss/gtests/ssl_gtest/tls_connect.h
@@ -110,7 +110,9 @@ class TlsConnectTestBase : public ::testing::Test {
void ConfigureSessionCache(SessionResumptionMode client,
SessionResumptionMode server);
void EnableAlpn();
- void EnableAlpn(const uint8_t* val, size_t len);
+ void EnableAlpnWithCallback(const std::vector<uint8_t>& client,
+ std::string server_choice);
+ void EnableAlpn(const std::vector<uint8_t>& vals);
void EnsureModelSockets();
void CheckAlpn(const std::string& val);
void EnableSrtp();
diff --git a/security/nss/gtests/ssl_gtest/tls_filter.cc b/security/nss/gtests/ssl_gtest/tls_filter.cc
index d34b13bcb5..aa03cba70b 100644
--- a/security/nss/gtests/ssl_gtest/tls_filter.cc
+++ b/security/nss/gtests/ssl_gtest/tls_filter.cc
@@ -30,11 +30,9 @@ void TlsVersioned::WriteStream(std::ostream& stream) const {
case SSL_LIBRARY_VERSION_TLS_1_0:
stream << "1.0";
break;
- case SSL_LIBRARY_VERSION_DTLS_1_0_WIRE:
case SSL_LIBRARY_VERSION_TLS_1_1:
stream << (is_dtls() ? "1.0" : "1.1");
break;
- case SSL_LIBRARY_VERSION_DTLS_1_2_WIRE:
case SSL_LIBRARY_VERSION_TLS_1_2:
stream << "1.2";
break;
@@ -67,8 +65,14 @@ void TlsRecordFilter::CipherSpecChanged(void* arg, PRBool sending,
return;
}
- self->in_sequence_number_ = 0;
- self->out_sequence_number_ = 0;
+ uint64_t seq_no;
+ if (self->agent()->variant() == ssl_variant_datagram) {
+ seq_no = static_cast<uint64_t>(SSLInt_CipherSpecToEpoch(newSpec)) << 48;
+ } else {
+ seq_no = 0;
+ }
+ self->in_sequence_number_ = seq_no;
+ self->out_sequence_number_ = seq_no;
self->dropped_record_ = false;
self->cipher_spec_.reset(new TlsCipherSpec());
bool ret = self->cipher_spec_->Init(
@@ -77,33 +81,59 @@ void TlsRecordFilter::CipherSpecChanged(void* arg, PRBool sending,
EXPECT_EQ(true, ret);
}
+bool TlsRecordFilter::is_dtls13() const {
+ if (agent()->variant() != ssl_variant_datagram) {
+ return false;
+ }
+ if (agent()->state() == TlsAgent::STATE_CONNECTED) {
+ return agent()->version() >= SSL_LIBRARY_VERSION_TLS_1_3;
+ }
+ SSLPreliminaryChannelInfo info;
+ EXPECT_EQ(SECSuccess, SSL_GetPreliminaryChannelInfo(agent()->ssl_fd(), &info,
+ sizeof(info)));
+ return (info.protocolVersion >= SSL_LIBRARY_VERSION_TLS_1_3) ||
+ info.canSendEarlyData;
+}
+
PacketFilter::Action TlsRecordFilter::Filter(const DataBuffer& input,
DataBuffer* output) {
+ // Disable during shutdown.
+ if (!agent()) {
+ return KEEP;
+ }
+
bool changed = false;
size_t offset = 0U;
- output->Allocate(input.len());
+ output->Allocate(input.len());
TlsParser parser(input);
while (parser.remaining()) {
TlsRecordHeader header;
DataBuffer record;
- if (!header.Parse(in_sequence_number_, &parser, &record)) {
+ if (!header.Parse(is_dtls13(), in_sequence_number_, &parser, &record)) {
ADD_FAILURE() << "not a valid record";
return KEEP;
}
- // Track the sequence number, which is necessary for stream mode (the
- // sequence number is in the header for datagram).
+ // Track the sequence number, which is necessary for stream mode when
+ // decrypting and for TLS 1.3 datagram to recover the sequence number.
+ //
+ // We reset the counter when the cipher spec changes, but that notification
+ // appears before a record is sent. If multiple records are sent with
+ // different cipher specs, this would fail. This filters out cleartext
+ // records, so we don't get confused by handshake messages that are sent at
+ // the same time as encrypted records. Sequence numbers are therefore
+ // likely to be incorrect for cleartext records.
//
- // This isn't perfectly robust. If there is a change from an active cipher
+ // This isn't perfectly robust: if there is a change from an active cipher
// spec to another active cipher spec (KeyUpdate for instance) AND writes
- // are consolidated across that change AND packets were dropped from the
- // older epoch, we will not correctly re-encrypt records in the old epoch to
- // update their sequence numbers.
- if (cipher_spec_ && header.content_type() == kTlsApplicationDataType) {
- ++in_sequence_number_;
+ // are consolidated across that change, this code could use the wrong
+ // sequence numbers when re-encrypting records with the old keys.
+ if (header.content_type() == kTlsApplicationDataType) {
+ in_sequence_number_ =
+ (std::max)(in_sequence_number_, header.sequence_number() + 1);
}
if (FilterRecord(header, record, &offset, output) != KEEP) {
@@ -131,11 +161,14 @@ PacketFilter::Action TlsRecordFilter::FilterRecord(
DataBuffer plaintext;
if (!Unprotect(header, record, &inner_content_type, &plaintext)) {
+ if (g_ssl_gtest_verbose) {
+ std::cerr << "unprotect failed: " << header << ":" << record << std::endl;
+ }
return KEEP;
}
- TlsRecordHeader real_header = {header.version(), inner_content_type,
- header.sequence_number()};
+ TlsRecordHeader real_header(header.variant(), header.version(),
+ inner_content_type, header.sequence_number());
PacketFilter::Action action = FilterRecord(real_header, plaintext, &filtered);
// In stream mode, even if something doesn't change we need to re-encrypt if
@@ -166,8 +199,8 @@ PacketFilter::Action TlsRecordFilter::FilterRecord(
} else {
seq_num = out_sequence_number_++;
}
- TlsRecordHeader out_header = {header.version(), header.content_type(),
- seq_num};
+ TlsRecordHeader out_header(header.variant(), header.version(),
+ header.content_type(), seq_num);
DataBuffer ciphertext;
bool rv = Protect(out_header, inner_content_type, filtered, &ciphertext);
@@ -179,20 +212,119 @@ PacketFilter::Action TlsRecordFilter::FilterRecord(
return CHANGE;
}
-bool TlsRecordHeader::Parse(uint64_t sequence_number, TlsParser* parser,
+size_t TlsRecordHeader::header_length() const {
+ // If we have a header, return it's length.
+ if (header_.len()) {
+ return header_.len();
+ }
+
+ // Otherwise make a dummy header and return the length.
+ DataBuffer buf;
+ return WriteHeader(&buf, 0, 0);
+}
+
+uint64_t TlsRecordHeader::RecoverSequenceNumber(uint64_t expected,
+ uint32_t partial,
+ size_t partial_bits) {
+ EXPECT_GE(32U, partial_bits);
+ uint64_t mask = (1 << partial_bits) - 1;
+ // First we determine the highest possible value. This is half the
+ // expressible range above the expected value.
+ uint64_t cap = expected + (1ULL << (partial_bits - 1));
+ // Add the partial piece in. e.g., xxxx789a and 1234 becomes xxxx1234.
+ uint64_t seq_no = (cap & ~mask) | partial;
+ // If the partial value is higher than the same partial piece from the cap,
+ // then the real value has to be lower. e.g., xxxx1234 can't become xxxx5678.
+ if (partial > (cap & mask)) {
+ seq_no -= 1ULL << partial_bits;
+ }
+ return seq_no;
+}
+
+// Determine the full epoch and sequence number from an expected and raw value.
+// The expected and output values are packed as they are in DTLS 1.2 and
+// earlier: with 16 bits of epoch and 48 bits of sequence number.
+uint64_t TlsRecordHeader::ParseSequenceNumber(uint64_t expected, uint32_t raw,
+ size_t seq_no_bits,
+ size_t epoch_bits) {
+ uint64_t epoch_mask = (1ULL << epoch_bits) - 1;
+ uint64_t epoch = RecoverSequenceNumber(
+ expected >> 48, (raw >> seq_no_bits) & epoch_mask, epoch_bits);
+ if (epoch > (expected >> 48)) {
+ // If the epoch has changed, reset the expected sequence number.
+ expected = 0;
+ } else {
+ // Otherwise, retain just the sequence number part.
+ expected &= (1ULL << 48) - 1;
+ }
+ uint64_t seq_no_mask = (1ULL << seq_no_bits) - 1;
+ uint64_t seq_no =
+ RecoverSequenceNumber(expected, raw & seq_no_mask, seq_no_bits);
+ return (epoch << 48) | seq_no;
+}
+
+bool TlsRecordHeader::Parse(bool is_dtls13, uint64_t seqno, TlsParser* parser,
DataBuffer* body) {
+ auto mark = parser->consumed();
+
if (!parser->Read(&content_type_)) {
return false;
}
- uint32_t version;
- if (!parser->Read(&version, 2)) {
+ if (is_dtls13) {
+ variant_ = ssl_variant_datagram;
+ version_ = SSL_LIBRARY_VERSION_TLS_1_3;
+
+#ifndef UNSAFE_FUZZER_MODE
+ // Deal with the 7 octet header.
+ if (content_type_ == kTlsApplicationDataType) {
+ uint32_t tmp;
+ if (!parser->Read(&tmp, 4)) {
+ return false;
+ }
+ sequence_number_ = ParseSequenceNumber(seqno, tmp, 30, 2);
+ if (!parser->ReadFromMark(&header_, parser->consumed() + 2 - mark,
+ mark)) {
+ return false;
+ }
+ return parser->ReadVariable(body, 2);
+ }
+
+ // The short, 2 octet header.
+ if ((content_type_ & 0xe0) == 0x20) {
+ uint32_t tmp;
+ if (!parser->Read(&tmp, 1)) {
+ return false;
+ }
+ // Need to use the low 5 bits of the first octet too.
+ tmp |= (content_type_ & 0x1f) << 8;
+ content_type_ = kTlsApplicationDataType;
+ sequence_number_ = ParseSequenceNumber(seqno, tmp, 12, 1);
+
+ if (!parser->ReadFromMark(&header_, parser->consumed() - mark, mark)) {
+ return false;
+ }
+ return parser->Read(body, parser->remaining());
+ }
+
+ // The full 13 octet header can only be used for a few types.
+ EXPECT_TRUE(content_type_ == kTlsAlertType ||
+ content_type_ == kTlsHandshakeType ||
+ content_type_ == kTlsAckType);
+#endif
+ }
+
+ uint32_t ver;
+ if (!parser->Read(&ver, 2)) {
return false;
}
- version_ = version;
+ if (!is_dtls13) {
+ variant_ = IsDtls(ver) ? ssl_variant_datagram : ssl_variant_stream;
+ }
+ version_ = NormalizeTlsVersion(ver);
- // If this is DTLS, overwrite the sequence number.
- if (IsDtls(version)) {
+ if (is_dtls()) {
+ // If this is DTLS, read the sequence number.
uint32_t tmp;
if (!parser->Read(&tmp, 4)) {
return false;
@@ -203,21 +335,40 @@ bool TlsRecordHeader::Parse(uint64_t sequence_number, TlsParser* parser,
}
sequence_number_ |= static_cast<uint64_t>(tmp);
} else {
- sequence_number_ = sequence_number;
+ sequence_number_ = seqno;
+ }
+ if (!parser->ReadFromMark(&header_, parser->consumed() + 2 - mark, mark)) {
+ return false;
}
return parser->ReadVariable(body, 2);
}
-size_t TlsRecordHeader::Write(DataBuffer* buffer, size_t offset,
- const DataBuffer& body) const {
+size_t TlsRecordHeader::WriteHeader(DataBuffer* buffer, size_t offset,
+ size_t body_len) const {
offset = buffer->Write(offset, content_type_, 1);
- offset = buffer->Write(offset, version_, 2);
- if (is_dtls()) {
- // write epoch (2 octet), and seqnum (6 octet)
- offset = buffer->Write(offset, sequence_number_ >> 32, 4);
- offset = buffer->Write(offset, sequence_number_ & 0xffffffff, 4);
+ if (is_dtls() && version_ >= SSL_LIBRARY_VERSION_TLS_1_3 &&
+ content_type() == kTlsApplicationDataType) {
+ // application_data records in TLS 1.3 have a different header format.
+ // Always use the long header here for simplicity.
+ uint32_t e = (sequence_number_ >> 48) & 0x3;
+ uint32_t seqno = sequence_number_ & ((1ULL << 30) - 1);
+ offset = buffer->Write(offset, (e << 30) | seqno, 4);
+ } else {
+ uint16_t v = is_dtls() ? TlsVersionToDtlsVersion(version_) : version_;
+ offset = buffer->Write(offset, v, 2);
+ if (is_dtls()) {
+ // write epoch (2 octet), and seqnum (6 octet)
+ offset = buffer->Write(offset, sequence_number_ >> 32, 4);
+ offset = buffer->Write(offset, sequence_number_ & 0xffffffff, 4);
+ }
}
- offset = buffer->Write(offset, body.len(), 2);
+ offset = buffer->Write(offset, body_len, 2);
+ return offset;
+}
+
+size_t TlsRecordHeader::Write(DataBuffer* buffer, size_t offset,
+ const DataBuffer& body) const {
+ offset = WriteHeader(buffer, offset, body.len());
offset = buffer->Write(offset, body);
return offset;
}
@@ -259,7 +410,7 @@ bool TlsRecordFilter::Unprotect(const TlsRecordHeader& header,
bool TlsRecordFilter::Protect(const TlsRecordHeader& header,
uint8_t inner_content_type,
const DataBuffer& plaintext,
- DataBuffer* ciphertext) {
+ DataBuffer* ciphertext, size_t padding) {
if (!cipher_spec_ || header.content_type() != kTlsApplicationDataType) {
*ciphertext = plaintext;
return true;
@@ -267,8 +418,10 @@ bool TlsRecordFilter::Protect(const TlsRecordHeader& header,
if (g_ssl_gtest_verbose) {
std::cerr << "protect: " << header.sequence_number() << std::endl;
}
- DataBuffer padded = plaintext;
- padded.Write(padded.len(), inner_content_type, 1);
+ DataBuffer padded;
+ padded.Allocate(plaintext.len() + 1 + padding);
+ size_t offset = padded.Write(0, plaintext.data(), plaintext.len());
+ padded.Write(offset, inner_content_type, 1);
return cipher_spec_->Protect(header, padded, ciphertext);
}
@@ -406,6 +559,7 @@ bool TlsHandshakeFilter::HandshakeHeader::Parse(
const DataBuffer& preceding_fragment, DataBuffer* body, bool* complete) {
*complete = false;
+ variant_ = record_header.variant();
version_ = record_header.version();
if (!parser->Read(&handshake_type_)) {
return false; // malformed
@@ -487,10 +641,10 @@ PacketFilter::Action TlsConversationRecorder::FilterRecord(
return KEEP;
}
-PacketFilter::Action TlsHeaderRecorder::FilterRecord(
- const TlsRecordHeader& header, const DataBuffer& input,
- DataBuffer* output) {
- headers_.push_back(header);
+PacketFilter::Action TlsHeaderRecorder::FilterRecord(const TlsRecordHeader& hdr,
+ const DataBuffer& input,
+ DataBuffer* output) {
+ headers_.push_back(hdr);
return KEEP;
}
diff --git a/security/nss/gtests/ssl_gtest/tls_filter.h b/security/nss/gtests/ssl_gtest/tls_filter.h
index 1bbe190abe..effda4aa06 100644
--- a/security/nss/gtests/ssl_gtest/tls_filter.h
+++ b/security/nss/gtests/ssl_gtest/tls_filter.h
@@ -11,7 +11,7 @@
#include <memory>
#include <set>
#include <vector>
-
+#include "sslt.h"
#include "test_io.h"
#include "tls_agent.h"
#include "tls_parser.h"
@@ -27,43 +27,57 @@ class TlsCipherSpec;
class TlsVersioned {
public:
- TlsVersioned() : version_(0) {}
- explicit TlsVersioned(uint16_t version) : version_(version) {}
+ TlsVersioned() : variant_(ssl_variant_stream), version_(0) {}
+ TlsVersioned(SSLProtocolVariant var, uint16_t ver)
+ : variant_(var), version_(ver) {}
- bool is_dtls() const { return IsDtls(version_); }
+ bool is_dtls() const { return variant_ == ssl_variant_datagram; }
+ SSLProtocolVariant variant() const { return variant_; }
uint16_t version() const { return version_; }
void WriteStream(std::ostream& stream) const;
protected:
+ SSLProtocolVariant variant_;
uint16_t version_;
};
class TlsRecordHeader : public TlsVersioned {
public:
- TlsRecordHeader() : TlsVersioned(), content_type_(0), sequence_number_(0) {}
- TlsRecordHeader(uint16_t version, uint8_t content_type,
- uint64_t sequence_number)
- : TlsVersioned(version),
- content_type_(content_type),
- sequence_number_(sequence_number) {}
+ TlsRecordHeader()
+ : TlsVersioned(), content_type_(0), sequence_number_(0), header_() {}
+ TlsRecordHeader(SSLProtocolVariant var, uint16_t ver, uint8_t ct,
+ uint64_t seqno)
+ : TlsVersioned(var, ver),
+ content_type_(ct),
+ sequence_number_(seqno),
+ header_() {}
uint8_t content_type() const { return content_type_; }
uint64_t sequence_number() const { return sequence_number_; }
uint16_t epoch() const {
return static_cast<uint16_t>(sequence_number_ >> 48);
}
- size_t header_length() const { return is_dtls() ? 13 : 5; }
+ size_t header_length() const;
+ const DataBuffer& header() const { return header_; }
// Parse the header; return true if successful; body in an outparam if OK.
- bool Parse(uint64_t sequence_number, TlsParser* parser, DataBuffer* body);
+ bool Parse(bool is_dtls13, uint64_t sequence_number, TlsParser* parser,
+ DataBuffer* body);
// Write the header and body to a buffer at the given offset.
// Return the offset of the end of the write.
size_t Write(DataBuffer* buffer, size_t offset, const DataBuffer& body) const;
+ size_t WriteHeader(DataBuffer* buffer, size_t offset, size_t body_len) const;
private:
+ static uint64_t RecoverSequenceNumber(uint64_t expected, uint32_t partial,
+ size_t partial_bits);
+ static uint64_t ParseSequenceNumber(uint64_t expected, uint32_t raw,
+ size_t seq_no_bits, size_t epoch_bits);
+
uint8_t content_type_;
uint64_t sequence_number_;
+ DataBuffer header_;
};
struct TlsRecord {
@@ -83,8 +97,8 @@ inline std::shared_ptr<T> MakeTlsFilter(const std::shared_ptr<TlsAgent>& agent,
// Abstract filter that operates on entire (D)TLS records.
class TlsRecordFilter : public PacketFilter {
public:
- TlsRecordFilter(const std::shared_ptr<TlsAgent>& agent)
- : agent_(agent),
+ TlsRecordFilter(const std::shared_ptr<TlsAgent>& a)
+ : agent_(a),
count_(0),
cipher_spec_(),
dropped_record_(false),
@@ -106,7 +120,8 @@ class TlsRecordFilter : public PacketFilter {
bool Unprotect(const TlsRecordHeader& header, const DataBuffer& cipherText,
uint8_t* inner_content_type, DataBuffer* plaintext);
bool Protect(const TlsRecordHeader& header, uint8_t inner_content_type,
- const DataBuffer& plaintext, DataBuffer* ciphertext);
+ const DataBuffer& plaintext, DataBuffer* ciphertext,
+ size_t padding = 0);
protected:
// There are two filter functions which can be overriden. Both are
@@ -130,6 +145,8 @@ class TlsRecordFilter : public PacketFilter {
return KEEP;
}
+ bool is_dtls13() const;
+
private:
static void CipherSpecChanged(void* arg, PRBool sending,
ssl3CipherSpec* newSpec);
@@ -183,13 +200,11 @@ inline std::ostream& operator<<(std::ostream& stream,
// records and that they don't span records or anything crazy like that.
class TlsHandshakeFilter : public TlsRecordFilter {
public:
- TlsHandshakeFilter(const std::shared_ptr<TlsAgent>& agent)
- : TlsRecordFilter(agent), handshake_types_(), preceding_fragment_() {}
- TlsHandshakeFilter(const std::shared_ptr<TlsAgent>& agent,
+ TlsHandshakeFilter(const std::shared_ptr<TlsAgent>& a)
+ : TlsRecordFilter(a), handshake_types_(), preceding_fragment_() {}
+ TlsHandshakeFilter(const std::shared_ptr<TlsAgent>& a,
const std::set<uint8_t>& types)
- : TlsRecordFilter(agent),
- handshake_types_(types),
- preceding_fragment_() {}
+ : TlsRecordFilter(a), handshake_types_(types), preceding_fragment_() {}
// This filter can be set to be selective based on handshake message type. If
// this function isn't used (or the set is empty), then all handshake messages
@@ -243,12 +258,12 @@ class TlsHandshakeFilter : public TlsRecordFilter {
// Make a copy of the first instance of a handshake message.
class TlsHandshakeRecorder : public TlsHandshakeFilter {
public:
- TlsHandshakeRecorder(const std::shared_ptr<TlsAgent>& agent,
+ TlsHandshakeRecorder(const std::shared_ptr<TlsAgent>& a,
uint8_t handshake_type)
- : TlsHandshakeFilter(agent, {handshake_type}), buffer_() {}
- TlsHandshakeRecorder(const std::shared_ptr<TlsAgent>& agent,
+ : TlsHandshakeFilter(a, {handshake_type}), buffer_() {}
+ TlsHandshakeRecorder(const std::shared_ptr<TlsAgent>& a,
const std::set<uint8_t>& handshake_types)
- : TlsHandshakeFilter(agent, handshake_types), buffer_() {}
+ : TlsHandshakeFilter(a, handshake_types), buffer_() {}
virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
const DataBuffer& input,
@@ -265,10 +280,10 @@ class TlsHandshakeRecorder : public TlsHandshakeFilter {
// Replace all instances of a handshake message.
class TlsInspectorReplaceHandshakeMessage : public TlsHandshakeFilter {
public:
- TlsInspectorReplaceHandshakeMessage(const std::shared_ptr<TlsAgent>& agent,
+ TlsInspectorReplaceHandshakeMessage(const std::shared_ptr<TlsAgent>& a,
uint8_t handshake_type,
const DataBuffer& replacement)
- : TlsHandshakeFilter(agent, {handshake_type}), buffer_(replacement) {}
+ : TlsHandshakeFilter(a, {handshake_type}), buffer_(replacement) {}
virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
const DataBuffer& input,
@@ -281,10 +296,10 @@ class TlsInspectorReplaceHandshakeMessage : public TlsHandshakeFilter {
// Make a copy of each record of a given type.
class TlsRecordRecorder : public TlsRecordFilter {
public:
- TlsRecordRecorder(const std::shared_ptr<TlsAgent>& agent, uint8_t ct)
- : TlsRecordFilter(agent), filter_(true), ct_(ct), records_() {}
- TlsRecordRecorder(const std::shared_ptr<TlsAgent>& agent)
- : TlsRecordFilter(agent),
+ TlsRecordRecorder(const std::shared_ptr<TlsAgent>& a, uint8_t ct)
+ : TlsRecordFilter(a), filter_(true), ct_(ct), records_() {}
+ TlsRecordRecorder(const std::shared_ptr<TlsAgent>& a)
+ : TlsRecordFilter(a),
filter_(false),
ct_(content_handshake), // dummy (<optional> is C++14)
records_() {}
@@ -306,9 +321,9 @@ class TlsRecordRecorder : public TlsRecordFilter {
// Make a copy of the complete conversation.
class TlsConversationRecorder : public TlsRecordFilter {
public:
- TlsConversationRecorder(const std::shared_ptr<TlsAgent>& agent,
+ TlsConversationRecorder(const std::shared_ptr<TlsAgent>& a,
DataBuffer& buffer)
- : TlsRecordFilter(agent), buffer_(buffer) {}
+ : TlsRecordFilter(a), buffer_(buffer) {}
virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
const DataBuffer& input,
@@ -321,8 +336,7 @@ class TlsConversationRecorder : public TlsRecordFilter {
// Make a copy of the records
class TlsHeaderRecorder : public TlsRecordFilter {
public:
- TlsHeaderRecorder(const std::shared_ptr<TlsAgent>& agent)
- : TlsRecordFilter(agent) {}
+ TlsHeaderRecorder(const std::shared_ptr<TlsAgent>& a) : TlsRecordFilter(a) {}
virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
const DataBuffer& input,
DataBuffer* output);
@@ -359,15 +373,15 @@ typedef std::function<bool(TlsParser* parser, const TlsVersioned& header)>
class TlsExtensionFilter : public TlsHandshakeFilter {
public:
- TlsExtensionFilter(const std::shared_ptr<TlsAgent>& agent)
- : TlsHandshakeFilter(agent,
+ TlsExtensionFilter(const std::shared_ptr<TlsAgent>& a)
+ : TlsHandshakeFilter(a,
{kTlsHandshakeClientHello, kTlsHandshakeServerHello,
kTlsHandshakeHelloRetryRequest,
kTlsHandshakeEncryptedExtensions}) {}
- TlsExtensionFilter(const std::shared_ptr<TlsAgent>& agent,
+ TlsExtensionFilter(const std::shared_ptr<TlsAgent>& a,
const std::set<uint8_t>& types)
- : TlsHandshakeFilter(agent, types) {}
+ : TlsHandshakeFilter(a, types) {}
static bool FindExtensions(TlsParser* parser, const HandshakeHeader& header);
@@ -388,9 +402,9 @@ class TlsExtensionFilter : public TlsHandshakeFilter {
class TlsExtensionCapture : public TlsExtensionFilter {
public:
- TlsExtensionCapture(const std::shared_ptr<TlsAgent>& agent, uint16_t ext,
+ TlsExtensionCapture(const std::shared_ptr<TlsAgent>& a, uint16_t ext,
bool last = false)
- : TlsExtensionFilter(agent),
+ : TlsExtensionFilter(a),
extension_(ext),
captured_(false),
last_(last),
@@ -413,9 +427,9 @@ class TlsExtensionCapture : public TlsExtensionFilter {
class TlsExtensionReplacer : public TlsExtensionFilter {
public:
- TlsExtensionReplacer(const std::shared_ptr<TlsAgent>& agent,
- uint16_t extension, const DataBuffer& data)
- : TlsExtensionFilter(agent), extension_(extension), data_(data) {}
+ TlsExtensionReplacer(const std::shared_ptr<TlsAgent>& a, uint16_t extension,
+ const DataBuffer& data)
+ : TlsExtensionFilter(a), extension_(extension), data_(data) {}
PacketFilter::Action FilterExtension(uint16_t extension_type,
const DataBuffer& input,
DataBuffer* output) override;
@@ -427,9 +441,8 @@ class TlsExtensionReplacer : public TlsExtensionFilter {
class TlsExtensionDropper : public TlsExtensionFilter {
public:
- TlsExtensionDropper(const std::shared_ptr<TlsAgent>& agent,
- uint16_t extension)
- : TlsExtensionFilter(agent), extension_(extension) {}
+ TlsExtensionDropper(const std::shared_ptr<TlsAgent>& a, uint16_t extension)
+ : TlsExtensionFilter(a), extension_(extension) {}
PacketFilter::Action FilterExtension(uint16_t extension_type,
const DataBuffer&, DataBuffer*) override;
@@ -439,9 +452,9 @@ class TlsExtensionDropper : public TlsExtensionFilter {
class TlsExtensionInjector : public TlsHandshakeFilter {
public:
- TlsExtensionInjector(const std::shared_ptr<TlsAgent>& agent, uint16_t ext,
+ TlsExtensionInjector(const std::shared_ptr<TlsAgent>& a, uint16_t ext,
const DataBuffer& data)
- : TlsHandshakeFilter(agent), extension_(ext), data_(data) {}
+ : TlsHandshakeFilter(a), extension_(ext), data_(data) {}
protected:
PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
@@ -453,7 +466,6 @@ class TlsExtensionInjector : public TlsHandshakeFilter {
const DataBuffer data_;
};
-class TlsAgent;
typedef std::function<void(void)> VoidFunction;
class AfterRecordN : public TlsRecordFilter {
@@ -495,6 +507,22 @@ class TlsClientHelloVersionChanger : public TlsHandshakeFilter {
std::weak_ptr<TlsAgent> server_;
};
+// Damage a record.
+class TlsRecordLastByteDamager : public TlsRecordFilter {
+ public:
+ TlsRecordLastByteDamager(const std::shared_ptr<TlsAgent>& a)
+ : TlsRecordFilter(a) {}
+
+ protected:
+ PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
+ const DataBuffer& data,
+ DataBuffer* changed) override {
+ *changed = data;
+ changed->data()[changed->len() - 1]++;
+ return CHANGE;
+ }
+};
+
// This class selectively drops complete writes. This relies on the fact that
// writes in libssl are on record boundaries.
class SelectiveDropFilter : public PacketFilter {
@@ -515,16 +543,16 @@ class SelectiveDropFilter : public PacketFilter {
// datagram, we just drop one.
class SelectiveRecordDropFilter : public TlsRecordFilter {
public:
- SelectiveRecordDropFilter(const std::shared_ptr<TlsAgent>& agent,
+ SelectiveRecordDropFilter(const std::shared_ptr<TlsAgent>& a,
uint32_t pattern, bool enabled = true)
- : TlsRecordFilter(agent), pattern_(pattern), counter_(0) {
+ : TlsRecordFilter(a), pattern_(pattern), counter_(0) {
if (!enabled) {
Disable();
}
}
- SelectiveRecordDropFilter(const std::shared_ptr<TlsAgent>& agent,
+ SelectiveRecordDropFilter(const std::shared_ptr<TlsAgent>& a,
std::initializer_list<size_t> records)
- : SelectiveRecordDropFilter(agent, ToPattern(records), true) {}
+ : SelectiveRecordDropFilter(a, ToPattern(records), true) {}
void Reset(uint32_t pattern) {
counter_ = 0;
@@ -551,10 +579,9 @@ class SelectiveRecordDropFilter : public TlsRecordFilter {
// Set the version number in the ClientHello.
class TlsClientHelloVersionSetter : public TlsHandshakeFilter {
public:
- TlsClientHelloVersionSetter(const std::shared_ptr<TlsAgent>& agent,
+ TlsClientHelloVersionSetter(const std::shared_ptr<TlsAgent>& a,
uint16_t version)
- : TlsHandshakeFilter(agent, {kTlsHandshakeClientHello}),
- version_(version) {}
+ : TlsHandshakeFilter(a, {kTlsHandshakeClientHello}), version_(version) {}
virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
const DataBuffer& input,
@@ -567,8 +594,8 @@ class TlsClientHelloVersionSetter : public TlsHandshakeFilter {
// Damages the last byte of a handshake message.
class TlsLastByteDamager : public TlsHandshakeFilter {
public:
- TlsLastByteDamager(const std::shared_ptr<TlsAgent>& agent, uint8_t type)
- : TlsHandshakeFilter(agent), type_(type) {}
+ TlsLastByteDamager(const std::shared_ptr<TlsAgent>& a, uint8_t type)
+ : TlsHandshakeFilter(a), type_(type) {}
PacketFilter::Action FilterHandshake(
const TlsHandshakeFilter::HandshakeHeader& header,
const DataBuffer& input, DataBuffer* output) override {
@@ -588,9 +615,9 @@ class TlsLastByteDamager : public TlsHandshakeFilter {
class SelectedCipherSuiteReplacer : public TlsHandshakeFilter {
public:
- SelectedCipherSuiteReplacer(const std::shared_ptr<TlsAgent>& agent,
+ SelectedCipherSuiteReplacer(const std::shared_ptr<TlsAgent>& a,
uint16_t suite)
- : TlsHandshakeFilter(agent, {kTlsHandshakeServerHello}),
+ : TlsHandshakeFilter(a, {kTlsHandshakeServerHello}),
cipher_suite_(suite) {}
protected:
diff --git a/security/nss/gtests/ssl_gtest/tls_protect.cc b/security/nss/gtests/ssl_gtest/tls_protect.cc
index 6c945f66eb..c715a36a6b 100644
--- a/security/nss/gtests/ssl_gtest/tls_protect.cc
+++ b/security/nss/gtests/ssl_gtest/tls_protect.cc
@@ -54,17 +54,17 @@ bool AeadCipher::AeadInner(bool decrypt, void *params, size_t param_length,
return rv == SECSuccess;
}
-bool AeadCipherAesGcm::Aead(bool decrypt, uint64_t seq, const uint8_t *in,
- size_t inlen, uint8_t *out, size_t *outlen,
- size_t maxlen) {
+bool AeadCipherAesGcm::Aead(bool decrypt, const uint8_t *hdr, size_t hdr_len,
+ uint64_t seq, const uint8_t *in, size_t inlen,
+ uint8_t *out, size_t *outlen, size_t maxlen) {
CK_GCM_PARAMS aeadParams;
unsigned char nonce[12];
memset(&aeadParams, 0, sizeof(aeadParams));
aeadParams.pIv = nonce;
aeadParams.ulIvLen = sizeof(nonce);
- aeadParams.pAAD = NULL;
- aeadParams.ulAADLen = 0;
+ aeadParams.pAAD = const_cast<uint8_t *>(hdr);
+ aeadParams.ulAADLen = hdr_len;
aeadParams.ulTagBits = 128;
FormatNonce(seq, nonce);
@@ -72,7 +72,8 @@ bool AeadCipherAesGcm::Aead(bool decrypt, uint64_t seq, const uint8_t *in,
in, inlen, out, outlen, maxlen);
}
-bool AeadCipherChacha20Poly1305::Aead(bool decrypt, uint64_t seq,
+bool AeadCipherChacha20Poly1305::Aead(bool decrypt, const uint8_t *hdr,
+ size_t hdr_len, uint64_t seq,
const uint8_t *in, size_t inlen,
uint8_t *out, size_t *outlen,
size_t maxlen) {
@@ -82,8 +83,8 @@ bool AeadCipherChacha20Poly1305::Aead(bool decrypt, uint64_t seq,
memset(&aeadParams, 0, sizeof(aeadParams));
aeadParams.pNonce = nonce;
aeadParams.ulNonceLen = sizeof(nonce);
- aeadParams.pAAD = NULL;
- aeadParams.ulAADLen = 0;
+ aeadParams.pAAD = const_cast<uint8_t *>(hdr);
+ aeadParams.ulAADLen = hdr_len;
aeadParams.ulTagLen = 16;
FormatNonce(seq, nonce);
@@ -91,9 +92,9 @@ bool AeadCipherChacha20Poly1305::Aead(bool decrypt, uint64_t seq,
in, inlen, out, outlen, maxlen);
}
-bool TlsCipherSpec::Init(uint16_t epoch, SSLCipherAlgorithm cipher,
+bool TlsCipherSpec::Init(uint16_t epoc, SSLCipherAlgorithm cipher,
PK11SymKey *key, const uint8_t *iv) {
- epoch_ = epoch;
+ epoch_ = epoc;
switch (cipher) {
case ssl_calg_aes_gcm:
aead_.reset(new AeadCipherAesGcm());
@@ -114,10 +115,12 @@ bool TlsCipherSpec::Unprotect(const TlsRecordHeader &header,
// Make space.
plaintext->Allocate(ciphertext.len());
+ auto header_bytes = header.header();
size_t len;
bool ret =
- aead_->Aead(true, header.sequence_number(), ciphertext.data(),
- ciphertext.len(), plaintext->data(), &len, plaintext->len());
+ aead_->Aead(true, header_bytes.data(), header_bytes.len(),
+ header.sequence_number(), ciphertext.data(), ciphertext.len(),
+ plaintext->data(), &len, plaintext->len());
if (!ret) return false;
plaintext->Truncate(len);
@@ -133,9 +136,13 @@ bool TlsCipherSpec::Protect(const TlsRecordHeader &header,
ciphertext->Allocate(plaintext.len() +
32); // Room for any plausible auth tag
size_t len;
+
+ DataBuffer header_bytes;
+ (void)header.WriteHeader(&header_bytes, 0, plaintext.len() + 16);
bool ret =
- aead_->Aead(false, header.sequence_number(), plaintext.data(),
- plaintext.len(), ciphertext->data(), &len, ciphertext->len());
+ aead_->Aead(false, header_bytes.data(), header_bytes.len(),
+ header.sequence_number(), plaintext.data(), plaintext.len(),
+ ciphertext->data(), &len, ciphertext->len());
if (!ret) return false;
ciphertext->Truncate(len);
diff --git a/security/nss/gtests/ssl_gtest/tls_protect.h b/security/nss/gtests/ssl_gtest/tls_protect.h
index 93ffd63227..6f129a4eb6 100644
--- a/security/nss/gtests/ssl_gtest/tls_protect.h
+++ b/security/nss/gtests/ssl_gtest/tls_protect.h
@@ -23,8 +23,9 @@ class AeadCipher {
virtual ~AeadCipher();
bool Init(PK11SymKey *key, const uint8_t *iv);
- virtual bool Aead(bool decrypt, uint64_t seq, const uint8_t *in, size_t inlen,
- uint8_t *out, size_t *outlen, size_t maxlen) = 0;
+ virtual bool Aead(bool decrypt, const uint8_t *hdr, size_t hdr_len,
+ uint64_t seq, const uint8_t *in, size_t inlen, uint8_t *out,
+ size_t *outlen, size_t maxlen) = 0;
protected:
void FormatNonce(uint64_t seq, uint8_t *nonce);
@@ -42,8 +43,9 @@ class AeadCipherChacha20Poly1305 : public AeadCipher {
AeadCipherChacha20Poly1305() : AeadCipher(CKM_NSS_CHACHA20_POLY1305) {}
protected:
- bool Aead(bool decrypt, uint64_t seq, const uint8_t *in, size_t inlen,
- uint8_t *out, size_t *outlen, size_t maxlen);
+ bool Aead(bool decrypt, const uint8_t *hdr, size_t hdr_len, uint64_t seq,
+ const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen,
+ size_t maxlen);
};
class AeadCipherAesGcm : public AeadCipher {
@@ -51,8 +53,9 @@ class AeadCipherAesGcm : public AeadCipher {
AeadCipherAesGcm() : AeadCipher(CKM_AES_GCM) {}
protected:
- bool Aead(bool decrypt, uint64_t seq, const uint8_t *in, size_t inlen,
- uint8_t *out, size_t *outlen, size_t maxlen);
+ bool Aead(bool decrypt, const uint8_t *hdr, size_t hdr_len, uint64_t seq,
+ const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen,
+ size_t maxlen);
};
// Our analog of ssl3CipherSpec
diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c
index d1c48dfba6..63adcad46d 100644
--- a/security/nss/lib/certdb/crl.c
+++ b/security/nss/lib/certdb/crl.c
@@ -898,13 +898,13 @@ static PLHashAllocOps preAllocOps = { PreAllocTable, PreFreeTable,
/* destructor for PreAllocator object */
void
-PreAllocator_Destroy(PreAllocator* PreAllocator)
+PreAllocator_Destroy(PreAllocator* allocator)
{
- if (!PreAllocator) {
+ if (!allocator) {
return;
}
- if (PreAllocator->arena) {
- PORT_FreeArena(PreAllocator->arena, PR_TRUE);
+ if (allocator->arena) {
+ PORT_FreeArena(allocator->arena, PR_TRUE);
}
}
diff --git a/security/nss/lib/ckfw/Makefile b/security/nss/lib/ckfw/Makefile
index 484dbb511a..2902bef48b 100644
--- a/security/nss/lib/ckfw/Makefile
+++ b/security/nss/lib/ckfw/Makefile
@@ -33,7 +33,3 @@ ifdef NSS_BUILD_CAPI
DIRS += capi
endif
endif
-
-#ifeq ($(OS_ARCH), Darwin)
-#DIRS += nssmkey
-#endif
diff --git a/security/nss/lib/ckfw/builtins/certdata.txt b/security/nss/lib/ckfw/builtins/certdata.txt
index 5d2baf3a56..d291f28a5d 100644
--- a/security/nss/lib/ckfw/builtins/certdata.txt
+++ b/security/nss/lib/ckfw/builtins/certdata.txt
@@ -7241,163 +7241,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
-# Certificate "TC TrustCenter Class 3 CA II"
-#
-# Issuer: CN=TC TrustCenter Class 3 CA II,OU=TC TrustCenter Class 3 CA,O=TC TrustCenter GmbH,C=DE
-# Serial Number:4a:47:00:01:00:02:e5:a0:5d:d6:3f:00:51:bf
-# Subject: CN=TC TrustCenter Class 3 CA II,OU=TC TrustCenter Class 3 CA,O=TC TrustCenter GmbH,C=DE
-# Not Valid Before: Thu Jan 12 14:41:57 2006
-# Not Valid After : Wed Dec 31 22:59:59 2025
-# Fingerprint (MD5): 56:5F:AA:80:61:12:17:F6:67:21:E6:2B:6D:61:56:8E
-# Fingerprint (SHA1): 80:25:EF:F4:6E:70:C8:D4:72:24:65:84:FE:40:3B:8A:8D:6A:DB:F5
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TC TrustCenter Class 3 CA II"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\166\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\042\060
-\040\006\003\125\004\013\023\031\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\103\154\141\163\163\040\063\040\103
-\101\061\045\060\043\006\003\125\004\003\023\034\124\103\040\124
-\162\165\163\164\103\145\156\164\145\162\040\103\154\141\163\163
-\040\063\040\103\101\040\111\111
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\166\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\042\060
-\040\006\003\125\004\013\023\031\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\103\154\141\163\163\040\063\040\103
-\101\061\045\060\043\006\003\125\004\003\023\034\124\103\040\124
-\162\165\163\164\103\145\156\164\145\162\040\103\154\141\163\163
-\040\063\040\103\101\040\111\111
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\016\112\107\000\001\000\002\345\240\135\326\077\000\121\277
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\252\060\202\003\222\240\003\002\001\002\002\016\112
-\107\000\001\000\002\345\240\135\326\077\000\121\277\060\015\006
-\011\052\206\110\206\367\015\001\001\005\005\000\060\166\061\013
-\060\011\006\003\125\004\006\023\002\104\105\061\034\060\032\006
-\003\125\004\012\023\023\124\103\040\124\162\165\163\164\103\145
-\156\164\145\162\040\107\155\142\110\061\042\060\040\006\003\125
-\004\013\023\031\124\103\040\124\162\165\163\164\103\145\156\164
-\145\162\040\103\154\141\163\163\040\063\040\103\101\061\045\060
-\043\006\003\125\004\003\023\034\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\103\154\141\163\163\040\063\040\103
-\101\040\111\111\060\036\027\015\060\066\060\061\061\062\061\064
-\064\061\065\067\132\027\015\062\065\061\062\063\061\062\062\065
-\071\065\071\132\060\166\061\013\060\011\006\003\125\004\006\023
-\002\104\105\061\034\060\032\006\003\125\004\012\023\023\124\103
-\040\124\162\165\163\164\103\145\156\164\145\162\040\107\155\142
-\110\061\042\060\040\006\003\125\004\013\023\031\124\103\040\124
-\162\165\163\164\103\145\156\164\145\162\040\103\154\141\163\163
-\040\063\040\103\101\061\045\060\043\006\003\125\004\003\023\034
-\124\103\040\124\162\165\163\164\103\145\156\164\145\162\040\103
-\154\141\163\163\040\063\040\103\101\040\111\111\060\202\001\042
-\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003
-\202\001\017\000\060\202\001\012\002\202\001\001\000\264\340\273
-\121\273\071\134\213\004\305\114\171\034\043\206\061\020\143\103
-\125\047\077\306\105\307\244\075\354\011\015\032\036\040\302\126
-\036\336\033\067\007\060\042\057\157\361\006\361\253\255\326\310
-\253\141\243\057\103\304\260\262\055\374\303\226\151\173\176\212
-\344\314\300\071\022\220\102\140\311\314\065\150\356\332\137\220
-\126\137\315\034\115\133\130\111\353\016\001\117\144\372\054\074
-\211\130\330\057\056\342\260\150\351\042\073\165\211\326\104\032
-\145\362\033\227\046\035\050\155\254\350\275\131\035\053\044\366
-\326\204\003\146\210\044\000\170\140\361\370\253\376\002\262\153
-\373\042\373\065\346\026\321\255\366\056\022\344\372\065\152\345
-\031\271\135\333\073\036\032\373\323\377\025\024\010\330\011\152
-\272\105\235\024\171\140\175\257\100\212\007\163\263\223\226\323
-\164\064\215\072\067\051\336\134\354\365\356\056\061\302\040\334
-\276\361\117\177\043\122\331\133\342\144\331\234\252\007\010\265
-\105\275\321\320\061\301\253\124\237\251\322\303\142\140\003\361
-\273\071\112\222\112\075\012\271\235\305\240\376\067\002\003\001
-\000\001\243\202\001\064\060\202\001\060\060\017\006\003\125\035
-\023\001\001\377\004\005\060\003\001\001\377\060\016\006\003\125
-\035\017\001\001\377\004\004\003\002\001\006\060\035\006\003\125
-\035\016\004\026\004\024\324\242\374\237\263\303\330\003\323\127
-\134\007\244\320\044\247\300\362\000\324\060\201\355\006\003\125
-\035\037\004\201\345\060\201\342\060\201\337\240\201\334\240\201
-\331\206\065\150\164\164\160\072\057\057\167\167\167\056\164\162
-\165\163\164\143\145\156\164\145\162\056\144\145\057\143\162\154
-\057\166\062\057\164\143\137\143\154\141\163\163\137\063\137\143
-\141\137\111\111\056\143\162\154\206\201\237\154\144\141\160\072
-\057\057\167\167\167\056\164\162\165\163\164\143\145\156\164\145
-\162\056\144\145\057\103\116\075\124\103\045\062\060\124\162\165
-\163\164\103\145\156\164\145\162\045\062\060\103\154\141\163\163
-\045\062\060\063\045\062\060\103\101\045\062\060\111\111\054\117
-\075\124\103\045\062\060\124\162\165\163\164\103\145\156\164\145
-\162\045\062\060\107\155\142\110\054\117\125\075\162\157\157\164
-\143\145\162\164\163\054\104\103\075\164\162\165\163\164\143\145
-\156\164\145\162\054\104\103\075\144\145\077\143\145\162\164\151
-\146\151\143\141\164\145\122\145\166\157\143\141\164\151\157\156
-\114\151\163\164\077\142\141\163\145\077\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\202\001\001\000\066\140
-\344\160\367\006\040\103\331\043\032\102\362\370\243\262\271\115
-\212\264\363\302\232\125\061\174\304\073\147\232\264\337\115\016
-\212\223\112\027\213\033\215\312\211\341\317\072\036\254\035\361
-\234\062\264\216\131\166\242\101\205\045\067\240\023\320\365\174
-\116\325\352\226\342\156\162\301\273\052\376\154\156\370\221\230
-\106\374\311\033\127\133\352\310\032\073\077\260\121\230\074\007
-\332\054\131\001\332\213\104\350\341\164\375\247\150\335\124\272
-\203\106\354\310\106\265\370\257\227\300\073\011\034\217\316\162
-\226\075\063\126\160\274\226\313\330\325\175\040\232\203\237\032
-\334\071\361\305\162\243\021\003\375\073\102\122\051\333\350\001
-\367\233\136\214\326\215\206\116\031\372\274\034\276\305\041\245
-\207\236\170\056\066\333\011\161\243\162\064\370\154\343\006\011
-\362\136\126\245\323\335\230\372\324\346\006\364\360\266\040\143
-\113\352\051\275\252\202\146\036\373\201\252\247\067\255\023\030
-\346\222\303\201\301\063\273\210\036\241\347\342\264\275\061\154
-\016\121\075\157\373\226\126\200\342\066\027\321\334\344
-END
-CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
-
-# Trust for Certificate "TC TrustCenter Class 3 CA II"
-# Issuer: CN=TC TrustCenter Class 3 CA II,OU=TC TrustCenter Class 3 CA,O=TC TrustCenter GmbH,C=DE
-# Serial Number:4a:47:00:01:00:02:e5:a0:5d:d6:3f:00:51:bf
-# Subject: CN=TC TrustCenter Class 3 CA II,OU=TC TrustCenter Class 3 CA,O=TC TrustCenter GmbH,C=DE
-# Not Valid Before: Thu Jan 12 14:41:57 2006
-# Not Valid After : Wed Dec 31 22:59:59 2025
-# Fingerprint (MD5): 56:5F:AA:80:61:12:17:F6:67:21:E6:2B:6D:61:56:8E
-# Fingerprint (SHA1): 80:25:EF:F4:6E:70:C8:D4:72:24:65:84:FE:40:3B:8A:8D:6A:DB:F5
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TC TrustCenter Class 3 CA II"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\200\045\357\364\156\160\310\324\162\044\145\204\376\100\073\212
-\215\152\333\365
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\126\137\252\200\141\022\027\366\147\041\346\053\155\141\126\216
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\166\061\013\060\011\006\003\125\004\006\023\002\104\105\061
-\034\060\032\006\003\125\004\012\023\023\124\103\040\124\162\165
-\163\164\103\145\156\164\145\162\040\107\155\142\110\061\042\060
-\040\006\003\125\004\013\023\031\124\103\040\124\162\165\163\164
-\103\145\156\164\145\162\040\103\154\141\163\163\040\063\040\103
-\101\061\045\060\043\006\003\125\004\003\023\034\124\103\040\124
-\162\165\163\164\103\145\156\164\145\162\040\103\154\141\163\163
-\040\063\040\103\101\040\111\111
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\016\112\107\000\001\000\002\345\240\135\326\077\000\121\277
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
# Certificate "Deutsche Telekom Root CA 2"
#
# Issuer: CN=Deutsche Telekom Root CA 2,OU=T-TeleSec Trust Center,O=Deutsche Telekom AG,C=DE
@@ -17883,155 +17726,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
-# Certificate "S-TRUST Universal Root CA"
-#
-# Issuer: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE
-# Serial Number:60:56:c5:4b:23:40:5b:64:d4:ed:25:da:d9:d6:1e:1e
-# Subject: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE
-# Not Valid Before: Tue Oct 22 00:00:00 2013
-# Not Valid After : Thu Oct 21 23:59:59 2038
-# Fingerprint (SHA-256): D8:0F:EF:91:0A:E3:F1:04:72:3B:04:5C:EC:2D:01:9F:44:1C:E6:21:3A:DF:15:67:91:E7:0C:17:90:11:0A:31
-# Fingerprint (SHA1): 1B:3D:11:14:EA:7A:0F:95:58:54:41:95:BF:6B:25:82:AB:40:CE:9A
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "S-TRUST Universal Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\205\061\013\060\011\006\003\125\004\006\023\002\104\105
-\061\051\060\047\006\003\125\004\012\023\040\104\145\165\164\163
-\143\150\145\162\040\123\160\141\162\153\141\163\163\145\156\040
-\126\145\162\154\141\147\040\107\155\142\110\061\047\060\045\006
-\003\125\004\013\023\036\123\055\124\122\125\123\124\040\103\145
-\162\164\151\146\151\143\141\164\151\157\156\040\123\145\162\166
-\151\143\145\163\061\042\060\040\006\003\125\004\003\023\031\123
-\055\124\122\125\123\124\040\125\156\151\166\145\162\163\141\154
-\040\122\157\157\164\040\103\101
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\205\061\013\060\011\006\003\125\004\006\023\002\104\105
-\061\051\060\047\006\003\125\004\012\023\040\104\145\165\164\163
-\143\150\145\162\040\123\160\141\162\153\141\163\163\145\156\040
-\126\145\162\154\141\147\040\107\155\142\110\061\047\060\045\006
-\003\125\004\013\023\036\123\055\124\122\125\123\124\040\103\145
-\162\164\151\146\151\143\141\164\151\157\156\040\123\145\162\166
-\151\143\145\163\061\042\060\040\006\003\125\004\003\023\031\123
-\055\124\122\125\123\124\040\125\156\151\166\145\162\163\141\154
-\040\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\140\126\305\113\043\100\133\144\324\355\045\332\331\326
-\036\036
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\003\330\060\202\002\300\240\003\002\001\002\002\020\140
-\126\305\113\043\100\133\144\324\355\045\332\331\326\036\036\060
-\015\006\011\052\206\110\206\367\015\001\001\013\005\000\060\201
-\205\061\013\060\011\006\003\125\004\006\023\002\104\105\061\051
-\060\047\006\003\125\004\012\023\040\104\145\165\164\163\143\150
-\145\162\040\123\160\141\162\153\141\163\163\145\156\040\126\145
-\162\154\141\147\040\107\155\142\110\061\047\060\045\006\003\125
-\004\013\023\036\123\055\124\122\125\123\124\040\103\145\162\164
-\151\146\151\143\141\164\151\157\156\040\123\145\162\166\151\143
-\145\163\061\042\060\040\006\003\125\004\003\023\031\123\055\124
-\122\125\123\124\040\125\156\151\166\145\162\163\141\154\040\122
-\157\157\164\040\103\101\060\036\027\015\061\063\061\060\062\062
-\060\060\060\060\060\060\132\027\015\063\070\061\060\062\061\062
-\063\065\071\065\071\132\060\201\205\061\013\060\011\006\003\125
-\004\006\023\002\104\105\061\051\060\047\006\003\125\004\012\023
-\040\104\145\165\164\163\143\150\145\162\040\123\160\141\162\153
-\141\163\163\145\156\040\126\145\162\154\141\147\040\107\155\142
-\110\061\047\060\045\006\003\125\004\013\023\036\123\055\124\122
-\125\123\124\040\103\145\162\164\151\146\151\143\141\164\151\157
-\156\040\123\145\162\166\151\143\145\163\061\042\060\040\006\003
-\125\004\003\023\031\123\055\124\122\125\123\124\040\125\156\151
-\166\145\162\163\141\154\040\122\157\157\164\040\103\101\060\202
-\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005
-\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000\250
-\343\013\337\021\067\205\202\232\265\154\146\174\141\077\300\107
-\032\035\106\343\260\125\144\345\270\202\071\050\007\176\027\377
-\364\233\212\360\221\201\352\070\077\041\170\154\110\354\153\057
-\242\323\212\162\262\247\327\331\352\177\264\300\111\153\060\045
-\211\214\353\267\325\100\141\230\342\334\074\040\222\315\145\112
-\162\237\032\216\214\372\045\025\277\363\041\203\050\015\213\257
-\131\021\202\103\134\233\115\045\121\177\130\030\143\140\073\263
-\265\212\213\130\143\067\110\110\220\104\302\100\335\135\367\103
-\151\051\230\134\022\145\136\253\220\222\113\146\337\325\165\022
-\123\124\030\246\336\212\326\273\127\003\071\131\231\030\005\014
-\371\375\025\306\220\144\106\027\202\327\302\112\101\075\375\000
-\276\127\162\030\224\167\033\123\132\211\001\366\063\162\016\223
-\072\334\350\036\375\005\005\326\274\163\340\210\334\253\117\354
-\265\030\206\117\171\204\016\110\052\146\052\335\062\310\170\145
-\310\013\235\130\001\005\161\355\201\365\150\027\156\313\015\264
-\113\330\241\354\256\070\353\034\130\057\241\145\003\064\057\002
-\003\001\000\001\243\102\060\100\060\017\006\003\125\035\023\001
-\001\377\004\005\060\003\001\001\377\060\016\006\003\125\035\017
-\001\001\377\004\004\003\002\001\006\060\035\006\003\125\035\016
-\004\026\004\024\232\175\327\353\353\177\124\230\105\051\264\040
-\253\155\013\226\043\031\244\302\060\015\006\011\052\206\110\206
-\367\015\001\001\013\005\000\003\202\001\001\000\116\226\022\333
-\176\167\136\222\047\236\041\027\030\202\166\330\077\274\245\011
-\004\146\210\211\255\333\125\263\063\152\306\145\304\217\115\363
-\062\066\334\171\004\226\251\167\062\321\227\365\030\153\214\272
-\355\316\021\320\104\307\222\361\264\104\216\355\210\122\110\236
-\325\375\131\370\243\036\121\373\001\122\345\137\345\172\335\252
-\044\117\042\213\335\166\106\366\245\240\017\065\330\312\017\230
-\271\060\135\040\157\302\201\036\275\275\300\376\025\323\070\052
-\011\223\230\047\033\223\173\320\053\064\136\150\245\025\117\321
-\122\303\240\312\240\203\105\035\365\365\267\131\163\135\131\001
-\217\252\302\107\057\024\161\325\051\343\020\265\107\223\045\314
-\043\051\332\267\162\330\221\324\354\033\110\212\042\344\301\052
-\367\072\150\223\237\105\031\156\103\267\314\376\270\221\232\141
-\032\066\151\143\144\222\050\363\157\141\222\205\023\237\311\007
-\054\213\127\334\353\236\171\325\302\336\010\325\124\262\127\116
-\052\062\215\241\342\072\321\020\040\042\071\175\064\105\157\161
-\073\303\035\374\377\262\117\250\342\366\060\036
-END
-CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
-
-# Trust for "S-TRUST Universal Root CA"
-# Issuer: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE
-# Serial Number:60:56:c5:4b:23:40:5b:64:d4:ed:25:da:d9:d6:1e:1e
-# Subject: CN=S-TRUST Universal Root CA,OU=S-TRUST Certification Services,O=Deutscher Sparkassen Verlag GmbH,C=DE
-# Not Valid Before: Tue Oct 22 00:00:00 2013
-# Not Valid After : Thu Oct 21 23:59:59 2038
-# Fingerprint (SHA-256): D8:0F:EF:91:0A:E3:F1:04:72:3B:04:5C:EC:2D:01:9F:44:1C:E6:21:3A:DF:15:67:91:E7:0C:17:90:11:0A:31
-# Fingerprint (SHA1): 1B:3D:11:14:EA:7A:0F:95:58:54:41:95:BF:6B:25:82:AB:40:CE:9A
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "S-TRUST Universal Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\033\075\021\024\352\172\017\225\130\124\101\225\277\153\045\202
-\253\100\316\232
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\130\366\101\001\256\365\133\121\231\116\134\041\350\117\324\146
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\205\061\013\060\011\006\003\125\004\006\023\002\104\105
-\061\051\060\047\006\003\125\004\012\023\040\104\145\165\164\163
-\143\150\145\162\040\123\160\141\162\153\141\163\163\145\156\040
-\126\145\162\154\141\147\040\107\155\142\110\061\047\060\045\006
-\003\125\004\013\023\036\123\055\124\122\125\123\124\040\103\145
-\162\164\151\146\151\143\141\164\151\157\156\040\123\145\162\166
-\151\143\145\163\061\042\060\040\006\003\125\004\003\023\031\123
-\055\124\122\125\123\124\040\125\156\151\166\145\162\163\141\154
-\040\122\157\157\164\040\103\101
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\140\126\305\113\043\100\133\144\324\355\045\332\331\326
-\036\036
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
# Certificate "Entrust Root Certification Authority - G2"
#
# Issuer: CN=Entrust Root Certification Authority - G2,OU="(c) 2009 Entrust, Inc. - for authorized use only",OU=See www.entrust.net/legal-terms,O="Entrust, Inc.",C=US
@@ -18509,167 +18203,6 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
#
-# Certificate "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5"
-#
-# Issuer: CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. H5,O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A....,L=Ankara,C=TR
-# Serial Number:00:8e:17:fe:24:20:81
-# Subject: CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. H5,O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A....,L=Ankara,C=TR
-# Not Valid Before: Tue Apr 30 08:07:01 2013
-# Not Valid After : Fri Apr 28 08:07:01 2023
-# Fingerprint (SHA-256): 49:35:1B:90:34:44:C1:85:CC:DC:5C:69:3D:24:D8:55:5C:B2:08:D6:A8:14:13:07:69:9F:4A:F0:63:19:9D:78
-# Fingerprint (SHA1): C4:18:F6:4D:46:D1:DF:00:3D:27:30:13:72:43:A9:12:11:C6:75:FB
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\201\261\061\013\060\011\006\003\125\004\006\023\002\124\122
-\061\017\060\015\006\003\125\004\007\014\006\101\156\153\141\162
-\141\061\115\060\113\006\003\125\004\012\014\104\124\303\234\122
-\113\124\122\125\123\124\040\102\151\154\147\151\040\304\260\154
-\145\164\151\305\237\151\155\040\166\145\040\102\151\154\151\305
-\237\151\155\040\107\303\274\166\145\156\154\151\304\237\151\040
-\110\151\172\155\145\164\154\145\162\151\040\101\056\305\236\056
-\061\102\060\100\006\003\125\004\003\014\071\124\303\234\122\113
-\124\122\125\123\124\040\105\154\145\153\164\162\157\156\151\153
-\040\123\145\162\164\151\146\151\153\141\040\110\151\172\155\145
-\164\040\123\141\304\237\154\141\171\304\261\143\304\261\163\304
-\261\040\110\065
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\261\061\013\060\011\006\003\125\004\006\023\002\124\122
-\061\017\060\015\006\003\125\004\007\014\006\101\156\153\141\162
-\141\061\115\060\113\006\003\125\004\012\014\104\124\303\234\122
-\113\124\122\125\123\124\040\102\151\154\147\151\040\304\260\154
-\145\164\151\305\237\151\155\040\166\145\040\102\151\154\151\305
-\237\151\155\040\107\303\274\166\145\156\154\151\304\237\151\040
-\110\151\172\155\145\164\154\145\162\151\040\101\056\305\236\056
-\061\102\060\100\006\003\125\004\003\014\071\124\303\234\122\113
-\124\122\125\123\124\040\105\154\145\153\164\162\157\156\151\153
-\040\123\145\162\164\151\146\151\153\141\040\110\151\172\155\145
-\164\040\123\141\304\237\154\141\171\304\261\143\304\261\163\304
-\261\040\110\065
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\007\000\216\027\376\044\040\201
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\004\047\060\202\003\017\240\003\002\001\002\002\007\000
-\216\027\376\044\040\201\060\015\006\011\052\206\110\206\367\015
-\001\001\013\005\000\060\201\261\061\013\060\011\006\003\125\004
-\006\023\002\124\122\061\017\060\015\006\003\125\004\007\014\006
-\101\156\153\141\162\141\061\115\060\113\006\003\125\004\012\014
-\104\124\303\234\122\113\124\122\125\123\124\040\102\151\154\147
-\151\040\304\260\154\145\164\151\305\237\151\155\040\166\145\040
-\102\151\154\151\305\237\151\155\040\107\303\274\166\145\156\154
-\151\304\237\151\040\110\151\172\155\145\164\154\145\162\151\040
-\101\056\305\236\056\061\102\060\100\006\003\125\004\003\014\071
-\124\303\234\122\113\124\122\125\123\124\040\105\154\145\153\164
-\162\157\156\151\153\040\123\145\162\164\151\146\151\153\141\040
-\110\151\172\155\145\164\040\123\141\304\237\154\141\171\304\261
-\143\304\261\163\304\261\040\110\065\060\036\027\015\061\063\060
-\064\063\060\060\070\060\067\060\061\132\027\015\062\063\060\064
-\062\070\060\070\060\067\060\061\132\060\201\261\061\013\060\011
-\006\003\125\004\006\023\002\124\122\061\017\060\015\006\003\125
-\004\007\014\006\101\156\153\141\162\141\061\115\060\113\006\003
-\125\004\012\014\104\124\303\234\122\113\124\122\125\123\124\040
-\102\151\154\147\151\040\304\260\154\145\164\151\305\237\151\155
-\040\166\145\040\102\151\154\151\305\237\151\155\040\107\303\274
-\166\145\156\154\151\304\237\151\040\110\151\172\155\145\164\154
-\145\162\151\040\101\056\305\236\056\061\102\060\100\006\003\125
-\004\003\014\071\124\303\234\122\113\124\122\125\123\124\040\105
-\154\145\153\164\162\157\156\151\153\040\123\145\162\164\151\146
-\151\153\141\040\110\151\172\155\145\164\040\123\141\304\237\154
-\141\171\304\261\143\304\261\163\304\261\040\110\065\060\202\001
-\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000
-\003\202\001\017\000\060\202\001\012\002\202\001\001\000\244\045
-\031\341\145\236\353\110\041\120\112\010\345\021\360\132\272\046
-\377\203\131\316\104\052\057\376\341\316\140\003\374\215\003\245
-\355\377\153\250\272\314\064\006\237\131\065\366\354\054\273\235
-\373\215\122\151\343\234\047\020\123\363\244\002\305\247\371\021
-\032\151\165\156\303\035\213\321\230\215\223\207\247\161\227\015
-\041\307\231\371\122\323\054\143\135\125\274\350\037\001\110\271
-\140\376\102\112\366\310\200\256\315\146\172\236\105\212\150\167
-\342\110\150\237\242\332\361\341\301\020\237\353\074\051\201\247
-\341\062\010\324\240\005\261\214\373\215\226\000\016\076\045\337
-\123\206\042\073\374\364\275\363\011\176\167\354\206\353\017\063
-\345\103\117\364\124\165\155\051\231\056\146\132\103\337\313\134
-\312\310\345\070\361\176\073\065\235\017\364\305\132\241\314\363
-\040\200\044\323\127\354\025\272\165\045\233\350\144\113\263\064
-\204\357\004\270\366\311\154\252\002\076\266\125\342\062\067\137
-\374\146\227\137\315\326\236\307\040\277\115\306\254\077\165\137
-\034\355\062\234\174\151\000\151\221\343\043\030\123\351\002\003
-\001\000\001\243\102\060\100\060\035\006\003\125\035\016\004\026
-\004\024\126\231\007\036\323\254\014\151\144\264\014\120\107\336
-\103\054\276\040\300\373\060\016\006\003\125\035\017\001\001\377
-\004\004\003\002\001\006\060\017\006\003\125\035\023\001\001\377
-\004\005\060\003\001\001\377\060\015\006\011\052\206\110\206\367
-\015\001\001\013\005\000\003\202\001\001\000\236\105\166\173\027
-\110\062\362\070\213\051\275\356\226\112\116\201\030\261\121\107
-\040\315\320\144\261\016\311\331\001\331\011\316\310\231\334\150
-\045\023\324\134\362\243\350\004\376\162\011\307\013\252\035\045
-\125\176\226\232\127\267\272\305\021\172\031\346\247\176\075\205
-\016\365\371\056\051\057\347\371\154\130\026\127\120\045\366\076
-\056\076\252\355\167\161\252\252\231\226\106\012\256\216\354\052
-\121\026\260\136\315\352\147\004\034\130\060\365\140\212\275\246
-\275\115\345\226\264\374\102\211\001\153\366\160\310\120\071\014
-\055\325\146\331\310\322\263\062\267\033\031\155\313\063\371\337
-\245\346\025\204\067\360\302\362\145\226\222\220\167\360\255\364
-\220\351\021\170\327\223\211\300\075\013\272\051\364\350\231\235
-\162\216\355\235\057\356\222\175\241\361\377\135\272\063\140\205
-\142\376\007\002\241\204\126\106\276\226\012\232\023\327\041\114
-\267\174\007\237\116\116\077\221\164\373\047\235\021\314\335\346
-\261\312\161\115\023\027\071\046\305\051\041\053\223\051\152\226
-\372\253\101\341\113\266\065\013\300\233\025
-END
-CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
-
-# Trust for "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5"
-# Issuer: CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. H5,O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A....,L=Ankara,C=TR
-# Serial Number:00:8e:17:fe:24:20:81
-# Subject: CN=T..RKTRUST Elektronik Sertifika Hizmet Sa..lay..c..s.. H5,O=T..RKTRUST Bilgi ..leti..im ve Bili..im G..venli..i Hizmetleri A....,L=Ankara,C=TR
-# Not Valid Before: Tue Apr 30 08:07:01 2013
-# Not Valid After : Fri Apr 28 08:07:01 2023
-# Fingerprint (SHA-256): 49:35:1B:90:34:44:C1:85:CC:DC:5C:69:3D:24:D8:55:5C:B2:08:D6:A8:14:13:07:69:9F:4A:F0:63:19:9D:78
-# Fingerprint (SHA1): C4:18:F6:4D:46:D1:DF:00:3D:27:30:13:72:43:A9:12:11:C6:75:FB
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\304\030\366\115\106\321\337\000\075\047\060\023\162\103\251\022
-\021\306\165\373
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\332\160\216\360\042\337\223\046\366\137\237\323\025\006\122\116
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\201\261\061\013\060\011\006\003\125\004\006\023\002\124\122
-\061\017\060\015\006\003\125\004\007\014\006\101\156\153\141\162
-\141\061\115\060\113\006\003\125\004\012\014\104\124\303\234\122
-\113\124\122\125\123\124\040\102\151\154\147\151\040\304\260\154
-\145\164\151\305\237\151\155\040\166\145\040\102\151\154\151\305
-\237\151\155\040\107\303\274\166\145\156\154\151\304\237\151\040
-\110\151\172\155\145\164\154\145\162\151\040\101\056\305\236\056
-\061\102\060\100\006\003\125\004\003\014\071\124\303\234\122\113
-\124\122\125\123\124\040\105\154\145\153\164\162\157\156\151\153
-\040\123\145\162\164\151\146\151\153\141\040\110\151\172\155\145
-\164\040\123\141\304\237\154\141\171\304\261\143\304\261\163\304
-\261\040\110\065
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\007\000\216\027\376\044\040\201
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
-#
# Certificate "Certinomis - Root CA"
#
# Issuer: CN=Certinomis - Root CA,OU=0002 433998903,O=Certinomis,C=FR
diff --git a/security/nss/lib/ckfw/builtins/nssckbi.h b/security/nss/lib/ckfw/builtins/nssckbi.h
index 0189369b1b..d40c8080eb 100644
--- a/security/nss/lib/ckfw/builtins/nssckbi.h
+++ b/security/nss/lib/ckfw/builtins/nssckbi.h
@@ -32,7 +32,7 @@
* - whenever possible, if older branches require a modification to the
* list, these changes should be made on the main line of development (trunk),
* and the older branches should update to the most recent list.
- *
+ *
* - ODD minor version numbers are reserved to indicate a snapshot that has
* deviated from the main line of development, e.g. if it was necessary
* to modify the list on a stable branch.
@@ -46,8 +46,8 @@
* It's recommend to switch back to 0 after having reached version 98/99.
*/
#define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 2
-#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 22
-#define NSS_BUILTINS_LIBRARY_VERSION "2.22"
+#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 24
+#define NSS_BUILTINS_LIBRARY_VERSION "2.24"
/* These version numbers detail the semantic changes to the ckfw engine. */
#define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1
diff --git a/security/nss/lib/ckfw/nssmkey/Makefile b/security/nss/lib/ckfw/nssmkey/Makefile
deleted file mode 100644
index e630e84b0f..0000000000
--- a/security/nss/lib/ckfw/nssmkey/Makefile
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-include manifest.mn
-include $(CORE_DEPTH)/coreconf/config.mk
-include config.mk
-
-EXTRA_LIBS = \
- $(DIST)/lib/$(LIB_PREFIX)nssckfw.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)secutil.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
- $(NULL)
-
-# can't do this in manifest.mn because OS_TARGET isn't defined there.
-ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-
-ifdef NS_USE_GCC
-EXTRA_LIBS += \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- $(NULL)
-else
-EXTRA_SHARED_LIBS += \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
- $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
- $(NULL)
-endif # NS_USE_GCC
-else
-
-EXTRA_LIBS += \
- -L$(NSPR_LIB_DIR) \
- -lplc4 \
- -lplds4 \
- -lnspr4 \
- -framework Security \
- -framework CoreServices \
- $(NULL)
-endif
-
-
-include $(CORE_DEPTH)/coreconf/rules.mk
-
-# Generate certdata.c.
-generate:
- perl certdata.perl < certdata.txt
-
-# This'll need some help from a build person.
-
-
-ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.1)
-DSO_LDOPTS = -bM:SRE -bh:4 -bnoentry
-EXTRA_DSO_LDOPTS = -lc
-MKSHLIB = xlC $(DSO_LDOPTS)
-
-$(SHARED_LIBRARY): $(OBJS)
- @$(MAKE_OBJDIR)
- rm -f $@
- $(MKSHLIB) -o $@ $(OBJS) $(EXTRA_LIBS) $(EXTRA_DSO_LDOPTS)
- chmod +x $@
-
-endif
-
-ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.2)
-LD += -G
-endif
-
-
diff --git a/security/nss/lib/ckfw/nssmkey/README b/security/nss/lib/ckfw/nssmkey/README
deleted file mode 100644
index c060d9c3c0..0000000000
--- a/security/nss/lib/ckfw/nssmkey/README
+++ /dev/null
@@ -1,21 +0,0 @@
-This Cryptoki module provides acces to certs and keys stored in
-Macintosh key Ring.
-
-- It does not yet export PKCS #12 keys. To get this to work should be
- implemented using exporting the key object in PKCS #8 wrapped format.
- PSM work needs to happen before this can be completed.
-- It does not import or export CA Root trust from the mac keychain.
-- It does not handle S/MIME objects (pkcs #7 in mac keychain terms?).
-- The AuthRoots don't show up on the default list.
-- Only RSA keys are supported currently.
-
-There are a number of things that have not been tested that other PKCS #11
-apps may need:
-- reading Modulus and Public Exponents from private keys and public keys.
-- storing public keys.
-- setting attributes other than CKA_ID and CKA_LABEL.
-
-Other TODOs:
-- Check for and plug memory leaks.
-- Need to map mac errors into something more intellegible than
- CKR_GENERAL_ERROR.
diff --git a/security/nss/lib/ckfw/nssmkey/ckmk.h b/security/nss/lib/ckfw/nssmkey/ckmk.h
deleted file mode 100644
index 4f3ab82d72..0000000000
--- a/security/nss/lib/ckfw/nssmkey/ckmk.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CKMK_H
-#define CKMK_H 1
-
-#include <Security/SecKeychainSearch.h>
-#include <Security/SecKeychainItem.h>
-#include <Security/SecKeychain.h>
-#include <Security/cssmtype.h>
-#include <Security/cssmapi.h>
-#include <Security/SecKey.h>
-#include <Security/SecCertificate.h>
-
-#define NTO
-
-#include "nssckmdt.h"
-#include "nssckfw.h"
-/*
- * I'm including this for access to the arena functions.
- * Looks like we should publish that API.
- */
-#ifndef BASE_H
-#include "base.h"
-#endif /* BASE_H */
-/*
- * This is where the Netscape extensions live, at least for now.
- */
-#ifndef CKT_H
-#include "ckt.h"
-#endif /* CKT_H */
-
-/*
- * statically defined raw objects. Allows us to data description objects
- * to this PKCS #11 module.
- */
-struct ckmkRawObjectStr {
- CK_ULONG n;
- const CK_ATTRIBUTE_TYPE *types;
- const NSSItem *items;
-};
-typedef struct ckmkRawObjectStr ckmkRawObject;
-
-/*
- * Key/Cert Items
- */
-struct ckmkItemObjectStr {
- SecKeychainItemRef itemRef;
- SecItemClass itemClass;
- PRBool hasID;
- NSSItem modify;
- NSSItem private;
- NSSItem encrypt;
- NSSItem decrypt;
- NSSItem derive;
- NSSItem sign;
- NSSItem signRecover;
- NSSItem verify;
- NSSItem verifyRecover;
- NSSItem wrap;
- NSSItem unwrap;
- NSSItem label;
- NSSItem subject;
- NSSItem issuer;
- NSSItem serial;
- NSSItem derCert;
- NSSItem id;
- NSSItem modulus;
- NSSItem exponent;
- NSSItem privateExponent;
- NSSItem prime1;
- NSSItem prime2;
- NSSItem exponent1;
- NSSItem exponent2;
- NSSItem coefficient;
-};
-typedef struct ckmkItemObjectStr ckmkItemObject;
-
-typedef enum {
- ckmkRaw,
- ckmkItem,
-} ckmkObjectType;
-
-/*
- * all the various types of objects are abstracted away in cobject and
- * cfind as ckmkInternalObjects.
- */
-struct ckmkInternalObjectStr {
- ckmkObjectType type;
- union {
- ckmkRawObject raw;
- ckmkItemObject item;
- } u;
- CK_OBJECT_CLASS objClass;
- NSSItem hashKey;
- unsigned char hashKeyData[128];
- NSSCKMDObject mdObject;
-};
-typedef struct ckmkInternalObjectStr ckmkInternalObject;
-
-/* our raw object data array */
-NSS_EXTERN_DATA ckmkInternalObject nss_ckmk_data[];
-NSS_EXTERN_DATA const PRUint32 nss_ckmk_nObjects;
-
-NSS_EXTERN_DATA const CK_VERSION nss_ckmk_CryptokiVersion;
-NSS_EXTERN_DATA const NSSUTF8 *nss_ckmk_ManufacturerID;
-NSS_EXTERN_DATA const NSSUTF8 *nss_ckmk_LibraryDescription;
-NSS_EXTERN_DATA const CK_VERSION nss_ckmk_LibraryVersion;
-NSS_EXTERN_DATA const NSSUTF8 *nss_ckmk_SlotDescription;
-NSS_EXTERN_DATA const CK_VERSION nss_ckmk_HardwareVersion;
-NSS_EXTERN_DATA const CK_VERSION nss_ckmk_FirmwareVersion;
-NSS_EXTERN_DATA const NSSUTF8 *nss_ckmk_TokenLabel;
-NSS_EXTERN_DATA const NSSUTF8 *nss_ckmk_TokenModel;
-NSS_EXTERN_DATA const NSSUTF8 *nss_ckmk_TokenSerialNumber;
-
-NSS_EXTERN_DATA const NSSCKMDInstance nss_ckmk_mdInstance;
-NSS_EXTERN_DATA const NSSCKMDSlot nss_ckmk_mdSlot;
-NSS_EXTERN_DATA const NSSCKMDToken nss_ckmk_mdToken;
-NSS_EXTERN_DATA const NSSCKMDMechanism nss_ckmk_mdMechanismRSA;
-
-NSS_EXTERN NSSCKMDSession *
-nss_ckmk_CreateSession(
- NSSCKFWSession *fwSession,
- CK_RV *pError);
-
-NSS_EXTERN NSSCKMDFindObjects *
-nss_ckmk_FindObjectsInit(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError);
-
-/*
- * Object Utilities
- */
-NSS_EXTERN NSSCKMDObject *
-nss_ckmk_CreateMDObject(
- NSSArena *arena,
- ckmkInternalObject *io,
- CK_RV *pError);
-
-NSS_EXTERN NSSCKMDObject *
-nss_ckmk_CreateObject(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError);
-
-NSS_EXTERN const NSSItem *
-nss_ckmk_FetchAttribute(
- ckmkInternalObject *io,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError);
-
-NSS_EXTERN void
-nss_ckmk_DestroyInternalObject(
- ckmkInternalObject *io);
-
-unsigned char *
-nss_ckmk_DERUnwrap(
- unsigned char *src,
- int size,
- int *outSize,
- unsigned char **next);
-
-CK_ULONG
-nss_ckmk_GetULongAttribute(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_RV *pError);
-
-#define NSS_CKMK_ARRAY_SIZE(x) ((sizeof(x)) / (sizeof((x)[0])))
-
-#ifdef DEBUG
-#define CKMK_MACERR(str, err) cssmPerror(str, err)
-#else
-#define CKMK_MACERR(str, err)
-#endif
-
-#endif
diff --git a/security/nss/lib/ckfw/nssmkey/ckmkver.c b/security/nss/lib/ckfw/nssmkey/ckmkver.c
deleted file mode 100644
index 2b99f1e228..0000000000
--- a/security/nss/lib/ckfw/nssmkey/ckmkver.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* Library identity and versioning */
-
-#include "nssmkey.h"
-
-#if defined(DEBUG)
-#define _DEBUG_STRING " (debug)"
-#else
-#define _DEBUG_STRING ""
-#endif
-
-/*
- * Version information
- */
-const char __nss_ckmk_version[] = "Version: NSS Access to the MAC OS X Key Ring " NSS_CKMK_LIBRARY_VERSION _DEBUG_STRING;
diff --git a/security/nss/lib/ckfw/nssmkey/config.mk b/security/nss/lib/ckfw/nssmkey/config.mk
deleted file mode 100644
index 7096910679..0000000000
--- a/security/nss/lib/ckfw/nssmkey/config.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-ifdef BUILD_IDG
-DEFINES += -DNSSDEBUG
-endif
-
-ifdef NS_USE_CKFW_TRACE
-DEFINES += -DTRACE
-endif
-
-#
-# Override TARGETS variable so that only static libraries
-# are specifed as dependencies within rules.mk.
-#
-
-TARGETS = $(LIBRARY)
-SHARED_LIBRARY =
-IMPORT_LIBRARY =
-PROGRAM =
-
-
diff --git a/security/nss/lib/ckfw/nssmkey/manchor.c b/security/nss/lib/ckfw/nssmkey/manchor.c
deleted file mode 100644
index 3b8bc2dbbe..0000000000
--- a/security/nss/lib/ckfw/nssmkey/manchor.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * nssmkey/manchor.c
- *
- * This file "anchors" the actual cryptoki entry points in this module's
- * shared library, which is required for dynamic loading. See the
- * comments in nssck.api for more information.
- */
-
-#include "ckmk.h"
-
-#define MODULE_NAME ckmk
-#define INSTANCE_NAME (NSSCKMDInstance *)&nss_ckmk_mdInstance
-#include "nssck.api"
diff --git a/security/nss/lib/ckfw/nssmkey/manifest.mn b/security/nss/lib/ckfw/nssmkey/manifest.mn
deleted file mode 100644
index 036d9bc3f4..0000000000
--- a/security/nss/lib/ckfw/nssmkey/manifest.mn
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-CORE_DEPTH = ../../../..
-
-MODULE = nss
-MAPFILE = $(OBJDIR)/nssmkey.def
-
-EXPORTS = \
- nssmkey.h \
- $(NULL)
-
-CSRCS = \
- manchor.c \
- mconstants.c \
- mfind.c \
- minst.c \
- mobject.c \
- mrsa.c \
- msession.c \
- mslot.c \
- mtoken.c \
- ckmkver.c \
- staticobj.c \
- $(NULL)
-
-REQUIRES = nspr
-
-LIBRARY_NAME = nssmkey
-
-#EXTRA_SHARED_LIBS = -L$(DIST)/lib -lnssckfw -lnssb -lplc4 -lplds4
diff --git a/security/nss/lib/ckfw/nssmkey/mconstants.c b/security/nss/lib/ckfw/nssmkey/mconstants.c
deleted file mode 100644
index c26298ada3..0000000000
--- a/security/nss/lib/ckfw/nssmkey/mconstants.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/*
- * nssmkey/constants.c
- *
- * Identification and other constants, all collected here in one place.
- */
-
-#ifndef NSSBASET_H
-#include "nssbaset.h"
-#endif /* NSSBASET_H */
-
-#ifndef NSSCKT_H
-#include "nssckt.h"
-#endif /* NSSCKT_H */
-
-#include "nssmkey.h"
-
-NSS_IMPLEMENT_DATA const CK_VERSION
- nss_ckmk_CryptokiVersion = {
- NSS_CKMK_CRYPTOKI_VERSION_MAJOR,
- NSS_CKMK_CRYPTOKI_VERSION_MINOR
- };
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
- nss_ckmk_ManufacturerID = (NSSUTF8 *)"Mozilla Foundation";
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
- nss_ckmk_LibraryDescription = (NSSUTF8 *)"NSS Access to Mac OS X Key Ring";
-
-NSS_IMPLEMENT_DATA const CK_VERSION
- nss_ckmk_LibraryVersion = {
- NSS_CKMK_LIBRARY_VERSION_MAJOR,
- NSS_CKMK_LIBRARY_VERSION_MINOR
- };
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
- nss_ckmk_SlotDescription = (NSSUTF8 *)"Mac OS X Key Ring";
-
-NSS_IMPLEMENT_DATA const CK_VERSION
- nss_ckmk_HardwareVersion = {
- NSS_CKMK_HARDWARE_VERSION_MAJOR,
- NSS_CKMK_HARDWARE_VERSION_MINOR
- };
-
-NSS_IMPLEMENT_DATA const CK_VERSION
- nss_ckmk_FirmwareVersion = {
- NSS_CKMK_FIRMWARE_VERSION_MAJOR,
- NSS_CKMK_FIRMWARE_VERSION_MINOR
- };
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
- nss_ckmk_TokenLabel = (NSSUTF8 *)"Mac OS X Key Ring";
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
- nss_ckmk_TokenModel = (NSSUTF8 *)"1";
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
- nss_ckmk_TokenSerialNumber = (NSSUTF8 *)"1";
diff --git a/security/nss/lib/ckfw/nssmkey/mfind.c b/security/nss/lib/ckfw/nssmkey/mfind.c
deleted file mode 100644
index d193a8de70..0000000000
--- a/security/nss/lib/ckfw/nssmkey/mfind.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CKMK_H
-#include "ckmk.h"
-#endif /* CKMK_H */
-
-/*
- * nssmkey/mfind.c
- *
- * This file implements the NSSCKMDFindObjects object for the
- * "nssmkey" cryptoki module.
- */
-
-struct ckmkFOStr {
- NSSArena *arena;
- CK_ULONG n;
- CK_ULONG i;
- ckmkInternalObject **objs;
-};
-
-static void
-ckmk_mdFindObjects_Final(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- struct ckmkFOStr *fo = (struct ckmkFOStr *)mdFindObjects->etc;
- NSSArena *arena = fo->arena;
- PRUint32 i;
-
- /* walk down an free the unused 'objs' */
- for (i = fo->i; i < fo->n; i++) {
- nss_ckmk_DestroyInternalObject(fo->objs[i]);
- }
-
- nss_ZFreeIf(fo->objs);
- nss_ZFreeIf(fo);
- nss_ZFreeIf(mdFindObjects);
- if ((NSSArena *)NULL != arena) {
- NSSArena_Destroy(arena);
- }
-
- return;
-}
-
-static NSSCKMDObject *
-ckmk_mdFindObjects_Next(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError)
-{
- struct ckmkFOStr *fo = (struct ckmkFOStr *)mdFindObjects->etc;
- ckmkInternalObject *io;
-
- if (fo->i == fo->n) {
- *pError = CKR_OK;
- return (NSSCKMDObject *)NULL;
- }
-
- io = fo->objs[fo->i];
- fo->i++;
-
- return nss_ckmk_CreateMDObject(arena, io, pError);
-}
-
-static CK_BBOOL
-ckmk_attrmatch(
- CK_ATTRIBUTE_PTR a,
- ckmkInternalObject *o)
-{
- PRBool prb;
- const NSSItem *b;
- CK_RV error;
-
- b = nss_ckmk_FetchAttribute(o, a->type, &error);
- if (b == NULL) {
- return CK_FALSE;
- }
-
- if (a->ulValueLen != b->size) {
- /* match a decoded serial number */
- if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
- int len;
- unsigned char *data;
-
- data = nss_ckmk_DERUnwrap(b->data, b->size, &len, NULL);
- if ((len == a->ulValueLen) &&
- nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
- return CK_TRUE;
- }
- }
- return CK_FALSE;
- }
-
- prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
-
- if (PR_TRUE == prb) {
- return CK_TRUE;
- } else {
- return CK_FALSE;
- }
-}
-
-static CK_BBOOL
-ckmk_match(
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckmkInternalObject *o)
-{
- CK_ULONG i;
-
- for (i = 0; i < ulAttributeCount; i++) {
- if (CK_FALSE == ckmk_attrmatch(&pTemplate[i], o)) {
- return CK_FALSE;
- }
- }
-
- /* Every attribute passed */
- return CK_TRUE;
-}
-
-#define CKMK_ITEM_CHUNK 20
-
-#define PUT_OBJECT(obj, err, size, count, list) \
- { \
- if (count >= size) { \
- (list) = (list) ? nss_ZREALLOCARRAY(list, ckmkInternalObject *, \
- ((size) + \
- CKMK_ITEM_CHUNK)) \
- : nss_ZNEWARRAY(NULL, ckmkInternalObject *, \
- ((size) + \
- CKMK_ITEM_CHUNK)); \
- if ((ckmkInternalObject **)NULL == list) { \
- err = CKR_HOST_MEMORY; \
- goto loser; \
- } \
- (size) += CKMK_ITEM_CHUNK; \
- } \
- (list)[count] = (obj); \
- count++; \
- }
-
-/* find all the certs that represent the appropriate object (cert, priv key, or
- * pub key) in the cert store.
- */
-static PRUint32
-collect_class(
- CK_OBJECT_CLASS objClass,
- SecItemClass itemClass,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckmkInternalObject ***listp,
- PRUint32 *sizep,
- PRUint32 count,
- CK_RV *pError)
-{
- ckmkInternalObject *next = NULL;
- SecKeychainSearchRef searchRef = 0;
- SecKeychainItemRef itemRef = 0;
- OSStatus error;
-
- /* future, build the attribute list based on the template
- * so we can refine the search */
- error = SecKeychainSearchCreateFromAttributes(
- NULL, itemClass, NULL, &searchRef);
-
- while (noErr == SecKeychainSearchCopyNext(searchRef, &itemRef)) {
- /* if we don't have an internal object structure, get one */
- if ((ckmkInternalObject *)NULL == next) {
- next = nss_ZNEW(NULL, ckmkInternalObject);
- if ((ckmkInternalObject *)NULL == next) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
- }
- /* fill in the relevant object data */
- next->type = ckmkItem;
- next->objClass = objClass;
- next->u.item.itemRef = itemRef;
- next->u.item.itemClass = itemClass;
-
- /* see if this is one of the objects we are looking for */
- if (CK_TRUE == ckmk_match(pTemplate, ulAttributeCount, next)) {
- /* yes, put it on the list */
- PUT_OBJECT(next, *pError, *sizep, count, *listp);
- next = NULL; /* this one is on the list, need to allocate a new one now */
- } else {
- /* no , release the current item and clear out the structure for reuse */
- CFRelease(itemRef);
- /* don't cache the values we just loaded */
- nsslibc_memset(next, 0, sizeof(*next));
- }
- }
-loser:
- if (searchRef) {
- CFRelease(searchRef);
- }
- nss_ZFreeIf(next);
- return count;
-}
-
-static PRUint32
-collect_objects(
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckmkInternalObject ***listp,
- CK_RV *pError)
-{
- PRUint32 i;
- PRUint32 count = 0;
- PRUint32 size = 0;
- CK_OBJECT_CLASS objClass;
-
- /*
- * first handle the static build in objects (if any)
- */
- for (i = 0; i < nss_ckmk_nObjects; i++) {
- ckmkInternalObject *o = (ckmkInternalObject *)&nss_ckmk_data[i];
-
- if (CK_TRUE == ckmk_match(pTemplate, ulAttributeCount, o)) {
- PUT_OBJECT(o, *pError, size, count, *listp);
- }
- }
-
- /*
- * now handle the various object types
- */
- objClass = nss_ckmk_GetULongAttribute(CKA_CLASS,
- pTemplate, ulAttributeCount, pError);
- if (CKR_OK != *pError) {
- objClass = CK_INVALID_HANDLE;
- }
- *pError = CKR_OK;
- switch (objClass) {
- case CKO_CERTIFICATE:
- count = collect_class(objClass, kSecCertificateItemClass,
- pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- case CKO_PUBLIC_KEY:
- count = collect_class(objClass, CSSM_DL_DB_RECORD_PUBLIC_KEY,
- pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- case CKO_PRIVATE_KEY:
- count = collect_class(objClass, CSSM_DL_DB_RECORD_PRIVATE_KEY,
- pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- /* all of them */
- case CK_INVALID_HANDLE:
- count = collect_class(CKO_CERTIFICATE, kSecCertificateItemClass,
- pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- count = collect_class(CKO_PUBLIC_KEY, CSSM_DL_DB_RECORD_PUBLIC_KEY,
- pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- count = collect_class(CKO_PUBLIC_KEY, CSSM_DL_DB_RECORD_PRIVATE_KEY,
- pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- default:
- break;
- }
- if (CKR_OK != *pError) {
- goto loser;
- }
-
- return count;
-loser:
- nss_ZFreeIf(*listp);
- return 0;
-}
-
-NSS_IMPLEMENT NSSCKMDFindObjects *
-nss_ckmk_FindObjectsInit(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError)
-{
- /* This could be made more efficient. I'm rather rushed. */
- NSSArena *arena;
- NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
- struct ckmkFOStr *fo = (struct ckmkFOStr *)NULL;
- ckmkInternalObject **temp = (ckmkInternalObject **)NULL;
-
- arena = NSSArena_Create();
- if ((NSSArena *)NULL == arena) {
- goto loser;
- }
-
- rv = nss_ZNEW(arena, NSSCKMDFindObjects);
- if ((NSSCKMDFindObjects *)NULL == rv) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- fo = nss_ZNEW(arena, struct ckmkFOStr);
- if ((struct ckmkFOStr *)NULL == fo) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- fo->arena = arena;
- /* fo->n and fo->i are already zero */
-
- rv->etc = (void *)fo;
- rv->Final = ckmk_mdFindObjects_Final;
- rv->Next = ckmk_mdFindObjects_Next;
- rv->null = (void *)NULL;
-
- fo->n = collect_objects(pTemplate, ulAttributeCount, &temp, pError);
- if (*pError != CKR_OK) {
- goto loser;
- }
-
- fo->objs = nss_ZNEWARRAY(arena, ckmkInternalObject *, fo->n);
- if ((ckmkInternalObject **)NULL == fo->objs) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- (void)nsslibc_memcpy(fo->objs, temp, sizeof(ckmkInternalObject *) * fo->n);
- nss_ZFreeIf(temp);
- temp = (ckmkInternalObject **)NULL;
-
- return rv;
-
-loser:
- nss_ZFreeIf(temp);
- nss_ZFreeIf(fo);
- nss_ZFreeIf(rv);
- if ((NSSArena *)NULL != arena) {
- NSSArena_Destroy(arena);
- }
- return (NSSCKMDFindObjects *)NULL;
-}
diff --git a/security/nss/lib/ckfw/nssmkey/minst.c b/security/nss/lib/ckfw/nssmkey/minst.c
deleted file mode 100644
index fcb96c6527..0000000000
--- a/security/nss/lib/ckfw/nssmkey/minst.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ckmk.h"
-
-/*
- * nssmkey/minstance.c
- *
- * This file implements the NSSCKMDInstance object for the
- * "nssmkey" cryptoki module.
- */
-
-/*
- * NSSCKMDInstance methods
- */
-
-static CK_ULONG
-ckmk_mdInstance_GetNSlots(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (CK_ULONG)1;
-}
-
-static CK_VERSION
-ckmk_mdInstance_GetCryptokiVersion(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return nss_ckmk_CryptokiVersion;
-}
-
-static NSSUTF8 *
-ckmk_mdInstance_GetManufacturerID(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckmk_ManufacturerID;
-}
-
-static NSSUTF8 *
-ckmk_mdInstance_GetLibraryDescription(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckmk_LibraryDescription;
-}
-
-static CK_VERSION
-ckmk_mdInstance_GetLibraryVersion(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return nss_ckmk_LibraryVersion;
-}
-
-static CK_RV
-ckmk_mdInstance_GetSlots(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *slots[])
-{
- slots[0] = (NSSCKMDSlot *)&nss_ckmk_mdSlot;
- return CKR_OK;
-}
-
-static CK_BBOOL
-ckmk_mdInstance_ModuleHandlesSessionObjects(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- /* we don't want to allow any session object creation, at least
- * until we can investigate whether or not we can use those objects
- */
- return CK_TRUE;
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDInstance
- nss_ckmk_mdInstance = {
- (void *)NULL, /* etc */
- NULL, /* Initialize */
- NULL, /* Finalize */
- ckmk_mdInstance_GetNSlots,
- ckmk_mdInstance_GetCryptokiVersion,
- ckmk_mdInstance_GetManufacturerID,
- ckmk_mdInstance_GetLibraryDescription,
- ckmk_mdInstance_GetLibraryVersion,
- ckmk_mdInstance_ModuleHandlesSessionObjects,
- /*NULL, /* HandleSessionObjects */
- ckmk_mdInstance_GetSlots,
- NULL, /* WaitForSlotEvent */
- (void *)NULL /* null terminator */
- };
diff --git a/security/nss/lib/ckfw/nssmkey/mobject.c b/security/nss/lib/ckfw/nssmkey/mobject.c
deleted file mode 100644
index b19a8fdbde..0000000000
--- a/security/nss/lib/ckfw/nssmkey/mobject.c
+++ /dev/null
@@ -1,1861 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ckmk.h"
-#include "nssbase.h"
-
-#include "secdert.h" /* for DER_INTEGER */
-#include "string.h"
-
-/* asn1 encoder (to build pkcs#8 blobs) */
-#include <seccomon.h>
-#include <secitem.h>
-#include <blapit.h>
-#include <secoid.h>
-#include <secasn1.h>
-
-/* for importing the keys */
-#include <CoreFoundation/CoreFoundation.h>
-#include <security/SecImportExport.h>
-
-/*
- * nssmkey/mobject.c
- *
- * This file implements the NSSCKMDObject object for the
- * "nssmkey" cryptoki module.
- */
-
-const CK_ATTRIBUTE_TYPE certAttrs[] = {
- CKA_CLASS,
- CKA_TOKEN,
- CKA_PRIVATE,
- CKA_MODIFIABLE,
- CKA_LABEL,
- CKA_CERTIFICATE_TYPE,
- CKA_SUBJECT,
- CKA_ISSUER,
- CKA_SERIAL_NUMBER,
- CKA_VALUE
-};
-const PRUint32 certAttrsCount = NSS_CKMK_ARRAY_SIZE(certAttrs);
-
-/* private keys, for now only support RSA */
-const CK_ATTRIBUTE_TYPE privKeyAttrs[] = {
- CKA_CLASS,
- CKA_TOKEN,
- CKA_PRIVATE,
- CKA_MODIFIABLE,
- CKA_LABEL,
- CKA_KEY_TYPE,
- CKA_DERIVE,
- CKA_LOCAL,
- CKA_SUBJECT,
- CKA_SENSITIVE,
- CKA_DECRYPT,
- CKA_SIGN,
- CKA_SIGN_RECOVER,
- CKA_UNWRAP,
- CKA_EXTRACTABLE,
- CKA_ALWAYS_SENSITIVE,
- CKA_NEVER_EXTRACTABLE,
- CKA_MODULUS,
- CKA_PUBLIC_EXPONENT,
-};
-const PRUint32 privKeyAttrsCount = NSS_CKMK_ARRAY_SIZE(privKeyAttrs);
-
-/* public keys, for now only support RSA */
-const CK_ATTRIBUTE_TYPE pubKeyAttrs[] = {
- CKA_CLASS,
- CKA_TOKEN,
- CKA_PRIVATE,
- CKA_MODIFIABLE,
- CKA_LABEL,
- CKA_KEY_TYPE,
- CKA_DERIVE,
- CKA_LOCAL,
- CKA_SUBJECT,
- CKA_ENCRYPT,
- CKA_VERIFY,
- CKA_VERIFY_RECOVER,
- CKA_WRAP,
- CKA_MODULUS,
- CKA_PUBLIC_EXPONENT,
-};
-const PRUint32 pubKeyAttrsCount = NSS_CKMK_ARRAY_SIZE(pubKeyAttrs);
-static const CK_BBOOL ck_true = CK_TRUE;
-static const CK_BBOOL ck_false = CK_FALSE;
-static const CK_CERTIFICATE_TYPE ckc_x509 = CKC_X_509;
-static const CK_KEY_TYPE ckk_rsa = CKK_RSA;
-static const CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE;
-static const CK_OBJECT_CLASS cko_private_key = CKO_PRIVATE_KEY;
-static const CK_OBJECT_CLASS cko_public_key = CKO_PUBLIC_KEY;
-static const NSSItem ckmk_trueItem = {
- (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL)
-};
-static const NSSItem ckmk_falseItem = {
- (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL)
-};
-static const NSSItem ckmk_x509Item = {
- (void *)&ckc_x509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE)
-};
-static const NSSItem ckmk_rsaItem = {
- (void *)&ckk_rsa, (PRUint32)sizeof(CK_KEY_TYPE)
-};
-static const NSSItem ckmk_certClassItem = {
- (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS)
-};
-static const NSSItem ckmk_privKeyClassItem = {
- (void *)&cko_private_key, (PRUint32)sizeof(CK_OBJECT_CLASS)
-};
-static const NSSItem ckmk_pubKeyClassItem = {
- (void *)&cko_public_key, (PRUint32)sizeof(CK_OBJECT_CLASS)
-};
-static const NSSItem ckmk_emptyItem = {
- (void *)&ck_true, 0
-};
-
-/*
- * these are utilities. The chould be moved to a new utilities file.
- */
-#ifdef DEBUG
-static void
-itemdump(char *str, void *data, int size, CK_RV error)
-{
- unsigned char *ptr = (unsigned char *)data;
- int i;
- fprintf(stderr, str);
- for (i = 0; i < size; i++) {
- fprintf(stderr, "%02x ", (unsigned int)ptr[i]);
- }
- fprintf(stderr, " (error = %d)\n", (int)error);
-}
-#endif
-
-/*
- * unwrap a single DER value
- * now that we have util linked in, we should probably use
- * the ANS1_Decoder for this work...
- */
-unsigned char *
-nss_ckmk_DERUnwrap(
- unsigned char *src,
- int size,
- int *outSize,
- unsigned char **next)
-{
- unsigned char *start = src;
- unsigned int len = 0;
-
- /* initialize error condition return values */
- *outSize = 0;
- if (next) {
- *next = src;
- }
-
- if (size < 2) {
- return start;
- }
- src++; /* skip the tag -- should check it against an expected value! */
- len = (unsigned)*src++;
- if (len & 0x80) {
- int count = len & 0x7f;
- len = 0;
-
- if (count + 2 > size) {
- return start;
- }
- while (count-- > 0) {
- len = (len << 8) | (unsigned)*src++;
- }
- }
- if (len + (src - start) > (unsigned int)size) {
- return start;
- }
- if (next) {
- *next = src + len;
- }
- *outSize = len;
-
- return src;
-}
-
-/*
- * get an attribute from a template. Value is returned in NSS item.
- * data for the item is owned by the template.
- */
-CK_RV
-nss_ckmk_GetAttribute(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- NSSItem *item)
-{
- CK_ULONG i;
-
- for (i = 0; i < templateSize; i++) {
- if (template[i].type == type) {
- item->data = template[i].pValue;
- item->size = template[i].ulValueLen;
- return CKR_OK;
- }
- }
- return CKR_TEMPLATE_INCOMPLETE;
-}
-
-/*
- * get an attribute which is type CK_ULONG.
- */
-CK_ULONG
-nss_ckmk_GetULongAttribute(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_RV *pError)
-{
- NSSItem item;
-
- *pError = nss_ckmk_GetAttribute(type, template, templateSize, &item);
- if (CKR_OK != *pError) {
- return (CK_ULONG)0;
- }
- if (item.size != sizeof(CK_ULONG)) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- return (CK_ULONG)0;
- }
- return *(CK_ULONG *)item.data;
-}
-
-/*
- * get an attribute which is type CK_BBOOL.
- */
-CK_BBOOL
-nss_ckmk_GetBoolAttribute(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_BBOOL defaultBool)
-{
- NSSItem item;
- CK_RV error;
-
- error = nss_ckmk_GetAttribute(type, template, templateSize, &item);
- if (CKR_OK != error) {
- return defaultBool;
- }
- if (item.size != sizeof(CK_BBOOL)) {
- return defaultBool;
- }
- return *(CK_BBOOL *)item.data;
-}
-
-/*
- * get an attribute as a NULL terminated string. Caller is responsible to
- * free the string.
- */
-char *
-nss_ckmk_GetStringAttribute(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_RV *pError)
-{
- NSSItem item;
- char *str;
-
- /* get the attribute */
- *pError = nss_ckmk_GetAttribute(type, template, templateSize, &item);
- if (CKR_OK != *pError) {
- return (char *)NULL;
- }
- /* make sure it is null terminated */
- str = nss_ZNEWARRAY(NULL, char, item.size + 1);
- if ((char *)NULL == str) {
- *pError = CKR_HOST_MEMORY;
- return (char *)NULL;
- }
-
- nsslibc_memcpy(str, item.data, item.size);
- str[item.size] = 0;
-
- return str;
-}
-
-/*
- * Apple doesn't seem to have a public interface to the DER encoder,
- * wip out a quick one for integers only (anything more complicated,
- * we should use one of the 3 in lib/util). -- especially since we
- * now link with it.
- */
-static CK_RV
-ckmk_encodeInt(NSSItem *dest, void *src, int srcLen)
-{
- int dataLen = srcLen;
- int lenLen = 1;
- int encLen;
- int isSigned = 0;
- int offset = 0;
- unsigned char *data = NULL;
- int i;
-
- if (*(unsigned char *)src & 0x80) {
- dataLen++;
- isSigned = 1;
- }
-
- /* calculate the length of the length specifier */
- /* (NOTE: destroys dataLen value) */
- if (dataLen > 0x7f) {
- do {
- lenLen++;
- dataLen >>= 8;
- } while (dataLen);
- }
-
- /* calculate our total length */
- dataLen = isSigned + srcLen;
- encLen = 1 + lenLen + dataLen;
- data = nss_ZNEWARRAY(NULL, unsigned char, encLen);
- if ((unsigned char *)NULL == data) {
- return CKR_HOST_MEMORY;
- }
- data[0] = DER_INTEGER;
- if (1 == lenLen) {
- data[1] = dataLen;
- } else {
- data[1] = 0x80 + lenLen;
- for (i = 0; i < lenLen; i++) {
- data[i + 1] = ((dataLen >> ((lenLen -
- i - 1) *
- 8)) &
- 0xff);
- }
- }
- offset = lenLen + 1;
-
- if (isSigned) {
- data[offset++] = 0;
- }
- nsslibc_memcpy(&data[offset], src, srcLen);
- dest->data = data;
- dest->size = encLen;
- return CKR_OK;
-}
-
-/*
- * Get a Keyring attribute. If content is set to true, then we get the
- * content, not the attribute.
- */
-static CK_RV
-ckmk_GetCommonAttribute(
- ckmkInternalObject *io,
- SecItemAttr itemAttr,
- PRBool content,
- NSSItem *item,
- char *dbString)
-{
- SecKeychainAttributeList *attrList = NULL;
- SecKeychainAttributeInfo attrInfo;
- PRUint32 len = 0;
- PRUint32 dataLen = 0;
- PRUint32 attrFormat = 0;
- void *dataVal = 0;
- void *out = NULL;
- CK_RV error = CKR_OK;
- OSStatus macErr;
-
- attrInfo.count = 1;
- attrInfo.tag = &itemAttr;
- attrInfo.format = &attrFormat;
-
- macErr = SecKeychainItemCopyAttributesAndData(io->u.item.itemRef,
- &attrInfo, NULL, &attrList, &len, &out);
- if (noErr != macErr) {
- CKMK_MACERR(dbString, macErr);
- return CKR_ATTRIBUTE_TYPE_INVALID;
- }
- dataLen = content ? len : attrList->attr->length;
- dataVal = content ? out : attrList->attr->data;
-
- /* Apple's documentation says this value is DER Encoded, but it clearly isn't
- * der encode it before we ship it back off to NSS
- */
- if (kSecSerialNumberItemAttr == itemAttr) {
- error = ckmk_encodeInt(item, dataVal, dataLen);
- goto loser; /* logically 'done' if error == CKR_OK */
- }
- item->data = nss_ZNEWARRAY(NULL, char, dataLen);
- if (NULL == item->data) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- nsslibc_memcpy(item->data, dataVal, dataLen);
- item->size = dataLen;
-
-loser:
- SecKeychainItemFreeAttributesAndData(attrList, out);
- return error;
-}
-
-/*
- * change an attribute (does not operate on the content).
- */
-static CK_RV
-ckmk_updateAttribute(
- SecKeychainItemRef itemRef,
- SecItemAttr itemAttr,
- void *data,
- PRUint32 len,
- char *dbString)
-{
- SecKeychainAttributeList attrList;
- SecKeychainAttribute attrAttr;
- OSStatus macErr;
- CK_RV error = CKR_OK;
-
- attrList.count = 1;
- attrList.attr = &attrAttr;
- attrAttr.tag = itemAttr;
- attrAttr.data = data;
- attrAttr.length = len;
- macErr = SecKeychainItemModifyAttributesAndData(itemRef, &attrList, 0, NULL);
- if (noErr != macErr) {
- CKMK_MACERR(dbString, macErr);
- error = CKR_ATTRIBUTE_TYPE_INVALID;
- }
- return error;
-}
-
-/*
- * get an attribute (does not operate on the content)
- */
-static CK_RV
-ckmk_GetDataAttribute(
- ckmkInternalObject *io,
- SecItemAttr itemAttr,
- NSSItem *item,
- char *dbString)
-{
- return ckmk_GetCommonAttribute(io, itemAttr, PR_FALSE, item, dbString);
-}
-
-/*
- * get an attribute we know is a BOOL.
- */
-static CK_RV
-ckmk_GetBoolAttribute(
- ckmkInternalObject *io,
- SecItemAttr itemAttr,
- NSSItem *item,
- char *dbString)
-{
- SecKeychainAttribute attr;
- SecKeychainAttributeList attrList;
- CK_BBOOL *boolp = NULL;
- PRUint32 len = 0;
- ;
- void *out = NULL;
- CK_RV error = CKR_OK;
- OSStatus macErr;
-
- attr.tag = itemAttr;
- attr.length = 0;
- attr.data = NULL;
- attrList.count = 1;
- attrList.attr = &attr;
-
- boolp = nss_ZNEW(NULL, CK_BBOOL);
- if ((CK_BBOOL *)NULL == boolp) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
-
- macErr = SecKeychainItemCopyContent(io->u.item.itemRef, NULL,
- &attrList, &len, &out);
- if (noErr != macErr) {
- CKMK_MACERR(dbString, macErr);
- error = CKR_ATTRIBUTE_TYPE_INVALID;
- goto loser;
- }
- if (sizeof(PRUint32) != attr.length) {
- error = CKR_ATTRIBUTE_TYPE_INVALID;
- goto loser;
- }
- *boolp = *(PRUint32 *)attr.data ? 1 : 0;
- item->data = boolp;
- boolp = NULL;
- item->size = sizeof(CK_BBOOL);
-
-loser:
- nss_ZFreeIf(boolp);
- SecKeychainItemFreeContent(&attrList, out);
- return error;
-}
-
-/*
- * macros for fetching attributes into a cache and returning the
- * appropriate value. These operate inside switch statements
- */
-#define CKMK_HANDLE_ITEM(func, io, type, loc, item, error, str) \
- if (0 == (item)->loc.size) { \
- error = func(io, type, &(item)->loc, str); \
- } \
- return (CKR_OK == (error)) ? &(item)->loc : NULL;
-
-#define CKMK_HANDLE_OPT_ITEM(func, io, type, loc, item, error, str) \
- if (0 == (item)->loc.size) { \
- (void)func(io, type, &(item)->loc, str); \
- } \
- return &(item)->loc;
-
-#define CKMK_HANDLE_BOOL_ITEM(io, type, loc, item, error, str) \
- CKMK_HANDLE_ITEM(ckmk_GetBoolAttribute, io, type, loc, item, error, str)
-#define CKMK_HANDLE_DATA_ITEM(io, type, loc, item, error, str) \
- CKMK_HANDLE_ITEM(ckmk_GetDataAttribute, io, type, loc, item, error, str)
-#define CKMK_HANDLE_OPT_DATA_ITEM(io, type, loc, item, error, str) \
- CKMK_HANDLE_OPT_ITEM(ckmk_GetDataAttribute, io, type, loc, item, error, str)
-
-/*
- * fetch the unique identifier for each object type.
- */
-static void
-ckmk_FetchHashKey(
- ckmkInternalObject *io)
-{
- NSSItem *key = &io->hashKey;
-
- if (io->objClass == CKO_CERTIFICATE) {
- ckmk_GetCommonAttribute(io, kSecCertEncodingItemAttr,
- PR_TRUE, key, "Fetching HashKey (cert)");
- } else {
- ckmk_GetCommonAttribute(io, kSecKeyLabel,
- PR_FALSE, key, "Fetching HashKey (key)");
- }
-}
-
-/*
- * Apple mucks with the actual subject and issuer, so go fetch
- * the real ones ourselves.
- */
-static void
-ckmk_fetchCert(
- ckmkInternalObject *io)
-{
- CK_RV error;
- unsigned char *cert, *next;
- int certSize, thisEntrySize;
-
- error = ckmk_GetCommonAttribute(io, kSecCertEncodingItemAttr, PR_TRUE,
- &io->u.item.derCert, "Fetching Value (cert)");
- if (CKR_OK != error) {
- return;
- }
- /* unwrap the cert bundle */
- cert = nss_ckmk_DERUnwrap((unsigned char *)io->u.item.derCert.data,
- io->u.item.derCert.size,
- &certSize, NULL);
- /* unwrap the cert itself */
- /* cert == certdata */
- cert = nss_ckmk_DERUnwrap(cert, certSize, &certSize, NULL);
-
- /* skip the optional version */
- if ((cert[0] & 0xa0) == 0xa0) {
- nss_ckmk_DERUnwrap(cert, certSize, &thisEntrySize, &next);
- certSize -= next - cert;
- cert = next;
- }
- /* skip the serial number */
- nss_ckmk_DERUnwrap(cert, certSize, &thisEntrySize, &next);
- certSize -= next - cert;
- cert = next;
-
- /* skip the OID */
- nss_ckmk_DERUnwrap(cert, certSize, &thisEntrySize, &next);
- certSize -= next - cert;
- cert = next;
-
- /* save the (wrapped) issuer */
- io->u.item.issuer.data = cert;
- nss_ckmk_DERUnwrap(cert, certSize, &thisEntrySize, &next);
- io->u.item.issuer.size = next - cert;
- certSize -= io->u.item.issuer.size;
- cert = next;
-
- /* skip the OID */
- nss_ckmk_DERUnwrap(cert, certSize, &thisEntrySize, &next);
- certSize -= next - cert;
- cert = next;
-
- /* save the (wrapped) subject */
- io->u.item.subject.data = cert;
- nss_ckmk_DERUnwrap(cert, certSize, &thisEntrySize, &next);
- io->u.item.subject.size = next - cert;
- certSize -= io->u.item.subject.size;
- cert = next;
-}
-
-static void
-ckmk_fetchModulus(
- ckmkInternalObject *io)
-{
- NSSItem item;
- PRInt32 modLen;
- CK_RV error;
-
- /* we can't reliably get the modulus for private keys through CSSM (sigh).
- * For NSS this is OK because we really only use this to get the modulus
- * length (unless we are trying to get a public key from a private keys,
- * something CSSM ALSO does not do!).
- */
- error = ckmk_GetDataAttribute(io, kSecKeyKeySizeInBits, &item,
- "Key Fetch Modulus");
- if (CKR_OK != error) {
- return;
- }
-
- modLen = *(PRInt32 *)item.data;
- modLen = modLen / 8; /* convert from bits to bytes */
-
- nss_ZFreeIf(item.data);
- io->u.item.modulus.data = nss_ZNEWARRAY(NULL, char, modLen);
- if (NULL == io->u.item.modulus.data) {
- return;
- }
- *(char *)io->u.item.modulus.data = 0x80; /* fake NSS out or it will
- * drop the first byte */
- io->u.item.modulus.size = modLen;
- return;
-}
-
-const NSSItem *
-ckmk_FetchCertAttribute(
- ckmkInternalObject *io,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError)
-{
- ckmkItemObject *item = &io->u.item;
- *pError = CKR_OK;
- switch (type) {
- case CKA_CLASS:
- return &ckmk_certClassItem;
- case CKA_TOKEN:
- case CKA_MODIFIABLE:
- return &ckmk_trueItem;
- case CKA_PRIVATE:
- return &ckmk_falseItem;
- case CKA_CERTIFICATE_TYPE:
- return &ckmk_x509Item;
- case CKA_LABEL:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecLabelItemAttr, label, item, *pError,
- "Cert:Label attr")
- case CKA_SUBJECT:
- /* OK, well apple does provide an subject and issuer attribute, but they
- * decided to cannonicalize that value. Probably a good move for them,
- * but makes it useless for most users of PKCS #11.. Get the real subject
- * from the certificate */
- if (0 == item->derCert.size) {
- ckmk_fetchCert(io);
- }
- return &item->subject;
- case CKA_ISSUER:
- if (0 == item->derCert.size) {
- ckmk_fetchCert(io);
- }
- return &item->issuer;
- case CKA_SERIAL_NUMBER:
- CKMK_HANDLE_DATA_ITEM(io, kSecSerialNumberItemAttr, serial, item, *pError,
- "Cert:Serial Number attr")
- case CKA_VALUE:
- if (0 == item->derCert.size) {
- ckmk_fetchCert(io);
- }
- return &item->derCert;
- case CKA_ID:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecPublicKeyHashItemAttr, id, item, *pError,
- "Cert:ID attr")
- default:
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- break;
- }
- return NULL;
-}
-
-const NSSItem *
-ckmk_FetchPubKeyAttribute(
- ckmkInternalObject *io,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError)
-{
- ckmkItemObject *item = &io->u.item;
- *pError = CKR_OK;
-
- switch (type) {
- case CKA_CLASS:
- return &ckmk_pubKeyClassItem;
- case CKA_TOKEN:
- case CKA_LOCAL:
- return &ckmk_trueItem;
- case CKA_KEY_TYPE:
- return &ckmk_rsaItem;
- case CKA_LABEL:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecKeyPrintName, label, item, *pError,
- "PubKey:Label attr")
- case CKA_ENCRYPT:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyEncrypt, encrypt, item, *pError,
- "PubKey:Encrypt attr")
- case CKA_VERIFY:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyVerify, verify, item, *pError,
- "PubKey:Verify attr")
- case CKA_VERIFY_RECOVER:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyVerifyRecover, verifyRecover,
- item, *pError, "PubKey:VerifyRecover attr")
- case CKA_PRIVATE:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyPrivate, private, item, *pError,
- "PubKey:Private attr")
- case CKA_MODIFIABLE:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyModifiable, modify, item, *pError,
- "PubKey:Modify attr")
- case CKA_DERIVE:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyDerive, derive, item, *pError,
- "PubKey:Derive attr")
- case CKA_WRAP:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyWrap, wrap, item, *pError,
- "PubKey:Wrap attr")
- case CKA_SUBJECT:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecSubjectItemAttr, subject, item, *pError,
- "PubKey:Subect attr")
- case CKA_MODULUS:
- return &ckmk_emptyItem;
- case CKA_PUBLIC_EXPONENT:
- return &ckmk_emptyItem;
- case CKA_ID:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecKeyLabel, id, item, *pError,
- "PubKey:ID attr")
- default:
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- break;
- }
- return NULL;
-}
-
-const NSSItem *
-ckmk_FetchPrivKeyAttribute(
- ckmkInternalObject *io,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError)
-{
- ckmkItemObject *item = &io->u.item;
- *pError = CKR_OK;
-
- switch (type) {
- case CKA_CLASS:
- return &ckmk_privKeyClassItem;
- case CKA_TOKEN:
- case CKA_LOCAL:
- return &ckmk_trueItem;
- case CKA_SENSITIVE:
- case CKA_EXTRACTABLE: /* will probably move in the future */
- case CKA_ALWAYS_SENSITIVE:
- case CKA_NEVER_EXTRACTABLE:
- return &ckmk_falseItem;
- case CKA_KEY_TYPE:
- return &ckmk_rsaItem;
- case CKA_LABEL:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecKeyPrintName, label, item, *pError,
- "PrivateKey:Label attr")
- case CKA_DECRYPT:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyDecrypt, decrypt, item, *pError,
- "PrivateKey:Decrypt attr")
- case CKA_SIGN:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeySign, sign, item, *pError,
- "PrivateKey:Sign attr")
- case CKA_SIGN_RECOVER:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeySignRecover, signRecover, item, *pError,
- "PrivateKey:Sign Recover attr")
- case CKA_PRIVATE:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyPrivate, private, item, *pError,
- "PrivateKey:Private attr")
- case CKA_MODIFIABLE:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyModifiable, modify, item, *pError,
- "PrivateKey:Modify attr")
- case CKA_DERIVE:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyDerive, derive, item, *pError,
- "PrivateKey:Derive attr")
- case CKA_UNWRAP:
- CKMK_HANDLE_BOOL_ITEM(io, kSecKeyUnwrap, unwrap, item, *pError,
- "PrivateKey:Unwrap attr")
- case CKA_SUBJECT:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecSubjectItemAttr, subject, item, *pError,
- "PrivateKey:Subject attr")
- case CKA_MODULUS:
- if (0 == item->modulus.size) {
- ckmk_fetchModulus(io);
- }
- return &item->modulus;
- case CKA_PUBLIC_EXPONENT:
- return &ckmk_emptyItem;
-#ifdef notdef
- /* the following are sensitive attributes. We could implement them for
- * sensitive keys using the key export function, but it's better to
- * just support wrap through this token. That will more reliably allow us
- * to export any private key that is truly exportable.
- */
- case CKA_PRIVATE_EXPONENT:
- CKMK_HANDLE_DATA_ITEM(io, kSecPrivateExponentItemAttr, privateExponent,
- item, *pError)
- case CKA_PRIME_1:
- CKMK_HANDLE_DATA_ITEM(io, kSecPrime1ItemAttr, prime1, item, *pError)
- case CKA_PRIME_2:
- CKMK_HANDLE_DATA_ITEM(io, kSecPrime2ItemAttr, prime2, item, *pError)
- case CKA_EXPONENT_1:
- CKMK_HANDLE_DATA_ITEM(io, kSecExponent1ItemAttr, exponent1, item, *pError)
- case CKA_EXPONENT_2:
- CKMK_HANDLE_DATA_ITEM(io, kSecExponent2ItemAttr, exponent2, item, *pError)
- case CKA_COEFFICIENT:
- CKMK_HANDLE_DATA_ITEM(io, kSecCoefficientItemAttr, coefficient,
- item, *pError)
-#endif
- case CKA_ID:
- CKMK_HANDLE_OPT_DATA_ITEM(io, kSecKeyLabel, id, item, *pError,
- "PrivateKey:ID attr")
- default:
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- return NULL;
- }
-}
-
-const NSSItem *
-nss_ckmk_FetchAttribute(
- ckmkInternalObject *io,
- CK_ATTRIBUTE_TYPE type,
- CK_RV *pError)
-{
- CK_ULONG i;
- const NSSItem *value = NULL;
-
- if (io->type == ckmkRaw) {
- for (i = 0; i < io->u.raw.n; i++) {
- if (type == io->u.raw.types[i]) {
- return &io->u.raw.items[i];
- }
- }
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- return NULL;
- }
- /* deal with the common attributes */
- switch (io->objClass) {
- case CKO_CERTIFICATE:
- value = ckmk_FetchCertAttribute(io, type, pError);
- break;
- case CKO_PRIVATE_KEY:
- value = ckmk_FetchPrivKeyAttribute(io, type, pError);
- break;
- case CKO_PUBLIC_KEY:
- value = ckmk_FetchPubKeyAttribute(io, type, pError);
- break;
- default:
- *pError = CKR_OBJECT_HANDLE_INVALID;
- return NULL;
- }
-
-#ifdef DEBUG
- if (CKA_ID == type) {
- itemdump("id: ", value->data, value->size, *pError);
- }
-#endif
- return value;
-}
-
-static void
-ckmk_removeObjectFromHash(
- ckmkInternalObject *io);
-
-/*
- *
- * These are the MSObject functions we need to implement
- *
- * Finalize - unneeded (actually we should clean up the hashtables)
- * Destroy
- * IsTokenObject - CK_TRUE
- * GetAttributeCount
- * GetAttributeTypes
- * GetAttributeSize
- * GetAttribute
- * SetAttribute
- * GetObjectSize
- */
-
-static CK_RV
-ckmk_mdObject_Destroy(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- ckmkInternalObject *io = (ckmkInternalObject *)mdObject->etc;
- OSStatus macErr;
-
- if (ckmkRaw == io->type) {
- /* there is not 'object write protected' error, use the next best thing */
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- /* This API is done well. The following 4 lines are the complete apple
- * specific part of this implementation */
- macErr = SecKeychainItemDelete(io->u.item.itemRef);
- if (noErr != macErr) {
- CKMK_MACERR("Delete object", macErr);
- }
-
- /* remove it from the hash */
- ckmk_removeObjectFromHash(io);
-
- /* free the puppy.. */
- nss_ckmk_DestroyInternalObject(io);
-
- return CKR_OK;
-}
-
-static CK_BBOOL
-ckmk_mdObject_IsTokenObject(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return CK_TRUE;
-}
-
-static CK_ULONG
-ckmk_mdObject_GetAttributeCount(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- ckmkInternalObject *io = (ckmkInternalObject *)mdObject->etc;
-
- if (ckmkRaw == io->type) {
- return io->u.raw.n;
- }
- switch (io->objClass) {
- case CKO_CERTIFICATE:
- return certAttrsCount;
- case CKO_PUBLIC_KEY:
- return pubKeyAttrsCount;
- case CKO_PRIVATE_KEY:
- return privKeyAttrsCount;
- default:
- break;
- }
- return 0;
-}
-
-static CK_RV
-ckmk_mdObject_GetAttributeTypes(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE_PTR typeArray,
- CK_ULONG ulCount)
-{
- ckmkInternalObject *io = (ckmkInternalObject *)mdObject->etc;
- CK_ULONG i;
- CK_RV error = CKR_OK;
- const CK_ATTRIBUTE_TYPE *attrs = NULL;
- CK_ULONG size = ckmk_mdObject_GetAttributeCount(
- mdObject, fwObject, mdSession, fwSession,
- mdToken, fwToken, mdInstance, fwInstance, &error);
-
- if (size != ulCount) {
- return CKR_BUFFER_TOO_SMALL;
- }
- if (io->type == ckmkRaw) {
- attrs = io->u.raw.types;
- } else
- switch (io->objClass) {
- case CKO_CERTIFICATE:
- attrs =
- certAttrs;
- break;
- case CKO_PUBLIC_KEY:
- attrs =
- pubKeyAttrs;
- break;
- case CKO_PRIVATE_KEY:
- attrs =
- privKeyAttrs;
- break;
- default:
- return CKR_OK;
- }
-
- for (i = 0; i < size; i++) {
- typeArray[i] = attrs[i];
- }
-
- return CKR_OK;
-}
-
-static CK_ULONG
-ckmk_mdObject_GetAttributeSize(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError)
-{
- ckmkInternalObject *io = (ckmkInternalObject *)mdObject->etc;
-
- const NSSItem *b;
-
- b = nss_ckmk_FetchAttribute(io, attribute, pError);
-
- if ((const NSSItem *)NULL == b) {
- return 0;
- }
- return b->size;
-}
-
-static CK_RV
-ckmk_mdObject_SetAttribute(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *value)
-{
- ckmkInternalObject *io = (ckmkInternalObject *)mdObject->etc;
- SecKeychainItemRef itemRef;
-
- if (io->type == ckmkRaw) {
- return CKR_TOKEN_WRITE_PROTECTED;
- }
- itemRef = io->u.item.itemRef;
-
- switch (io->objClass) {
- case CKO_PRIVATE_KEY:
- case CKO_PUBLIC_KEY:
- switch (attribute) {
- case CKA_ID:
- ckmk_updateAttribute(itemRef, kSecKeyLabel,
- value->data, value->size, "Set Attr Key ID");
-#ifdef DEBUG
- itemdump("key id: ", value->data, value->size, CKR_OK);
-#endif
- break;
- case CKA_LABEL:
- ckmk_updateAttribute(itemRef, kSecKeyPrintName, value->data,
- value->size, "Set Attr Key Label");
- break;
- default:
- break;
- }
- break;
-
- case CKO_CERTIFICATE:
- switch (attribute) {
- case CKA_ID:
- ckmk_updateAttribute(itemRef, kSecPublicKeyHashItemAttr,
- value->data, value->size, "Set Attr Cert ID");
- break;
- case CKA_LABEL:
- ckmk_updateAttribute(itemRef, kSecLabelItemAttr, value->data,
- value->size, "Set Attr Cert Label");
- break;
- default:
- break;
- }
- break;
-
- default:
- break;
- }
- return CKR_OK;
-}
-
-static NSSCKFWItem
-ckmk_mdObject_GetAttribute(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- CK_RV *pError)
-{
- NSSCKFWItem mdItem;
- ckmkInternalObject *io = (ckmkInternalObject *)mdObject->etc;
-
- mdItem.needsFreeing = PR_FALSE;
- mdItem.item = (NSSItem *)nss_ckmk_FetchAttribute(io, attribute, pError);
-
- return mdItem;
-}
-
-static CK_ULONG
-ckmk_mdObject_GetObjectSize(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- CK_ULONG rv = 1;
-
- /* size is irrelevant to this token */
- return rv;
-}
-
-static const NSSCKMDObject
- ckmk_prototype_mdObject = {
- (void *)NULL, /* etc */
- NULL, /* Finalize */
- ckmk_mdObject_Destroy,
- ckmk_mdObject_IsTokenObject,
- ckmk_mdObject_GetAttributeCount,
- ckmk_mdObject_GetAttributeTypes,
- ckmk_mdObject_GetAttributeSize,
- ckmk_mdObject_GetAttribute,
- NULL, /* FreeAttribute */
- ckmk_mdObject_SetAttribute,
- ckmk_mdObject_GetObjectSize,
- (void *)NULL /* null terminator */
- };
-
-static nssHash *ckmkInternalObjectHash = NULL;
-
-NSS_IMPLEMENT NSSCKMDObject *
-nss_ckmk_CreateMDObject(
- NSSArena *arena,
- ckmkInternalObject *io,
- CK_RV *pError)
-{
- if ((nssHash *)NULL == ckmkInternalObjectHash) {
- ckmkInternalObjectHash = nssHash_CreateItem(NULL, 10);
- }
- if (ckmkItem == io->type) {
- /* the hash key, not a cryptographic key */
- NSSItem *key = &io->hashKey;
- ckmkInternalObject *old_o = NULL;
-
- if (key->size == 0) {
- ckmk_FetchHashKey(io);
- }
- old_o = (ckmkInternalObject *)
- nssHash_Lookup(ckmkInternalObjectHash, key);
- if (!old_o) {
- nssHash_Add(ckmkInternalObjectHash, key, io);
- } else if (old_o != io) {
- nss_ckmk_DestroyInternalObject(io);
- io = old_o;
- }
- }
-
- if ((void *)NULL == io->mdObject.etc) {
- (void)nsslibc_memcpy(&io->mdObject, &ckmk_prototype_mdObject,
- sizeof(ckmk_prototype_mdObject));
- io->mdObject.etc = (void *)io;
- }
- return &io->mdObject;
-}
-
-static void
-ckmk_removeObjectFromHash(
- ckmkInternalObject *io)
-{
- NSSItem *key = &io->hashKey;
-
- if ((nssHash *)NULL == ckmkInternalObjectHash) {
- return;
- }
- if (key->size == 0) {
- ckmk_FetchHashKey(io);
- }
- nssHash_Remove(ckmkInternalObjectHash, key);
- return;
-}
-
-void
-nss_ckmk_DestroyInternalObject(
- ckmkInternalObject *io)
-{
- switch (io->type) {
- case ckmkRaw:
- return;
- case ckmkItem:
- nss_ZFreeIf(io->u.item.modify.data);
- nss_ZFreeIf(io->u.item.private.data);
- nss_ZFreeIf(io->u.item.encrypt.data);
- nss_ZFreeIf(io->u.item.decrypt.data);
- nss_ZFreeIf(io->u.item.derive.data);
- nss_ZFreeIf(io->u.item.sign.data);
- nss_ZFreeIf(io->u.item.signRecover.data);
- nss_ZFreeIf(io->u.item.verify.data);
- nss_ZFreeIf(io->u.item.verifyRecover.data);
- nss_ZFreeIf(io->u.item.wrap.data);
- nss_ZFreeIf(io->u.item.unwrap.data);
- nss_ZFreeIf(io->u.item.label.data);
- /*nss_ZFreeIf(io->u.item.subject.data); */
- /*nss_ZFreeIf(io->u.item.issuer.data); */
- nss_ZFreeIf(io->u.item.serial.data);
- nss_ZFreeIf(io->u.item.modulus.data);
- nss_ZFreeIf(io->u.item.exponent.data);
- nss_ZFreeIf(io->u.item.privateExponent.data);
- nss_ZFreeIf(io->u.item.prime1.data);
- nss_ZFreeIf(io->u.item.prime2.data);
- nss_ZFreeIf(io->u.item.exponent1.data);
- nss_ZFreeIf(io->u.item.exponent2.data);
- nss_ZFreeIf(io->u.item.coefficient.data);
- break;
- }
- nss_ZFreeIf(io);
- return;
-}
-
-static ckmkInternalObject *
-nss_ckmk_NewInternalObject(
- CK_OBJECT_CLASS objClass,
- SecKeychainItemRef itemRef,
- SecItemClass itemClass,
- CK_RV *pError)
-{
- ckmkInternalObject *io = nss_ZNEW(NULL, ckmkInternalObject);
-
- if ((ckmkInternalObject *)NULL == io) {
- *pError = CKR_HOST_MEMORY;
- return io;
- }
- io->type = ckmkItem;
- io->objClass = objClass;
- io->u.item.itemRef = itemRef;
- io->u.item.itemClass = itemClass;
- return io;
-}
-
-/*
- * Apple doesn't alway have a default keyChain set by the OS, use the
- * SearchList to try to find one.
- */
-static CK_RV
-ckmk_GetSafeDefaultKeychain(
- SecKeychainRef *keychainRef)
-{
- OSStatus macErr;
- CFArrayRef searchList = 0;
- CK_RV error = CKR_OK;
-
- macErr = SecKeychainCopyDefault(keychainRef);
- if (noErr != macErr) {
- int searchCount = 0;
- if (errSecNoDefaultKeychain != macErr) {
- CKMK_MACERR("Getting default key chain", macErr);
- error = CKR_GENERAL_ERROR;
- goto loser;
- }
- /* ok, we don't have a default key chain, find one */
- macErr = SecKeychainCopySearchList(&searchList);
- if (noErr != macErr) {
- CKMK_MACERR("failed to find a keyring searchList", macErr);
- error = CKR_DEVICE_REMOVED;
- goto loser;
- }
- searchCount = CFArrayGetCount(searchList);
- if (searchCount < 1) {
- error = CKR_DEVICE_REMOVED;
- goto loser;
- }
- *keychainRef =
- (SecKeychainRef)CFRetain(CFArrayGetValueAtIndex(searchList, 0));
- if (0 == *keychainRef) {
- error = CKR_DEVICE_REMOVED;
- goto loser;
- }
- /* should we set it as default? */
- }
-loser:
- if (0 != searchList) {
- CFRelease(searchList);
- }
- return error;
-}
-static ckmkInternalObject *
-nss_ckmk_CreateCertificate(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError)
-{
- NSSItem value;
- ckmkInternalObject *io = NULL;
- OSStatus macErr;
- SecCertificateRef certRef;
- SecKeychainItemRef itemRef;
- SecKeychainRef keychainRef;
- CSSM_DATA certData;
-
- *pError = nss_ckmk_GetAttribute(CKA_VALUE, pTemplate,
- ulAttributeCount, &value);
- if (CKR_OK != *pError) {
- goto loser;
- }
-
- certData.Data = value.data;
- certData.Length = value.size;
- macErr = SecCertificateCreateFromData(&certData, CSSM_CERT_X_509v3,
- CSSM_CERT_ENCODING_BER, &certRef);
- if (noErr != macErr) {
- CKMK_MACERR("Create cert from data Failed", macErr);
- *pError = CKR_GENERAL_ERROR; /* need to map macErr */
- goto loser;
- }
-
- *pError = ckmk_GetSafeDefaultKeychain(&keychainRef);
- if (CKR_OK != *pError) {
- goto loser;
- }
-
- macErr = SecCertificateAddToKeychain(certRef, keychainRef);
- itemRef = (SecKeychainItemRef)certRef;
- if (errSecDuplicateItem != macErr) {
- NSSItem keyID = { NULL, 0 };
- char *nickname = NULL;
- CK_RV dummy;
-
- if (noErr != macErr) {
- CKMK_MACERR("Add cert to keychain Failed", macErr);
- *pError = CKR_GENERAL_ERROR; /* need to map macErr */
- goto loser;
- }
- /* these two are optional */
- nickname = nss_ckmk_GetStringAttribute(CKA_LABEL, pTemplate,
- ulAttributeCount, &dummy);
- /* we've added a new one, update the attributes in the key ring */
- if (nickname) {
- ckmk_updateAttribute(itemRef, kSecLabelItemAttr, nickname,
- strlen(nickname) + 1, "Modify Cert Label");
- nss_ZFreeIf(nickname);
- }
- dummy = nss_ckmk_GetAttribute(CKA_ID, pTemplate,
- ulAttributeCount, &keyID);
- if (CKR_OK == dummy) {
- dummy = ckmk_updateAttribute(itemRef, kSecPublicKeyHashItemAttr,
- keyID.data, keyID.size, "Modify Cert ID");
- }
- }
-
- io = nss_ckmk_NewInternalObject(CKO_CERTIFICATE, itemRef,
- kSecCertificateItemClass, pError);
- if ((ckmkInternalObject *)NULL != io) {
- itemRef = 0;
- }
-
-loser:
- if (0 != itemRef) {
- CFRelease(itemRef);
- }
- if (0 != keychainRef) {
- CFRelease(keychainRef);
- }
-
- return io;
-}
-
-/*
- * PKCS #8 attributes
- */
-struct ckmk_AttributeStr {
- SECItem attrType;
- SECItem *attrValue;
-};
-typedef struct ckmk_AttributeStr ckmk_Attribute;
-
-/*
- ** A PKCS#8 private key info object
- */
-struct PrivateKeyInfoStr {
- PLArenaPool *arena;
- SECItem version;
- SECAlgorithmID algorithm;
- SECItem privateKey;
- ckmk_Attribute **attributes;
-};
-typedef struct PrivateKeyInfoStr PrivateKeyInfo;
-
-const SEC_ASN1Template ckmk_RSAPrivateKeyTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(RSAPrivateKey) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, version) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, modulus) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, publicExponent) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, privateExponent) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, prime1) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, prime2) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, exponent1) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, exponent2) },
- { SEC_ASN1_INTEGER, offsetof(RSAPrivateKey, coefficient) },
- { 0 }
-};
-
-const SEC_ASN1Template ckmk_AttributeTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(ckmk_Attribute) },
- { SEC_ASN1_OBJECT_ID, offsetof(ckmk_Attribute, attrType) },
- { SEC_ASN1_SET_OF, offsetof(ckmk_Attribute, attrValue),
- SEC_AnyTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template ckmk_SetOfAttributeTemplate[] = {
- { SEC_ASN1_SET_OF, 0, ckmk_AttributeTemplate },
-};
-
-SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-
-/* ASN1 Templates for new decoder/encoder */
-const SEC_ASN1Template ckmk_PrivateKeyInfoTemplate[] = {
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PrivateKeyInfo) },
- { SEC_ASN1_INTEGER, offsetof(PrivateKeyInfo, version) },
- { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(PrivateKeyInfo, algorithm),
- SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
- { SEC_ASN1_OCTET_STRING, offsetof(PrivateKeyInfo, privateKey) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(PrivateKeyInfo, attributes), ckmk_SetOfAttributeTemplate },
- { 0 }
-};
-
-#define CKMK_PRIVATE_KEY_INFO_VERSION 0
-static CK_RV
-ckmk_CreateRSAKeyBlob(
- RSAPrivateKey *lk,
- NSSItem *keyBlob)
-{
- PrivateKeyInfo *pki = NULL;
- PLArenaPool *arena = NULL;
- SECOidTag algorithm = SEC_OID_UNKNOWN;
- void *dummy;
- SECStatus rv;
- SECItem *encodedKey = NULL;
- CK_RV error = CKR_OK;
-
- arena = PORT_NewArena(2048); /* XXX different size? */
- if (!arena) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
-
- pki = (PrivateKeyInfo *)PORT_ArenaZAlloc(arena, sizeof(PrivateKeyInfo));
- if (!pki) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- pki->arena = arena;
-
- dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
- ckmk_RSAPrivateKeyTemplate);
- algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
-
- if (!dummy) {
- error = CKR_DEVICE_ERROR; /* should map NSS SECError */
- goto loser;
- }
-
- rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, algorithm,
- (SECItem *)NULL);
- if (rv != SECSuccess) {
- error = CKR_DEVICE_ERROR; /* should map NSS SECError */
- goto loser;
- }
-
- dummy = SEC_ASN1EncodeInteger(arena, &pki->version,
- CKMK_PRIVATE_KEY_INFO_VERSION);
- if (!dummy) {
- error = CKR_DEVICE_ERROR; /* should map NSS SECError */
- goto loser;
- }
-
- encodedKey = SEC_ASN1EncodeItem(NULL, NULL, pki,
- ckmk_PrivateKeyInfoTemplate);
- if (!encodedKey) {
- error = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- keyBlob->data = nss_ZNEWARRAY(NULL, char, encodedKey->len);
- if (NULL == keyBlob->data) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
- nsslibc_memcpy(keyBlob->data, encodedKey->data, encodedKey->len);
- keyBlob->size = encodedKey->len;
-
-loser:
- if (arena) {
- PORT_FreeArena(arena, PR_TRUE);
- }
- if (encodedKey) {
- SECITEM_FreeItem(encodedKey, PR_TRUE);
- }
-
- return error;
-}
-/*
- * There MUST be a better way to do this. For now, find the key based on the
- * default name Apple gives it once we import.
- */
-#define IMPORTED_NAME "Imported Private Key"
-static CK_RV
-ckmk_FindImportedKey(
- SecKeychainRef keychainRef,
- SecItemClass itemClass,
- SecKeychainItemRef *outItemRef)
-{
- OSStatus macErr;
- SecKeychainSearchRef searchRef = 0;
- SecKeychainItemRef newItemRef;
-
- macErr = SecKeychainSearchCreateFromAttributes(keychainRef, itemClass,
- NULL, &searchRef);
- if (noErr != macErr) {
- CKMK_MACERR("Can't search for Key", macErr);
- return CKR_GENERAL_ERROR;
- }
- while (noErr == SecKeychainSearchCopyNext(searchRef, &newItemRef)) {
- SecKeychainAttributeList *attrList = NULL;
- SecKeychainAttributeInfo attrInfo;
- SecItemAttr itemAttr = kSecKeyPrintName;
- PRUint32 attrFormat = 0;
- OSStatus macErr;
-
- attrInfo.count = 1;
- attrInfo.tag = &itemAttr;
- attrInfo.format = &attrFormat;
-
- macErr = SecKeychainItemCopyAttributesAndData(newItemRef,
- &attrInfo, NULL, &attrList, NULL, NULL);
- if (noErr == macErr) {
- if (nsslibc_memcmp(attrList->attr->data, IMPORTED_NAME,
- attrList->attr->length, NULL) == 0) {
- *outItemRef = newItemRef;
- CFRelease(searchRef);
- SecKeychainItemFreeAttributesAndData(attrList, NULL);
- return CKR_OK;
- }
- SecKeychainItemFreeAttributesAndData(attrList, NULL);
- }
- CFRelease(newItemRef);
- }
- CFRelease(searchRef);
- return CKR_GENERAL_ERROR; /* we can come up with something better! */
-}
-
-static ckmkInternalObject *
-nss_ckmk_CreatePrivateKey(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError)
-{
- NSSItem attribute;
- RSAPrivateKey lk;
- NSSItem keyID;
- char *nickname = NULL;
- ckmkInternalObject *io = NULL;
- CK_KEY_TYPE keyType;
- OSStatus macErr;
- SecKeychainItemRef itemRef = 0;
- NSSItem keyBlob = { NULL, 0 };
- CFDataRef dataRef = 0;
- SecExternalFormat inputFormat = kSecFormatBSAFE;
- /*SecExternalFormat inputFormat = kSecFormatOpenSSL; */
- SecExternalItemType itemType = kSecItemTypePrivateKey;
- SecKeyImportExportParameters keyParams;
- SecKeychainRef targetKeychain = 0;
- unsigned char zero = 0;
- CK_RV error;
-
- keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
- keyParams.flags = 0;
- keyParams.passphrase = 0;
- keyParams.alertTitle = 0;
- keyParams.alertPrompt = 0;
- keyParams.accessRef = 0; /* default */
- keyParams.keyUsage = 0; /* will get filled in */
- keyParams.keyAttributes = CSSM_KEYATTR_PERMANENT; /* will get filled in */
- keyType = nss_ckmk_GetULongAttribute(CKA_KEY_TYPE, pTemplate, ulAttributeCount, pError);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- if (CKK_RSA != keyType) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- return (ckmkInternalObject *)NULL;
- }
- if (nss_ckmk_GetBoolAttribute(CKA_DECRYPT,
- pTemplate, ulAttributeCount, CK_TRUE)) {
- keyParams.keyUsage |= CSSM_KEYUSE_DECRYPT;
- }
- if (nss_ckmk_GetBoolAttribute(CKA_UNWRAP,
- pTemplate, ulAttributeCount, CK_TRUE)) {
- keyParams.keyUsage |= CSSM_KEYUSE_UNWRAP;
- }
- if (nss_ckmk_GetBoolAttribute(CKA_SIGN,
- pTemplate, ulAttributeCount, CK_TRUE)) {
- keyParams.keyUsage |= CSSM_KEYUSE_SIGN;
- }
- if (nss_ckmk_GetBoolAttribute(CKA_DERIVE,
- pTemplate, ulAttributeCount, CK_FALSE)) {
- keyParams.keyUsage |= CSSM_KEYUSE_DERIVE;
- }
- if (nss_ckmk_GetBoolAttribute(CKA_SENSITIVE,
- pTemplate, ulAttributeCount, CK_TRUE)) {
- keyParams.keyAttributes |= CSSM_KEYATTR_SENSITIVE;
- }
- if (nss_ckmk_GetBoolAttribute(CKA_EXTRACTABLE,
- pTemplate, ulAttributeCount, CK_TRUE)) {
- keyParams.keyAttributes |= CSSM_KEYATTR_EXTRACTABLE;
- }
-
- lk.version.type = siUnsignedInteger;
- lk.version.data = &zero;
- lk.version.len = 1;
-
- *pError = nss_ckmk_GetAttribute(CKA_MODULUS, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.modulus.type = siUnsignedInteger;
- lk.modulus.data = attribute.data;
- lk.modulus.len = attribute.size;
-
- *pError = nss_ckmk_GetAttribute(CKA_PUBLIC_EXPONENT, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.publicExponent.type = siUnsignedInteger;
- lk.publicExponent.data = attribute.data;
- lk.publicExponent.len = attribute.size;
-
- *pError = nss_ckmk_GetAttribute(CKA_PRIVATE_EXPONENT, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.privateExponent.type = siUnsignedInteger;
- lk.privateExponent.data = attribute.data;
- lk.privateExponent.len = attribute.size;
-
- *pError = nss_ckmk_GetAttribute(CKA_PRIME_1, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.prime1.type = siUnsignedInteger;
- lk.prime1.data = attribute.data;
- lk.prime1.len = attribute.size;
-
- *pError = nss_ckmk_GetAttribute(CKA_PRIME_2, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.prime2.type = siUnsignedInteger;
- lk.prime2.data = attribute.data;
- lk.prime2.len = attribute.size;
-
- *pError = nss_ckmk_GetAttribute(CKA_EXPONENT_1, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.exponent1.type = siUnsignedInteger;
- lk.exponent1.data = attribute.data;
- lk.exponent1.len = attribute.size;
-
- *pError = nss_ckmk_GetAttribute(CKA_EXPONENT_2, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.exponent2.type = siUnsignedInteger;
- lk.exponent2.data = attribute.data;
- lk.exponent2.len = attribute.size;
-
- *pError = nss_ckmk_GetAttribute(CKA_COEFFICIENT, pTemplate,
- ulAttributeCount, &attribute);
- if (CKR_OK != *pError) {
- return (ckmkInternalObject *)NULL;
- }
- lk.coefficient.type = siUnsignedInteger;
- lk.coefficient.data = attribute.data;
- lk.coefficient.len = attribute.size;
-
- /* ASN1 Encode the pkcs8 structure... look at softoken to see how this
- * is done... */
- error = ckmk_CreateRSAKeyBlob(&lk, &keyBlob);
- if (CKR_OK != error) {
- goto loser;
- }
-
- dataRef = CFDataCreate(NULL, (UInt8 *)keyBlob.data, keyBlob.size);
- if (0 == dataRef) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- *pError == ckmk_GetSafeDefaultKeychain(&targetKeychain);
- if (CKR_OK != *pError) {
- goto loser;
- }
-
- /* the itemArray that is returned is useless. the item does not
- * is 'not on the key chain' so none of the modify calls work on it.
- * It also has a key that isn't the same key as the one in the actual
- * key chain. In short it isn't the item we want, and it gives us zero
- * information about the item we want, so don't even bother with it...
- */
- macErr = SecKeychainItemImport(dataRef, NULL, &inputFormat, &itemType, 0,
- &keyParams, targetKeychain, NULL);
- if (noErr != macErr) {
- CKMK_MACERR("Import Private Key", macErr);
- *pError = CKR_GENERAL_ERROR;
- goto loser;
- }
-
- *pError = ckmk_FindImportedKey(targetKeychain,
- CSSM_DL_DB_RECORD_PRIVATE_KEY,
- &itemRef);
- if (CKR_OK != *pError) {
-#ifdef DEBUG
- fprintf(stderr, "couldn't find key in keychain \n");
-#endif
- goto loser;
- }
-
- /* set the CKA_ID and the CKA_LABEL */
- error = nss_ckmk_GetAttribute(CKA_ID, pTemplate,
- ulAttributeCount, &keyID);
- if (CKR_OK == error) {
- error = ckmk_updateAttribute(itemRef, kSecKeyLabel,
- keyID.data, keyID.size, "Modify Key ID");
-#ifdef DEBUG
- itemdump("key id: ", keyID.data, keyID.size, error);
-#endif
- }
- nickname = nss_ckmk_GetStringAttribute(CKA_LABEL, pTemplate,
- ulAttributeCount, &error);
- if (nickname) {
- ckmk_updateAttribute(itemRef, kSecKeyPrintName, nickname,
- strlen(nickname) + 1, "Modify Key Label");
- } else {
-#define DEFAULT_NICKNAME "NSS Imported Key"
- ckmk_updateAttribute(itemRef, kSecKeyPrintName, DEFAULT_NICKNAME,
- sizeof(DEFAULT_NICKNAME), "Modify Key Label");
- }
-
- io = nss_ckmk_NewInternalObject(CKO_PRIVATE_KEY, itemRef,
- CSSM_DL_DB_RECORD_PRIVATE_KEY, pError);
- if ((ckmkInternalObject *)NULL == io) {
- CFRelease(itemRef);
- }
-
- return io;
-
-loser:
- /* free the key blob */
- if (keyBlob.data) {
- nss_ZFreeIf(keyBlob.data);
- }
- if (0 != targetKeychain) {
- CFRelease(targetKeychain);
- }
- if (0 != dataRef) {
- CFRelease(dataRef);
- }
- return io;
-}
-
-NSS_EXTERN NSSCKMDObject *
-nss_ckmk_CreateObject(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError)
-{
- CK_OBJECT_CLASS objClass;
- ckmkInternalObject *io = NULL;
- CK_BBOOL isToken;
-
- /*
- * only create token objects
- */
- isToken = nss_ckmk_GetBoolAttribute(CKA_TOKEN, pTemplate,
- ulAttributeCount, CK_FALSE);
- if (!isToken) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- return (NSSCKMDObject *)NULL;
- }
-
- /*
- * only create keys and certs.
- */
- objClass = nss_ckmk_GetULongAttribute(CKA_CLASS, pTemplate,
- ulAttributeCount, pError);
- if (CKR_OK != *pError) {
- return (NSSCKMDObject *)NULL;
- }
-#ifdef notdef
- if (objClass == CKO_PUBLIC_KEY) {
- return CKR_OK; /* fake public key creation, happens as a side effect of
- * private key creation */
- }
-#endif
- if (objClass == CKO_CERTIFICATE) {
- io = nss_ckmk_CreateCertificate(fwSession, pTemplate,
- ulAttributeCount, pError);
- } else if (objClass == CKO_PRIVATE_KEY) {
- io = nss_ckmk_CreatePrivateKey(fwSession, pTemplate,
- ulAttributeCount, pError);
- } else {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- if ((ckmkInternalObject *)NULL == io) {
- return (NSSCKMDObject *)NULL;
- }
- return nss_ckmk_CreateMDObject(NULL, io, pError);
-}
diff --git a/security/nss/lib/ckfw/nssmkey/mrsa.c b/security/nss/lib/ckfw/nssmkey/mrsa.c
deleted file mode 100644
index 00175b47a8..0000000000
--- a/security/nss/lib/ckfw/nssmkey/mrsa.c
+++ /dev/null
@@ -1,479 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ckmk.h"
-
-/* Sigh, For all the talk about 'ease of use', apple has hidden the interfaces
- * needed to be able to truly use CSSM. These came from their modification
- * to NSS's S/MIME code. The following two functions currently are not
- * part of the SecKey.h interface.
- */
-OSStatus
-SecKeyGetCredentials(
- SecKeyRef keyRef,
- CSSM_ACL_AUTHORIZATION_TAG authTag,
- int type,
- const CSSM_ACCESS_CREDENTIALS **creds);
-
-/* this function could be implemented using 'SecKeychainItemCopyKeychain' and
- * 'SecKeychainGetCSPHandle' */
-OSStatus
-SecKeyGetCSPHandle(
- SecKeyRef keyRef,
- CSSM_CSP_HANDLE *cspHandle);
-
-typedef struct ckmkInternalCryptoOperationRSAPrivStr
- ckmkInternalCryptoOperationRSAPriv;
-struct ckmkInternalCryptoOperationRSAPrivStr {
- NSSCKMDCryptoOperation mdOperation;
- NSSCKMDMechanism *mdMechanism;
- ckmkInternalObject *iKey;
- NSSItem *buffer;
- CSSM_CC_HANDLE cssmContext;
-};
-
-typedef enum {
- CKMK_DECRYPT,
- CKMK_SIGN
-} ckmkRSAOpType;
-
-/*
- * ckmk_mdCryptoOperationRSAPriv_Create
- */
-static NSSCKMDCryptoOperation *
-ckmk_mdCryptoOperationRSAPriv_Create(
- const NSSCKMDCryptoOperation *proto,
- NSSCKMDMechanism *mdMechanism,
- NSSCKMDObject *mdKey,
- ckmkRSAOpType type,
- CK_RV *pError)
-{
- ckmkInternalObject *iKey = (ckmkInternalObject *)mdKey->etc;
- const NSSItem *classItem = nss_ckmk_FetchAttribute(iKey, CKA_CLASS, pError);
- const NSSItem *keyType = nss_ckmk_FetchAttribute(iKey, CKA_KEY_TYPE, pError);
- ckmkInternalCryptoOperationRSAPriv *iOperation;
- SecKeyRef privateKey;
- OSStatus macErr;
- CSSM_RETURN cssmErr;
- const CSSM_KEY *cssmKey;
- CSSM_CSP_HANDLE cspHandle;
- const CSSM_ACCESS_CREDENTIALS *creds = NULL;
- CSSM_CC_HANDLE cssmContext;
- CSSM_ACL_AUTHORIZATION_TAG authType;
-
- /* make sure we have the right objects */
- if (((const NSSItem *)NULL == classItem) ||
- (sizeof(CK_OBJECT_CLASS) != classItem->size) ||
- (CKO_PRIVATE_KEY != *(CK_OBJECT_CLASS *)classItem->data) ||
- ((const NSSItem *)NULL == keyType) ||
- (sizeof(CK_KEY_TYPE) != keyType->size) ||
- (CKK_RSA != *(CK_KEY_TYPE *)keyType->data)) {
- *pError = CKR_KEY_TYPE_INCONSISTENT;
- return (NSSCKMDCryptoOperation *)NULL;
- }
-
- privateKey = (SecKeyRef)iKey->u.item.itemRef;
- macErr = SecKeyGetCSSMKey(privateKey, &cssmKey);
- if (noErr != macErr) {
- CKMK_MACERR("Getting CSSM Key", macErr);
- *pError = CKR_KEY_HANDLE_INVALID;
- return (NSSCKMDCryptoOperation *)NULL;
- }
- macErr = SecKeyGetCSPHandle(privateKey, &cspHandle);
- if (noErr != macErr) {
- CKMK_MACERR("Getting CSP for Key", macErr);
- *pError = CKR_KEY_HANDLE_INVALID;
- return (NSSCKMDCryptoOperation *)NULL;
- }
- switch (type) {
- case CKMK_DECRYPT:
- authType = CSSM_ACL_AUTHORIZATION_DECRYPT;
- break;
- case CKMK_SIGN:
- authType = CSSM_ACL_AUTHORIZATION_SIGN;
- break;
- default:
- *pError = CKR_GENERAL_ERROR;
-#ifdef DEBUG
- fprintf(stderr, "RSAPriv_Create: bad type = %d\n", type);
-#endif
- return (NSSCKMDCryptoOperation *)NULL;
- }
-
- macErr = SecKeyGetCredentials(privateKey, authType, 0, &creds);
- if (noErr != macErr) {
- CKMK_MACERR("Getting Credentials for Key", macErr);
- *pError = CKR_KEY_HANDLE_INVALID;
- return (NSSCKMDCryptoOperation *)NULL;
- }
-
- switch (type) {
- case CKMK_DECRYPT:
- cssmErr = CSSM_CSP_CreateAsymmetricContext(cspHandle, CSSM_ALGID_RSA,
- creds, cssmKey, CSSM_PADDING_PKCS1, &cssmContext);
- break;
- case CKMK_SIGN:
- cssmErr = CSSM_CSP_CreateSignatureContext(cspHandle, CSSM_ALGID_RSA,
- creds, cssmKey, &cssmContext);
- break;
- default:
- *pError = CKR_GENERAL_ERROR;
-#ifdef DEBUG
- fprintf(stderr, "RSAPriv_Create: bad type = %d\n", type);
-#endif
- return (NSSCKMDCryptoOperation *)NULL;
- }
- if (noErr != cssmErr) {
- CKMK_MACERR("Getting Context for Key", cssmErr);
- *pError = CKR_GENERAL_ERROR;
- return (NSSCKMDCryptoOperation *)NULL;
- }
-
- iOperation = nss_ZNEW(NULL, ckmkInternalCryptoOperationRSAPriv);
- if ((ckmkInternalCryptoOperationRSAPriv *)NULL == iOperation) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDCryptoOperation *)NULL;
- }
- iOperation->mdMechanism = mdMechanism;
- iOperation->iKey = iKey;
- iOperation->cssmContext = cssmContext;
-
- nsslibc_memcpy(&iOperation->mdOperation,
- proto, sizeof(NSSCKMDCryptoOperation));
- iOperation->mdOperation.etc = iOperation;
-
- return &iOperation->mdOperation;
-}
-
-static void
-ckmk_mdCryptoOperationRSAPriv_Destroy(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- ckmkInternalCryptoOperationRSAPriv *iOperation =
- (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc;
-
- if (iOperation->buffer) {
- nssItem_Destroy(iOperation->buffer);
- }
- if (iOperation->cssmContext) {
- CSSM_DeleteContext(iOperation->cssmContext);
- }
- nss_ZFreeIf(iOperation);
- return;
-}
-
-static CK_ULONG
-ckmk_mdCryptoOperationRSA_GetFinalLength(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- ckmkInternalCryptoOperationRSAPriv *iOperation =
- (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc;
- const NSSItem *modulus =
- nss_ckmk_FetchAttribute(iOperation->iKey, CKA_MODULUS, pError);
-
- return modulus->size;
-}
-
-/*
- * ckmk_mdCryptoOperationRSADecrypt_GetOperationLength
- * we won't know the length until we actually decrypt the
- * input block. Since we go to all the work to decrypt the
- * the block, we'll save if for when the block is asked for
- */
-static CK_ULONG
-ckmk_mdCryptoOperationRSADecrypt_GetOperationLength(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *input,
- CK_RV *pError)
-{
- ckmkInternalCryptoOperationRSAPriv *iOperation =
- (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc;
- CSSM_DATA cssmInput;
- CSSM_DATA cssmOutput = { 0, NULL };
- PRUint32 bytesDecrypted;
- CSSM_DATA remainder = { 0, NULL };
- NSSItem output;
- CSSM_RETURN cssmErr;
-
- if (iOperation->buffer) {
- return iOperation->buffer->size;
- }
-
- cssmInput.Data = input->data;
- cssmInput.Length = input->size;
-
- cssmErr = CSSM_DecryptData(iOperation->cssmContext,
- &cssmInput, 1, &cssmOutput, 1,
- &bytesDecrypted, &remainder);
- if (CSSM_OK != cssmErr) {
- CKMK_MACERR("Decrypt Failed", cssmErr);
- *pError = CKR_DATA_INVALID;
- return 0;
- }
- /* we didn't suppy any buffers, so it should all be in remainder */
- output.data = nss_ZNEWARRAY(NULL, char, bytesDecrypted + remainder.Length);
- if (NULL == output.data) {
- free(cssmOutput.Data);
- free(remainder.Data);
- *pError = CKR_HOST_MEMORY;
- return 0;
- }
- output.size = bytesDecrypted + remainder.Length;
-
- if (0 != bytesDecrypted) {
- nsslibc_memcpy(output.data, cssmOutput.Data, bytesDecrypted);
- free(cssmOutput.Data);
- }
- if (0 != remainder.Length) {
- nsslibc_memcpy(((char *)output.data) + bytesDecrypted,
- remainder.Data, remainder.Length);
- free(remainder.Data);
- }
-
- iOperation->buffer = nssItem_Duplicate(&output, NULL, NULL);
- nss_ZFreeIf(output.data);
- if ((NSSItem *)NULL == iOperation->buffer) {
- *pError = CKR_HOST_MEMORY;
- return 0;
- }
-
- return iOperation->buffer->size;
-}
-
-/*
- * ckmk_mdCryptoOperationRSADecrypt_UpdateFinal
- *
- * NOTE: ckmk_mdCryptoOperationRSADecrypt_GetOperationLength is presumed to
- * have been called previously.
- */
-static CK_RV
-ckmk_mdCryptoOperationRSADecrypt_UpdateFinal(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *input,
- NSSItem *output)
-{
- ckmkInternalCryptoOperationRSAPriv *iOperation =
- (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc;
- NSSItem *buffer = iOperation->buffer;
-
- if ((NSSItem *)NULL == buffer) {
- return CKR_GENERAL_ERROR;
- }
- nsslibc_memcpy(output->data, buffer->data, buffer->size);
- output->size = buffer->size;
- return CKR_OK;
-}
-
-/*
- * ckmk_mdCryptoOperationRSASign_UpdateFinal
- *
- */
-static CK_RV
-ckmk_mdCryptoOperationRSASign_UpdateFinal(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *input,
- NSSItem *output)
-{
- ckmkInternalCryptoOperationRSAPriv *iOperation =
- (ckmkInternalCryptoOperationRSAPriv *)mdOperation->etc;
- CSSM_DATA cssmInput;
- CSSM_DATA cssmOutput = { 0, NULL };
- CSSM_RETURN cssmErr;
-
- cssmInput.Data = input->data;
- cssmInput.Length = input->size;
-
- cssmErr = CSSM_SignData(iOperation->cssmContext, &cssmInput, 1,
- CSSM_ALGID_NONE, &cssmOutput);
- if (CSSM_OK != cssmErr) {
- CKMK_MACERR("Signed Failed", cssmErr);
- return CKR_FUNCTION_FAILED;
- }
- if (cssmOutput.Length > output->size) {
- free(cssmOutput.Data);
- return CKR_BUFFER_TOO_SMALL;
- }
- nsslibc_memcpy(output->data, cssmOutput.Data, cssmOutput.Length);
- free(cssmOutput.Data);
- output->size = cssmOutput.Length;
-
- return CKR_OK;
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation
- ckmk_mdCryptoOperationRSADecrypt_proto = {
- NULL, /* etc */
- ckmk_mdCryptoOperationRSAPriv_Destroy,
- NULL, /* GetFinalLengh - not needed for one shot Decrypt/Encrypt */
- ckmk_mdCryptoOperationRSADecrypt_GetOperationLength,
- NULL, /* Final - not needed for one shot operation */
- NULL, /* Update - not needed for one shot operation */
- NULL, /* DigetUpdate - not needed for one shot operation */
- ckmk_mdCryptoOperationRSADecrypt_UpdateFinal,
- NULL, /* UpdateCombo - not needed for one shot operation */
- NULL, /* DigetKey - not needed for one shot operation */
- (void *)NULL /* null terminator */
- };
-
-NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation
- ckmk_mdCryptoOperationRSASign_proto = {
- NULL, /* etc */
- ckmk_mdCryptoOperationRSAPriv_Destroy,
- ckmk_mdCryptoOperationRSA_GetFinalLength,
- NULL, /* GetOperationLengh - not needed for one shot Sign/Verify */
- NULL, /* Final - not needed for one shot operation */
- NULL, /* Update - not needed for one shot operation */
- NULL, /* DigetUpdate - not needed for one shot operation */
- ckmk_mdCryptoOperationRSASign_UpdateFinal,
- NULL, /* UpdateCombo - not needed for one shot operation */
- NULL, /* DigetKey - not needed for one shot operation */
- (void *)NULL /* null terminator */
- };
-
-/********** NSSCKMDMechansim functions ***********************/
-/*
- * ckmk_mdMechanismRSA_Destroy
- */
-static void
-ckmk_mdMechanismRSA_Destroy(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- nss_ZFreeIf(fwMechanism);
-}
-
-/*
- * ckmk_mdMechanismRSA_GetMinKeySize
- */
-static CK_ULONG
-ckmk_mdMechanismRSA_GetMinKeySize(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return 384;
-}
-
-/*
- * ckmk_mdMechanismRSA_GetMaxKeySize
- */
-static CK_ULONG
-ckmk_mdMechanismRSA_GetMaxKeySize(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return 16384;
-}
-
-/*
- * ckmk_mdMechanismRSA_DecryptInit
- */
-static NSSCKMDCryptoOperation *
-ckmk_mdMechanismRSA_DecryptInit(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdKey,
- NSSCKFWObject *fwKey,
- CK_RV *pError)
-{
- return ckmk_mdCryptoOperationRSAPriv_Create(
- &ckmk_mdCryptoOperationRSADecrypt_proto,
- mdMechanism, mdKey, CKMK_DECRYPT, pError);
-}
-
-/*
- * ckmk_mdMechanismRSA_SignInit
- */
-static NSSCKMDCryptoOperation *
-ckmk_mdMechanismRSA_SignInit(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- CK_MECHANISM *pMechanism,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDObject *mdKey,
- NSSCKFWObject *fwKey,
- CK_RV *pError)
-{
- return ckmk_mdCryptoOperationRSAPriv_Create(
- &ckmk_mdCryptoOperationRSASign_proto,
- mdMechanism, mdKey, CKMK_SIGN, pError);
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDMechanism
- nss_ckmk_mdMechanismRSA = {
- (void *)NULL, /* etc */
- ckmk_mdMechanismRSA_Destroy,
- ckmk_mdMechanismRSA_GetMinKeySize,
- ckmk_mdMechanismRSA_GetMaxKeySize,
- NULL, /* GetInHardware - default false */
- NULL, /* EncryptInit - default errs */
- ckmk_mdMechanismRSA_DecryptInit,
- NULL, /* DigestInit - default errs*/
- ckmk_mdMechanismRSA_SignInit,
- NULL, /* VerifyInit - default errs */
- ckmk_mdMechanismRSA_SignInit, /* SignRecoverInit */
- NULL, /* VerifyRecoverInit - default errs */
- NULL, /* GenerateKey - default errs */
- NULL, /* GenerateKeyPair - default errs */
- NULL, /* GetWrapKeyLength - default errs */
- NULL, /* WrapKey - default errs */
- NULL, /* UnwrapKey - default errs */
- NULL, /* DeriveKey - default errs */
- (void *)NULL /* null terminator */
- };
diff --git a/security/nss/lib/ckfw/nssmkey/msession.c b/security/nss/lib/ckfw/nssmkey/msession.c
deleted file mode 100644
index e6a29244a1..0000000000
--- a/security/nss/lib/ckfw/nssmkey/msession.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ckmk.h"
-
-/*
- * nssmkey/msession.c
- *
- * This file implements the NSSCKMDSession object for the
- * "nssmkey" cryptoki module.
- */
-
-static NSSCKMDFindObjects *
-ckmk_mdSession_FindObjectsInit(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError)
-{
- return nss_ckmk_FindObjectsInit(fwSession, pTemplate, ulAttributeCount, pError);
-}
-
-static NSSCKMDObject *
-ckmk_mdSession_CreateObject(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError)
-{
- return nss_ckmk_CreateObject(fwSession, pTemplate, ulAttributeCount, pError);
-}
-
-NSS_IMPLEMENT NSSCKMDSession *
-nss_ckmk_CreateSession(
- NSSCKFWSession *fwSession,
- CK_RV *pError)
-{
- NSSArena *arena;
- NSSCKMDSession *rv;
-
- arena = NSSCKFWSession_GetArena(fwSession, pError);
- if ((NSSArena *)NULL == arena) {
- return (NSSCKMDSession *)NULL;
- }
-
- rv = nss_ZNEW(arena, NSSCKMDSession);
- if ((NSSCKMDSession *)NULL == rv) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDSession *)NULL;
- }
-
- /*
- * rv was zeroed when allocated, so we only
- * need to set the non-zero members.
- */
-
- rv->etc = (void *)fwSession;
- /* rv->Close */
- /* rv->GetDeviceError */
- /* rv->Login */
- /* rv->Logout */
- /* rv->InitPIN */
- /* rv->SetPIN */
- /* rv->GetOperationStateLen */
- /* rv->GetOperationState */
- /* rv->SetOperationState */
- rv->CreateObject = ckmk_mdSession_CreateObject;
- /* rv->CopyObject */
- rv->FindObjectsInit = ckmk_mdSession_FindObjectsInit;
- /* rv->SeedRandom */
- /* rv->GetRandom */
- /* rv->null */
-
- return rv;
-}
diff --git a/security/nss/lib/ckfw/nssmkey/mslot.c b/security/nss/lib/ckfw/nssmkey/mslot.c
deleted file mode 100644
index b2747ff7b2..0000000000
--- a/security/nss/lib/ckfw/nssmkey/mslot.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ckmk.h"
-
-/*
- * nssmkey/mslot.c
- *
- * This file implements the NSSCKMDSlot object for the
- * "nssmkey" cryptoki module.
- */
-
-static NSSUTF8 *
-ckmk_mdSlot_GetSlotDescription(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckmk_SlotDescription;
-}
-
-static NSSUTF8 *
-ckmk_mdSlot_GetManufacturerID(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckmk_ManufacturerID;
-}
-
-static CK_VERSION
-ckmk_mdSlot_GetHardwareVersion(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return nss_ckmk_HardwareVersion;
-}
-
-static CK_VERSION
-ckmk_mdSlot_GetFirmwareVersion(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return nss_ckmk_FirmwareVersion;
-}
-
-static NSSCKMDToken *
-ckmk_mdSlot_GetToken(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSCKMDToken *)&nss_ckmk_mdToken;
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDSlot
- nss_ckmk_mdSlot = {
- (void *)NULL, /* etc */
- NULL, /* Initialize */
- NULL, /* Destroy */
- ckmk_mdSlot_GetSlotDescription,
- ckmk_mdSlot_GetManufacturerID,
- NULL, /* GetTokenPresent -- defaults to true */
- NULL, /* GetRemovableDevice -- defaults to false */
- NULL, /* GetHardwareSlot -- defaults to false */
- ckmk_mdSlot_GetHardwareVersion,
- ckmk_mdSlot_GetFirmwareVersion,
- ckmk_mdSlot_GetToken,
- (void *)NULL /* null terminator */
- };
diff --git a/security/nss/lib/ckfw/nssmkey/mtoken.c b/security/nss/lib/ckfw/nssmkey/mtoken.c
deleted file mode 100644
index e18d612405..0000000000
--- a/security/nss/lib/ckfw/nssmkey/mtoken.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "ckmk.h"
-
-/*
- * nssmkey/mtoken.c
- *
- * This file implements the NSSCKMDToken object for the
- * "nssmkey" cryptoki module.
- */
-
-static NSSUTF8 *
-ckmk_mdToken_GetLabel(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckmk_TokenLabel;
-}
-
-static NSSUTF8 *
-ckmk_mdToken_GetManufacturerID(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckmk_ManufacturerID;
-}
-
-static NSSUTF8 *
-ckmk_mdToken_GetModel(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckmk_TokenModel;
-}
-
-static NSSUTF8 *
-ckmk_mdToken_GetSerialNumber(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckmk_TokenSerialNumber;
-}
-
-static CK_BBOOL
-ckmk_mdToken_GetIsWriteProtected(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return CK_FALSE;
-}
-
-/* fake out Mozilla so we don't try to initialize the token */
-static CK_BBOOL
-ckmk_mdToken_GetUserPinInitialized(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return CK_TRUE;
-}
-
-static CK_VERSION
-ckmk_mdToken_GetHardwareVersion(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return nss_ckmk_HardwareVersion;
-}
-
-static CK_VERSION
-ckmk_mdToken_GetFirmwareVersion(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return nss_ckmk_FirmwareVersion;
-}
-
-static NSSCKMDSession *
-ckmk_mdToken_OpenSession(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession,
- CK_BBOOL rw,
- CK_RV *pError)
-{
- return nss_ckmk_CreateSession(fwSession, pError);
-}
-
-static CK_ULONG
-ckmk_mdToken_GetMechanismCount(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return (CK_ULONG)1;
-}
-
-static CK_RV
-ckmk_mdToken_GetMechanismTypes(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_MECHANISM_TYPE types[])
-{
- types[0] = CKM_RSA_PKCS;
- return CKR_OK;
-}
-
-static NSSCKMDMechanism *
-ckmk_mdToken_GetMechanism(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_MECHANISM_TYPE which,
- CK_RV *pError)
-{
- if (which != CKM_RSA_PKCS) {
- *pError = CKR_MECHANISM_INVALID;
- return (NSSCKMDMechanism *)NULL;
- }
- return (NSSCKMDMechanism *)&nss_ckmk_mdMechanismRSA;
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDToken
- nss_ckmk_mdToken = {
- (void *)NULL, /* etc */
- NULL, /* Setup */
- NULL, /* Invalidate */
- NULL, /* InitToken -- default errs */
- ckmk_mdToken_GetLabel,
- ckmk_mdToken_GetManufacturerID,
- ckmk_mdToken_GetModel,
- ckmk_mdToken_GetSerialNumber,
- NULL, /* GetHasRNG -- default is false */
- ckmk_mdToken_GetIsWriteProtected,
- NULL, /* GetLoginRequired -- default is false */
- ckmk_mdToken_GetUserPinInitialized,
- NULL, /* GetRestoreKeyNotNeeded -- irrelevant */
- NULL, /* GetHasClockOnToken -- default is false */
- NULL, /* GetHasProtectedAuthenticationPath -- default is false */
- NULL, /* GetSupportsDualCryptoOperations -- default is false */
- NULL, /* GetMaxSessionCount -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetMaxRwSessionCount -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetMaxPinLen -- irrelevant */
- NULL, /* GetMinPinLen -- irrelevant */
- NULL, /* GetTotalPublicMemory -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetFreePublicMemory -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetTotalPrivateMemory -- default is CK_UNAVAILABLE_INFORMATION */
- NULL, /* GetFreePrivateMemory -- default is CK_UNAVAILABLE_INFORMATION */
- ckmk_mdToken_GetHardwareVersion,
- ckmk_mdToken_GetFirmwareVersion,
- NULL, /* GetUTCTime -- no clock */
- ckmk_mdToken_OpenSession,
- ckmk_mdToken_GetMechanismCount,
- ckmk_mdToken_GetMechanismTypes,
- ckmk_mdToken_GetMechanism,
- (void *)NULL /* null terminator */
- };
diff --git a/security/nss/lib/ckfw/nssmkey/nssmkey.def b/security/nss/lib/ckfw/nssmkey/nssmkey.def
deleted file mode 100644
index 45d307ff01..0000000000
--- a/security/nss/lib/ckfw/nssmkey/nssmkey.def
+++ /dev/null
@@ -1,26 +0,0 @@
-;+#
-;+# This Source Code Form is subject to the terms of the Mozilla Public
-;+# License, v. 2.0. If a copy of the MPL was not distributed with this
-;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;+#
-;+# 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 ";-"
-;+
-;+NSSMKEY_3.0 { # First release of nssmkey
-;+ global:
-LIBRARY nssmkey ;-
-EXPORTS ;-
-C_GetFunctionList;
-;+ local:
-;+*;
-;+};
diff --git a/security/nss/lib/ckfw/nssmkey/nssmkey.h b/security/nss/lib/ckfw/nssmkey/nssmkey.h
deleted file mode 100644
index ba58233e62..0000000000
--- a/security/nss/lib/ckfw/nssmkey/nssmkey.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef NSSMKEY_H
-#define NSSMKEY_H
-
-/*
- * NSS CKMK Version numbers.
- *
- * These are the version numbers for the nssmkey module packaged with
- * this release on NSS. To determine the version numbers of the builtin
- * module you are using, use the appropriate PKCS #11 calls.
- *
- * These version numbers detail changes to the PKCS #11 interface. They map
- * to the PKCS #11 spec versions.
- */
-#define NSS_CKMK_CRYPTOKI_VERSION_MAJOR 2
-#define NSS_CKMK_CRYPTOKI_VERSION_MINOR 20
-
-/* These version numbers detail the changes
- * to the list of trusted certificates.
- *
- * NSS_CKMK_LIBRARY_VERSION_MINOR is a CK_BYTE. It's not clear
- * whether we may use its full range (0-255) or only 0-99 because
- * of the comment in the CK_VERSION type definition.
- */
-#define NSS_CKMK_LIBRARY_VERSION_MAJOR 1
-#define NSS_CKMK_LIBRARY_VERSION_MINOR 1
-#define NSS_CKMK_LIBRARY_VERSION "1.1"
-
-/* These version numbers detail the semantic changes to the ckfw engine. */
-#define NSS_CKMK_HARDWARE_VERSION_MAJOR 1
-#define NSS_CKMK_HARDWARE_VERSION_MINOR 0
-
-/* These version numbers detail the semantic changes to ckbi itself
- * (new PKCS #11 objects), etc. */
-#define NSS_CKMK_FIRMWARE_VERSION_MAJOR 1
-#define NSS_CKMK_FIRMWARE_VERSION_MINOR 0
-
-#endif /* NSSMKEY_H */
diff --git a/security/nss/lib/ckfw/nssmkey/staticobj.c b/security/nss/lib/ckfw/nssmkey/staticobj.c
deleted file mode 100644
index 5f3bb7c720..0000000000
--- a/security/nss/lib/ckfw/nssmkey/staticobj.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef CKMK_H
-#include "ckmk.h"
-#endif /* CKMK_H */
-
-static const CK_TRUST ckt_netscape_valid = CKT_NETSCAPE_VALID;
-static const CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE;
-static const CK_TRUST ckt_netscape_trusted_delegator = CKT_NETSCAPE_TRUSTED_DELEGATOR;
-static const CK_OBJECT_CLASS cko_netscape_trust = CKO_NETSCAPE_TRUST;
-static const CK_BBOOL ck_true = CK_TRUE;
-static const CK_OBJECT_CLASS cko_data = CKO_DATA;
-static const CK_CERTIFICATE_TYPE ckc_x_509 = CKC_X_509;
-static const CK_BBOOL ck_false = CK_FALSE;
-static const CK_OBJECT_CLASS cko_netscape_builtin_root_list = CKO_NETSCAPE_BUILTIN_ROOT_LIST;
-
-/* example of a static object */
-static const CK_ATTRIBUTE_TYPE nss_ckmk_types_1[] = {
- CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL
-};
-
-static const NSSItem nss_ckmk_items_1[] = {
- { (void *)&cko_data, (PRUint32)sizeof(CK_OBJECT_CLASS) },
- { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) },
- { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
- { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
- { (void *)"Mozilla Mac Key Ring Access", (PRUint32)28 }
-};
-
-ckmkInternalObject nss_ckmk_data[] = {
- { ckmkRaw, { { 5, nss_ckmk_types_1, nss_ckmk_items_1 } }, CKO_DATA, { NULL } },
-};
-
-const PRUint32 nss_ckmk_nObjects = 1;
diff --git a/security/nss/lib/ckfw/session.c b/security/nss/lib/ckfw/session.c
index a3119345ca..7efedf4035 100644
--- a/security/nss/lib/ckfw/session.c
+++ b/security/nss/lib/ckfw/session.c
@@ -1419,9 +1419,8 @@ nssCKFWSession_CopyObject(
/* use create object */
NSSArena *tmpArena;
CK_ATTRIBUTE_PTR newTemplate;
- CK_ULONG i, j, n, newLength, k;
+ CK_ULONG j, n, newLength, k;
CK_ATTRIBUTE_TYPE_PTR oldTypes;
- NSSCKFWObject *rv;
n = nssCKFWObject_GetAttributeCount(fwObject, pError);
if ((0 == n) && (CKR_OK != *pError)) {
diff --git a/security/nss/lib/dev/devtoken.c b/security/nss/lib/dev/devtoken.c
index 0d4c3b5a72..41ffe86da5 100644
--- a/security/nss/lib/dev/devtoken.c
+++ b/security/nss/lib/dev/devtoken.c
@@ -528,7 +528,9 @@ nssToken_ImportCertificate(
*/
NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize);
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
- NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);
+ if (!rvObject->label && nickname) {
+ NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);
+ }
NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);
/* reset the mutable attributes on the token */
nssCKObject_SetAttributes(rvObject->handle,
diff --git a/security/nss/lib/freebl/Makefile b/security/nss/lib/freebl/Makefile
index a4b1a86aec..bff11c7c8e 100644
--- a/security/nss/lib/freebl/Makefile
+++ b/security/nss/lib/freebl/Makefile
@@ -517,13 +517,13 @@ ifndef NSS_DISABLE_CHACHAPOLY
ifdef HAVE_INT128_SUPPORT
EXTRA_SRCS += Hacl_Poly1305_64.c
else
- EXTRA_SRCS += poly1305.c
+ EXTRA_SRCS += Hacl_Poly1305_32.c
endif
else
ifeq ($(CPU_ARCH),aarch64)
EXTRA_SRCS += Hacl_Poly1305_64.c
else
- EXTRA_SRCS += poly1305.c
+ EXTRA_SRCS += Hacl_Poly1305_32.c
endif
endif # x86_64
@@ -535,12 +535,16 @@ ifeq (,$(filter-out i386 x386 x86 x86_64 aarch64,$(CPU_ARCH)))
# All intel architectures get the 64 bit version
# With custom uint128 if necessary (faster than generic 32 bit version).
ECL_SRCS += curve25519_64.c
- VERIFIED_SRCS += Hacl_Curve25519.c FStar.c
+ VERIFIED_SRCS += Hacl_Curve25519.c
else
# All non intel architectures get the generic 32 bit implementation (slow!)
ECL_SRCS += curve25519_32.c
endif
+ifndef HAVE_INT128_SUPPORT
+ VERIFIED_SRCS += FStar.c
+endif
+
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
diff --git a/security/nss/lib/freebl/blake2b.c b/security/nss/lib/freebl/blake2b.c
index 4099c67e01..b4a0442c95 100644
--- a/security/nss/lib/freebl/blake2b.c
+++ b/security/nss/lib/freebl/blake2b.c
@@ -180,7 +180,7 @@ blake2b_Begin(BLAKE2BContext* ctx, uint8_t outlen, const uint8_t* key,
return SECSuccess;
failure:
- PORT_Memset(&ctx, 0, sizeof(ctx));
+ PORT_Memset(ctx, 0, sizeof(*ctx));
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
diff --git a/security/nss/lib/freebl/chacha20poly1305.c b/security/nss/lib/freebl/chacha20poly1305.c
index 859d05316e..302f0db9e7 100644
--- a/security/nss/lib/freebl/chacha20poly1305.c
+++ b/security/nss/lib/freebl/chacha20poly1305.c
@@ -24,36 +24,60 @@ extern void Hacl_Chacha20_Vec128_chacha20(uint8_t *output, uint8_t *plain,
extern void Hacl_Chacha20_chacha20(uint8_t *output, uint8_t *plain, uint32_t len,
uint8_t *k, uint8_t *n1, uint32_t ctr);
-/* Poly1305Do writes the Poly1305 authenticator of the given additional data
- * and ciphertext to |out|. */
#if defined(HAVE_INT128_SUPPORT) && (defined(NSS_X86_OR_X64) || defined(__aarch64__))
/* Use HACL* Poly1305 on 64-bit Intel and ARM */
#include "verified/Hacl_Poly1305_64.h"
+#define NSS_POLY1305_64 1
+#define Hacl_Poly1305_update Hacl_Poly1305_64_update
+#define Hacl_Poly1305_mk_state Hacl_Poly1305_64_mk_state
+#define Hacl_Poly1305_init Hacl_Poly1305_64_init
+#define Hacl_Poly1305_finish Hacl_Poly1305_64_finish
+typedef Hacl_Impl_Poly1305_64_State_poly1305_state Hacl_Impl_Poly1305_State_poly1305_state;
+#else
+/* All other platforms get the 32-bit poly1305 HACL* implementation. */
+#include "verified/Hacl_Poly1305_32.h"
+#define NSS_POLY1305_32 1
+#define Hacl_Poly1305_update Hacl_Poly1305_32_update
+#define Hacl_Poly1305_mk_state Hacl_Poly1305_32_mk_state
+#define Hacl_Poly1305_init Hacl_Poly1305_32_init
+#define Hacl_Poly1305_finish Hacl_Poly1305_32_finish
+typedef Hacl_Impl_Poly1305_32_State_poly1305_state Hacl_Impl_Poly1305_State_poly1305_state;
+#endif /* HAVE_INT128_SUPPORT */
static void
-Poly1305PadUpdate(Hacl_Impl_Poly1305_64_State_poly1305_state state,
+Poly1305PadUpdate(Hacl_Impl_Poly1305_State_poly1305_state state,
unsigned char *block, const unsigned char *p,
const unsigned int pLen)
{
unsigned int pRemLen = pLen % 16;
- Hacl_Poly1305_64_update(state, (uint8_t *)p, (pLen / 16));
+ Hacl_Poly1305_update(state, (uint8_t *)p, (pLen / 16));
if (pRemLen > 0) {
memcpy(block, p + (pLen - pRemLen), pRemLen);
- Hacl_Poly1305_64_update(state, block, 1);
+ Hacl_Poly1305_update(state, block, 1);
}
}
+/* Poly1305Do writes the Poly1305 authenticator of the given additional data
+ * and ciphertext to |out|. */
static void
Poly1305Do(unsigned char *out, const unsigned char *ad, unsigned int adLen,
const unsigned char *ciphertext, unsigned int ciphertextLen,
const unsigned char key[32])
{
- uint64_t tmp1[6U] = { 0U };
- Hacl_Impl_Poly1305_64_State_poly1305_state state =
- Hacl_Poly1305_64_mk_state(tmp1, tmp1 + 3);
+#ifdef NSS_POLY1305_64
+ uint64_t stateStack[6U] = { 0U };
+ size_t offset = 3;
+#elif defined NSS_POLY1305_32
+ uint32_t stateStack[10U] = { 0U };
+ size_t offset = 5;
+#else
+#error "This can't happen."
+#endif
+ Hacl_Impl_Poly1305_State_poly1305_state state =
+ Hacl_Poly1305_mk_state(stateStack, stateStack + offset);
unsigned char block[16] = { 0 };
- Hacl_Poly1305_64_init(state, (uint8_t *)key);
+ Hacl_Poly1305_init(state, (uint8_t *)key);
Poly1305PadUpdate(state, block, ad, adLen);
memset(block, 0, 16);
@@ -68,49 +92,11 @@ Poly1305Do(unsigned char *out, const unsigned char *ad, unsigned int adLen,
block[i] = j;
}
- Hacl_Poly1305_64_update(state, block, 1);
- Hacl_Poly1305_64_finish(state, out, (uint8_t *)(key + 16));
+ Hacl_Poly1305_update(state, block, 1);
+ Hacl_Poly1305_finish(state, out, (uint8_t *)(key + 16));
+#undef NSS_POLY1305_64
+#undef NSS_POLY1305_32
}
-#else
-/* All other platforms get the 32-bit poly1305 reference implementation. */
-#include "poly1305.h"
-
-static void
-Poly1305Do(unsigned char *out, const unsigned char *ad, unsigned int adLen,
- const unsigned char *ciphertext, unsigned int ciphertextLen,
- const unsigned char key[32])
-{
- poly1305_state state;
- unsigned int j;
- unsigned char lengthBytes[8];
- static const unsigned char zeros[15];
- unsigned int i;
-
- Poly1305Init(&state, key);
- Poly1305Update(&state, ad, adLen);
- if (adLen % 16 > 0) {
- Poly1305Update(&state, zeros, 16 - adLen % 16);
- }
- Poly1305Update(&state, ciphertext, ciphertextLen);
- if (ciphertextLen % 16 > 0) {
- Poly1305Update(&state, zeros, 16 - ciphertextLen % 16);
- }
- j = adLen;
- for (i = 0; i < sizeof(lengthBytes); i++) {
- lengthBytes[i] = j;
- j >>= 8;
- }
- Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
- j = ciphertextLen;
- for (i = 0; i < sizeof(lengthBytes); i++) {
- lengthBytes[i] = j;
- j >>= 8;
- }
- Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
- Poly1305Finish(&state, out);
-}
-
-#endif /* HAVE_INT128_SUPPORT */
#endif /* NSS_DISABLE_CHACHAPOLY */
SECStatus
diff --git a/security/nss/lib/freebl/dsa.c b/security/nss/lib/freebl/dsa.c
index 9324d306b1..aef353967d 100644
--- a/security/nss/lib/freebl/dsa.c
+++ b/security/nss/lib/freebl/dsa.c
@@ -16,14 +16,11 @@
#include "blapi.h"
#include "nssilock.h"
#include "secitem.h"
-#include "blapi.h"
+#include "blapit.h"
#include "mpi.h"
#include "secmpi.h"
#include "pqg.h"
-/* XXX to be replaced by define in blapit.h */
-#define NSS_FREEBL_DSA_DEFAULT_CHUNKSIZE 2048
-
/*
* FIPS 186-2 requires result from random output to be reduced mod q when
* generating random numbers for DSA.
@@ -168,7 +165,7 @@ dsa_NewKeyExtended(const PQGParams *params, const SECItem *seed,
return SECFailure;
}
/* Initialize an arena for the DSA key. */
- arena = PORT_NewArena(NSS_FREEBL_DSA_DEFAULT_CHUNKSIZE);
+ arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
if (!arena) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return SECFailure;
@@ -213,8 +210,9 @@ cleanup:
mp_clear(&g);
mp_clear(&x);
mp_clear(&y);
- if (key)
+ if (key) {
PORT_FreeArena(key->params.arena, PR_TRUE);
+ }
if (err) {
translate_mpi_error(err);
return SECFailure;
@@ -321,6 +319,7 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
mp_int x, k; /* private key & pseudo-random integer */
mp_int r, s; /* tuple (r, s) is signature) */
mp_int t; /* holding tmp values */
+ mp_int ar; /* holding blinding values */
mp_err err = MP_OKAY;
SECStatus rv = SECSuccess;
unsigned int dsa_subprime_len, dsa_signature_len, offset;
@@ -364,6 +363,7 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
MP_DIGITS(&r) = 0;
MP_DIGITS(&s) = 0;
MP_DIGITS(&t) = 0;
+ MP_DIGITS(&ar) = 0;
CHECK_MPI_OK(mp_init(&p));
CHECK_MPI_OK(mp_init(&q));
CHECK_MPI_OK(mp_init(&g));
@@ -372,6 +372,7 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
CHECK_MPI_OK(mp_init(&r));
CHECK_MPI_OK(mp_init(&s));
CHECK_MPI_OK(mp_init(&t));
+ CHECK_MPI_OK(mp_init(&ar));
/*
** Convert stored PQG and private key into MPI integers.
*/
@@ -397,14 +398,28 @@ dsa_SignDigest(DSAPrivateKey *key, SECItem *signature, const SECItem *digest,
rv = SECFailure;
goto cleanup;
}
- SECITEM_TO_MPINT(t2, &t); /* t <-$ Zq */
+ SECITEM_TO_MPINT(t2, &t); /* t <-$ Zq */
+ SECITEM_FreeItem(&t2, PR_FALSE);
+ if (DSA_NewRandom(NULL, &key->params.subPrime, &t2) != SECSuccess) {
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ rv = SECFailure;
+ goto cleanup;
+ }
+ SECITEM_TO_MPINT(t2, &ar); /* ar <-$ Zq */
+ SECITEM_FreeItem(&t2, PR_FALSE);
+
+ /* Using mp_invmod on k directly would leak bits from k. */
+ CHECK_MPI_OK(mp_mul(&k, &ar, &k)); /* k = k * ar */
CHECK_MPI_OK(mp_mulmod(&k, &t, &q, &k)); /* k = k * t mod q */
CHECK_MPI_OK(mp_invmod(&k, &q, &k)); /* k = k**-1 mod q */
CHECK_MPI_OK(mp_mulmod(&k, &t, &q, &k)); /* k = k * t mod q */
SECITEM_TO_MPINT(localDigest, &s); /* s = HASH(M) */
- CHECK_MPI_OK(mp_mulmod(&x, &r, &q, &x)); /* x = x * r mod q */
- CHECK_MPI_OK(mp_addmod(&s, &x, &q, &s)); /* s = s + x mod q */
- CHECK_MPI_OK(mp_mulmod(&s, &k, &q, &s)); /* s = s * k mod q */
+ /* To avoid leaking secret bits here the addition is blinded. */
+ CHECK_MPI_OK(mp_mul(&x, &ar, &x)); /* x = x * ar */
+ CHECK_MPI_OK(mp_mulmod(&x, &r, &q, &x)); /* x = x * r mod q */
+ CHECK_MPI_OK(mp_mulmod(&s, &ar, &q, &t)); /* t = s * ar mod q */
+ CHECK_MPI_OK(mp_add(&t, &x, &s)); /* s = t + x */
+ CHECK_MPI_OK(mp_mulmod(&s, &k, &q, &s)); /* s = s * k mod q */
/*
** verify r != 0 and s != 0
** mentioned as optional in FIPS 186-1.
@@ -438,7 +453,7 @@ cleanup:
mp_clear(&r);
mp_clear(&s);
mp_clear(&t);
- SECITEM_FreeItem(&t2, PR_FALSE);
+ mp_clear(&ar);
if (err) {
translate_mpi_error(err);
rv = SECFailure;
diff --git a/security/nss/lib/freebl/ec.c b/security/nss/lib/freebl/ec.c
index b28815ade9..6468a10d63 100644
--- a/security/nss/lib/freebl/ec.c
+++ b/security/nss/lib/freebl/ec.c
@@ -653,6 +653,7 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
mp_int r, s; /* tuple (r, s) is the signature */
mp_int t; /* holding tmp values */
mp_int n;
+ mp_int ar; /* blinding value */
mp_err err = MP_OKAY;
ECParams *ecParams = NULL;
SECItem kGpoint = { siBuffer, NULL, 0 };
@@ -674,6 +675,7 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
MP_DIGITS(&s) = 0;
MP_DIGITS(&n) = 0;
MP_DIGITS(&t) = 0;
+ MP_DIGITS(&ar) = 0;
/* Check args */
if (!key || !signature || !digest || !kb || (kblen < 0)) {
@@ -700,6 +702,7 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
CHECK_MPI_OK(mp_init(&s));
CHECK_MPI_OK(mp_init(&n));
CHECK_MPI_OK(mp_init(&t));
+ CHECK_MPI_OK(mp_init(&ar));
SECITEM_TO_MPINT(ecParams->order, &n);
SECITEM_TO_MPINT(key->privateValue, &d);
@@ -815,12 +818,25 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature,
goto cleanup;
}
CHECK_MPI_OK(mp_read_unsigned_octets(&t, t2, 2 * ecParams->order.len)); /* t <-$ Zn */
- CHECK_MPI_OK(mp_mulmod(&k, &t, &n, &k)); /* k = k * t mod n */
- CHECK_MPI_OK(mp_invmod(&k, &n, &k)); /* k = k**-1 mod n */
- CHECK_MPI_OK(mp_mulmod(&k, &t, &n, &k)); /* k = k * t mod n */
- CHECK_MPI_OK(mp_mulmod(&d, &r, &n, &d)); /* d = d * r mod n */
- CHECK_MPI_OK(mp_addmod(&s, &d, &n, &s)); /* s = s + d mod n */
- CHECK_MPI_OK(mp_mulmod(&s, &k, &n, &s)); /* s = s * k mod n */
+ PORT_Memset(t2, 0, 2 * ecParams->order.len);
+ if (RNG_GenerateGlobalRandomBytes(t2, 2 * ecParams->order.len) != SECSuccess) {
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ rv = SECFailure;
+ goto cleanup;
+ }
+ CHECK_MPI_OK(mp_read_unsigned_octets(&ar, t2, 2 * ecParams->order.len)); /* ar <-$ Zn */
+
+ /* Using mp_invmod on k directly would leak bits from k. */
+ CHECK_MPI_OK(mp_mul(&k, &ar, &k)); /* k = k * ar */
+ CHECK_MPI_OK(mp_mulmod(&k, &t, &n, &k)); /* k = k * t mod n */
+ CHECK_MPI_OK(mp_invmod(&k, &n, &k)); /* k = k**-1 mod n */
+ CHECK_MPI_OK(mp_mulmod(&k, &t, &n, &k)); /* k = k * t mod n */
+ /* To avoid leaking secret bits here the addition is blinded. */
+ CHECK_MPI_OK(mp_mul(&d, &ar, &t)); /* t = d * ar */
+ CHECK_MPI_OK(mp_mulmod(&t, &r, &n, &d)); /* d = t * r mod n */
+ CHECK_MPI_OK(mp_mulmod(&s, &ar, &n, &t)); /* t = s * ar mod n */
+ CHECK_MPI_OK(mp_add(&t, &d, &s)); /* s = t + d */
+ CHECK_MPI_OK(mp_mulmod(&s, &k, &n, &s)); /* s = s * k mod n */
#if EC_DEBUG
mp_todecimal(&s, mpstr);
@@ -858,6 +874,7 @@ cleanup:
mp_clear(&s);
mp_clear(&n);
mp_clear(&t);
+ mp_clear(&ar);
if (t2) {
PORT_Free(t2);
diff --git a/security/nss/lib/freebl/freebl.gyp b/security/nss/lib/freebl/freebl.gyp
index fae56f709e..004807483e 100644
--- a/security/nss/lib/freebl/freebl.gyp
+++ b/security/nss/lib/freebl/freebl.gyp
@@ -272,28 +272,15 @@
},
}],
[ 'cc_use_gnu_ld==1 and OS=="win" and target_arch=="x64"', {
+ # mingw x64
'defines': [
'MP_IS_LITTLE_ENDIAN',
- 'NSS_BEVAND_ARCFOUR',
- 'MPI_AMD64',
- 'MP_ASSEMBLY_MULTIPLY',
- 'NSS_USE_COMBA',
- 'USE_HW_AES',
- 'INTEL_GCM',
],
}],
- [ 'OS!="win"', {
- 'conditions': [
- [ 'target_arch=="x64" or target_arch=="arm64" or target_arch=="aarch64"', {
- 'defines': [
- # The Makefile does version-tests on GCC, but we're not doing that here.
- 'HAVE_INT128_SUPPORT',
- ],
- }, {
- 'defines': [
- 'KRML_NOUINT128',
- ],
- }],
+ [ 'have_int128_support==1', {
+ 'defines': [
+ # The Makefile does version-tests on GCC, but we're not doing that here.
+ 'HAVE_INT128_SUPPORT',
],
}, {
'defines': [
@@ -355,5 +342,18 @@
},
'variables': {
'module': 'nss',
+ 'conditions': [
+ [ 'OS!="win"', {
+ 'conditions': [
+ [ 'target_arch=="x64" or target_arch=="arm64" or target_arch=="aarch64"', {
+ 'have_int128_support%': 1,
+ }, {
+ 'have_int128_support%': 0,
+ }],
+ ],
+ }, {
+ 'have_int128_support%': 0,
+ }],
+ ],
}
}
diff --git a/security/nss/lib/freebl/freebl_base.gypi b/security/nss/lib/freebl/freebl_base.gypi
index ebd1018d81..1372994f4c 100644
--- a/security/nss/lib/freebl/freebl_base.gypi
+++ b/security/nss/lib/freebl/freebl_base.gypi
@@ -59,7 +59,7 @@
'sha_fast.c',
'shvfy.c',
'sysrand.c',
- 'tlsprfalg.c'
+ 'tlsprfalg.c',
],
'conditions': [
[ 'OS=="linux" or OS=="android"', {
@@ -122,6 +122,11 @@
'intel-gcm-x86-masm.asm',
],
}],
+ [ 'cc_use_gnu_ld==1', {
+ # mingw
+ 'sources': [
+ ],
+ }],
[ 'cc_is_clang!=1', {
# MSVC
'sources': [
@@ -135,7 +140,6 @@
# All intel and 64-bit ARM architectures get the 64 bit version.
'ecl/curve25519_64.c',
'verified/Hacl_Curve25519.c',
- 'verified/FStar.c',
],
}, {
'sources': [
@@ -167,7 +171,7 @@
}, {
# !Windows & !x64 & !arm64 & !aarch64
'sources': [
- 'poly1305.c',
+ 'verified/Hacl_Poly1305_32.c',
],
}],
],
@@ -176,7 +180,7 @@
}, {
# Windows
'sources': [
- 'poly1305.c',
+ 'verified/Hacl_Poly1305_32.c',
],
}],
],
@@ -215,6 +219,9 @@
}],
],
}],
+ [ 'have_int128_support==0', {
+ 'sources': [ 'verified/FStar.c' ],
+ }],
],
'ldflags': [
'-Wl,-Bsymbolic'
diff --git a/security/nss/lib/freebl/loader.c b/security/nss/lib/freebl/loader.c
index fe5e0a6680..6d200e6dd1 100644
--- a/security/nss/lib/freebl/loader.c
+++ b/security/nss/lib/freebl/loader.c
@@ -2164,12 +2164,12 @@ BLAKE2B_NewContext(void)
}
void
-BLAKE2B_DestroyContext(BLAKE2BContext *BLAKE2BContext, PRBool freeit)
+BLAKE2B_DestroyContext(BLAKE2BContext *ctx, PRBool freeit)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) {
return;
}
- (vector->p_BLAKE2B_DestroyContext)(BLAKE2BContext, freeit);
+ (vector->p_BLAKE2B_DestroyContext)(ctx, freeit);
}
SECStatus
diff --git a/security/nss/lib/freebl/mpi/mpi.c b/security/nss/lib/freebl/mpi/mpi.c
index ae404019d8..8c893fb5fa 100644
--- a/security/nss/lib/freebl/mpi/mpi.c
+++ b/security/nss/lib/freebl/mpi/mpi.c
@@ -2657,10 +2657,10 @@ mp_toradix(mp_int *mp, char *str, int radix)
/* Reverse the digits and sign indicator */
ix = 0;
while (ix < pos) {
- char tmp = str[ix];
+ char tmpc = str[ix];
str[ix] = str[pos];
- str[pos] = tmp;
+ str[pos] = tmpc;
++ix;
--pos;
}
@@ -3313,13 +3313,14 @@ s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r)
/* could check for power of 2 here, but mp_div_d does that. */
if (MP_USED(mp) == 1) {
mp_digit n = MP_DIGIT(mp, 0);
- mp_digit rem;
+ mp_digit remdig;
q = n / d;
- rem = n % d;
+ remdig = n % d;
MP_DIGIT(mp, 0) = q;
- if (r)
- *r = rem;
+ if (r) {
+ *r = remdig;
+ }
return MP_OKAY;
}
diff --git a/security/nss/lib/freebl/poly1305-donna-x64-sse2-incremental-source.c b/security/nss/lib/freebl/poly1305-donna-x64-sse2-incremental-source.c
deleted file mode 100644
index 3c803c167d..0000000000
--- a/security/nss/lib/freebl/poly1305-donna-x64-sse2-incremental-source.c
+++ /dev/null
@@ -1,881 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* This implementation of poly1305 is by Andrew Moon
- * (https://github.com/floodyberry/poly1305-donna) and released as public
- * domain. It implements SIMD vectorization based on the algorithm described in
- * http://cr.yp.to/papers.html#neoncrypto. Unrolled to 2 powers, i.e. 64 byte
- * block size. */
-
-#include <emmintrin.h>
-#include <stdint.h>
-
-#include "poly1305.h"
-#include "blapii.h"
-
-#define ALIGN(x) __attribute__((aligned(x)))
-#define INLINE inline
-#define U8TO64_LE(m) (*(uint64_t *)(m))
-#define U8TO32_LE(m) (*(uint32_t *)(m))
-#define U64TO8_LE(m, v) (*(uint64_t *)(m)) = v
-
-typedef __m128i xmmi;
-typedef unsigned __int128 uint128_t;
-
-static const uint32_t ALIGN(16) poly1305_x64_sse2_message_mask[4] = { (1 << 26) - 1, 0, (1 << 26) - 1, 0 };
-static const uint32_t ALIGN(16) poly1305_x64_sse2_5[4] = { 5, 0, 5, 0 };
-static const uint32_t ALIGN(16) poly1305_x64_sse2_1shl128[4] = { (1 << 24), 0, (1 << 24), 0 };
-
-static uint128_t INLINE
-add128(uint128_t a, uint128_t b)
-{
- return a + b;
-}
-
-static uint128_t INLINE
-add128_64(uint128_t a, uint64_t b)
-{
- return a + b;
-}
-
-static uint128_t INLINE
-mul64x64_128(uint64_t a, uint64_t b)
-{
- return (uint128_t)a * b;
-}
-
-static uint64_t INLINE
-lo128(uint128_t a)
-{
- return (uint64_t)a;
-}
-
-static uint64_t INLINE
-shr128(uint128_t v, const int shift)
-{
- return (uint64_t)(v >> shift);
-}
-
-static uint64_t INLINE
-shr128_pair(uint64_t hi, uint64_t lo, const int shift)
-{
- return (uint64_t)((((uint128_t)hi << 64) | lo) >> shift);
-}
-
-typedef struct poly1305_power_t {
- union {
- xmmi v;
- uint64_t u[2];
- uint32_t d[4];
- } R20, R21, R22, R23, R24, S21, S22, S23, S24;
-} poly1305_power;
-
-typedef struct poly1305_state_internal_t {
- poly1305_power P[2]; /* 288 bytes, top 32 bit halves unused = 144 bytes of free storage */
- union {
- xmmi H[5]; /* 80 bytes */
- uint64_t HH[10];
- };
- /* uint64_t r0,r1,r2; [24 bytes] */
- /* uint64_t pad0,pad1; [16 bytes] */
- uint64_t started; /* 8 bytes */
- uint64_t leftover; /* 8 bytes */
- uint8_t buffer[64]; /* 64 bytes */
-} poly1305_state_internal; /* 448 bytes total + 63 bytes for alignment = 511 bytes raw */
-
-static poly1305_state_internal INLINE
- *
- poly1305_aligned_state(poly1305_state *state)
-{
- return (poly1305_state_internal *)(((uint64_t)state + 63) & ~63);
-}
-
-/* copy 0-63 bytes */
-static void INLINE NO_SANITIZE_ALIGNMENT
-poly1305_block_copy(uint8_t *dst, const uint8_t *src, size_t bytes)
-{
- size_t offset = src - dst;
- if (bytes & 32) {
- _mm_storeu_si128((xmmi *)(dst + 0), _mm_loadu_si128((xmmi *)(dst + offset + 0)));
- _mm_storeu_si128((xmmi *)(dst + 16), _mm_loadu_si128((xmmi *)(dst + offset + 16)));
- dst += 32;
- }
- if (bytes & 16) {
- _mm_storeu_si128((xmmi *)dst, _mm_loadu_si128((xmmi *)(dst + offset)));
- dst += 16;
- }
- if (bytes & 8) {
- *(uint64_t *)dst = *(uint64_t *)(dst + offset);
- dst += 8;
- }
- if (bytes & 4) {
- *(uint32_t *)dst = *(uint32_t *)(dst + offset);
- dst += 4;
- }
- if (bytes & 2) {
- *(uint16_t *)dst = *(uint16_t *)(dst + offset);
- dst += 2;
- }
- if (bytes & 1) {
- *(uint8_t *)dst = *(uint8_t *)(dst + offset);
- }
-}
-
-/* zero 0-15 bytes */
-static void INLINE
-poly1305_block_zero(uint8_t *dst, size_t bytes)
-{
- if (bytes & 8) {
- *(uint64_t *)dst = 0;
- dst += 8;
- }
- if (bytes & 4) {
- *(uint32_t *)dst = 0;
- dst += 4;
- }
- if (bytes & 2) {
- *(uint16_t *)dst = 0;
- dst += 2;
- }
- if (bytes & 1) {
- *(uint8_t *)dst = 0;
- }
-}
-
-static size_t INLINE
-poly1305_min(size_t a, size_t b)
-{
- return (a < b) ? a : b;
-}
-
-void
-Poly1305Init(poly1305_state *state, const unsigned char key[32])
-{
- poly1305_state_internal *st = poly1305_aligned_state(state);
- poly1305_power *p;
- uint64_t r0, r1, r2;
- uint64_t t0, t1;
-
- /* clamp key */
- t0 = U8TO64_LE(key + 0);
- t1 = U8TO64_LE(key + 8);
- r0 = t0 & 0xffc0fffffff;
- t0 >>= 44;
- t0 |= t1 << 20;
- r1 = t0 & 0xfffffc0ffff;
- t1 >>= 24;
- r2 = t1 & 0x00ffffffc0f;
-
- /* store r in un-used space of st->P[1] */
- p = &st->P[1];
- p->R20.d[1] = (uint32_t)(r0);
- p->R20.d[3] = (uint32_t)(r0 >> 32);
- p->R21.d[1] = (uint32_t)(r1);
- p->R21.d[3] = (uint32_t)(r1 >> 32);
- p->R22.d[1] = (uint32_t)(r2);
- p->R22.d[3] = (uint32_t)(r2 >> 32);
-
- /* store pad */
- p->R23.d[1] = U8TO32_LE(key + 16);
- p->R23.d[3] = U8TO32_LE(key + 20);
- p->R24.d[1] = U8TO32_LE(key + 24);
- p->R24.d[3] = U8TO32_LE(key + 28);
-
- /* H = 0 */
- st->H[0] = _mm_setzero_si128();
- st->H[1] = _mm_setzero_si128();
- st->H[2] = _mm_setzero_si128();
- st->H[3] = _mm_setzero_si128();
- st->H[4] = _mm_setzero_si128();
-
- st->started = 0;
- st->leftover = 0;
-}
-
-static void
-poly1305_first_block(poly1305_state_internal *st, const uint8_t *m)
-{
- const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
- const xmmi FIVE = _mm_load_si128((xmmi *)poly1305_x64_sse2_5);
- const xmmi HIBIT = _mm_load_si128((xmmi *)poly1305_x64_sse2_1shl128);
- xmmi T5, T6;
- poly1305_power *p;
- uint128_t d[3];
- uint64_t r0, r1, r2;
- uint64_t r20, r21, r22, s22;
- uint64_t pad0, pad1;
- uint64_t c;
- uint64_t i;
-
- /* pull out stored info */
- p = &st->P[1];
-
- r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1];
- r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1];
- r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1];
- pad0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1];
- pad1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1];
-
- /* compute powers r^2,r^4 */
- r20 = r0;
- r21 = r1;
- r22 = r2;
- for (i = 0; i < 2; i++) {
- s22 = r22 * (5 << 2);
-
- d[0] = add128(mul64x64_128(r20, r20), mul64x64_128(r21 * 2, s22));
- d[1] = add128(mul64x64_128(r22, s22), mul64x64_128(r20 * 2, r21));
- d[2] = add128(mul64x64_128(r21, r21), mul64x64_128(r22 * 2, r20));
-
- r20 = lo128(d[0]) & 0xfffffffffff;
- c = shr128(d[0], 44);
- d[1] = add128_64(d[1], c);
- r21 = lo128(d[1]) & 0xfffffffffff;
- c = shr128(d[1], 44);
- d[2] = add128_64(d[2], c);
- r22 = lo128(d[2]) & 0x3ffffffffff;
- c = shr128(d[2], 42);
- r20 += c * 5;
- c = (r20 >> 44);
- r20 = r20 & 0xfffffffffff;
- r21 += c;
-
- p->R20.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)(r20)&0x3ffffff), _MM_SHUFFLE(1, 0, 1, 0));
- p->R21.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r20 >> 26) | (r21 << 18)) & 0x3ffffff), _MM_SHUFFLE(1, 0, 1, 0));
- p->R22.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r21 >> 8)) & 0x3ffffff), _MM_SHUFFLE(1, 0, 1, 0));
- p->R23.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r21 >> 34) | (r22 << 10)) & 0x3ffffff), _MM_SHUFFLE(1, 0, 1, 0));
- p->R24.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r22 >> 16))), _MM_SHUFFLE(1, 0, 1, 0));
- p->S21.v = _mm_mul_epu32(p->R21.v, FIVE);
- p->S22.v = _mm_mul_epu32(p->R22.v, FIVE);
- p->S23.v = _mm_mul_epu32(p->R23.v, FIVE);
- p->S24.v = _mm_mul_epu32(p->R24.v, FIVE);
- p--;
- }
-
- /* put saved info back */
- p = &st->P[1];
- p->R20.d[1] = (uint32_t)(r0);
- p->R20.d[3] = (uint32_t)(r0 >> 32);
- p->R21.d[1] = (uint32_t)(r1);
- p->R21.d[3] = (uint32_t)(r1 >> 32);
- p->R22.d[1] = (uint32_t)(r2);
- p->R22.d[3] = (uint32_t)(r2 >> 32);
- p->R23.d[1] = (uint32_t)(pad0);
- p->R23.d[3] = (uint32_t)(pad0 >> 32);
- p->R24.d[1] = (uint32_t)(pad1);
- p->R24.d[3] = (uint32_t)(pad1 >> 32);
-
- /* H = [Mx,My] */
- T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)), _mm_loadl_epi64((xmmi *)(m + 16)));
- T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)), _mm_loadl_epi64((xmmi *)(m + 24)));
- st->H[0] = _mm_and_si128(MMASK, T5);
- st->H[1] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
- T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
- st->H[2] = _mm_and_si128(MMASK, T5);
- st->H[3] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
- st->H[4] = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
-}
-
-static void
-poly1305_blocks(poly1305_state_internal *st, const uint8_t *m, size_t bytes)
-{
- const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
- const xmmi FIVE = _mm_load_si128((xmmi *)poly1305_x64_sse2_5);
- const xmmi HIBIT = _mm_load_si128((xmmi *)poly1305_x64_sse2_1shl128);
-
- poly1305_power *p;
- xmmi H0, H1, H2, H3, H4;
- xmmi T0, T1, T2, T3, T4, T5, T6;
- xmmi M0, M1, M2, M3, M4;
- xmmi C1, C2;
-
- H0 = st->H[0];
- H1 = st->H[1];
- H2 = st->H[2];
- H3 = st->H[3];
- H4 = st->H[4];
-
- while (bytes >= 64) {
- /* H *= [r^4,r^4] */
- p = &st->P[0];
- T0 = _mm_mul_epu32(H0, p->R20.v);
- T1 = _mm_mul_epu32(H0, p->R21.v);
- T2 = _mm_mul_epu32(H0, p->R22.v);
- T3 = _mm_mul_epu32(H0, p->R23.v);
- T4 = _mm_mul_epu32(H0, p->R24.v);
- T5 = _mm_mul_epu32(H1, p->S24.v);
- T6 = _mm_mul_epu32(H1, p->R20.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(H2, p->S23.v);
- T6 = _mm_mul_epu32(H2, p->S24.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(H3, p->S22.v);
- T6 = _mm_mul_epu32(H3, p->S23.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(H4, p->S21.v);
- T6 = _mm_mul_epu32(H4, p->S22.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(H1, p->R21.v);
- T6 = _mm_mul_epu32(H1, p->R22.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(H2, p->R20.v);
- T6 = _mm_mul_epu32(H2, p->R21.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(H3, p->S24.v);
- T6 = _mm_mul_epu32(H3, p->R20.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(H4, p->S23.v);
- T6 = _mm_mul_epu32(H4, p->S24.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(H1, p->R23.v);
- T4 = _mm_add_epi64(T4, T5);
- T5 = _mm_mul_epu32(H2, p->R22.v);
- T4 = _mm_add_epi64(T4, T5);
- T5 = _mm_mul_epu32(H3, p->R21.v);
- T4 = _mm_add_epi64(T4, T5);
- T5 = _mm_mul_epu32(H4, p->R20.v);
- T4 = _mm_add_epi64(T4, T5);
-
- /* H += [Mx,My]*[r^2,r^2] */
- T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)), _mm_loadl_epi64((xmmi *)(m + 16)));
- T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)), _mm_loadl_epi64((xmmi *)(m + 24)));
- M0 = _mm_and_si128(MMASK, T5);
- M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
- T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
- M2 = _mm_and_si128(MMASK, T5);
- M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
- M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
-
- p = &st->P[1];
- T5 = _mm_mul_epu32(M0, p->R20.v);
- T6 = _mm_mul_epu32(M0, p->R21.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(M1, p->S24.v);
- T6 = _mm_mul_epu32(M1, p->R20.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(M2, p->S23.v);
- T6 = _mm_mul_epu32(M2, p->S24.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(M3, p->S22.v);
- T6 = _mm_mul_epu32(M3, p->S23.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(M4, p->S21.v);
- T6 = _mm_mul_epu32(M4, p->S22.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(M0, p->R22.v);
- T6 = _mm_mul_epu32(M0, p->R23.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(M1, p->R21.v);
- T6 = _mm_mul_epu32(M1, p->R22.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(M2, p->R20.v);
- T6 = _mm_mul_epu32(M2, p->R21.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(M3, p->S24.v);
- T6 = _mm_mul_epu32(M3, p->R20.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(M4, p->S23.v);
- T6 = _mm_mul_epu32(M4, p->S24.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(M0, p->R24.v);
- T4 = _mm_add_epi64(T4, T5);
- T5 = _mm_mul_epu32(M1, p->R23.v);
- T4 = _mm_add_epi64(T4, T5);
- T5 = _mm_mul_epu32(M2, p->R22.v);
- T4 = _mm_add_epi64(T4, T5);
- T5 = _mm_mul_epu32(M3, p->R21.v);
- T4 = _mm_add_epi64(T4, T5);
- T5 = _mm_mul_epu32(M4, p->R20.v);
- T4 = _mm_add_epi64(T4, T5);
-
- /* H += [Mx,My] */
- T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 32)), _mm_loadl_epi64((xmmi *)(m + 48)));
- T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 40)), _mm_loadl_epi64((xmmi *)(m + 56)));
- M0 = _mm_and_si128(MMASK, T5);
- M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
- T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
- M2 = _mm_and_si128(MMASK, T5);
- M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
- M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
-
- T0 = _mm_add_epi64(T0, M0);
- T1 = _mm_add_epi64(T1, M1);
- T2 = _mm_add_epi64(T2, M2);
- T3 = _mm_add_epi64(T3, M3);
- T4 = _mm_add_epi64(T4, M4);
-
- /* reduce */
- C1 = _mm_srli_epi64(T0, 26);
- C2 = _mm_srli_epi64(T3, 26);
- T0 = _mm_and_si128(T0, MMASK);
- T3 = _mm_and_si128(T3, MMASK);
- T1 = _mm_add_epi64(T1, C1);
- T4 = _mm_add_epi64(T4, C2);
- C1 = _mm_srli_epi64(T1, 26);
- C2 = _mm_srli_epi64(T4, 26);
- T1 = _mm_and_si128(T1, MMASK);
- T4 = _mm_and_si128(T4, MMASK);
- T2 = _mm_add_epi64(T2, C1);
- T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE));
- C1 = _mm_srli_epi64(T2, 26);
- C2 = _mm_srli_epi64(T0, 26);
- T2 = _mm_and_si128(T2, MMASK);
- T0 = _mm_and_si128(T0, MMASK);
- T3 = _mm_add_epi64(T3, C1);
- T1 = _mm_add_epi64(T1, C2);
- C1 = _mm_srli_epi64(T3, 26);
- T3 = _mm_and_si128(T3, MMASK);
- T4 = _mm_add_epi64(T4, C1);
-
- /* H = (H*[r^4,r^4] + [Mx,My]*[r^2,r^2] + [Mx,My]) */
- H0 = T0;
- H1 = T1;
- H2 = T2;
- H3 = T3;
- H4 = T4;
-
- m += 64;
- bytes -= 64;
- }
-
- st->H[0] = H0;
- st->H[1] = H1;
- st->H[2] = H2;
- st->H[3] = H3;
- st->H[4] = H4;
-}
-
-static size_t
-poly1305_combine(poly1305_state_internal *st, const uint8_t *m, size_t bytes)
-{
- const xmmi MMASK = _mm_load_si128((xmmi *)poly1305_x64_sse2_message_mask);
- const xmmi HIBIT = _mm_load_si128((xmmi *)poly1305_x64_sse2_1shl128);
- const xmmi FIVE = _mm_load_si128((xmmi *)poly1305_x64_sse2_5);
-
- poly1305_power *p;
- xmmi H0, H1, H2, H3, H4;
- xmmi M0, M1, M2, M3, M4;
- xmmi T0, T1, T2, T3, T4, T5, T6;
- xmmi C1, C2;
-
- uint64_t r0, r1, r2;
- uint64_t t0, t1, t2, t3, t4;
- uint64_t c;
- size_t consumed = 0;
-
- H0 = st->H[0];
- H1 = st->H[1];
- H2 = st->H[2];
- H3 = st->H[3];
- H4 = st->H[4];
-
- /* p = [r^2,r^2] */
- p = &st->P[1];
-
- if (bytes >= 32) {
- /* H *= [r^2,r^2] */
- T0 = _mm_mul_epu32(H0, p->R20.v);
- T1 = _mm_mul_epu32(H0, p->R21.v);
- T2 = _mm_mul_epu32(H0, p->R22.v);
- T3 = _mm_mul_epu32(H0, p->R23.v);
- T4 = _mm_mul_epu32(H0, p->R24.v);
- T5 = _mm_mul_epu32(H1, p->S24.v);
- T6 = _mm_mul_epu32(H1, p->R20.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(H2, p->S23.v);
- T6 = _mm_mul_epu32(H2, p->S24.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(H3, p->S22.v);
- T6 = _mm_mul_epu32(H3, p->S23.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(H4, p->S21.v);
- T6 = _mm_mul_epu32(H4, p->S22.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(H1, p->R21.v);
- T6 = _mm_mul_epu32(H1, p->R22.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(H2, p->R20.v);
- T6 = _mm_mul_epu32(H2, p->R21.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(H3, p->S24.v);
- T6 = _mm_mul_epu32(H3, p->R20.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(H4, p->S23.v);
- T6 = _mm_mul_epu32(H4, p->S24.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(H1, p->R23.v);
- T4 = _mm_add_epi64(T4, T5);
- T5 = _mm_mul_epu32(H2, p->R22.v);
- T4 = _mm_add_epi64(T4, T5);
- T5 = _mm_mul_epu32(H3, p->R21.v);
- T4 = _mm_add_epi64(T4, T5);
- T5 = _mm_mul_epu32(H4, p->R20.v);
- T4 = _mm_add_epi64(T4, T5);
-
- /* H += [Mx,My] */
- T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 0)), _mm_loadl_epi64((xmmi *)(m + 16)));
- T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((xmmi *)(m + 8)), _mm_loadl_epi64((xmmi *)(m + 24)));
- M0 = _mm_and_si128(MMASK, T5);
- M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
- T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12));
- M2 = _mm_and_si128(MMASK, T5);
- M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26));
- M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT);
-
- T0 = _mm_add_epi64(T0, M0);
- T1 = _mm_add_epi64(T1, M1);
- T2 = _mm_add_epi64(T2, M2);
- T3 = _mm_add_epi64(T3, M3);
- T4 = _mm_add_epi64(T4, M4);
-
- /* reduce */
- C1 = _mm_srli_epi64(T0, 26);
- C2 = _mm_srli_epi64(T3, 26);
- T0 = _mm_and_si128(T0, MMASK);
- T3 = _mm_and_si128(T3, MMASK);
- T1 = _mm_add_epi64(T1, C1);
- T4 = _mm_add_epi64(T4, C2);
- C1 = _mm_srli_epi64(T1, 26);
- C2 = _mm_srli_epi64(T4, 26);
- T1 = _mm_and_si128(T1, MMASK);
- T4 = _mm_and_si128(T4, MMASK);
- T2 = _mm_add_epi64(T2, C1);
- T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE));
- C1 = _mm_srli_epi64(T2, 26);
- C2 = _mm_srli_epi64(T0, 26);
- T2 = _mm_and_si128(T2, MMASK);
- T0 = _mm_and_si128(T0, MMASK);
- T3 = _mm_add_epi64(T3, C1);
- T1 = _mm_add_epi64(T1, C2);
- C1 = _mm_srli_epi64(T3, 26);
- T3 = _mm_and_si128(T3, MMASK);
- T4 = _mm_add_epi64(T4, C1);
-
- /* H = (H*[r^2,r^2] + [Mx,My]) */
- H0 = T0;
- H1 = T1;
- H2 = T2;
- H3 = T3;
- H4 = T4;
-
- consumed = 32;
- }
-
- /* finalize, H *= [r^2,r] */
- r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1];
- r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1];
- r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1];
-
- p->R20.d[2] = (uint32_t)(r0)&0x3ffffff;
- p->R21.d[2] = (uint32_t)((r0 >> 26) | (r1 << 18)) & 0x3ffffff;
- p->R22.d[2] = (uint32_t)((r1 >> 8)) & 0x3ffffff;
- p->R23.d[2] = (uint32_t)((r1 >> 34) | (r2 << 10)) & 0x3ffffff;
- p->R24.d[2] = (uint32_t)((r2 >> 16));
- p->S21.d[2] = p->R21.d[2] * 5;
- p->S22.d[2] = p->R22.d[2] * 5;
- p->S23.d[2] = p->R23.d[2] * 5;
- p->S24.d[2] = p->R24.d[2] * 5;
-
- /* H *= [r^2,r] */
- T0 = _mm_mul_epu32(H0, p->R20.v);
- T1 = _mm_mul_epu32(H0, p->R21.v);
- T2 = _mm_mul_epu32(H0, p->R22.v);
- T3 = _mm_mul_epu32(H0, p->R23.v);
- T4 = _mm_mul_epu32(H0, p->R24.v);
- T5 = _mm_mul_epu32(H1, p->S24.v);
- T6 = _mm_mul_epu32(H1, p->R20.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(H2, p->S23.v);
- T6 = _mm_mul_epu32(H2, p->S24.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(H3, p->S22.v);
- T6 = _mm_mul_epu32(H3, p->S23.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(H4, p->S21.v);
- T6 = _mm_mul_epu32(H4, p->S22.v);
- T0 = _mm_add_epi64(T0, T5);
- T1 = _mm_add_epi64(T1, T6);
- T5 = _mm_mul_epu32(H1, p->R21.v);
- T6 = _mm_mul_epu32(H1, p->R22.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(H2, p->R20.v);
- T6 = _mm_mul_epu32(H2, p->R21.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(H3, p->S24.v);
- T6 = _mm_mul_epu32(H3, p->R20.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(H4, p->S23.v);
- T6 = _mm_mul_epu32(H4, p->S24.v);
- T2 = _mm_add_epi64(T2, T5);
- T3 = _mm_add_epi64(T3, T6);
- T5 = _mm_mul_epu32(H1, p->R23.v);
- T4 = _mm_add_epi64(T4, T5);
- T5 = _mm_mul_epu32(H2, p->R22.v);
- T4 = _mm_add_epi64(T4, T5);
- T5 = _mm_mul_epu32(H3, p->R21.v);
- T4 = _mm_add_epi64(T4, T5);
- T5 = _mm_mul_epu32(H4, p->R20.v);
- T4 = _mm_add_epi64(T4, T5);
-
- C1 = _mm_srli_epi64(T0, 26);
- C2 = _mm_srli_epi64(T3, 26);
- T0 = _mm_and_si128(T0, MMASK);
- T3 = _mm_and_si128(T3, MMASK);
- T1 = _mm_add_epi64(T1, C1);
- T4 = _mm_add_epi64(T4, C2);
- C1 = _mm_srli_epi64(T1, 26);
- C2 = _mm_srli_epi64(T4, 26);
- T1 = _mm_and_si128(T1, MMASK);
- T4 = _mm_and_si128(T4, MMASK);
- T2 = _mm_add_epi64(T2, C1);
- T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE));
- C1 = _mm_srli_epi64(T2, 26);
- C2 = _mm_srli_epi64(T0, 26);
- T2 = _mm_and_si128(T2, MMASK);
- T0 = _mm_and_si128(T0, MMASK);
- T3 = _mm_add_epi64(T3, C1);
- T1 = _mm_add_epi64(T1, C2);
- C1 = _mm_srli_epi64(T3, 26);
- T3 = _mm_and_si128(T3, MMASK);
- T4 = _mm_add_epi64(T4, C1);
-
- /* H = H[0]+H[1] */
- H0 = _mm_add_epi64(T0, _mm_srli_si128(T0, 8));
- H1 = _mm_add_epi64(T1, _mm_srli_si128(T1, 8));
- H2 = _mm_add_epi64(T2, _mm_srli_si128(T2, 8));
- H3 = _mm_add_epi64(T3, _mm_srli_si128(T3, 8));
- H4 = _mm_add_epi64(T4, _mm_srli_si128(T4, 8));
-
- t0 = _mm_cvtsi128_si32(H0);
- c = (t0 >> 26);
- t0 &= 0x3ffffff;
- t1 = _mm_cvtsi128_si32(H1) + c;
- c = (t1 >> 26);
- t1 &= 0x3ffffff;
- t2 = _mm_cvtsi128_si32(H2) + c;
- c = (t2 >> 26);
- t2 &= 0x3ffffff;
- t3 = _mm_cvtsi128_si32(H3) + c;
- c = (t3 >> 26);
- t3 &= 0x3ffffff;
- t4 = _mm_cvtsi128_si32(H4) + c;
- c = (t4 >> 26);
- t4 &= 0x3ffffff;
- t0 = t0 + (c * 5);
- c = (t0 >> 26);
- t0 &= 0x3ffffff;
- t1 = t1 + c;
-
- st->HH[0] = ((t0) | (t1 << 26)) & 0xfffffffffffull;
- st->HH[1] = ((t1 >> 18) | (t2 << 8) | (t3 << 34)) & 0xfffffffffffull;
- st->HH[2] = ((t3 >> 10) | (t4 << 16)) & 0x3ffffffffffull;
-
- return consumed;
-}
-
-void
-Poly1305Update(poly1305_state *state, const unsigned char *m, size_t bytes)
-{
- poly1305_state_internal *st = poly1305_aligned_state(state);
- size_t want;
-
- /* need at least 32 initial bytes to start the accelerated branch */
- if (!st->started) {
- if ((st->leftover == 0) && (bytes > 32)) {
- poly1305_first_block(st, m);
- m += 32;
- bytes -= 32;
- } else {
- want = poly1305_min(32 - st->leftover, bytes);
- poly1305_block_copy(st->buffer + st->leftover, m, want);
- bytes -= want;
- m += want;
- st->leftover += want;
- if ((st->leftover < 32) || (bytes == 0))
- return;
- poly1305_first_block(st, st->buffer);
- st->leftover = 0;
- }
- st->started = 1;
- }
-
- /* handle leftover */
- if (st->leftover) {
- want = poly1305_min(64 - st->leftover, bytes);
- poly1305_block_copy(st->buffer + st->leftover, m, want);
- bytes -= want;
- m += want;
- st->leftover += want;
- if (st->leftover < 64)
- return;
- poly1305_blocks(st, st->buffer, 64);
- st->leftover = 0;
- }
-
- /* process 64 byte blocks */
- if (bytes >= 64) {
- want = (bytes & ~63);
- poly1305_blocks(st, m, want);
- m += want;
- bytes -= want;
- }
-
- if (bytes) {
- poly1305_block_copy(st->buffer + st->leftover, m, bytes);
- st->leftover += bytes;
- }
-}
-
-void
-Poly1305Finish(poly1305_state *state, unsigned char mac[16])
-{
- poly1305_state_internal *st = poly1305_aligned_state(state);
- size_t leftover = st->leftover;
- uint8_t *m = st->buffer;
- uint128_t d[3];
- uint64_t h0, h1, h2;
- uint64_t t0, t1;
- uint64_t g0, g1, g2, c, nc;
- uint64_t r0, r1, r2, s1, s2;
- poly1305_power *p;
-
- if (st->started) {
- size_t consumed = poly1305_combine(st, m, leftover);
- leftover -= consumed;
- m += consumed;
- }
-
- /* st->HH will either be 0 or have the combined result */
- h0 = st->HH[0];
- h1 = st->HH[1];
- h2 = st->HH[2];
-
- p = &st->P[1];
- r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1];
- r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1];
- r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1];
- s1 = r1 * (5 << 2);
- s2 = r2 * (5 << 2);
-
- if (leftover < 16)
- goto poly1305_donna_atmost15bytes;
-
-poly1305_donna_atleast16bytes:
- t0 = U8TO64_LE(m + 0);
- t1 = U8TO64_LE(m + 8);
- h0 += t0 & 0xfffffffffff;
- t0 = shr128_pair(t1, t0, 44);
- h1 += t0 & 0xfffffffffff;
- h2 += (t1 >> 24) | ((uint64_t)1 << 40);
-
-poly1305_donna_mul:
- d[0] = add128(add128(mul64x64_128(h0, r0), mul64x64_128(h1, s2)), mul64x64_128(h2, s1));
- d[1] = add128(add128(mul64x64_128(h0, r1), mul64x64_128(h1, r0)), mul64x64_128(h2, s2));
- d[2] = add128(add128(mul64x64_128(h0, r2), mul64x64_128(h1, r1)), mul64x64_128(h2, r0));
- h0 = lo128(d[0]) & 0xfffffffffff;
- c = shr128(d[0], 44);
- d[1] = add128_64(d[1], c);
- h1 = lo128(d[1]) & 0xfffffffffff;
- c = shr128(d[1], 44);
- d[2] = add128_64(d[2], c);
- h2 = lo128(d[2]) & 0x3ffffffffff;
- c = shr128(d[2], 42);
- h0 += c * 5;
-
- m += 16;
- leftover -= 16;
- if (leftover >= 16)
- goto poly1305_donna_atleast16bytes;
-
-/* final bytes */
-poly1305_donna_atmost15bytes:
- if (!leftover)
- goto poly1305_donna_finish;
-
- m[leftover++] = 1;
- poly1305_block_zero(m + leftover, 16 - leftover);
- leftover = 16;
-
- t0 = U8TO64_LE(m + 0);
- t1 = U8TO64_LE(m + 8);
- h0 += t0 & 0xfffffffffff;
- t0 = shr128_pair(t1, t0, 44);
- h1 += t0 & 0xfffffffffff;
- h2 += (t1 >> 24);
-
- goto poly1305_donna_mul;
-
-poly1305_donna_finish:
- c = (h0 >> 44);
- h0 &= 0xfffffffffff;
- h1 += c;
- c = (h1 >> 44);
- h1 &= 0xfffffffffff;
- h2 += c;
- c = (h2 >> 42);
- h2 &= 0x3ffffffffff;
- h0 += c * 5;
-
- g0 = h0 + 5;
- c = (g0 >> 44);
- g0 &= 0xfffffffffff;
- g1 = h1 + c;
- c = (g1 >> 44);
- g1 &= 0xfffffffffff;
- g2 = h2 + c - ((uint64_t)1 << 42);
-
- c = (g2 >> 63) - 1;
- nc = ~c;
- h0 = (h0 & nc) | (g0 & c);
- h1 = (h1 & nc) | (g1 & c);
- h2 = (h2 & nc) | (g2 & c);
-
- /* pad */
- t0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1];
- t1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1];
- h0 += (t0 & 0xfffffffffff);
- c = (h0 >> 44);
- h0 &= 0xfffffffffff;
- t0 = shr128_pair(t1, t0, 44);
- h1 += (t0 & 0xfffffffffff) + c;
- c = (h1 >> 44);
- h1 &= 0xfffffffffff;
- t1 = (t1 >> 24);
- h2 += (t1) + c;
-
- U64TO8_LE(mac + 0, ((h0) | (h1 << 44)));
- U64TO8_LE(mac + 8, ((h1 >> 20) | (h2 << 24)));
-}
diff --git a/security/nss/lib/freebl/poly1305.c b/security/nss/lib/freebl/poly1305.c
deleted file mode 100644
index eb3e3cd55c..0000000000
--- a/security/nss/lib/freebl/poly1305.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* This implementation of poly1305 is by Andrew Moon
- * (https://github.com/floodyberry/poly1305-donna) and released as public
- * domain. */
-
-#include <string.h>
-
-#include "poly1305.h"
-
-#if defined(_MSC_VER) && _MSC_VER < 1600
-#include "prtypes.h"
-typedef PRUint32 uint32_t;
-typedef PRUint64 uint64_t;
-#else
-#include <stdint.h>
-#endif
-
-#if defined(NSS_X86) || defined(NSS_X64)
-/* We can assume little-endian. */
-static uint32_t
-U8TO32_LE(const unsigned char *m)
-{
- uint32_t r;
- memcpy(&r, m, sizeof(r));
- return r;
-}
-
-static void
-U32TO8_LE(unsigned char *m, uint32_t v)
-{
- memcpy(m, &v, sizeof(v));
-}
-#else
-static uint32_t
-U8TO32_LE(const unsigned char *m)
-{
- return (uint32_t)m[0] |
- (uint32_t)m[1] << 8 |
- (uint32_t)m[2] << 16 |
- (uint32_t)m[3] << 24;
-}
-
-static void
-U32TO8_LE(unsigned char *m, uint32_t v)
-{
- m[0] = v;
- m[1] = v >> 8;
- m[2] = v >> 16;
- m[3] = v >> 24;
-}
-#endif
-
-static uint64_t
-mul32x32_64(uint32_t a, uint32_t b)
-{
- return (uint64_t)a * b;
-}
-
-struct poly1305_state_st {
- uint32_t r0, r1, r2, r3, r4;
- uint32_t s1, s2, s3, s4;
- uint32_t h0, h1, h2, h3, h4;
- unsigned char buf[16];
- unsigned int buf_used;
- unsigned char key[16];
-};
-
-/* update updates |state| given some amount of input data. This function may
- * only be called with a |len| that is not a multiple of 16 at the end of the
- * data. Otherwise the input must be buffered into 16 byte blocks. */
-static void
-update(struct poly1305_state_st *state, const unsigned char *in,
- size_t len)
-{
- uint32_t t0, t1, t2, t3;
- uint64_t t[5];
- uint32_t b;
- uint64_t c;
- size_t j;
- unsigned char mp[16];
-
- if (len < 16)
- goto poly1305_donna_atmost15bytes;
-
-poly1305_donna_16bytes:
- t0 = U8TO32_LE(in);
- t1 = U8TO32_LE(in + 4);
- t2 = U8TO32_LE(in + 8);
- t3 = U8TO32_LE(in + 12);
-
- in += 16;
- len -= 16;
-
- state->h0 += t0 & 0x3ffffff;
- state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
- state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
- state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
- state->h4 += (t3 >> 8) | (1 << 24);
-
-poly1305_donna_mul:
- t[0] = mul32x32_64(state->h0, state->r0) +
- mul32x32_64(state->h1, state->s4) +
- mul32x32_64(state->h2, state->s3) +
- mul32x32_64(state->h3, state->s2) +
- mul32x32_64(state->h4, state->s1);
- t[1] = mul32x32_64(state->h0, state->r1) +
- mul32x32_64(state->h1, state->r0) +
- mul32x32_64(state->h2, state->s4) +
- mul32x32_64(state->h3, state->s3) +
- mul32x32_64(state->h4, state->s2);
- t[2] = mul32x32_64(state->h0, state->r2) +
- mul32x32_64(state->h1, state->r1) +
- mul32x32_64(state->h2, state->r0) +
- mul32x32_64(state->h3, state->s4) +
- mul32x32_64(state->h4, state->s3);
- t[3] = mul32x32_64(state->h0, state->r3) +
- mul32x32_64(state->h1, state->r2) +
- mul32x32_64(state->h2, state->r1) +
- mul32x32_64(state->h3, state->r0) +
- mul32x32_64(state->h4, state->s4);
- t[4] = mul32x32_64(state->h0, state->r4) +
- mul32x32_64(state->h1, state->r3) +
- mul32x32_64(state->h2, state->r2) +
- mul32x32_64(state->h3, state->r1) +
- mul32x32_64(state->h4, state->r0);
-
- state->h0 = (uint32_t)t[0] & 0x3ffffff;
- c = (t[0] >> 26);
- t[1] += c;
- state->h1 = (uint32_t)t[1] & 0x3ffffff;
- b = (uint32_t)(t[1] >> 26);
- t[2] += b;
- state->h2 = (uint32_t)t[2] & 0x3ffffff;
- b = (uint32_t)(t[2] >> 26);
- t[3] += b;
- state->h3 = (uint32_t)t[3] & 0x3ffffff;
- b = (uint32_t)(t[3] >> 26);
- t[4] += b;
- state->h4 = (uint32_t)t[4] & 0x3ffffff;
- b = (uint32_t)(t[4] >> 26);
- state->h0 += b * 5;
-
- if (len >= 16)
- goto poly1305_donna_16bytes;
-
-/* final bytes */
-poly1305_donna_atmost15bytes:
- if (!len)
- return;
-
- for (j = 0; j < len; j++)
- mp[j] = in[j];
- mp[j++] = 1;
- for (; j < 16; j++)
- mp[j] = 0;
- len = 0;
-
- t0 = U8TO32_LE(mp + 0);
- t1 = U8TO32_LE(mp + 4);
- t2 = U8TO32_LE(mp + 8);
- t3 = U8TO32_LE(mp + 12);
-
- state->h0 += t0 & 0x3ffffff;
- state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
- state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
- state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
- state->h4 += (t3 >> 8);
-
- goto poly1305_donna_mul;
-}
-
-void
-Poly1305Init(poly1305_state *statep, const unsigned char key[32])
-{
- struct poly1305_state_st *state = (struct poly1305_state_st *)statep;
- uint32_t t0, t1, t2, t3;
-
- t0 = U8TO32_LE(key + 0);
- t1 = U8TO32_LE(key + 4);
- t2 = U8TO32_LE(key + 8);
- t3 = U8TO32_LE(key + 12);
-
- /* precompute multipliers */
- state->r0 = t0 & 0x3ffffff;
- t0 >>= 26;
- t0 |= t1 << 6;
- state->r1 = t0 & 0x3ffff03;
- t1 >>= 20;
- t1 |= t2 << 12;
- state->r2 = t1 & 0x3ffc0ff;
- t2 >>= 14;
- t2 |= t3 << 18;
- state->r3 = t2 & 0x3f03fff;
- t3 >>= 8;
- state->r4 = t3 & 0x00fffff;
-
- state->s1 = state->r1 * 5;
- state->s2 = state->r2 * 5;
- state->s3 = state->r3 * 5;
- state->s4 = state->r4 * 5;
-
- /* init state */
- state->h0 = 0;
- state->h1 = 0;
- state->h2 = 0;
- state->h3 = 0;
- state->h4 = 0;
-
- state->buf_used = 0;
- memcpy(state->key, key + 16, sizeof(state->key));
-}
-
-void
-Poly1305Update(poly1305_state *statep, const unsigned char *in,
- size_t in_len)
-{
- unsigned int i;
- struct poly1305_state_st *state = (struct poly1305_state_st *)statep;
-
- if (state->buf_used) {
- unsigned int todo = 16 - state->buf_used;
- if (todo > in_len)
- todo = in_len;
- for (i = 0; i < todo; i++)
- state->buf[state->buf_used + i] = in[i];
- state->buf_used += todo;
- in_len -= todo;
- in += todo;
-
- if (state->buf_used == 16) {
- update(state, state->buf, 16);
- state->buf_used = 0;
- }
- }
-
- if (in_len >= 16) {
- size_t todo = in_len & ~0xf;
- update(state, in, todo);
- in += todo;
- in_len &= 0xf;
- }
-
- if (in_len) {
- for (i = 0; i < in_len; i++)
- state->buf[i] = in[i];
- state->buf_used = in_len;
- }
-}
-
-void
-Poly1305Finish(poly1305_state *statep, unsigned char mac[16])
-{
- struct poly1305_state_st *state = (struct poly1305_state_st *)statep;
- uint64_t f0, f1, f2, f3;
- uint32_t g0, g1, g2, g3, g4;
- uint32_t b, nb;
-
- if (state->buf_used)
- update(state, state->buf, state->buf_used);
-
- b = state->h0 >> 26;
- state->h0 = state->h0 & 0x3ffffff;
- state->h1 += b;
- b = state->h1 >> 26;
- state->h1 = state->h1 & 0x3ffffff;
- state->h2 += b;
- b = state->h2 >> 26;
- state->h2 = state->h2 & 0x3ffffff;
- state->h3 += b;
- b = state->h3 >> 26;
- state->h3 = state->h3 & 0x3ffffff;
- state->h4 += b;
- b = state->h4 >> 26;
- state->h4 = state->h4 & 0x3ffffff;
- state->h0 += b * 5;
-
- g0 = state->h0 + 5;
- b = g0 >> 26;
- g0 &= 0x3ffffff;
- g1 = state->h1 + b;
- b = g1 >> 26;
- g1 &= 0x3ffffff;
- g2 = state->h2 + b;
- b = g2 >> 26;
- g2 &= 0x3ffffff;
- g3 = state->h3 + b;
- b = g3 >> 26;
- g3 &= 0x3ffffff;
- g4 = state->h4 + b - (1 << 26);
-
- b = (g4 >> 31) - 1;
- nb = ~b;
- state->h0 = (state->h0 & nb) | (g0 & b);
- state->h1 = (state->h1 & nb) | (g1 & b);
- state->h2 = (state->h2 & nb) | (g2 & b);
- state->h3 = (state->h3 & nb) | (g3 & b);
- state->h4 = (state->h4 & nb) | (g4 & b);
-
- f0 = ((state->h0) | (state->h1 << 26)) + (uint64_t)U8TO32_LE(&state->key[0]);
- f1 = ((state->h1 >> 6) | (state->h2 << 20)) + (uint64_t)U8TO32_LE(&state->key[4]);
- f2 = ((state->h2 >> 12) | (state->h3 << 14)) + (uint64_t)U8TO32_LE(&state->key[8]);
- f3 = ((state->h3 >> 18) | (state->h4 << 8)) + (uint64_t)U8TO32_LE(&state->key[12]);
-
- U32TO8_LE(&mac[0], (uint32_t)f0);
- f1 += (f0 >> 32);
- U32TO8_LE(&mac[4], (uint32_t)f1);
- f2 += (f1 >> 32);
- U32TO8_LE(&mac[8], (uint32_t)f2);
- f3 += (f2 >> 32);
- U32TO8_LE(&mac[12], (uint32_t)f3);
-}
diff --git a/security/nss/lib/freebl/poly1305.h b/security/nss/lib/freebl/poly1305.h
deleted file mode 100644
index 125f49b3ba..0000000000
--- a/security/nss/lib/freebl/poly1305.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * poly1305.h - header file for Poly1305 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/. */
-
-#ifndef FREEBL_POLY1305_H_
-#define FREEBL_POLY1305_H_
-
-#include "stddef.h"
-
-typedef unsigned char poly1305_state[512];
-
-/* Poly1305Init sets up |state| so that it can be used to calculate an
- * authentication tag with the one-time key |key|. Note that |key| is a
- * one-time key and therefore there is no `reset' method because that would
- * enable several messages to be authenticated with the same key. */
-extern void Poly1305Init(poly1305_state* state, const unsigned char key[32]);
-
-/* Poly1305Update processes |in_len| bytes from |in|. It can be called zero or
- * more times after poly1305_init. */
-extern void Poly1305Update(poly1305_state* state, const unsigned char* in,
- size_t inLen);
-
-/* Poly1305Finish completes the poly1305 calculation and writes a 16 byte
- * authentication tag to |mac|. */
-extern void Poly1305Finish(poly1305_state* state, unsigned char mac[16]);
-
-#endif /* FREEBL_POLY1305_H_ */
diff --git a/security/nss/lib/freebl/unix_urandom.c b/security/nss/lib/freebl/unix_urandom.c
index 25e6ad91cf..869a5ed8cc 100644
--- a/security/nss/lib/freebl/unix_urandom.c
+++ b/security/nss/lib/freebl/unix_urandom.c
@@ -4,10 +4,14 @@
#include <fcntl.h>
#include <unistd.h>
+#include <errno.h>
#include "secerr.h"
#include "secrng.h"
#include "prprf.h"
+/* syscall getentropy() is limited to retrieving 256 bytes */
+#define GETENTROPY_MAX_BYTES 256
+
void
RNG_SystemInfoForRNG(void)
{
@@ -28,6 +32,35 @@ RNG_SystemRNG(void *dest, size_t maxLen)
size_t fileBytes = 0;
unsigned char *buffer = dest;
+#if defined(__OpenBSD__) || (defined(LINUX) && defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 25))))
+ int result;
+
+ while (fileBytes < maxLen) {
+ size_t getBytes = maxLen - fileBytes;
+ if (getBytes > GETENTROPY_MAX_BYTES) {
+ getBytes = GETENTROPY_MAX_BYTES;
+ }
+ result = getentropy(buffer, getBytes);
+ if (result == 0) { /* success */
+ fileBytes += getBytes;
+ buffer += getBytes;
+ } else {
+ break;
+ }
+ }
+ if (fileBytes == maxLen) { /* success */
+ return maxLen;
+ }
+ /* If we failed with an error other than ENOSYS, it means the destination
+ * buffer is not writeable. We don't need to try writing to it again. */
+ if (errno != ENOSYS) {
+ PORT_SetError(SEC_ERROR_NEED_RANDOM);
+ return 0;
+ }
+ /* ENOSYS means the kernel doesn't support getentropy()/getrandom().
+ * Reset the number of bytes to get and fall back to /dev/urandom. */
+ fileBytes = 0;
+#endif
fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
diff --git a/security/nss/lib/freebl/verified/Hacl_Poly1305_32.c b/security/nss/lib/freebl/verified/Hacl_Poly1305_32.c
new file mode 100644
index 0000000000..246a41af39
--- /dev/null
+++ b/security/nss/lib/freebl/verified/Hacl_Poly1305_32.c
@@ -0,0 +1,578 @@
+/* Copyright 2016-2017 INRIA and Microsoft Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Hacl_Poly1305_32.h"
+
+inline static void
+Hacl_Bignum_Modulo_reduce(uint32_t *b)
+{
+ uint32_t b0 = b[0U];
+ b[0U] = (b0 << (uint32_t)2U) + b0;
+}
+
+inline static void
+Hacl_Bignum_Modulo_carry_top(uint32_t *b)
+{
+ uint32_t b4 = b[4U];
+ uint32_t b0 = b[0U];
+ uint32_t b4_26 = b4 >> (uint32_t)26U;
+ b[4U] = b4 & (uint32_t)0x3ffffffU;
+ b[0U] = (b4_26 << (uint32_t)2U) + b4_26 + b0;
+}
+
+inline static void
+Hacl_Bignum_Modulo_carry_top_wide(uint64_t *b)
+{
+ uint64_t b4 = b[4U];
+ uint64_t b0 = b[0U];
+ uint64_t b4_ = b4 & (uint64_t)(uint32_t)0x3ffffffU;
+ uint32_t b4_26 = (uint32_t)(b4 >> (uint32_t)26U);
+ uint64_t b0_ = b0 + (uint64_t)((b4_26 << (uint32_t)2U) + b4_26);
+ b[4U] = b4_;
+ b[0U] = b0_;
+}
+
+inline static void
+Hacl_Bignum_Fproduct_copy_from_wide_(uint32_t *output, uint64_t *input)
+{
+ for (uint32_t i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U) {
+ uint64_t xi = input[i];
+ output[i] = (uint32_t)xi;
+ }
+}
+
+inline static void
+Hacl_Bignum_Fproduct_sum_scalar_multiplication_(uint64_t *output, uint32_t *input, uint32_t s)
+{
+ for (uint32_t i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U) {
+ uint64_t xi = output[i];
+ uint32_t yi = input[i];
+ uint64_t x_wide = (uint64_t)yi;
+ uint64_t y_wide = (uint64_t)s;
+ output[i] = xi + x_wide * y_wide;
+ }
+}
+
+inline static void
+Hacl_Bignum_Fproduct_carry_wide_(uint64_t *tmp)
+{
+ for (uint32_t i = (uint32_t)0U; i < (uint32_t)4U; i = i + (uint32_t)1U) {
+ uint32_t ctr = i;
+ uint64_t tctr = tmp[ctr];
+ uint64_t tctrp1 = tmp[ctr + (uint32_t)1U];
+ uint32_t r0 = (uint32_t)tctr & (uint32_t)0x3ffffffU;
+ uint64_t c = tctr >> (uint32_t)26U;
+ tmp[ctr] = (uint64_t)r0;
+ tmp[ctr + (uint32_t)1U] = tctrp1 + c;
+ }
+}
+
+inline static void
+Hacl_Bignum_Fproduct_carry_limb_(uint32_t *tmp)
+{
+ for (uint32_t i = (uint32_t)0U; i < (uint32_t)4U; i = i + (uint32_t)1U) {
+ uint32_t ctr = i;
+ uint32_t tctr = tmp[ctr];
+ uint32_t tctrp1 = tmp[ctr + (uint32_t)1U];
+ uint32_t r0 = tctr & (uint32_t)0x3ffffffU;
+ uint32_t c = tctr >> (uint32_t)26U;
+ tmp[ctr] = r0;
+ tmp[ctr + (uint32_t)1U] = tctrp1 + c;
+ }
+}
+
+inline static void
+Hacl_Bignum_Fmul_shift_reduce(uint32_t *output)
+{
+ uint32_t tmp = output[4U];
+ for (uint32_t i = (uint32_t)0U; i < (uint32_t)4U; i = i + (uint32_t)1U) {
+ uint32_t ctr = (uint32_t)5U - i - (uint32_t)1U;
+ uint32_t z = output[ctr - (uint32_t)1U];
+ output[ctr] = z;
+ }
+ output[0U] = tmp;
+ Hacl_Bignum_Modulo_reduce(output);
+}
+
+static void
+Hacl_Bignum_Fmul_mul_shift_reduce_(uint64_t *output, uint32_t *input, uint32_t *input2)
+{
+ for (uint32_t i = (uint32_t)0U; i < (uint32_t)4U; i = i + (uint32_t)1U) {
+ uint32_t input2i = input2[i];
+ Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i);
+ Hacl_Bignum_Fmul_shift_reduce(input);
+ }
+ uint32_t i = (uint32_t)4U;
+ uint32_t input2i = input2[i];
+ Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i);
+}
+
+inline static void
+Hacl_Bignum_Fmul_fmul(uint32_t *output, uint32_t *input, uint32_t *input2)
+{
+ uint32_t tmp[5U] = { 0U };
+ memcpy(tmp, input, (uint32_t)5U * sizeof input[0U]);
+ uint64_t t[5U] = { 0U };
+ Hacl_Bignum_Fmul_mul_shift_reduce_(t, tmp, input2);
+ Hacl_Bignum_Fproduct_carry_wide_(t);
+ Hacl_Bignum_Modulo_carry_top_wide(t);
+ Hacl_Bignum_Fproduct_copy_from_wide_(output, t);
+ uint32_t i0 = output[0U];
+ uint32_t i1 = output[1U];
+ uint32_t i0_ = i0 & (uint32_t)0x3ffffffU;
+ uint32_t i1_ = i1 + (i0 >> (uint32_t)26U);
+ output[0U] = i0_;
+ output[1U] = i1_;
+}
+
+inline static void
+Hacl_Bignum_AddAndMultiply_add_and_multiply(uint32_t *acc, uint32_t *block, uint32_t *r)
+{
+ for (uint32_t i = (uint32_t)0U; i < (uint32_t)5U; i = i + (uint32_t)1U) {
+ uint32_t xi = acc[i];
+ uint32_t yi = block[i];
+ acc[i] = xi + yi;
+ }
+ Hacl_Bignum_Fmul_fmul(acc, acc, r);
+}
+
+inline static void
+Hacl_Impl_Poly1305_32_poly1305_update(
+ Hacl_Impl_Poly1305_32_State_poly1305_state st,
+ uint8_t *m)
+{
+ Hacl_Impl_Poly1305_32_State_poly1305_state scrut0 = st;
+ uint32_t *h = scrut0.h;
+ uint32_t *acc = h;
+ Hacl_Impl_Poly1305_32_State_poly1305_state scrut = st;
+ uint32_t *r = scrut.r;
+ uint32_t *r5 = r;
+ uint32_t tmp[5U] = { 0U };
+ uint8_t *s0 = m;
+ uint8_t *s1 = m + (uint32_t)3U;
+ uint8_t *s2 = m + (uint32_t)6U;
+ uint8_t *s3 = m + (uint32_t)9U;
+ uint8_t *s4 = m + (uint32_t)12U;
+ uint32_t i0 = load32_le(s0);
+ uint32_t i1 = load32_le(s1);
+ uint32_t i2 = load32_le(s2);
+ uint32_t i3 = load32_le(s3);
+ uint32_t i4 = load32_le(s4);
+ uint32_t r0 = i0 & (uint32_t)0x3ffffffU;
+ uint32_t r1 = i1 >> (uint32_t)2U & (uint32_t)0x3ffffffU;
+ uint32_t r2 = i2 >> (uint32_t)4U & (uint32_t)0x3ffffffU;
+ uint32_t r3 = i3 >> (uint32_t)6U & (uint32_t)0x3ffffffU;
+ uint32_t r4 = i4 >> (uint32_t)8U;
+ tmp[0U] = r0;
+ tmp[1U] = r1;
+ tmp[2U] = r2;
+ tmp[3U] = r3;
+ tmp[4U] = r4;
+ uint32_t b4 = tmp[4U];
+ uint32_t b4_ = (uint32_t)0x1000000U | b4;
+ tmp[4U] = b4_;
+ Hacl_Bignum_AddAndMultiply_add_and_multiply(acc, tmp, r5);
+}
+
+inline static void
+Hacl_Impl_Poly1305_32_poly1305_process_last_block_(
+ uint8_t *block,
+ Hacl_Impl_Poly1305_32_State_poly1305_state st,
+ uint8_t *m,
+ uint64_t rem_)
+{
+ uint32_t tmp[5U] = { 0U };
+ uint8_t *s0 = block;
+ uint8_t *s1 = block + (uint32_t)3U;
+ uint8_t *s2 = block + (uint32_t)6U;
+ uint8_t *s3 = block + (uint32_t)9U;
+ uint8_t *s4 = block + (uint32_t)12U;
+ uint32_t i0 = load32_le(s0);
+ uint32_t i1 = load32_le(s1);
+ uint32_t i2 = load32_le(s2);
+ uint32_t i3 = load32_le(s3);
+ uint32_t i4 = load32_le(s4);
+ uint32_t r0 = i0 & (uint32_t)0x3ffffffU;
+ uint32_t r1 = i1 >> (uint32_t)2U & (uint32_t)0x3ffffffU;
+ uint32_t r2 = i2 >> (uint32_t)4U & (uint32_t)0x3ffffffU;
+ uint32_t r3 = i3 >> (uint32_t)6U & (uint32_t)0x3ffffffU;
+ uint32_t r4 = i4 >> (uint32_t)8U;
+ tmp[0U] = r0;
+ tmp[1U] = r1;
+ tmp[2U] = r2;
+ tmp[3U] = r3;
+ tmp[4U] = r4;
+ Hacl_Impl_Poly1305_32_State_poly1305_state scrut0 = st;
+ uint32_t *h = scrut0.h;
+ Hacl_Impl_Poly1305_32_State_poly1305_state scrut = st;
+ uint32_t *r = scrut.r;
+ Hacl_Bignum_AddAndMultiply_add_and_multiply(h, tmp, r);
+}
+
+inline static void
+Hacl_Impl_Poly1305_32_poly1305_process_last_block(
+ Hacl_Impl_Poly1305_32_State_poly1305_state st,
+ uint8_t *m,
+ uint64_t rem_)
+{
+ uint8_t zero1 = (uint8_t)0U;
+ KRML_CHECK_SIZE(zero1, (uint32_t)16U);
+ uint8_t block[16U];
+ for (uint32_t _i = 0U; _i < (uint32_t)16U; ++_i)
+ block[_i] = zero1;
+ uint32_t i0 = (uint32_t)rem_;
+ uint32_t i = (uint32_t)rem_;
+ memcpy(block, m, i * sizeof m[0U]);
+ block[i0] = (uint8_t)1U;
+ Hacl_Impl_Poly1305_32_poly1305_process_last_block_(block, st, m, rem_);
+}
+
+static void
+Hacl_Impl_Poly1305_32_poly1305_last_pass(uint32_t *acc)
+{
+ Hacl_Bignum_Fproduct_carry_limb_(acc);
+ Hacl_Bignum_Modulo_carry_top(acc);
+ uint32_t t0 = acc[0U];
+ uint32_t t10 = acc[1U];
+ uint32_t t20 = acc[2U];
+ uint32_t t30 = acc[3U];
+ uint32_t t40 = acc[4U];
+ uint32_t t1_ = t10 + (t0 >> (uint32_t)26U);
+ uint32_t mask_261 = (uint32_t)0x3ffffffU;
+ uint32_t t0_ = t0 & mask_261;
+ uint32_t t2_ = t20 + (t1_ >> (uint32_t)26U);
+ uint32_t t1__ = t1_ & mask_261;
+ uint32_t t3_ = t30 + (t2_ >> (uint32_t)26U);
+ uint32_t t2__ = t2_ & mask_261;
+ uint32_t t4_ = t40 + (t3_ >> (uint32_t)26U);
+ uint32_t t3__ = t3_ & mask_261;
+ acc[0U] = t0_;
+ acc[1U] = t1__;
+ acc[2U] = t2__;
+ acc[3U] = t3__;
+ acc[4U] = t4_;
+ Hacl_Bignum_Modulo_carry_top(acc);
+ uint32_t t00 = acc[0U];
+ uint32_t t1 = acc[1U];
+ uint32_t t2 = acc[2U];
+ uint32_t t3 = acc[3U];
+ uint32_t t4 = acc[4U];
+ uint32_t t1_0 = t1 + (t00 >> (uint32_t)26U);
+ uint32_t t0_0 = t00 & (uint32_t)0x3ffffffU;
+ uint32_t t2_0 = t2 + (t1_0 >> (uint32_t)26U);
+ uint32_t t1__0 = t1_0 & (uint32_t)0x3ffffffU;
+ uint32_t t3_0 = t3 + (t2_0 >> (uint32_t)26U);
+ uint32_t t2__0 = t2_0 & (uint32_t)0x3ffffffU;
+ uint32_t t4_0 = t4 + (t3_0 >> (uint32_t)26U);
+ uint32_t t3__0 = t3_0 & (uint32_t)0x3ffffffU;
+ acc[0U] = t0_0;
+ acc[1U] = t1__0;
+ acc[2U] = t2__0;
+ acc[3U] = t3__0;
+ acc[4U] = t4_0;
+ Hacl_Bignum_Modulo_carry_top(acc);
+ uint32_t i0 = acc[0U];
+ uint32_t i1 = acc[1U];
+ uint32_t i0_ = i0 & (uint32_t)0x3ffffffU;
+ uint32_t i1_ = i1 + (i0 >> (uint32_t)26U);
+ acc[0U] = i0_;
+ acc[1U] = i1_;
+ uint32_t a0 = acc[0U];
+ uint32_t a1 = acc[1U];
+ uint32_t a2 = acc[2U];
+ uint32_t a3 = acc[3U];
+ uint32_t a4 = acc[4U];
+ uint32_t mask0 = FStar_UInt32_gte_mask(a0, (uint32_t)0x3fffffbU);
+ uint32_t mask1 = FStar_UInt32_eq_mask(a1, (uint32_t)0x3ffffffU);
+ uint32_t mask2 = FStar_UInt32_eq_mask(a2, (uint32_t)0x3ffffffU);
+ uint32_t mask3 = FStar_UInt32_eq_mask(a3, (uint32_t)0x3ffffffU);
+ uint32_t mask4 = FStar_UInt32_eq_mask(a4, (uint32_t)0x3ffffffU);
+ uint32_t mask = (((mask0 & mask1) & mask2) & mask3) & mask4;
+ uint32_t a0_ = a0 - ((uint32_t)0x3fffffbU & mask);
+ uint32_t a1_ = a1 - ((uint32_t)0x3ffffffU & mask);
+ uint32_t a2_ = a2 - ((uint32_t)0x3ffffffU & mask);
+ uint32_t a3_ = a3 - ((uint32_t)0x3ffffffU & mask);
+ uint32_t a4_ = a4 - ((uint32_t)0x3ffffffU & mask);
+ acc[0U] = a0_;
+ acc[1U] = a1_;
+ acc[2U] = a2_;
+ acc[3U] = a3_;
+ acc[4U] = a4_;
+}
+
+static Hacl_Impl_Poly1305_32_State_poly1305_state
+Hacl_Impl_Poly1305_32_mk_state(uint32_t *r, uint32_t *h)
+{
+ return ((Hacl_Impl_Poly1305_32_State_poly1305_state){.r = r, .h = h });
+}
+
+static void
+Hacl_Standalone_Poly1305_32_poly1305_blocks(
+ Hacl_Impl_Poly1305_32_State_poly1305_state st,
+ uint8_t *m,
+ uint64_t len1)
+{
+ if (!(len1 == (uint64_t)0U)) {
+ uint8_t *block = m;
+ uint8_t *tail1 = m + (uint32_t)16U;
+ Hacl_Impl_Poly1305_32_poly1305_update(st, block);
+ uint64_t len2 = len1 - (uint64_t)1U;
+ Hacl_Standalone_Poly1305_32_poly1305_blocks(st, tail1, len2);
+ }
+}
+
+static void
+Hacl_Standalone_Poly1305_32_poly1305_partial(
+ Hacl_Impl_Poly1305_32_State_poly1305_state st,
+ uint8_t *input,
+ uint64_t len1,
+ uint8_t *kr)
+{
+ Hacl_Impl_Poly1305_32_State_poly1305_state scrut = st;
+ uint32_t *r = scrut.r;
+ uint32_t *x0 = r;
+ FStar_UInt128_t k1 = load128_le(kr);
+ FStar_UInt128_t
+ k_clamped =
+ FStar_UInt128_logand(k1,
+ FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128((uint64_t)0x0ffffffc0ffffffcU),
+ (uint32_t)64U),
+ FStar_UInt128_uint64_to_uint128((uint64_t)0x0ffffffc0fffffffU)));
+ uint32_t r0 = (uint32_t)FStar_UInt128_uint128_to_uint64(k_clamped) & (uint32_t)0x3ffffffU;
+ uint32_t
+ r1 =
+ (uint32_t)FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)26U)) & (uint32_t)0x3ffffffU;
+ uint32_t
+ r2 =
+ (uint32_t)FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)52U)) & (uint32_t)0x3ffffffU;
+ uint32_t
+ r3 =
+ (uint32_t)FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)78U)) & (uint32_t)0x3ffffffU;
+ uint32_t
+ r4 =
+ (uint32_t)FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)104U)) & (uint32_t)0x3ffffffU;
+ x0[0U] = r0;
+ x0[1U] = r1;
+ x0[2U] = r2;
+ x0[3U] = r3;
+ x0[4U] = r4;
+ Hacl_Impl_Poly1305_32_State_poly1305_state scrut0 = st;
+ uint32_t *h = scrut0.h;
+ uint32_t *x00 = h;
+ x00[0U] = (uint32_t)0U;
+ x00[1U] = (uint32_t)0U;
+ x00[2U] = (uint32_t)0U;
+ x00[3U] = (uint32_t)0U;
+ x00[4U] = (uint32_t)0U;
+ Hacl_Standalone_Poly1305_32_poly1305_blocks(st, input, len1);
+}
+
+static void
+Hacl_Standalone_Poly1305_32_poly1305_complete(
+ Hacl_Impl_Poly1305_32_State_poly1305_state st,
+ uint8_t *m,
+ uint64_t len1,
+ uint8_t *k1)
+{
+ uint8_t *kr = k1;
+ uint64_t len16 = len1 >> (uint32_t)4U;
+ uint64_t rem16 = len1 & (uint64_t)0xfU;
+ uint8_t *part_input = m;
+ uint8_t *last_block = m + (uint32_t)((uint64_t)16U * len16);
+ Hacl_Standalone_Poly1305_32_poly1305_partial(st, part_input, len16, kr);
+ if (!(rem16 == (uint64_t)0U))
+ Hacl_Impl_Poly1305_32_poly1305_process_last_block(st, last_block, rem16);
+ Hacl_Impl_Poly1305_32_State_poly1305_state scrut = st;
+ uint32_t *h = scrut.h;
+ uint32_t *acc = h;
+ Hacl_Impl_Poly1305_32_poly1305_last_pass(acc);
+}
+
+static void
+Hacl_Standalone_Poly1305_32_crypto_onetimeauth_(
+ uint8_t *output,
+ uint8_t *input,
+ uint64_t len1,
+ uint8_t *k1)
+{
+ uint32_t buf[10U] = { 0U };
+ uint32_t *r = buf;
+ uint32_t *h = buf + (uint32_t)5U;
+ Hacl_Impl_Poly1305_32_State_poly1305_state st = Hacl_Impl_Poly1305_32_mk_state(r, h);
+ uint8_t *key_s = k1 + (uint32_t)16U;
+ Hacl_Standalone_Poly1305_32_poly1305_complete(st, input, len1, k1);
+ Hacl_Impl_Poly1305_32_State_poly1305_state scrut = st;
+ uint32_t *h5 = scrut.h;
+ uint32_t *acc = h5;
+ FStar_UInt128_t k_ = load128_le(key_s);
+ uint32_t h0 = acc[0U];
+ uint32_t h1 = acc[1U];
+ uint32_t h2 = acc[2U];
+ uint32_t h3 = acc[3U];
+ uint32_t h4 = acc[4U];
+ FStar_UInt128_t
+ acc_ =
+ FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128((uint64_t)h4),
+ (uint32_t)104U),
+ FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128((uint64_t)h3),
+ (uint32_t)78U),
+ FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128((uint64_t)h2),
+ (uint32_t)52U),
+ FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128((uint64_t)h1),
+ (uint32_t)26U),
+ FStar_UInt128_uint64_to_uint128((uint64_t)h0)))));
+ FStar_UInt128_t mac_ = FStar_UInt128_add_mod(acc_, k_);
+ store128_le(output, mac_);
+}
+
+static void
+Hacl_Standalone_Poly1305_32_crypto_onetimeauth(
+ uint8_t *output,
+ uint8_t *input,
+ uint64_t len1,
+ uint8_t *k1)
+{
+ Hacl_Standalone_Poly1305_32_crypto_onetimeauth_(output, input, len1, k1);
+}
+
+void *
+Hacl_Poly1305_32_op_String_Access(FStar_Monotonic_HyperStack_mem h, uint8_t *b)
+{
+ return (void *)(uint8_t)0U;
+}
+
+Hacl_Impl_Poly1305_32_State_poly1305_state
+Hacl_Poly1305_32_mk_state(uint32_t *r, uint32_t *acc)
+{
+ return Hacl_Impl_Poly1305_32_mk_state(r, acc);
+}
+
+void
+Hacl_Poly1305_32_init(Hacl_Impl_Poly1305_32_State_poly1305_state st, uint8_t *k1)
+{
+ Hacl_Impl_Poly1305_32_State_poly1305_state scrut = st;
+ uint32_t *r = scrut.r;
+ uint32_t *x0 = r;
+ FStar_UInt128_t k10 = load128_le(k1);
+ FStar_UInt128_t
+ k_clamped =
+ FStar_UInt128_logand(k10,
+ FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128((uint64_t)0x0ffffffc0ffffffcU),
+ (uint32_t)64U),
+ FStar_UInt128_uint64_to_uint128((uint64_t)0x0ffffffc0fffffffU)));
+ uint32_t r0 = (uint32_t)FStar_UInt128_uint128_to_uint64(k_clamped) & (uint32_t)0x3ffffffU;
+ uint32_t
+ r1 =
+ (uint32_t)FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)26U)) & (uint32_t)0x3ffffffU;
+ uint32_t
+ r2 =
+ (uint32_t)FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)52U)) & (uint32_t)0x3ffffffU;
+ uint32_t
+ r3 =
+ (uint32_t)FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)78U)) & (uint32_t)0x3ffffffU;
+ uint32_t
+ r4 =
+ (uint32_t)FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)104U)) & (uint32_t)0x3ffffffU;
+ x0[0U] = r0;
+ x0[1U] = r1;
+ x0[2U] = r2;
+ x0[3U] = r3;
+ x0[4U] = r4;
+ Hacl_Impl_Poly1305_32_State_poly1305_state scrut0 = st;
+ uint32_t *h = scrut0.h;
+ uint32_t *x00 = h;
+ x00[0U] = (uint32_t)0U;
+ x00[1U] = (uint32_t)0U;
+ x00[2U] = (uint32_t)0U;
+ x00[3U] = (uint32_t)0U;
+ x00[4U] = (uint32_t)0U;
+}
+
+void *Hacl_Poly1305_32_empty_log = (void *)(uint8_t)0U;
+
+void
+Hacl_Poly1305_32_update_block(Hacl_Impl_Poly1305_32_State_poly1305_state st, uint8_t *m)
+{
+ Hacl_Impl_Poly1305_32_poly1305_update(st, m);
+}
+
+void
+Hacl_Poly1305_32_update(
+ Hacl_Impl_Poly1305_32_State_poly1305_state st,
+ uint8_t *m,
+ uint32_t len1)
+{
+ if (!(len1 == (uint32_t)0U)) {
+ uint8_t *block = m;
+ uint8_t *m_ = m + (uint32_t)16U;
+ uint32_t len2 = len1 - (uint32_t)1U;
+ Hacl_Poly1305_32_update_block(st, block);
+ Hacl_Poly1305_32_update(st, m_, len2);
+ }
+}
+
+void
+Hacl_Poly1305_32_update_last(
+ Hacl_Impl_Poly1305_32_State_poly1305_state st,
+ uint8_t *m,
+ uint32_t len1)
+{
+ if (!((uint64_t)len1 == (uint64_t)0U))
+ Hacl_Impl_Poly1305_32_poly1305_process_last_block(st, m, (uint64_t)len1);
+ Hacl_Impl_Poly1305_32_State_poly1305_state scrut = st;
+ uint32_t *h = scrut.h;
+ uint32_t *acc = h;
+ Hacl_Impl_Poly1305_32_poly1305_last_pass(acc);
+}
+
+void
+Hacl_Poly1305_32_finish(
+ Hacl_Impl_Poly1305_32_State_poly1305_state st,
+ uint8_t *mac,
+ uint8_t *k1)
+{
+ Hacl_Impl_Poly1305_32_State_poly1305_state scrut = st;
+ uint32_t *h = scrut.h;
+ uint32_t *acc = h;
+ FStar_UInt128_t k_ = load128_le(k1);
+ uint32_t h0 = acc[0U];
+ uint32_t h1 = acc[1U];
+ uint32_t h2 = acc[2U];
+ uint32_t h3 = acc[3U];
+ uint32_t h4 = acc[4U];
+ FStar_UInt128_t
+ acc_ =
+ FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128((uint64_t)h4),
+ (uint32_t)104U),
+ FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128((uint64_t)h3),
+ (uint32_t)78U),
+ FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128((uint64_t)h2),
+ (uint32_t)52U),
+ FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128((uint64_t)h1),
+ (uint32_t)26U),
+ FStar_UInt128_uint64_to_uint128((uint64_t)h0)))));
+ FStar_UInt128_t mac_ = FStar_UInt128_add_mod(acc_, k_);
+ store128_le(mac, mac_);
+}
+
+void
+Hacl_Poly1305_32_crypto_onetimeauth(
+ uint8_t *output,
+ uint8_t *input,
+ uint64_t len1,
+ uint8_t *k1)
+{
+ Hacl_Standalone_Poly1305_32_crypto_onetimeauth(output, input, len1, k1);
+}
diff --git a/security/nss/lib/freebl/verified/Hacl_Poly1305_32.h b/security/nss/lib/freebl/verified/Hacl_Poly1305_32.h
new file mode 100644
index 0000000000..4dd0700267
--- /dev/null
+++ b/security/nss/lib/freebl/verified/Hacl_Poly1305_32.h
@@ -0,0 +1,103 @@
+/* Copyright 2016-2017 INRIA and Microsoft Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "kremlib.h"
+#ifndef __Hacl_Poly1305_32_H
+#define __Hacl_Poly1305_32_H
+
+typedef uint32_t Hacl_Bignum_Constants_limb;
+
+typedef uint64_t Hacl_Bignum_Constants_wide;
+
+typedef uint64_t Hacl_Bignum_Wide_t;
+
+typedef uint32_t Hacl_Bignum_Limb_t;
+
+typedef void *Hacl_Impl_Poly1305_32_State_log_t;
+
+typedef uint8_t *Hacl_Impl_Poly1305_32_State_uint8_p;
+
+typedef uint32_t *Hacl_Impl_Poly1305_32_State_bigint;
+
+typedef void *Hacl_Impl_Poly1305_32_State_seqelem;
+
+typedef uint32_t *Hacl_Impl_Poly1305_32_State_elemB;
+
+typedef uint8_t *Hacl_Impl_Poly1305_32_State_wordB;
+
+typedef uint8_t *Hacl_Impl_Poly1305_32_State_wordB_16;
+
+typedef struct
+{
+ uint32_t *r;
+ uint32_t *h;
+} Hacl_Impl_Poly1305_32_State_poly1305_state;
+
+typedef void *Hacl_Impl_Poly1305_32_log_t;
+
+typedef uint32_t *Hacl_Impl_Poly1305_32_bigint;
+
+typedef uint8_t *Hacl_Impl_Poly1305_32_uint8_p;
+
+typedef uint32_t *Hacl_Impl_Poly1305_32_elemB;
+
+typedef uint8_t *Hacl_Impl_Poly1305_32_wordB;
+
+typedef uint8_t *Hacl_Impl_Poly1305_32_wordB_16;
+
+typedef uint8_t *Hacl_Poly1305_32_uint8_p;
+
+typedef uint64_t Hacl_Poly1305_32_uint64_t;
+
+void *Hacl_Poly1305_32_op_String_Access(FStar_Monotonic_HyperStack_mem h, uint8_t *b);
+
+typedef uint8_t *Hacl_Poly1305_32_key;
+
+typedef Hacl_Impl_Poly1305_32_State_poly1305_state Hacl_Poly1305_32_state;
+
+Hacl_Impl_Poly1305_32_State_poly1305_state
+Hacl_Poly1305_32_mk_state(uint32_t *r, uint32_t *acc);
+
+void Hacl_Poly1305_32_init(Hacl_Impl_Poly1305_32_State_poly1305_state st, uint8_t *k1);
+
+extern void *Hacl_Poly1305_32_empty_log;
+
+void Hacl_Poly1305_32_update_block(Hacl_Impl_Poly1305_32_State_poly1305_state st, uint8_t *m);
+
+void
+Hacl_Poly1305_32_update(
+ Hacl_Impl_Poly1305_32_State_poly1305_state st,
+ uint8_t *m,
+ uint32_t len1);
+
+void
+Hacl_Poly1305_32_update_last(
+ Hacl_Impl_Poly1305_32_State_poly1305_state st,
+ uint8_t *m,
+ uint32_t len1);
+
+void
+Hacl_Poly1305_32_finish(
+ Hacl_Impl_Poly1305_32_State_poly1305_state st,
+ uint8_t *mac,
+ uint8_t *k1);
+
+void
+Hacl_Poly1305_32_crypto_onetimeauth(
+ uint8_t *output,
+ uint8_t *input,
+ uint64_t len1,
+ uint8_t *k1);
+#endif
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c
index 9954f0ca68..f73b95f686 100644
--- a/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c
@@ -70,7 +70,7 @@ static const PKIX_UInt32 httpprotocolLen = 5; /* strlen(httpprotocol) */
* The address at which the Boolean state machine flag is stored to
* indicate whether processing can continue without further input.
* Must be non-NULL.
- * "plContext"
+ * "plCtx"
* Platform-specific context pointer.
* THREAD SAFETY:
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
@@ -85,7 +85,7 @@ pkix_pl_HttpDefaultClient_HdrCheckComplete(
PKIX_PL_HttpDefaultClient *client,
PKIX_UInt32 bytesRead,
PKIX_Boolean *pKeepGoing,
- void *plContext)
+ void *plCtx)
{
PKIX_UInt32 alreadyScanned = 0;
PKIX_UInt32 comp = 0;
@@ -142,7 +142,7 @@ pkix_pl_HttpDefaultClient_HdrCheckComplete(
headerLength = (eoh - client->rcvBuf);
/* allocate space to copy header (and for the NULL terminator) */
- PKIX_CHECK(PKIX_PL_Malloc(headerLength + 1, (void **)&copy, plContext),
+ PKIX_CHECK(PKIX_PL_Malloc(headerLength + 1, (void **)&copy, plCtx),
PKIX_MALLOCFAILED);
/* copy header data before we corrupt it (by storing NULLs) */
@@ -301,7 +301,7 @@ pkix_pl_HttpDefaultClient_HdrCheckComplete(
if (contentLength > 0) {
/* allocate a buffer of size contentLength for the content */
- PKIX_CHECK(PKIX_PL_Malloc(contentLength, (void **)&body, plContext),
+ PKIX_CHECK(PKIX_PL_Malloc(contentLength, (void **)&body, plCtx),
PKIX_MALLOCFAILED);
/* copy any remaining bytes in current buffer into new buffer */
@@ -311,7 +311,7 @@ pkix_pl_HttpDefaultClient_HdrCheckComplete(
}
}
- PKIX_CHECK(PKIX_PL_Free(client->rcvBuf, plContext),
+ PKIX_CHECK(PKIX_PL_Free(client->rcvBuf, plCtx),
PKIX_FREEFAILED);
client->rcvBuf = body;
@@ -340,7 +340,7 @@ cleanup:
* "pClient"
* The address at which the created HttpDefaultClient is to be stored.
* Must be non-NULL.
- * "plContext"
+ * "plCtx"
* Platform-specific context pointer.
* THREAD SAFETY:
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
@@ -355,7 +355,7 @@ pkix_pl_HttpDefaultClient_Create(
const char *host,
PRUint16 portnum,
PKIX_PL_HttpDefaultClient **pClient,
- void *plContext)
+ void *plCtx)
{
PKIX_PL_HttpDefaultClient *client = NULL;
@@ -367,7 +367,7 @@ pkix_pl_HttpDefaultClient_Create(
(PKIX_HTTPDEFAULTCLIENT_TYPE,
sizeof (PKIX_PL_HttpDefaultClient),
(PKIX_PL_Object **)&client,
- plContext),
+ plCtx),
PKIX_COULDNOTCREATEHTTPDEFAULTCLIENTOBJECT);
/* Client timeout is overwritten in HttpDefaultClient_RequestCreate
@@ -408,10 +408,10 @@ pkix_pl_HttpDefaultClient_Create(
client->socket = NULL;
/*
- * The HttpClient API does not include a plContext argument in its
+ * The HttpClient API does not include a plCtx argument in its
* function calls. Save it here.
*/
- client->plContext = plContext;
+ client->plContext = plCtx;
*pClient = client;
@@ -430,7 +430,7 @@ cleanup:
static PKIX_Error *
pkix_pl_HttpDefaultClient_Destroy(
PKIX_PL_Object *object,
- void *plContext)
+ void *plCtx)
{
PKIX_PL_HttpDefaultClient *client = NULL;
@@ -438,13 +438,13 @@ pkix_pl_HttpDefaultClient_Destroy(
PKIX_NULLCHECK_ONE(object);
PKIX_CHECK(pkix_CheckType
- (object, PKIX_HTTPDEFAULTCLIENT_TYPE, plContext),
+ (object, PKIX_HTTPDEFAULTCLIENT_TYPE, plCtx),
PKIX_OBJECTNOTANHTTPDEFAULTCLIENT);
client = (PKIX_PL_HttpDefaultClient *)object;
if (client->rcvHeaders) {
- PKIX_PL_Free(client->rcvHeaders, plContext);
+ PKIX_PL_Free(client->rcvHeaders, plCtx);
client->rcvHeaders = NULL;
}
if (client->rcvContentType) {
@@ -456,11 +456,11 @@ pkix_pl_HttpDefaultClient_Destroy(
client->GETBuf = NULL;
}
if (client->POSTBuf != NULL) {
- PKIX_PL_Free(client->POSTBuf, plContext);
+ PKIX_PL_Free(client->POSTBuf, plCtx);
client->POSTBuf = NULL;
}
if (client->rcvBuf != NULL) {
- PKIX_PL_Free(client->rcvBuf, plContext);
+ PKIX_PL_Free(client->rcvBuf, plCtx);
client->rcvBuf = NULL;
}
if (client->host) {
@@ -493,7 +493,7 @@ cleanup:
* thread-safe.
*/
PKIX_Error *
-pkix_pl_HttpDefaultClient_RegisterSelf(void *plContext)
+pkix_pl_HttpDefaultClient_RegisterSelf(void *plCtx)
{
extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
pkix_ClassTable_Entry *entry =
@@ -529,7 +529,7 @@ pkix_pl_HttpDefaultClient_RegisterSelf(void *plContext)
* The address at which the Boolean state machine flag is stored to
* indicate whether processing can continue without further input.
* Must be non-NULL.
- * "plContext"
+ * "plCtx"
* Platform-specific context pointer.
* THREAD SAFETY:
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
@@ -543,7 +543,7 @@ static PKIX_Error *
pkix_pl_HttpDefaultClient_ConnectContinue(
PKIX_PL_HttpDefaultClient *client,
PKIX_Boolean *pKeepGoing,
- void *plContext)
+ void *plCtx)
{
PRErrorCode status;
PKIX_Boolean keepGoing = PKIX_FALSE;
@@ -557,7 +557,7 @@ pkix_pl_HttpDefaultClient_ConnectContinue(
callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;
PKIX_CHECK(callbackList->connectcontinueCallback
- (client->socket, &status, plContext),
+ (client->socket, &status, plCtx),
PKIX_SOCKETCONNECTCONTINUEFAILED);
if (status == 0) {
@@ -595,7 +595,7 @@ cleanup:
* "pBytesTransferred"
* The address at which the number of bytes sent is stored. Must be
* non-NULL.
- * "plContext"
+ * "plCtx"
* Platform-specific context pointer.
* THREAD SAFETY:
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
@@ -610,7 +610,7 @@ pkix_pl_HttpDefaultClient_Send(
PKIX_PL_HttpDefaultClient *client,
PKIX_Boolean *pKeepGoing,
PKIX_UInt32 *pBytesTransferred,
- void *plContext)
+ void *plCtx)
{
PKIX_Int32 bytesWritten = 0;
PKIX_Int32 lenToWrite = 0;
@@ -640,7 +640,7 @@ pkix_pl_HttpDefaultClient_Send(
dataToWrite,
lenToWrite,
&bytesWritten,
- plContext),
+ plCtx),
PKIX_SOCKETSENDFAILED);
client->rcvBuf = NULL;
@@ -690,7 +690,7 @@ cleanup:
* "pBytesTransferred"
* The address at which the number of bytes sent is stored. Must be
* non-NULL.
- * "plContext"
+ * "plCtx"
* Platform-specific context pointer.
* THREAD SAFETY:
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
@@ -705,7 +705,7 @@ pkix_pl_HttpDefaultClient_SendContinue(
PKIX_PL_HttpDefaultClient *client,
PKIX_Boolean *pKeepGoing,
PKIX_UInt32 *pBytesTransferred,
- void *plContext)
+ void *plCtx)
{
PKIX_Int32 bytesWritten = 0;
PKIX_PL_Socket_Callback *callbackList = NULL;
@@ -718,7 +718,7 @@ pkix_pl_HttpDefaultClient_SendContinue(
callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;
PKIX_CHECK(callbackList->pollCallback
- (client->socket, &bytesWritten, NULL, plContext),
+ (client->socket, &bytesWritten, NULL, plCtx),
PKIX_SOCKETPOLLFAILED);
/*
@@ -752,7 +752,7 @@ cleanup:
* The address at which the Boolean state machine flag is stored to
* indicate whether processing can continue without further input.
* Must be non-NULL.
- * "plContext"
+ * "plCtx"
* Platform-specific context pointer.
* THREAD SAFETY:
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
@@ -766,7 +766,7 @@ static PKIX_Error *
pkix_pl_HttpDefaultClient_RecvHdr(
PKIX_PL_HttpDefaultClient *client,
PKIX_Boolean *pKeepGoing,
- void *plContext)
+ void *plCtx)
{
PKIX_UInt32 bytesToRead = 0;
PKIX_Int32 bytesRead = 0;
@@ -787,7 +787,7 @@ pkix_pl_HttpDefaultClient_RecvHdr(
(client->rcvBuf,
client->capacity,
(void **)&(client->rcvBuf),
- plContext),
+ plCtx),
PKIX_REALLOCFAILED);
bytesToRead = client->capacity - client->filledupBytes;
@@ -799,7 +799,7 @@ pkix_pl_HttpDefaultClient_RecvHdr(
(void *)&(client->rcvBuf[client->filledupBytes]),
bytesToRead,
&bytesRead,
- plContext),
+ plCtx),
PKIX_SOCKETRECVFAILED);
if (bytesRead > 0) {
@@ -808,7 +808,7 @@ pkix_pl_HttpDefaultClient_RecvHdr(
PKIX_CHECK(
pkix_pl_HttpDefaultClient_HdrCheckComplete(client, bytesRead,
pKeepGoing,
- plContext),
+ plCtx),
PKIX_HTTPDEFAULTCLIENTHDRCHECKCOMPLETEFAILED);
} else {
client->connectStatus = HTTP_RECV_HDR_PENDING;
@@ -834,7 +834,7 @@ cleanup:
* The address at which the Boolean state machine flag is stored to
* indicate whether processing can continue without further input.
* Must be non-NULL.
- * "plContext"
+ * "plCtx"
* Platform-specific context pointer.
* THREAD SAFETY:
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
@@ -848,7 +848,7 @@ static PKIX_Error *
pkix_pl_HttpDefaultClient_RecvHdrContinue(
PKIX_PL_HttpDefaultClient *client,
PKIX_Boolean *pKeepGoing,
- void *plContext)
+ void *plCtx)
{
PKIX_Int32 bytesRead = 0;
PKIX_PL_Socket_Callback *callbackList = NULL;
@@ -861,14 +861,14 @@ pkix_pl_HttpDefaultClient_RecvHdrContinue(
callbackList = (PKIX_PL_Socket_Callback *)client->callbackList;
PKIX_CHECK(callbackList->pollCallback
- (client->socket, NULL, &bytesRead, plContext),
+ (client->socket, NULL, &bytesRead, plCtx),
PKIX_SOCKETPOLLFAILED);
if (bytesRead > 0) {
client->filledupBytes += bytesRead;
PKIX_CHECK(pkix_pl_HttpDefaultClient_HdrCheckComplete
- (client, bytesRead, pKeepGoing, plContext),
+ (client, bytesRead, pKeepGoing, plCtx),
PKIX_HTTPDEFAULTCLIENTHDRCHECKCOMPLETEFAILED);
} else {
@@ -897,7 +897,7 @@ cleanup:
* The address at which the Boolean state machine flag is stored to
* indicate whether processing can continue without further input.
* Must be non-NULL.
- * "plContext"
+ * "plCtx"
* Platform-specific context pointer.
* THREAD SAFETY:
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
@@ -911,7 +911,7 @@ static PKIX_Error *
pkix_pl_HttpDefaultClient_RecvBody(
PKIX_PL_HttpDefaultClient *client,
PKIX_Boolean *pKeepGoing,
- void *plContext)
+ void *plCtx)
{
PKIX_Int32 bytesRead = 0;
PKIX_Int32 bytesToRead = 0;
@@ -952,7 +952,7 @@ pkix_pl_HttpDefaultClient_RecvBody(
client->capacity = newLength;
PKIX_CHECK(
PKIX_PL_Realloc(client->rcvBuf, newLength,
- (void**)&client->rcvBuf, plContext),
+ (void**)&client->rcvBuf, plCtx),
PKIX_REALLOCFAILED);
freeBuffSize = client->capacity -
client->filledupBytes;
@@ -964,7 +964,7 @@ pkix_pl_HttpDefaultClient_RecvBody(
/* Use poll callback if waiting on non-blocking IO */
if (client->connectStatus == HTTP_RECV_BODY_PENDING) {
PKIX_CHECK(callbackList->pollCallback
- (client->socket, NULL, &bytesRead, plContext),
+ (client->socket, NULL, &bytesRead, plCtx),
PKIX_SOCKETPOLLFAILED);
} else {
PKIX_CHECK(callbackList->recvCallback
@@ -972,7 +972,7 @@ pkix_pl_HttpDefaultClient_RecvBody(
(void *)&(client->rcvBuf[client->filledupBytes]),
bytesToRead,
&bytesRead,
- plContext),
+ plCtx),
PKIX_SOCKETRECVFAILED);
}
@@ -1026,7 +1026,7 @@ cleanup:
* PARAMETERS:
* "client"
* The address of the HttpDefaultClient object. Must be non-NULL.
- * "plContext"
+ * "plCtx"
* Platform-specific context pointer.
* THREAD SAFETY:
* Thread Safe (see Thread Safety Definitions in Programmer's Guide)
@@ -1039,7 +1039,7 @@ cleanup:
static PKIX_Error *
pkix_pl_HttpDefaultClient_Dispatch(
PKIX_PL_HttpDefaultClient *client,
- void *plContext)
+ void *plCtx)
{
PKIX_UInt32 bytesTransferred = 0;
PKIX_Boolean keepGoing = PKIX_TRUE;
@@ -1051,33 +1051,33 @@ pkix_pl_HttpDefaultClient_Dispatch(
switch (client->connectStatus) {
case HTTP_CONNECT_PENDING:
PKIX_CHECK(pkix_pl_HttpDefaultClient_ConnectContinue
- (client, &keepGoing, plContext),
+ (client, &keepGoing, plCtx),
PKIX_HTTPDEFAULTCLIENTCONNECTCONTINUEFAILED);
break;
case HTTP_CONNECTED:
PKIX_CHECK(pkix_pl_HttpDefaultClient_Send
- (client, &keepGoing, &bytesTransferred, plContext),
+ (client, &keepGoing, &bytesTransferred, plCtx),
PKIX_HTTPDEFAULTCLIENTSENDFAILED);
break;
case HTTP_SEND_PENDING:
PKIX_CHECK(pkix_pl_HttpDefaultClient_SendContinue
- (client, &keepGoing, &bytesTransferred, plContext),
+ (client, &keepGoing, &bytesTransferred, plCtx),
PKIX_HTTPDEFAULTCLIENTSENDCONTINUEFAILED);
break;
case HTTP_RECV_HDR:
PKIX_CHECK(pkix_pl_HttpDefaultClient_RecvHdr
- (client, &keepGoing, plContext),
+ (client, &keepGoing, plCtx),
PKIX_HTTPDEFAULTCLIENTRECVHDRFAILED);
break;
case HTTP_RECV_HDR_PENDING:
PKIX_CHECK(pkix_pl_HttpDefaultClient_RecvHdrContinue
- (client, &keepGoing, plContext),
+ (client, &keepGoing, plCtx),
PKIX_HTTPDEFAULTCLIENTRECVHDRCONTINUEFAILED);
break;
case HTTP_RECV_BODY:
case HTTP_RECV_BODY_PENDING:
PKIX_CHECK(pkix_pl_HttpDefaultClient_RecvBody
- (client, &keepGoing, plContext),
+ (client, &keepGoing, plCtx),
PKIX_HTTPDEFAULTCLIENTRECVBODYFAILED);
break;
case HTTP_ERROR:
@@ -1106,7 +1106,7 @@ pkix_pl_HttpDefaultClient_CreateSession(
const char *host,
PRUint16 portnum,
SEC_HTTP_SERVER_SESSION *pSession,
- void *plContext)
+ void *plCtx)
{
PKIX_PL_HttpDefaultClient *client = NULL;
@@ -1115,7 +1115,7 @@ pkix_pl_HttpDefaultClient_CreateSession(
PKIX_NULLCHECK_TWO(host, pSession);
PKIX_CHECK(pkix_pl_HttpDefaultClient_Create
- (host, portnum, &client, plContext),
+ (host, portnum, &client, plCtx),
PKIX_HTTPDEFAULTCLIENTCREATEFAILED);
*pSession = (SEC_HTTP_SERVER_SESSION)client;
@@ -1130,7 +1130,7 @@ PKIX_Error *
pkix_pl_HttpDefaultClient_KeepAliveSession(
SEC_HTTP_SERVER_SESSION session,
PRPollDesc **pPollDesc,
- void *plContext)
+ void *plCtx)
{
PKIX_ENTER
(HTTPDEFAULTCLIENT,
@@ -1140,7 +1140,7 @@ pkix_pl_HttpDefaultClient_KeepAliveSession(
PKIX_CHECK(pkix_CheckType
((PKIX_PL_Object *)session,
PKIX_HTTPDEFAULTCLIENT_TYPE,
- plContext),
+ plCtx),
PKIX_SESSIONNOTANHTTPDEFAULTCLIENT);
/* XXX Not implemented */
@@ -1159,7 +1159,7 @@ pkix_pl_HttpDefaultClient_RequestCreate(
const char *http_request_method,
const PRIntervalTime timeout,
SEC_HTTP_REQUEST_SESSION *pRequest,
- void *plContext)
+ void *plCtx)
{
PKIX_PL_HttpDefaultClient *client = NULL;
PKIX_PL_Socket *socket = NULL;
@@ -1174,7 +1174,7 @@ pkix_pl_HttpDefaultClient_RequestCreate(
PKIX_CHECK(pkix_CheckType
((PKIX_PL_Object *)session,
PKIX_HTTPDEFAULTCLIENT_TYPE,
- plContext),
+ plCtx),
PKIX_SESSIONNOTANHTTPDEFAULTCLIENT);
client = (PKIX_PL_HttpDefaultClient *)session;
@@ -1212,7 +1212,7 @@ pkix_pl_HttpDefaultClient_RequestCreate(
2001, /* client->portnum, */
&status,
&socket,
- plContext),
+ plCtx),
PKIX_HTTPCERTSTOREFINDSOCKETCONNECTIONFAILED);
#else
PKIX_CHECK(pkix_HttpCertStore_FindSocketConnection
@@ -1221,20 +1221,20 @@ pkix_pl_HttpDefaultClient_RequestCreate(
client->portnum,
&status,
&socket,
- plContext),
+ plCtx),
PKIX_HTTPCERTSTOREFINDSOCKETCONNECTIONFAILED);
#endif
client->socket = socket;
PKIX_CHECK(pkix_pl_Socket_GetCallbackList
- (socket, &callbackList, plContext),
+ (socket, &callbackList, plCtx),
PKIX_SOCKETGETCALLBACKLISTFAILED);
client->callbackList = (void *)callbackList;
PKIX_CHECK(pkix_pl_Socket_GetPRFileDesc
- (socket, &fileDesc, plContext),
+ (socket, &fileDesc, plCtx),
PKIX_SOCKETGETPRFILEDESCFAILED);
client->pollDesc.fd = fileDesc;
@@ -1264,7 +1264,7 @@ pkix_pl_HttpDefaultClient_SetPostData(
const char *http_data,
const PRUint32 http_data_len,
const char *http_content_type,
- void *plContext)
+ void *plCtx)
{
PKIX_PL_HttpDefaultClient *client = NULL;
@@ -1276,7 +1276,7 @@ pkix_pl_HttpDefaultClient_SetPostData(
PKIX_CHECK(pkix_CheckType
((PKIX_PL_Object *)request,
PKIX_HTTPDEFAULTCLIENT_TYPE,
- plContext),
+ plCtx),
PKIX_REQUESTNOTANHTTPDEFAULTCLIENT);
client = (PKIX_PL_HttpDefaultClient *)request;
@@ -1307,7 +1307,7 @@ pkix_pl_HttpDefaultClient_TrySendAndReceive(
PRUint32 *http_response_data_len,
PRPollDesc **pPollDesc,
SECStatus *pSECReturn,
- void *plContext)
+ void *plCtx)
{
PKIX_PL_HttpDefaultClient *client = NULL;
PKIX_UInt32 postLen = 0;
@@ -1324,7 +1324,7 @@ pkix_pl_HttpDefaultClient_TrySendAndReceive(
PKIX_CHECK(pkix_CheckType
((PKIX_PL_Object *)request,
PKIX_HTTPDEFAULTCLIENT_TYPE,
- plContext),
+ plCtx),
PKIX_REQUESTNOTANHTTPDEFAULTCLIENT);
client = (PKIX_PL_HttpDefaultClient *)request;
@@ -1380,7 +1380,7 @@ pkix_pl_HttpDefaultClient_TrySendAndReceive(
PKIX_CHECK(PKIX_PL_Malloc
(client->POSTLen,
(void **)&(client->POSTBuf),
- plContext),
+ plCtx),
PKIX_MALLOCFAILED);
/* copy header into postBuffer */
@@ -1407,7 +1407,7 @@ pkix_pl_HttpDefaultClient_TrySendAndReceive(
}
/* continue according to state */
- PKIX_CHECK(pkix_pl_HttpDefaultClient_Dispatch(client, plContext),
+ PKIX_CHECK(pkix_pl_HttpDefaultClient_Dispatch(client, plCtx),
PKIX_HTTPDEFAULTCLIENTDISPATCHFAILED);
switch (client->connectStatus) {
@@ -1478,7 +1478,7 @@ cleanup:
PKIX_Error *
pkix_pl_HttpDefaultClient_Cancel(
SEC_HTTP_REQUEST_SESSION request,
- void *plContext)
+ void *plCtx)
{
PKIX_ENTER(HTTPDEFAULTCLIENT, "pkix_pl_HttpDefaultClient_Cancel");
PKIX_NULLCHECK_ONE(request);
@@ -1486,7 +1486,7 @@ pkix_pl_HttpDefaultClient_Cancel(
PKIX_CHECK(pkix_CheckType
((PKIX_PL_Object *)request,
PKIX_HTTPDEFAULTCLIENT_TYPE,
- plContext),
+ plCtx),
PKIX_REQUESTNOTANHTTPDEFAULTCLIENT);
/* XXX Not implemented */
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c
index 9fa8e92608..09b54a2be3 100644
--- a/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c
+++ b/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c
@@ -23,8 +23,8 @@
* PARAMETERS
* "method"
* The UInt32 value to be stored as the method field of the InfoAccess.
- * "generalName"
- * The GeneralName to be stored as the generalName field of the InfoAccess.
+ * "gName"
+ * The GeneralName to be stored as the gName field of the InfoAccess.
* Must be non-NULL.
* "pInfoAccess"
* Address where the result is stored. Must be non-NULL.
@@ -39,7 +39,7 @@
static PKIX_Error *
pkix_pl_InfoAccess_Create(
PKIX_UInt32 method,
- PKIX_PL_GeneralName *generalName,
+ PKIX_PL_GeneralName *gName,
PKIX_PL_InfoAccess **pInfoAccess,
void *plContext)
{
@@ -47,7 +47,7 @@ pkix_pl_InfoAccess_Create(
PKIX_PL_InfoAccess *infoAccess = NULL;
PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_Create");
- PKIX_NULLCHECK_TWO(generalName, pInfoAccess);
+ PKIX_NULLCHECK_TWO(gName, pInfoAccess);
PKIX_CHECK(PKIX_PL_Object_Alloc
(PKIX_INFOACCESS_TYPE,
@@ -58,8 +58,8 @@ pkix_pl_InfoAccess_Create(
infoAccess->method = method;
- PKIX_INCREF(generalName);
- infoAccess->location = generalName;
+ PKIX_INCREF(gName);
+ infoAccess->location = gName;
*pInfoAccess = infoAccess;
infoAccess = NULL;
@@ -678,7 +678,7 @@ pkix_pl_UnescapeURL(
* [binary|<other-type>]]*
*
* PARAMETERS
- * "generalName"
+ * "gName"
* Address of the GeneralName whose LDAPLocation is to be parsed. Must be
* non-NULL.
* "arena"
@@ -700,7 +700,7 @@ pkix_pl_UnescapeURL(
*/
PKIX_Error *
pkix_pl_InfoAccess_ParseLocation(
- PKIX_PL_GeneralName *generalName,
+ PKIX_PL_GeneralName *gName,
PLArenaPool *arena,
LDAPRequestParams *request,
char **pDomainName,
@@ -722,9 +722,9 @@ pkix_pl_InfoAccess_ParseLocation(
LDAPNameComponent *nameComponent = NULL;
PKIX_ENTER(INFOACCESS, "pkix_pl_InfoAccess_ParseLocation");
- PKIX_NULLCHECK_FOUR(generalName, arena, request, pDomainName);
+ PKIX_NULLCHECK_FOUR(gName, arena, request, pDomainName);
- PKIX_TOSTRING(generalName, &locationString, plContext,
+ PKIX_TOSTRING(gName, &locationString, plContext,
PKIX_GENERALNAMETOSTRINGFAILED);
PKIX_CHECK(PKIX_PL_String_GetEncoded
diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h
index d62f4957b2..efb0827c51 100644
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -22,10 +22,10 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
-#define NSS_VERSION "3.36.4" _NSS_CUSTOMIZED
+#define NSS_VERSION "3.38" _NSS_CUSTOMIZED
#define NSS_VMAJOR 3
-#define NSS_VMINOR 36
-#define NSS_VPATCH 4
+#define NSS_VMINOR 38
+#define NSS_VPATCH 0
#define NSS_VBUILD 0
#define NSS_BETA PR_FALSE
diff --git a/security/nss/lib/pk11wrap/pk11akey.c b/security/nss/lib/pk11wrap/pk11akey.c
index c45901ec39..346e473a96 100644
--- a/security/nss/lib/pk11wrap/pk11akey.c
+++ b/security/nss/lib/pk11wrap/pk11akey.c
@@ -804,12 +804,30 @@ PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
/* don't know? look it up */
if (keyType == nullKey) {
CK_KEY_TYPE pk11Type = CKK_RSA;
+ SECItem info;
pk11Type = PK11_ReadULongAttribute(slot, privID, CKA_KEY_TYPE);
isTemp = (PRBool)!PK11_HasAttributeSet(slot, privID, CKA_TOKEN, PR_FALSE);
switch (pk11Type) {
case CKK_RSA:
keyType = rsaKey;
+ /* determine RSA key type from the CKA_PUBLIC_KEY_INFO if present */
+ rv = PK11_ReadAttribute(slot, privID, CKA_PUBLIC_KEY_INFO, NULL, &info);
+ if (rv == SECSuccess) {
+ CERTSubjectPublicKeyInfo *spki;
+
+ spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&info);
+ if (spki) {
+ SECOidTag tag;
+
+ tag = SECOID_GetAlgorithmTag(&spki->algorithm);
+ if (tag == SEC_OID_PKCS1_RSA_PSS_SIGNATURE)
+ keyType = rsaPssKey;
+ SECKEY_DestroySubjectPublicKeyInfo(spki);
+ }
+ SECITEM_FreeItem(&info, PR_FALSE);
+ }
+
break;
case CKK_DSA:
keyType = dsaKey;
diff --git a/security/nss/lib/pk11wrap/pk11pars.c b/security/nss/lib/pk11wrap/pk11pars.c
index fc30222b3d..c165e1ef24 100644
--- a/security/nss/lib/pk11wrap/pk11pars.c
+++ b/security/nss/lib/pk11wrap/pk11pars.c
@@ -547,16 +547,16 @@ secmod_applyCryptoPolicy(const char *policyString,
for (i = 0; i < PR_ARRAY_SIZE(algOptList); i++) {
const oidValDef *algOpt = &algOptList[i];
unsigned name_size = algOpt->name_size;
- PRBool newValue = PR_FALSE;
+ PRBool newOption = PR_FALSE;
if ((length >= name_size) && (cipher[name_size] == '/')) {
- newValue = PR_TRUE;
+ newOption = PR_TRUE;
}
- if ((newValue || algOpt->name_size == length) &&
+ if ((newOption || algOpt->name_size == length) &&
PORT_Strncasecmp(algOpt->name, cipher, name_size) == 0) {
PRUint32 value = algOpt->val;
PRUint32 enable, disable;
- if (newValue) {
+ if (newOption) {
value = secmod_parsePolicyValue(&cipher[name_size] + 1,
length - name_size - 1);
}
diff --git a/security/nss/lib/pkcs12/p12e.c b/security/nss/lib/pkcs12/p12e.c
index 4a21d8955d..c42c4d2e2e 100644
--- a/security/nss/lib/pkcs12/p12e.c
+++ b/security/nss/lib/pkcs12/p12e.c
@@ -884,7 +884,9 @@ sec_PKCS12AddAttributeToBag(SEC_PKCS12ExportContext *p12ctxt,
unsigned int nItems = 0;
SECStatus rv;
- if (!safeBag || !p12ctxt) {
+ PORT_Assert(p12ctxt->arena == safeBag->arena);
+ if (!safeBag || !p12ctxt || p12ctxt->arena != safeBag->arena) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@@ -1589,6 +1591,7 @@ sec_pkcs12_encoder_start_context(SEC_PKCS12ExportContext *p12exp)
params = PK11_CreatePBEParams(salt, &pwd,
NSS_PBE_DEFAULT_ITERATION_COUNT);
SECITEM_ZfreeItem(salt, PR_TRUE);
+ salt = NULL;
SECITEM_ZfreeItem(&pwd, PR_FALSE);
/* get the PBA Mechanism to generate the key */
diff --git a/security/nss/lib/pkcs7/p7decode.c b/security/nss/lib/pkcs7/p7decode.c
index 4f17b8e842..ba51955abf 100644
--- a/security/nss/lib/pkcs7/p7decode.c
+++ b/security/nss/lib/pkcs7/p7decode.c
@@ -1596,7 +1596,6 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
} else {
SECItem *sig;
SECItem holder;
- SECStatus rv;
/*
* No authenticated attributes.
diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c
index fb3110a233..fab3a7a027 100644
--- a/security/nss/lib/pki/pki3hack.c
+++ b/security/nss/lib/pki/pki3hack.c
@@ -1143,8 +1143,8 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
(PRBool)(trust->sslFlags & CERTDB_GOVT_APPROVED_CA);
if (c->object.cryptoContext != NULL) {
/* The cert is in a context, set the trust there */
- NSSCryptoContext *cc = c->object.cryptoContext;
- nssrv = nssCryptoContext_ImportTrust(cc, nssTrust);
+ NSSCryptoContext *cctx = c->object.cryptoContext;
+ nssrv = nssCryptoContext_ImportTrust(cctx, nssTrust);
if (nssrv != PR_SUCCESS) {
goto done;
}
diff --git a/security/nss/lib/smime/cmsrecinfo.c b/security/nss/lib/smime/cmsrecinfo.c
index 2efb6b1f22..8cab288d2e 100644
--- a/security/nss/lib/smime/cmsrecinfo.c
+++ b/security/nss/lib/smime/cmsrecinfo.c
@@ -82,7 +82,7 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg,
if (DERinput) {
/* decode everything from DER */
SECItem newinput;
- SECStatus rv = SECITEM_CopyItem(poolp, &newinput, DERinput);
+ rv = SECITEM_CopyItem(poolp, &newinput, DERinput);
if (SECSuccess != rv)
goto loser;
rv = SEC_QuickDERDecodeItem(poolp, ri, NSSCMSRecipientInfoTemplate, &newinput);
diff --git a/security/nss/lib/softoken/legacydb/pcertdb.c b/security/nss/lib/softoken/legacydb/pcertdb.c
index 2e8b650ee9..47778190db 100644
--- a/security/nss/lib/softoken/legacydb/pcertdb.c
+++ b/security/nss/lib/softoken/legacydb/pcertdb.c
@@ -2577,14 +2577,13 @@ ReadDBSubjectEntry(NSSLOWCERTCertDBHandle *handle, SECItem *derSubject)
SECItem dbentry;
SECStatus rv;
+ PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
goto loser;
}
- PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
-
entry = (certDBEntrySubject *)PORT_ArenaAlloc(arena,
sizeof(certDBEntrySubject));
if (entry == NULL) {
diff --git a/security/nss/lib/softoken/lowkey.c b/security/nss/lib/softoken/lowkey.c
index 295d55f40b..a28a3a55ee 100644
--- a/security/nss/lib/softoken/lowkey.c
+++ b/security/nss/lib/softoken/lowkey.c
@@ -45,6 +45,23 @@ const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[] = {
{ 0 }
};
+const SEC_ASN1Template nsslowkey_SubjectPublicKeyInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYSubjectPublicKeyInfo) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
+ offsetof(NSSLOWKEYSubjectPublicKeyInfo, algorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_BIT_STRING,
+ offsetof(NSSLOWKEYSubjectPublicKeyInfo, subjectPublicKey) },
+ { 0 }
+};
+
+const SEC_ASN1Template nsslowkey_RSAPublicKeyTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWKEYPublicKey) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey, u.rsa.modulus) },
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWKEYPublicKey, u.rsa.publicExponent) },
+ { 0 }
+};
+
const SEC_ASN1Template nsslowkey_PQGParamsTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(PQGParams) },
{ SEC_ASN1_INTEGER, offsetof(PQGParams, prime) },
@@ -135,6 +152,13 @@ prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey *key)
}
void
+prepare_low_rsa_pub_key_for_asn1(NSSLOWKEYPublicKey *key)
+{
+ key->u.rsa.modulus.type = siUnsignedInteger;
+ key->u.rsa.publicExponent.type = siUnsignedInteger;
+}
+
+void
prepare_low_pqg_params_for_asn1(PQGParams *params)
{
params->prime.type = siUnsignedInteger;
diff --git a/security/nss/lib/softoken/lowkeyi.h b/security/nss/lib/softoken/lowkeyi.h
index f9ba3a75f3..e599f01fa0 100644
--- a/security/nss/lib/softoken/lowkeyi.h
+++ b/security/nss/lib/softoken/lowkeyi.h
@@ -27,6 +27,7 @@ extern void prepare_low_dsa_priv_key_export_for_asn1(NSSLOWKEYPrivateKey *key);
extern void prepare_low_dh_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
extern void prepare_low_ec_priv_key_for_asn1(NSSLOWKEYPrivateKey *key);
extern void prepare_low_ecparams_for_asn1(ECParams *params);
+extern void prepare_low_rsa_pub_key_for_asn1(NSSLOWKEYPublicKey *key);
/*
** Destroy a private key object.
diff --git a/security/nss/lib/softoken/lowkeyti.h b/security/nss/lib/softoken/lowkeyti.h
index c048b33e74..7e77592c53 100644
--- a/security/nss/lib/softoken/lowkeyti.h
+++ b/security/nss/lib/softoken/lowkeyti.h
@@ -25,6 +25,8 @@ extern const SEC_ASN1Template nsslowkey_ECPrivateKeyTemplate[];
extern const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[];
extern const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[];
+extern const SEC_ASN1Template nsslowkey_SubjectPublicKeyInfoTemplate[];
+extern const SEC_ASN1Template nsslowkey_RSAPublicKeyTemplate[];
/*
* PKCS #8 attributes
@@ -48,6 +50,13 @@ struct NSSLOWKEYPrivateKeyInfoStr {
typedef struct NSSLOWKEYPrivateKeyInfoStr NSSLOWKEYPrivateKeyInfo;
#define NSSLOWKEY_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
+struct NSSLOWKEYSubjectPublicKeyInfoStr {
+ PLArenaPool *arena;
+ SECAlgorithmID algorithm;
+ SECItem subjectPublicKey;
+};
+typedef struct NSSLOWKEYSubjectPublicKeyInfoStr NSSLOWKEYSubjectPublicKeyInfo;
+
typedef enum {
NSSLOWKEYNullKey = 0,
NSSLOWKEYRSAKey = 1,
diff --git a/security/nss/lib/softoken/lowpbe.c b/security/nss/lib/softoken/lowpbe.c
index 0a47804bf1..4a101c68c4 100644
--- a/security/nss/lib/softoken/lowpbe.c
+++ b/security/nss/lib/softoken/lowpbe.c
@@ -1073,15 +1073,15 @@ sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy,
}
if (encrypt != PR_FALSE) {
- void *dummy;
+ void *v;
- dummy = CBC_PadBuffer(NULL, dup_src->data,
- dup_src->len, &dup_src->len, 8 /* RC2_BLOCK_SIZE */);
- if (dummy == NULL) {
+ v = CBC_PadBuffer(NULL, dup_src->data,
+ dup_src->len, &dup_src->len, 8 /* RC2_BLOCK_SIZE */);
+ if (v == NULL) {
SECITEM_FreeItem(dup_src, PR_TRUE);
return NULL;
}
- dup_src->data = (unsigned char *)dummy;
+ dup_src->data = (unsigned char *)v;
}
dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index 77882a274e..34f25a9d06 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -1343,7 +1343,6 @@ sftk_handleSecretKeyObject(SFTKSession *session, SFTKObject *object,
if (sftk_isTrue(object, CKA_TOKEN)) {
SFTKSlot *slot = session->slot;
SFTKDBHandle *keyHandle = sftk_getKeyDB(slot);
- CK_RV crv;
if (keyHandle == NULL) {
return CKR_TOKEN_WRITE_PROTECTED;
@@ -3807,12 +3806,12 @@ NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
PZ_Unlock(slot->slotLock);
/* Reset login flags. */
if (ulNewLen == 0) {
- PRBool tokenRemoved = PR_FALSE;
PZ_Lock(slot->slotLock);
slot->isLoggedIn = PR_FALSE;
slot->ssoLoggedIn = PR_FALSE;
PZ_Unlock(slot->slotLock);
+ tokenRemoved = PR_FALSE;
rv = sftkdb_CheckPassword(handle, "", &tokenRemoved);
if (tokenRemoved) {
sftk_CloseAllSessions(slot, PR_FALSE);
@@ -4422,6 +4421,44 @@ NSC_GetObjectSize(CK_SESSION_HANDLE hSession,
return CKR_OK;
}
+static CK_RV
+nsc_GetTokenAttributeValue(SFTKSession *session, CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+{
+ SFTKSlot *slot = sftk_SlotFromSession(session);
+ SFTKDBHandle *dbHandle = sftk_getDBForTokenObject(slot, hObject);
+ SFTKDBHandle *keydb = NULL;
+ CK_RV crv;
+
+ if (dbHandle == NULL) {
+ return CKR_OBJECT_HANDLE_INVALID;
+ }
+
+ crv = sftkdb_GetAttributeValue(dbHandle, hObject, pTemplate, ulCount);
+
+ /* make sure we don't export any sensitive information */
+ keydb = sftk_getKeyDB(slot);
+ if (dbHandle == keydb) {
+ CK_ULONG i;
+ for (i = 0; i < ulCount; i++) {
+ if (sftk_isSensitive(pTemplate[i].type, CKO_PRIVATE_KEY)) {
+ crv = CKR_ATTRIBUTE_SENSITIVE;
+ if (pTemplate[i].pValue && (pTemplate[i].ulValueLen != -1)) {
+ PORT_Memset(pTemplate[i].pValue, 0,
+ pTemplate[i].ulValueLen);
+ }
+ pTemplate[i].ulValueLen = -1;
+ }
+ }
+ }
+
+ sftk_freeDB(dbHandle);
+ if (keydb) {
+ sftk_freeDB(keydb);
+ }
+ return crv;
+}
+
/* NSC_GetAttributeValue obtains the value of one or more object attributes. */
CK_RV
NSC_GetAttributeValue(CK_SESSION_HANDLE hSession,
@@ -4450,37 +4487,8 @@ NSC_GetAttributeValue(CK_SESSION_HANDLE hSession,
/* short circuit everything for token objects */
if (sftk_isToken(hObject)) {
- SFTKSlot *slot = sftk_SlotFromSession(session);
- SFTKDBHandle *dbHandle = sftk_getDBForTokenObject(slot, hObject);
- SFTKDBHandle *keydb = NULL;
-
- if (dbHandle == NULL) {
- sftk_FreeSession(session);
- return CKR_OBJECT_HANDLE_INVALID;
- }
-
- crv = sftkdb_GetAttributeValue(dbHandle, hObject, pTemplate, ulCount);
-
- /* make sure we don't export any sensitive information */
- keydb = sftk_getKeyDB(slot);
- if (dbHandle == keydb) {
- for (i = 0; i < (int)ulCount; i++) {
- if (sftk_isSensitive(pTemplate[i].type, CKO_PRIVATE_KEY)) {
- crv = CKR_ATTRIBUTE_SENSITIVE;
- if (pTemplate[i].pValue && (pTemplate[i].ulValueLen != -1)) {
- PORT_Memset(pTemplate[i].pValue, 0,
- pTemplate[i].ulValueLen);
- }
- pTemplate[i].ulValueLen = -1;
- }
- }
- }
-
+ crv = nsc_GetTokenAttributeValue(session, hObject, pTemplate, ulCount);
sftk_FreeSession(session);
- sftk_freeDB(dbHandle);
- if (keydb) {
- sftk_freeDB(keydb);
- }
return crv;
}
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
index d675d73315..385d3c1444 100644
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -5324,7 +5324,52 @@ sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp)
prepare_low_rsa_priv_key_for_asn1(lk);
dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk,
nsslowkey_RSAPrivateKeyTemplate);
- algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
+
+ /* determine RSA key type from the CKA_PUBLIC_KEY_INFO if present */
+ attribute = sftk_FindAttribute(key, CKA_PUBLIC_KEY_INFO);
+ if (attribute) {
+ NSSLOWKEYSubjectPublicKeyInfo *publicKeyInfo;
+ SECItem spki;
+
+ spki.data = attribute->attrib.pValue;
+ spki.len = attribute->attrib.ulValueLen;
+
+ publicKeyInfo = PORT_ArenaZAlloc(arena,
+ sizeof(NSSLOWKEYSubjectPublicKeyInfo));
+ if (!publicKeyInfo) {
+ sftk_FreeAttribute(attribute);
+ *crvp = CKR_HOST_MEMORY;
+ rv = SECFailure;
+ goto loser;
+ }
+ rv = SEC_QuickDERDecodeItem(arena, publicKeyInfo,
+ nsslowkey_SubjectPublicKeyInfoTemplate,
+ &spki);
+ if (rv != SECSuccess) {
+ sftk_FreeAttribute(attribute);
+ *crvp = CKR_KEY_TYPE_INCONSISTENT;
+ goto loser;
+ }
+ algorithm = SECOID_GetAlgorithmTag(&publicKeyInfo->algorithm);
+ if (algorithm != SEC_OID_PKCS1_RSA_ENCRYPTION &&
+ algorithm != SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
+ sftk_FreeAttribute(attribute);
+ rv = SECFailure;
+ *crvp = CKR_KEY_TYPE_INCONSISTENT;
+ goto loser;
+ }
+ param = SECITEM_DupItem(&publicKeyInfo->algorithm.parameters);
+ if (!param) {
+ sftk_FreeAttribute(attribute);
+ rv = SECFailure;
+ *crvp = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ sftk_FreeAttribute(attribute);
+ } else {
+ /* default to PKCS #1 */
+ algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION;
+ }
break;
case NSSLOWKEYDSAKey:
prepare_low_dsa_priv_key_export_for_asn1(lk);
@@ -5803,6 +5848,53 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki)
break;
}
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+
+ /* For RSA-PSS, record the original algorithm parameters so
+ * they can be encrypted altoghether when wrapping */
+ if (SECOID_GetAlgorithmTag(&pki->algorithm) == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
+ NSSLOWKEYSubjectPublicKeyInfo spki;
+ NSSLOWKEYPublicKey pubk;
+ SECItem *publicKeyInfo;
+
+ memset(&spki, 0, sizeof(NSSLOWKEYSubjectPublicKeyInfo));
+ rv = SECOID_CopyAlgorithmID(arena, &spki.algorithm, &pki->algorithm);
+ if (rv != SECSuccess) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ prepare_low_rsa_pub_key_for_asn1(&pubk);
+
+ rv = SECITEM_CopyItem(arena, &pubk.u.rsa.modulus, &lpk->u.rsa.modulus);
+ if (rv != SECSuccess) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ rv = SECITEM_CopyItem(arena, &pubk.u.rsa.publicExponent, &lpk->u.rsa.publicExponent);
+ if (rv != SECSuccess) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ if (SEC_ASN1EncodeItem(arena, &spki.subjectPublicKey,
+ &pubk, nsslowkey_RSAPublicKeyTemplate) == NULL) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ publicKeyInfo = SEC_ASN1EncodeItem(arena, NULL,
+ &spki, nsslowkey_SubjectPublicKeyInfoTemplate);
+ if (!publicKeyInfo) {
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ crv = sftk_AddAttributeType(key, CKA_PUBLIC_KEY_INFO,
+ sftk_item_expand(publicKeyInfo));
+ }
+
loser:
if (lpk) {
nsslowkey_DestroyPrivateKey(lpk);
@@ -7575,13 +7667,13 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
(const CK_NSS_HKDFParams *)pMechanism->pParameter;
const SECHashObject *rawHash;
unsigned hashLen;
- CK_BYTE buf[HASH_LENGTH_MAX];
+ CK_BYTE hashbuf[HASH_LENGTH_MAX];
CK_BYTE *prk; /* psuedo-random key */
CK_ULONG prkLen;
CK_BYTE *okm; /* output keying material */
rawHash = HASH_GetRawHashObject(hashType);
- if (rawHash == NULL || rawHash->length > sizeof buf) {
+ if (rawHash == NULL || rawHash->length > sizeof(hashbuf)) {
crv = CKR_FUNCTION_FAILED;
break;
}
@@ -7615,7 +7707,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
saltLen = params->ulSaltLen;
if (salt == NULL) {
saltLen = hashLen;
- salt = buf;
+ salt = hashbuf;
memset(salt, 0, saltLen);
}
hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS);
@@ -7626,10 +7718,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
HMAC_Begin(hmac);
HMAC_Update(hmac, (const unsigned char *)att->attrib.pValue,
att->attrib.ulValueLen);
- HMAC_Finish(hmac, buf, &bufLen, sizeof(buf));
+ HMAC_Finish(hmac, hashbuf, &bufLen, sizeof(hashbuf));
HMAC_Destroy(hmac, PR_TRUE);
PORT_Assert(bufLen == rawHash->length);
- prk = buf;
+ prk = hashbuf;
prkLen = bufLen;
} else {
/* PRK = base key value */
@@ -7646,24 +7738,24 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
* key material = T(1) | ... | T(n)
*/
HMACContext *hmac;
- CK_BYTE i;
+ CK_BYTE bi;
unsigned iterations = PR_ROUNDUP(keySize, hashLen) / hashLen;
hmac = HMAC_Create(rawHash, prk, prkLen, isFIPS);
if (hmac == NULL) {
crv = CKR_HOST_MEMORY;
break;
}
- for (i = 1; i <= iterations; ++i) {
+ for (bi = 1; bi <= iterations; ++bi) {
unsigned len;
HMAC_Begin(hmac);
- if (i > 1) {
- HMAC_Update(hmac, key_block + ((i - 2) * hashLen), hashLen);
+ if (bi > 1) {
+ HMAC_Update(hmac, key_block + ((bi - 2) * hashLen), hashLen);
}
if (params->ulInfoLen != 0) {
HMAC_Update(hmac, params->pInfo, params->ulInfoLen);
}
- HMAC_Update(hmac, &i, 1);
- HMAC_Finish(hmac, key_block + ((i - 1) * hashLen), &len,
+ HMAC_Update(hmac, &bi, 1);
+ HMAC_Finish(hmac, key_block + ((bi - 1) * hashLen), &len,
hashLen);
PORT_Assert(len == hashLen);
}
diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c
index 27e411759e..7b5fe732f3 100644
--- a/security/nss/lib/softoken/pkcs11u.c
+++ b/security/nss/lib/softoken/pkcs11u.c
@@ -1193,7 +1193,7 @@ sftk_DeleteObject(SFTKSession *session, SFTKObject *object)
/* Handle Token case */
if (so && so->session) {
- SFTKSession *session = so->session;
+ session = so->session;
PZ_Lock(session->objectLock);
sftkqueue_delete(&so->sessionList, 0, session->objects, 0);
PZ_Unlock(session->objectLock);
@@ -1269,7 +1269,7 @@ static const CK_ULONG ecPubKeyAttrsCount =
static const CK_ATTRIBUTE_TYPE commonPrivKeyAttrs[] = {
CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER, CKA_UNWRAP, CKA_SUBJECT,
- CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_NETSCAPE_DB
+ CKA_SENSITIVE, CKA_EXTRACTABLE, CKA_NETSCAPE_DB, CKA_PUBLIC_KEY_INFO
};
static const CK_ULONG commonPrivKeyAttrsCount =
sizeof(commonPrivKeyAttrs) / sizeof(commonPrivKeyAttrs[0]);
diff --git a/security/nss/lib/softoken/sdb.c b/security/nss/lib/softoken/sdb.c
index 96717cb268..fb897d68cc 100644
--- a/security/nss/lib/softoken/sdb.c
+++ b/security/nss/lib/softoken/sdb.c
@@ -37,6 +37,10 @@
#elif defined(XP_UNIX)
#include <unistd.h>
#endif
+#if defined(LINUX) && !defined(ANDROID)
+#include <linux/magic.h>
+#include <sys/vfs.h>
+#endif
#include "utilpars.h"
#ifdef SQLITE_UNSAFE_THREADS
@@ -154,7 +158,8 @@ static const CK_ATTRIBUTE_TYPE known_attributes[] = {
CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_IPSEC_END_SYSTEM,
CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, CKA_TRUST_TIME_STAMPING,
CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH,
- CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS
+ CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS,
+ CKA_PUBLIC_KEY_INFO
};
static int known_attributes_size = sizeof(known_attributes) /
@@ -643,13 +648,18 @@ static int
sdb_openDB(const char *name, sqlite3 **sqlDB, int flags)
{
int sqlerr;
- /*
- * in sqlite3 3.5.0, there is a new open call that allows us
- * to specify read only. Most new OS's are still on 3.3.x (including
- * NSS's internal version and the version shipped with Firefox).
- */
+ int openFlags;
+
*sqlDB = NULL;
- sqlerr = sqlite3_open(name, sqlDB);
+
+ if (flags & SDB_RDONLY) {
+ openFlags = SQLITE_OPEN_READONLY;
+ } else {
+ openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
+ }
+
+ /* Requires SQLite 3.5.0 or newer. */
+ sqlerr = sqlite3_open_v2(name, sqlDB, openFlags, NULL);
if (sqlerr != SQLITE_OK) {
return sqlerr;
}
@@ -1757,6 +1767,8 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
PRIntervalTime now = 0;
char *env;
PRBool enableCache = PR_FALSE;
+ PRBool checkFSType = PR_FALSE;
+ PRBool measureSpeed = PR_FALSE;
PRBool create;
int flags = inFlags & 0x7;
@@ -1917,11 +1929,48 @@ sdb_init(char *dbname, char *table, sdbDataType type, int *inUpdate,
env = PR_GetEnvSecure("NSS_SDB_USE_CACHE");
- if (!env || PORT_Strcasecmp(env, "no") == 0) {
- enableCache = PR_FALSE;
+ /* Variables enableCache, checkFSType, measureSpeed are PR_FALSE by default,
+ * which is the expected behavior for NSS_SDB_USE_CACHE="no".
+ * We don't need to check for "no" here. */
+ if (!env) {
+ /* By default, with no variable set, we avoid expensive measuring for
+ * most FS types. We start with inexpensive FS type checking, and
+ * might perform measuring for some types. */
+ checkFSType = PR_TRUE;
} else if (PORT_Strcasecmp(env, "yes") == 0) {
enableCache = PR_TRUE;
- } else {
+ } else if (PORT_Strcasecmp(env, "no") != 0) { /* not "no" => "auto" */
+ measureSpeed = PR_TRUE;
+ }
+
+ if (checkFSType) {
+#if defined(LINUX) && !defined(ANDROID)
+ struct statfs statfs_s;
+ if (statfs(dbname, &statfs_s) == 0) {
+ switch (statfs_s.f_type) {
+ case SMB_SUPER_MAGIC:
+ case 0xff534d42: /* CIFS_MAGIC_NUMBER */
+ case NFS_SUPER_MAGIC:
+ /* We assume these are slow. */
+ enableCache = PR_TRUE;
+ break;
+ case CODA_SUPER_MAGIC:
+ case 0x65735546: /* FUSE_SUPER_MAGIC */
+ case NCP_SUPER_MAGIC:
+ /* It's uncertain if this FS is fast or slow.
+ * It seems reasonable to perform slow measuring for users
+ * with questionable FS speed. */
+ measureSpeed = PR_TRUE;
+ break;
+ case AFS_SUPER_MAGIC: /* Already implements caching. */
+ default:
+ break;
+ }
+ }
+#endif
+ }
+
+ if (measureSpeed) {
char *tempDir = NULL;
PRUint32 tempOps = 0;
/*
diff --git a/security/nss/lib/softoken/sftkdb.c b/security/nss/lib/softoken/sftkdb.c
index 2ae0840682..409c910f46 100644
--- a/security/nss/lib/softoken/sftkdb.c
+++ b/security/nss/lib/softoken/sftkdb.c
@@ -1591,7 +1591,8 @@ static const CK_ATTRIBUTE_TYPE known_attributes[] = {
CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_IPSEC_END_SYSTEM,
CKA_TRUST_IPSEC_TUNNEL, CKA_TRUST_IPSEC_USER, CKA_TRUST_TIME_STAMPING,
CKA_TRUST_STEP_UP_APPROVED, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH,
- CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS
+ CKA_NETSCAPE_DB, CKA_NETSCAPE_TRUST, CKA_NSS_OVERRIDE_EXTENSIONS,
+ CKA_PUBLIC_KEY_INFO
};
static unsigned int known_attributes_size = sizeof(known_attributes) /
diff --git a/security/nss/lib/softoken/sftkpars.c b/security/nss/lib/softoken/sftkpars.c
index e972fe8541..5e96a1c040 100644
--- a/security/nss/lib/softoken/sftkpars.c
+++ b/security/nss/lib/softoken/sftkpars.c
@@ -162,7 +162,7 @@ sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS)
}
if (parsed->tokens == NULL) {
int count = isFIPS ? 1 : 2;
- int index = count - 1;
+ int i = count - 1;
sftk_token_parameters *tokens = NULL;
tokens = (sftk_token_parameters *)
@@ -172,30 +172,30 @@ sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS)
}
parsed->tokens = tokens;
parsed->token_count = count;
- tokens[index].slotID = isFIPS ? FIPS_SLOT_ID : PRIVATE_KEY_SLOT_ID;
- tokens[index].certPrefix = certPrefix;
- tokens[index].keyPrefix = keyPrefix;
- tokens[index].minPW = minPW ? atoi(minPW) : 0;
- tokens[index].readOnly = parsed->readOnly;
- tokens[index].noCertDB = parsed->noCertDB;
- tokens[index].noKeyDB = parsed->noCertDB;
- tokens[index].forceOpen = parsed->forceOpen;
- tokens[index].pwRequired = parsed->pwRequired;
- tokens[index].optimizeSpace = parsed->optimizeSpace;
+ tokens[i].slotID = isFIPS ? FIPS_SLOT_ID : PRIVATE_KEY_SLOT_ID;
+ tokens[i].certPrefix = certPrefix;
+ tokens[i].keyPrefix = keyPrefix;
+ tokens[i].minPW = minPW ? atoi(minPW) : 0;
+ tokens[i].readOnly = parsed->readOnly;
+ tokens[i].noCertDB = parsed->noCertDB;
+ tokens[i].noKeyDB = parsed->noCertDB;
+ tokens[i].forceOpen = parsed->forceOpen;
+ tokens[i].pwRequired = parsed->pwRequired;
+ tokens[i].optimizeSpace = parsed->optimizeSpace;
tokens[0].optimizeSpace = parsed->optimizeSpace;
certPrefix = NULL;
keyPrefix = NULL;
if (isFIPS) {
- tokens[index].tokdes = ftokdes;
- tokens[index].updtokdes = pupdtokdes;
- tokens[index].slotdes = fslotdes;
+ tokens[i].tokdes = ftokdes;
+ tokens[i].updtokdes = pupdtokdes;
+ tokens[i].slotdes = fslotdes;
fslotdes = NULL;
ftokdes = NULL;
pupdtokdes = NULL;
} else {
- tokens[index].tokdes = ptokdes;
- tokens[index].updtokdes = pupdtokdes;
- tokens[index].slotdes = pslotdes;
+ tokens[i].tokdes = ptokdes;
+ tokens[i].updtokdes = pupdtokdes;
+ tokens[i].slotdes = pslotdes;
tokens[0].slotID = NETSCAPE_SLOT_ID;
tokens[0].tokdes = tokdes;
tokens[0].slotdes = slotdes;
diff --git a/security/nss/lib/softoken/sftkpwd.c b/security/nss/lib/softoken/sftkpwd.c
index e0d2df9ab4..9834d3ba01 100644
--- a/security/nss/lib/softoken/sftkpwd.c
+++ b/security/nss/lib/softoken/sftkpwd.c
@@ -138,12 +138,14 @@ sftkdb_decodeCipherText(SECItem *cipherText, sftkCipherValue *cipherValue)
SFTKDBEncryptedDataInfo edi;
SECStatus rv;
+ PORT_Assert(cipherValue);
+ cipherValue->arena = NULL;
+ cipherValue->param = NULL;
+
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) {
return SECFailure;
}
- cipherValue->arena = NULL;
- cipherValue->param = NULL;
rv = SEC_QuickDERDecodeItem(arena, &edi, sftkdb_EncryptedDataInfoTemplate,
cipherText);
diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h
index f760ba21d8..827bf2e221 100644
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -17,10 +17,10 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
-#define SOFTOKEN_VERSION "3.36.4" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VERSION "3.38" SOFTOKEN_ECC_STRING
#define SOFTOKEN_VMAJOR 3
-#define SOFTOKEN_VMINOR 36
-#define SOFTOKEN_VPATCH 4
+#define SOFTOKEN_VMINOR 38
+#define SOFTOKEN_VPATCH 0
#define SOFTOKEN_VBUILD 0
#define SOFTOKEN_BETA PR_FALSE
diff --git a/security/nss/lib/ssl/SSLerrs.h b/security/nss/lib/ssl/SSLerrs.h
index d3f0875442..f01d165833 100644
--- a/security/nss/lib/ssl/SSLerrs.h
+++ b/security/nss/lib/ssl/SSLerrs.h
@@ -374,7 +374,7 @@ ER3(SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY, (SSL_ERROR_BASE + 115),
"SSL received a weak ephemeral Diffie-Hellman key in Server Key Exchange handshake message.")
ER3(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID, (SSL_ERROR_BASE + 116),
- "SSL received invalid NPN extension data.")
+ "SSL received invalid ALPN extension data.")
ER3(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2, (SSL_ERROR_BASE + 117),
"SSL feature not supported for SSL 2.0 connections.")
@@ -543,3 +543,12 @@ ER3(SSL_ERROR_TOO_MANY_KEY_UPDATES, (SSL_ERROR_BASE + 171),
ER3(SSL_ERROR_HANDSHAKE_FAILED, (SSL_ERROR_BASE + 172),
"SSL handshake has already failed. No more operations possible.")
+
+ER3(SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR, (SSL_ERROR_BASE + 173),
+ "SSL received an invalid resumption token.")
+
+ER3(SSL_ERROR_RX_MALFORMED_DTLS_ACK, (SSL_ERROR_BASE + 174),
+ "SSL received a malformed DTLS ACK")
+
+ER3(SSL_ERROR_DH_KEY_TOO_LONG, (SSL_ERROR_BASE + 175),
+ "SSL received a DH key share that's too long (>8192 bit).")
diff --git a/security/nss/lib/ssl/dtls13con.c b/security/nss/lib/ssl/dtls13con.c
index aba0f62ab8..de6cb47ca2 100644
--- a/security/nss/lib/ssl/dtls13con.c
+++ b/security/nss/lib/ssl/dtls13con.c
@@ -11,6 +11,43 @@
#include "sslimpl.h"
#include "sslproto.h"
+SECStatus
+dtls13_InsertCipherTextHeader(const sslSocket *ss, ssl3CipherSpec *cwSpec,
+ sslBuffer *wrBuf, PRBool *needsLength)
+{
+ PRUint32 seq;
+ SECStatus rv;
+
+ /* Avoid using short records for the handshake. We pack multiple records
+ * into the one datagram for the handshake. */
+ if (ss->opt.enableDtlsShortHeader &&
+ cwSpec->epoch != TrafficKeyHandshake) {
+ *needsLength = PR_FALSE;
+ /* The short header is comprised of two octets in the form
+ * 0b001essssssssssss where 'e' is the low bit of the epoch and 's' is
+ * the low 12 bits of the sequence number. */
+ seq = 0x2000 |
+ (((uint64_t)cwSpec->epoch & 1) << 12) |
+ (cwSpec->nextSeqNum & 0xfff);
+ return sslBuffer_AppendNumber(wrBuf, seq, 2);
+ }
+
+ rv = sslBuffer_AppendNumber(wrBuf, content_application_data, 1);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ /* The epoch and sequence number are encoded on 4 octets, with the epoch
+ * consuming the first two bits. */
+ seq = (((uint64_t)cwSpec->epoch & 3) << 30) | (cwSpec->nextSeqNum & 0x3fffffff);
+ rv = sslBuffer_AppendNumber(wrBuf, seq, 4);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ *needsLength = PR_TRUE;
+ return SECSuccess;
+}
+
/* DTLS 1.3 Record map for ACK processing.
* This represents a single fragment, so a record which includes
* multiple fragments will have one entry for each fragment on the
@@ -82,10 +119,15 @@ dtls13_SendAck(sslSocket *ss)
SECStatus rv = SECSuccess;
PRCList *cursor;
PRInt32 sent;
+ unsigned int offset;
SSL_TRC(10, ("%d: SSL3[%d]: Sending ACK",
SSL_GETPID(), ss->fd));
+ rv = sslBuffer_Skip(&buf, 2, &offset);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
for (cursor = PR_LIST_HEAD(&ss->ssl3.hs.dtlsRcvdHandshake);
cursor != &ss->ssl3.hs.dtlsRcvdHandshake;
cursor = PR_NEXT_LINK(cursor)) {
@@ -99,6 +141,11 @@ dtls13_SendAck(sslSocket *ss)
}
}
+ rv = sslBuffer_InsertLength(&buf, offset, 2);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
ssl_GetXmitBufLock(ss);
sent = ssl3_SendRecord(ss, NULL, content_ack,
buf.buf, buf.len, 0);
@@ -364,6 +411,7 @@ dtls13_HandleAck(sslSocket *ss, sslBuffer *databuf)
{
PRUint8 *b = databuf->buf;
PRUint32 l = databuf->len;
+ unsigned int length;
SECStatus rv;
/* Ensure we don't loop. */
@@ -372,10 +420,19 @@ dtls13_HandleAck(sslSocket *ss, sslBuffer *databuf)
PORT_Assert(IS_DTLS(ss));
if (!tls13_MaybeTls13(ss)) {
tls13_FatalError(ss, SSL_ERROR_RX_UNKNOWN_RECORD_TYPE, illegal_parameter);
- return SECSuccess;
+ return SECFailure;
}
SSL_TRC(10, ("%d: SSL3[%d]: Handling ACK", SSL_GETPID(), ss->fd));
+ rv = ssl3_ConsumeHandshakeNumber(ss, &length, 2, &b, &l);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ if (length != l) {
+ tls13_FatalError(ss, SSL_ERROR_RX_MALFORMED_DTLS_ACK, decode_error);
+ return SECFailure;
+ }
+
while (l > 0) {
PRUint64 seq;
PRCList *cursor;
diff --git a/security/nss/lib/ssl/dtls13con.h b/security/nss/lib/ssl/dtls13con.h
index bf14d3bd2e..ca48ef3638 100644
--- a/security/nss/lib/ssl/dtls13con.h
+++ b/security/nss/lib/ssl/dtls13con.h
@@ -9,6 +9,10 @@
#ifndef __dtls13con_h_
#define __dtls13con_h_
+SECStatus dtls13_InsertCipherTextHeader(const sslSocket *ss,
+ ssl3CipherSpec *cwSpec,
+ sslBuffer *wrBuf,
+ PRBool *needsLength);
SECStatus dtls13_RememberFragment(sslSocket *ss, PRCList *list,
PRUint32 sequence, PRUint32 offset,
PRUint32 length, DTLSEpoch epoch,
diff --git a/security/nss/lib/ssl/dtlscon.c b/security/nss/lib/ssl/dtlscon.c
index 2f335f9247..a82295c668 100644
--- a/security/nss/lib/ssl/dtlscon.c
+++ b/security/nss/lib/ssl/dtlscon.c
@@ -724,13 +724,16 @@ dtls_FragmentHandshake(sslSocket *ss, DTLSQueuedMessage *msg)
PORT_Assert(end <= contentLen);
fragmentLen = PR_MIN(end, contentLen) - fragmentOffset;
- /* Reduce to the space remaining in the MTU. Allow for any existing
- * messages, record expansion, and the handshake header. */
+ /* Limit further by the record size limit. Account for the header. */
+ fragmentLen = PR_MIN(fragmentLen,
+ msg->cwSpec->recordSizeLimit - DTLS_HS_HDR_LEN);
+
+ /* Reduce to the space remaining in the MTU. */
fragmentLen = PR_MIN(fragmentLen,
ss->ssl3.mtu - /* MTU estimate. */
- ss->pendingBuf.len - /* Less unsent records. */
+ ss->pendingBuf.len - /* Less any unsent records. */
DTLS_MAX_EXPANSION - /* Allow for expansion. */
- DTLS_HS_HDR_LEN); /* + handshake header. */
+ DTLS_HS_HDR_LEN); /* And the handshake header. */
PORT_Assert(fragmentLen > 0 || fragmentOffset == 0);
/* Make totally sure that we will fit in the buffer. This should be
@@ -776,7 +779,7 @@ dtls_FragmentHandshake(sslSocket *ss, DTLSQueuedMessage *msg)
rv = dtls13_RememberFragment(ss, &ss->ssl3.hs.dtlsSentHandshake,
msgSeq, fragmentOffset, fragmentLen,
msg->cwSpec->epoch,
- msg->cwSpec->seqNum);
+ msg->cwSpec->nextSeqNum);
if (rv != SECSuccess) {
return SECFailure;
}
@@ -1319,6 +1322,107 @@ DTLS_GetHandshakeTimeout(PRFileDesc *socket, PRIntervalTime *timeout)
return SECSuccess;
}
+PRBool
+dtls_IsLongHeader(SSL3ProtocolVersion version, PRUint8 firstOctet)
+{
+#ifndef UNSAFE_FUZZER_MODE
+ return version < SSL_LIBRARY_VERSION_TLS_1_3 ||
+ firstOctet == content_handshake ||
+ firstOctet == content_ack ||
+ firstOctet == content_alert;
+#else
+ return PR_TRUE;
+#endif
+}
+
+DTLSEpoch
+dtls_ReadEpoch(const ssl3CipherSpec *crSpec, const PRUint8 *hdr)
+{
+ DTLSEpoch epoch;
+ DTLSEpoch maxEpoch;
+ DTLSEpoch partial;
+
+ if (dtls_IsLongHeader(crSpec->version, hdr[0])) {
+ return ((DTLSEpoch)hdr[3] << 8) | hdr[4];
+ }
+
+ /* A lot of how we recover the epoch here will depend on how we plan to
+ * manage KeyUpdate. In the case that we decide to install a new read spec
+ * as a KeyUpdate is handled, crSpec will always be the highest epoch we can
+ * possibly receive. That makes this easier to manage. */
+ if ((hdr[0] & 0xe0) == 0x20) {
+ /* Use crSpec->epoch, or crSpec->epoch - 1 if the last bit differs. */
+ if (((hdr[0] >> 4) & 1) == (crSpec->epoch & 1)) {
+ return crSpec->epoch;
+ }
+ return crSpec->epoch - 1;
+ }
+
+ /* dtls_GatherData should ensure that this works. */
+ PORT_Assert(hdr[0] == content_application_data);
+
+ /* This uses the same method as is used to recover the sequence number in
+ * dtls_ReadSequenceNumber, except that the maximum value is set to the
+ * current epoch. */
+ partial = hdr[1] >> 6;
+ maxEpoch = PR_MAX(crSpec->epoch, 3);
+ epoch = (maxEpoch & 0xfffc) | partial;
+ if (partial > (maxEpoch & 0x03)) {
+ epoch -= 4;
+ }
+ return epoch;
+}
+
+static sslSequenceNumber
+dtls_ReadSequenceNumber(const ssl3CipherSpec *spec, const PRUint8 *hdr)
+{
+ sslSequenceNumber cap;
+ sslSequenceNumber partial;
+ sslSequenceNumber seqNum;
+ sslSequenceNumber mask;
+
+ if (dtls_IsLongHeader(spec->version, hdr[0])) {
+ static const unsigned int seqNumOffset = 5; /* type, version, epoch */
+ static const unsigned int seqNumLength = 6;
+ sslReader r = SSL_READER(hdr + seqNumOffset, seqNumLength);
+ (void)sslRead_ReadNumber(&r, seqNumLength, &seqNum);
+ return seqNum;
+ }
+
+ /* Only the least significant bits of the sequence number is available here.
+ * This recovers the value based on the next expected sequence number.
+ *
+ * This works by determining the maximum possible sequence number, which is
+ * half the range of possible values above the expected next value (the
+ * expected next value is in |spec->seqNum|). Then, the last part of the
+ * sequence number is replaced. If that causes the value to exceed the
+ * maximum, subtract an entire range.
+ */
+ if ((hdr[0] & 0xe0) == 0x20) {
+ /* A 12-bit sequence number. */
+ cap = spec->nextSeqNum + (1ULL << 11);
+ partial = (((sslSequenceNumber)hdr[0] & 0xf) << 8) |
+ (sslSequenceNumber)hdr[1];
+ mask = (1ULL << 12) - 1;
+ } else {
+ /* A 30-bit sequence number. */
+ cap = spec->nextSeqNum + (1ULL << 29);
+ partial = (((sslSequenceNumber)hdr[1] & 0x3f) << 24) |
+ ((sslSequenceNumber)hdr[2] << 16) |
+ ((sslSequenceNumber)hdr[3] << 8) |
+ (sslSequenceNumber)hdr[4];
+ mask = (1ULL << 30) - 1;
+ }
+ seqNum = (cap & ~mask) | partial;
+ /* The second check prevents the value from underflowing if we get a large
+ * gap at the start of a connection, where this subtraction would cause the
+ * sequence number to wrap to near UINT64_MAX. */
+ if ((partial > (cap & mask)) && (seqNum > mask)) {
+ seqNum -= mask + 1;
+ }
+ return seqNum;
+}
+
/*
* DTLS relevance checks:
* Note that this code currently ignores all out-of-epoch packets,
@@ -1336,7 +1440,7 @@ dtls_IsRelevant(sslSocket *ss, const ssl3CipherSpec *spec,
const SSL3Ciphertext *cText,
sslSequenceNumber *seqNumOut)
{
- sslSequenceNumber seqNum = cText->seq_num & RECORD_SEQ_MASK;
+ sslSequenceNumber seqNum = dtls_ReadSequenceNumber(spec, cText->hdr);
if (dtls_RecordGetRecvd(&spec->recvdRecords, seqNum) != 0) {
SSL_TRC(10, ("%d: SSL3[%d]: dtls_IsRelevant, rejecting "
"potentially replayed packet",
diff --git a/security/nss/lib/ssl/dtlscon.h b/security/nss/lib/ssl/dtlscon.h
index d094380f8c..45fc069b97 100644
--- a/security/nss/lib/ssl/dtlscon.h
+++ b/security/nss/lib/ssl/dtlscon.h
@@ -41,8 +41,10 @@ extern SSL3ProtocolVersion
dtls_TLSVersionToDTLSVersion(SSL3ProtocolVersion tlsv);
extern SSL3ProtocolVersion
dtls_DTLSVersionToTLSVersion(SSL3ProtocolVersion dtlsv);
+DTLSEpoch dtls_ReadEpoch(const ssl3CipherSpec *crSpec, const PRUint8 *hdr);
extern PRBool dtls_IsRelevant(sslSocket *ss, const ssl3CipherSpec *spec,
const SSL3Ciphertext *cText,
sslSequenceNumber *seqNum);
void dtls_ReceivedFirstMessageInFlight(sslSocket *ss);
+PRBool dtls_IsLongHeader(SSL3ProtocolVersion version, PRUint8 firstOctet);
#endif
diff --git a/security/nss/lib/ssl/ssl.h b/security/nss/lib/ssl/ssl.h
index 25aabbaa21..ecc4f95066 100644
--- a/security/nss/lib/ssl/ssl.h
+++ b/security/nss/lib/ssl/ssl.h
@@ -158,23 +158,18 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
#define SSL_CBC_RANDOM_IV 23
#define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */
-/* SSL_ENABLE_NPN controls whether the NPN extension is enabled for the initial
- * handshake when application layer protocol negotiation is used.
- * SSL_SetNextProtoCallback or SSL_SetNextProtoNego must be used to control the
- * application layer protocol negotiation; otherwise, the NPN extension will
- * not be negotiated. SSL_ENABLE_NPN is currently enabled by default but this
- * may change in future versions.
- */
+/* SSL_ENABLE_NPN is defunct and defaults to false.
+ * Using this option will not have any effect but won't produce an error. */
#define SSL_ENABLE_NPN 25
/* SSL_ENABLE_ALPN controls whether the ALPN extension is enabled for the
* initial handshake when application layer protocol negotiation is used.
- * SSL_SetNextProtoNego (not SSL_SetNextProtoCallback) must be used to control
- * the application layer protocol negotiation; otherwise, the ALPN extension
- * will not be negotiated. ALPN is not negotiated for renegotiation handshakes,
- * even though the ALPN specification defines a way to use ALPN during
- * renegotiations. SSL_ENABLE_ALPN is currently disabled by default, but this
- * may change in future versions.
+ * SSL_SetNextProtoNego or SSL_SetNextProtoCallback can be used to control
+ * the application layer protocol negotiation;
+ * ALPN is not negotiated for renegotiation handshakes, even though the ALPN
+ * specification defines a way to use ALPN during renegotiations.
+ * SSL_ENABLE_ALPN is currently enabled by default, but this may change in
+ * future versions.
*/
#define SSL_ENABLE_ALPN 26
@@ -248,12 +243,45 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd);
*/
#define SSL_ENABLE_0RTT_DATA 33
+/* Sets a limit to the size of encrypted records (see
+ * draft-ietf-tls-record-limit). This is the value that is advertised to peers,
+ * not a limit on the size of records that will be created. Setting this value
+ * reduces the size of records that will be received (not sent).
+ *
+ * This limit applies to the plaintext, but the records that appear on the wire
+ * will be bigger. This doesn't include record headers, IVs, block cipher
+ * padding, and authentication tags or MACs.
+ *
+ * NSS always advertises the record size limit extension. If this option is not
+ * set, the extension will contain the maximum allowed size for the selected TLS
+ * version (currently this is 16384 or 2^14 for TLS 1.2 and lower and 16385 for
+ * TLS 1.3).
+ *
+ * By default, NSS creates records that are the maximum size possible, using all
+ * the data that was written by the application. Writes larger than the maximum
+ * are split into maximum sized records, and any remainder (unless
+ * SSL_CBC_RANDOM_IV is enabled and active). If a peer advertises a record size
+ * limit then that value is used instead.
+ */
+#define SSL_RECORD_SIZE_LIMIT 34
+
/* Enables TLS 1.3 compatibility mode. In this mode, the client includes a fake
* session ID in the handshake and sends a ChangeCipherSpec. A server will
* always use the setting chosen by the client, so the value of this option has
* no effect for a server. This setting is ignored for DTLS. */
#define SSL_ENABLE_TLS13_COMPAT_MODE 35
+/* Enables the sending of DTLS records using the short (two octet) record
+ * header. Only do this if there are 2^10 or fewer packets in flight at a time;
+ * using this with a larger number of packets in flight could mean that packets
+ * are dropped if there is reordering.
+ *
+ * This applies to TLS 1.3 only. This is not a parameter that is negotiated
+ * during the TLS handshake. Unlike other socket options, this option can be
+ * changed after a handshake is complete.
+ */
+#define SSL_ENABLE_DTLS_SHORT_HEADER 36
+
#ifdef SSL_DEPRECATED_FUNCTION
/* Old deprecated function names */
SSL_IMPORT SECStatus SSL_Enable(PRFileDesc *fd, int option, PRIntn on);
@@ -272,10 +300,10 @@ SSL_IMPORT SECStatus SSL_OptionSetDefault(PRInt32 option, PRIntn val);
SSL_IMPORT SECStatus SSL_OptionGetDefault(PRInt32 option, PRIntn *val);
SSL_IMPORT SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle);
-/* SSLNextProtoCallback is called during the handshake for the client, when a
- * Next Protocol Negotiation (NPN) extension has been received from the server.
- * |protos| and |protosLen| define a buffer which contains the server's
- * advertisement. This data is guaranteed to be well formed per the NPN spec.
+/* SSLNextProtoCallback is called during the handshake for the server, when an
+ * Application-Layer Protocol Negotiation (ALPN) extension has been received
+ * from the client. |protos| and |protosLen| define a buffer which contains the
+ * client's advertisement.
* |protoOut| is a buffer provided by the caller, of length 255 (the maximum
* allowed by the protocol). On successful return, the protocol to be announced
* to the server will be in |protoOut| and its length in |*protoOutLen|.
@@ -291,27 +319,24 @@ typedef SECStatus(PR_CALLBACK *SSLNextProtoCallback)(
unsigned int *protoOutLen,
unsigned int protoMaxOut);
-/* SSL_SetNextProtoCallback sets a callback function to handle Next Protocol
- * Negotiation. It causes a client to advertise NPN. */
+/* SSL_SetNextProtoCallback sets a callback function to handle ALPN Negotiation.
+ * It causes a client to advertise ALPN. */
SSL_IMPORT SECStatus SSL_SetNextProtoCallback(PRFileDesc *fd,
SSLNextProtoCallback callback,
void *arg);
/* SSL_SetNextProtoNego can be used as an alternative to
- * SSL_SetNextProtoCallback. It also causes a client to advertise NPN and
- * installs a default callback function which selects the first supported
- * protocol in server-preference order. If no matching protocol is found it
- * selects the first supported protocol.
+ * SSL_SetNextProtoCallback.
*
- * Using this function also allows the client to transparently support ALPN.
+ * Using this function allows client and server to transparently support ALPN.
* The same set of protocols will be advertised via ALPN and, if the server
* uses ALPN to select a protocol, SSL_GetNextProto will return
* SSL_NEXT_PROTO_SELECTED as the state.
*
- * Since NPN uses the first protocol as the fallback protocol, when sending an
- * ALPN extension, the first protocol is moved to the end of the list. This
- * indicates that the fallback protocol is the least preferred. The other
- * protocols should be in preference order.
+ * Because the predecessor to ALPN, NPN, used the first protocol as the fallback
+ * protocol, when sending an ALPN extension, the first protocol is moved to the
+ * end of the list. This indicates that the fallback protocol is the least
+ * preferred. The other protocols should be in preference order.
*
* The supported protocols are specified in |data| in wire-format (8-bit
* length-prefixed). For example: "\010http/1.1\006spdy/2". */
diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c
index 2593bbaccb..466fc296ff 100644
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -990,27 +990,22 @@ ssl_ClientReadVersion(sslSocket *ss, PRUint8 **b, unsigned int *len,
if (rv != SECSuccess) {
return SECFailure; /* alert has been sent */
}
-
-#ifdef TLS_1_3_DRAFT_VERSION
- if (temp == SSL_LIBRARY_VERSION_TLS_1_3) {
- (void)SSL3_SendAlert(ss, alert_fatal, protocol_version);
- PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
- return SECFailure;
- }
- if (temp == tls13_EncodeDraftVersion(SSL_LIBRARY_VERSION_TLS_1_3)) {
- v = SSL_LIBRARY_VERSION_TLS_1_3;
- } else {
- v = (SSL3ProtocolVersion)temp;
- }
-#else
v = (SSL3ProtocolVersion)temp;
-#endif
if (IS_DTLS(ss)) {
- /* If this fails, we get 0 back and the next check to fails. */
v = dtls_DTLSVersionToTLSVersion(v);
+ /* Check for failure. */
+ if (!v || v > SSL_LIBRARY_VERSION_MAX_SUPPORTED) {
+ SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ return SECFailure;
+ }
}
+ /* You can't negotiate TLS 1.3 this way. */
+ if (v >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ return SECFailure;
+ }
*version = v;
return SECSuccess;
}
@@ -1415,7 +1410,7 @@ ssl3_SetupPendingCipherSpec(sslSocket *ss, CipherSpecDirection direction,
spec->macDef = ssl_GetMacDef(ss, suiteDef);
spec->epoch = prev->epoch + 1;
- spec->seqNum = 0;
+ spec->nextSeqNum = 0;
if (IS_DTLS(ss) && direction == CipherSpecRead) {
dtls_InitRecvdRecords(&spec->recvdRecords);
}
@@ -1481,6 +1476,13 @@ ssl3_SetupBothPendingCipherSpecs(sslSocket *ss)
goto loser;
}
+ if (ssl3_ExtensionNegotiated(ss, ssl_record_size_limit_xtn)) {
+ ss->ssl3.prSpec->recordSizeLimit = PR_MIN(MAX_FRAGMENT_LENGTH,
+ ss->opt.recordSizeLimit);
+ ss->ssl3.pwSpec->recordSizeLimit = PR_MIN(MAX_FRAGMENT_LENGTH,
+ ss->xtnData.recordSizeLimit);
+ }
+
ssl_ReleaseSpecWriteLock(ss); /*******************************/
return SECSuccess;
@@ -2004,6 +2006,7 @@ ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec,
unsigned int ivLen = 0;
unsigned char pseudoHeaderBuf[13];
sslBuffer pseudoHeader = SSL_BUFFER(pseudoHeaderBuf);
+ int len;
if (cwSpec->cipherDef->type == type_block &&
cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
@@ -2013,29 +2016,32 @@ ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec,
* record.
*/
ivLen = cwSpec->cipherDef->iv_size;
- if (ivLen > wrBuf->space) {
+ if (ivLen > SSL_BUFFER_SPACE(wrBuf)) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
- rv = PK11_GenerateRandom(wrBuf->buf, ivLen);
+ rv = PK11_GenerateRandom(SSL_BUFFER_NEXT(wrBuf), ivLen);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_GENERATE_RANDOM_FAILURE);
return rv;
}
rv = cwSpec->cipher(cwSpec->cipherContext,
- wrBuf->buf, /* output */
- (int *)&wrBuf->len, /* outlen */
- ivLen, /* max outlen */
- wrBuf->buf, /* input */
- ivLen); /* input len */
- if (rv != SECSuccess || wrBuf->len != ivLen) {
+ SSL_BUFFER_NEXT(wrBuf), /* output */
+ &len, /* outlen */
+ ivLen, /* max outlen */
+ SSL_BUFFER_NEXT(wrBuf), /* input */
+ ivLen); /* input len */
+ if (rv != SECSuccess || len != ivLen) {
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
return SECFailure;
}
+
+ rv = sslBuffer_Skip(wrBuf, len, NULL);
+ PORT_Assert(rv == SECSuccess); /* Can't fail. */
}
rv = ssl3_BuildRecordPseudoHeader(
- cwSpec->epoch, cwSpec->seqNum, type,
+ cwSpec->epoch, cwSpec->nextSeqNum, type,
cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_0, cwSpec->recordVersion,
isDTLS, contentLen, &pseudoHeader);
PORT_Assert(rv == SECSuccess);
@@ -2043,23 +2049,26 @@ ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec,
const int nonceLen = cwSpec->cipherDef->explicit_nonce_size;
const int tagLen = cwSpec->cipherDef->tag_size;
- if (nonceLen + contentLen + tagLen > wrBuf->space) {
+ if (nonceLen + contentLen + tagLen > SSL_BUFFER_SPACE(wrBuf)) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
rv = cwSpec->aead(
&cwSpec->keyMaterial,
- PR_FALSE, /* do encrypt */
- wrBuf->buf, /* output */
- (int *)&wrBuf->len, /* out len */
- wrBuf->space, /* max out */
- pIn, contentLen, /* input */
+ PR_FALSE, /* do encrypt */
+ SSL_BUFFER_NEXT(wrBuf), /* output */
+ &len, /* out len */
+ SSL_BUFFER_SPACE(wrBuf), /* max out */
+ pIn, contentLen, /* input */
SSL_BUFFER_BASE(&pseudoHeader), SSL_BUFFER_LEN(&pseudoHeader));
if (rv != SECSuccess) {
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
return SECFailure;
}
+
+ rv = sslBuffer_Skip(wrBuf, len, NULL);
+ PORT_Assert(rv == SECSuccess); /* Can't fail. */
} else {
int blockSize = cwSpec->cipherDef->block_size;
@@ -2069,7 +2078,7 @@ ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec,
rv = ssl3_ComputeRecordMAC(cwSpec, SSL_BUFFER_BASE(&pseudoHeader),
SSL_BUFFER_LEN(&pseudoHeader),
pIn, contentLen,
- wrBuf->buf + ivLen + contentLen, &macLen);
+ SSL_BUFFER_NEXT(wrBuf) + contentLen, &macLen);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
return SECFailure;
@@ -2095,7 +2104,7 @@ ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec,
PORT_Assert((fragLen % blockSize) == 0);
/* Pad according to TLS rules (also acceptable to SSL3). */
- pBuf = &wrBuf->buf[ivLen + fragLen - 1];
+ pBuf = SSL_BUFFER_NEXT(wrBuf) + fragLen - 1;
for (i = padding_length + 1; i > 0; --i) {
*pBuf-- = padding_length;
}
@@ -2112,14 +2121,14 @@ ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec,
p2Len += oddLen;
PORT_Assert((blockSize < 2) ||
(p2Len % blockSize) == 0);
- memmove(wrBuf->buf + ivLen + p1Len, pIn + p1Len, oddLen);
+ memmove(SSL_BUFFER_NEXT(wrBuf) + p1Len, pIn + p1Len, oddLen);
}
if (p1Len > 0) {
int cipherBytesPart1 = -1;
rv = cwSpec->cipher(cwSpec->cipherContext,
- wrBuf->buf + ivLen, /* output */
- &cipherBytesPart1, /* actual outlen */
- p1Len, /* max outlen */
+ SSL_BUFFER_NEXT(wrBuf), /* output */
+ &cipherBytesPart1, /* actual outlen */
+ p1Len, /* max outlen */
pIn,
p1Len); /* input, and inputlen */
PORT_Assert(rv == SECSuccess && cipherBytesPart1 == (int)p1Len);
@@ -2127,22 +2136,24 @@ ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec,
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
return SECFailure;
}
- wrBuf->len += cipherBytesPart1;
+ rv = sslBuffer_Skip(wrBuf, p1Len, NULL);
+ PORT_Assert(rv == SECSuccess);
}
if (p2Len > 0) {
int cipherBytesPart2 = -1;
rv = cwSpec->cipher(cwSpec->cipherContext,
- wrBuf->buf + ivLen + p1Len,
+ SSL_BUFFER_NEXT(wrBuf),
&cipherBytesPart2, /* output and actual outLen */
p2Len, /* max outlen */
- wrBuf->buf + ivLen + p1Len,
+ SSL_BUFFER_NEXT(wrBuf),
p2Len); /* input and inputLen*/
PORT_Assert(rv == SECSuccess && cipherBytesPart2 == (int)p2Len);
if (rv != SECSuccess || cipherBytesPart2 != (int)p2Len) {
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
return SECFailure;
}
- wrBuf->len += cipherBytesPart2;
+ rv = sslBuffer_Skip(wrBuf, p2Len, NULL);
+ PORT_Assert(rv == SECSuccess);
}
}
@@ -2150,16 +2161,20 @@ ssl3_MACEncryptRecord(ssl3CipherSpec *cwSpec,
}
/* Note: though this can report failure, it shouldn't. */
-static SECStatus
+SECStatus
ssl_InsertRecordHeader(const sslSocket *ss, ssl3CipherSpec *cwSpec,
- SSL3ContentType contentType, unsigned int len,
- sslBuffer *wrBuf)
+ SSL3ContentType contentType, sslBuffer *wrBuf,
+ PRBool *needsLength)
{
SECStatus rv;
#ifndef UNSAFE_FUZZER_MODE
if (cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
- cwSpec->cipherDef->calg != ssl_calg_null) {
+ cwSpec->epoch > TrafficKeyClearText) {
+ if (IS_DTLS(ss)) {
+ return dtls13_InsertCipherTextHeader(ss, cwSpec, wrBuf,
+ needsLength);
+ }
contentType = content_application_data;
}
#endif
@@ -2177,16 +2192,12 @@ ssl_InsertRecordHeader(const sslSocket *ss, ssl3CipherSpec *cwSpec,
if (rv != SECSuccess) {
return SECFailure;
}
- rv = sslBuffer_AppendNumber(wrBuf, cwSpec->seqNum, 6);
+ rv = sslBuffer_AppendNumber(wrBuf, cwSpec->nextSeqNum, 6);
if (rv != SECSuccess) {
return SECFailure;
}
}
- rv = sslBuffer_AppendNumber(wrBuf, len, 2);
- if (rv != SECSuccess) {
- return SECFailure;
- }
-
+ *needsLength = PR_TRUE;
return SECSuccess;
}
@@ -2194,66 +2205,67 @@ SECStatus
ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, SSL3ContentType type,
const PRUint8 *pIn, PRUint32 contentLen, sslBuffer *wrBuf)
{
- unsigned int headerLen = IS_DTLS(ss) ? DTLS_RECORD_HEADER_LENGTH
- : SSL3_RECORD_HEADER_LENGTH;
- sslBuffer protBuf = SSL_BUFFER_FIXED(SSL_BUFFER_BASE(wrBuf) + headerLen,
- SSL_BUFFER_SPACE(wrBuf) - headerLen);
- PRBool isTLS13;
+ PRBool needsLength;
+ unsigned int lenOffset;
SECStatus rv;
PORT_Assert(cwSpec->direction == CipherSpecWrite);
PORT_Assert(SSL_BUFFER_LEN(wrBuf) == 0);
PORT_Assert(cwSpec->cipherDef->max_records <= RECORD_SEQ_MAX);
- if (cwSpec->seqNum >= cwSpec->cipherDef->max_records) {
+
+ if (cwSpec->nextSeqNum >= cwSpec->cipherDef->max_records) {
/* We should have automatically updated before here in TLS 1.3. */
PORT_Assert(cwSpec->version < SSL_LIBRARY_VERSION_TLS_1_3);
SSL_TRC(3, ("%d: SSL[-]: write sequence number at limit 0x%0llx",
- SSL_GETPID(), cwSpec->seqNum));
+ SSL_GETPID(), cwSpec->nextSeqNum));
PORT_SetError(SSL_ERROR_TOO_MANY_RECORDS);
return SECFailure;
}
- isTLS13 = (PRBool)(cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_3);
+ rv = ssl_InsertRecordHeader(ss, cwSpec, type, wrBuf, &needsLength);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ if (needsLength) {
+ rv = sslBuffer_Skip(wrBuf, 2, &lenOffset);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ }
#ifdef UNSAFE_FUZZER_MODE
{
int len;
- rv = Null_Cipher(NULL, SSL_BUFFER_BASE(&protBuf), &len,
- SSL_BUFFER_SPACE(&protBuf), pIn, contentLen);
+ rv = Null_Cipher(NULL, SSL_BUFFER_NEXT(wrBuf), &len,
+ SSL_BUFFER_SPACE(wrBuf), pIn, contentLen);
if (rv != SECSuccess) {
return SECFailure; /* error was set */
}
- rv = sslBuffer_Skip(&protBuf, len, NULL);
+ rv = sslBuffer_Skip(wrBuf, len, NULL);
PORT_Assert(rv == SECSuccess); /* Can't fail. */
}
#else
- if (isTLS13) {
- rv = tls13_ProtectRecord(ss, cwSpec, type, pIn, contentLen, &protBuf);
+ if (cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ rv = tls13_ProtectRecord(ss, cwSpec, type, pIn, contentLen, wrBuf);
} else {
rv = ssl3_MACEncryptRecord(cwSpec, ss->sec.isServer, IS_DTLS(ss), type,
- pIn, contentLen, &protBuf);
+ pIn, contentLen, wrBuf);
}
#endif
if (rv != SECSuccess) {
return SECFailure; /* error was set */
}
- PORT_Assert(protBuf.len <= MAX_FRAGMENT_LENGTH + (isTLS13 ? 256 : 1024));
-
- rv = ssl_InsertRecordHeader(ss, cwSpec, type, SSL_BUFFER_LEN(&protBuf),
- wrBuf);
- if (rv != SECSuccess) {
- return SECFailure;
- }
-
- PORT_Assert(SSL_BUFFER_LEN(wrBuf) == headerLen);
- rv = sslBuffer_Skip(wrBuf, SSL_BUFFER_LEN(&protBuf), NULL);
- if (rv != SECSuccess) {
- PORT_Assert(0); /* Can't fail. */
- return SECFailure;
+ if (needsLength) {
+ /* Insert the length. */
+ rv = sslBuffer_InsertLength(wrBuf, lenOffset, 2);
+ if (rv != SECSuccess) {
+ PORT_Assert(0); /* Can't fail. */
+ return SECFailure;
+ }
}
- ++cwSpec->seqNum;
+ ++cwSpec->nextSeqNum;
return SECSuccess;
}
@@ -2267,7 +2279,7 @@ ssl_ProtectNextRecord(sslSocket *ss, ssl3CipherSpec *spec, SSL3ContentType type,
unsigned int spaceNeeded;
SECStatus rv;
- contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH);
+ contentLen = PR_MIN(nIn, spec->recordSizeLimit);
spaceNeeded = contentLen + SSL3_BUFFER_FUDGE;
if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_1 &&
spec->cipherDef->type == type_block) {
@@ -2291,6 +2303,7 @@ ssl_ProtectNextRecord(sslSocket *ss, ssl3CipherSpec *spec, SSL3ContentType type,
*written = contentLen;
return SECSuccess;
}
+
/* Process the plain text before sending it.
* Returns the number of bytes of plaintext that were successfully sent
* plus the number of bytes of plaintext that were copied into the
@@ -2368,7 +2381,7 @@ ssl3_SendRecord(sslSocket *ss,
rv = ssl_ProtectNextRecord(ss, spec, type, pIn, nIn, &written);
ssl_ReleaseSpecReadLock(ss);
if (rv != SECSuccess) {
- return SECFailure;
+ goto loser;
}
PORT_Assert(written > 0);
@@ -3034,7 +3047,6 @@ ssl3_SendChangeCipherSpecsInt(sslSocket *ss)
return SECFailure; /* error code set by ssl3_SendRecord */
}
} else {
- SECStatus rv;
rv = dtls_QueueMessage(ss, content_change_cipher_spec, &change, 1);
if (rv != SECSuccess) {
return SECFailure;
@@ -5567,13 +5579,20 @@ ssl3_SendRSAClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey)
}
/* Get the wrapped (encrypted) pre-master secret, enc_pms */
- enc_pms.len = SECKEY_PublicKeyStrength(svrPubKey);
+ unsigned int svrPubKeyBits = SECKEY_PublicKeyStrengthInBits(svrPubKey);
+ enc_pms.len = (svrPubKeyBits + 7) / 8;
+ /* Check that the RSA key isn't larger than 8k bit. */
+ if (svrPubKeyBits > SSL_MAX_RSA_KEY_BITS) {
+ (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
+ ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
+ goto loser;
+ }
enc_pms.data = (unsigned char *)PORT_Alloc(enc_pms.len);
if (enc_pms.data == NULL) {
goto loser; /* err set by PORT_Alloc */
}
- /* wrap pre-master secret in server's public key. */
+ /* Wrap pre-master secret in server's public key. */
rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, svrPubKey, pms, &enc_pms);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
@@ -5676,7 +5695,7 @@ ssl3_SendDHClientKeyExchange(sslSocket *ss, SECKEYPublicKey *svrPubKey)
};
sslEphemeralKeyPair *keyPair = NULL;
SECKEYPublicKey *pubKey;
- PRUint8 dhData[1026]; /* Enough for the 8192-bit group. */
+ PRUint8 dhData[SSL_MAX_DH_KEY_BITS / 8 + 2];
sslBuffer dhBuf = SSL_BUFFER(dhData);
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
@@ -6208,7 +6227,6 @@ ssl3_HandleServerHello(sslSocket *ss, PRUint8 *b, PRUint32 length)
SECItem sidBytes = { siBuffer, NULL, 0 };
PRBool isHelloRetry;
SSL3AlertDescription desc = illegal_parameter;
- TLSExtension *versionExtension;
const PRUint8 *savedMsg = b;
const PRUint32 savedLength = length;
#ifndef TLS_1_3_DRAFT_VERSION
@@ -6299,16 +6317,10 @@ ssl3_HandleServerHello(sslSocket *ss, PRUint8 *b, PRUint32 length)
}
}
- /* Update the version based on the extension, as necessary. */
- versionExtension = ssl3_FindExtension(ss, ssl_tls13_supported_versions_xtn);
- if (versionExtension) {
- rv = ssl_ClientReadVersion(ss, &versionExtension->data.data,
- &versionExtension->data.len,
- &ss->version);
- if (rv != SECSuccess) {
- errCode = PORT_GetError();
- goto loser; /* An alert is sent by ssl_ClientReadVersion */
- }
+ /* Read supported_versions if present. */
+ rv = tls13_ClientReadSupportedVersion(ss);
+ if (rv != SECSuccess) {
+ goto loser;
}
PORT_Assert(!SSL_ALL_VERSIONS_DISABLED(&ss->vrange));
@@ -6332,7 +6344,7 @@ ssl3_HandleServerHello(sslSocket *ss, PRUint8 *b, PRUint32 length)
/* The server didn't pick 1.3 although we either received a
* HelloRetryRequest, or we prepared to send early app data. */
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
- if (ss->ssl3.hs.helloRetry) {
+ if (isHelloRetry || ss->ssl3.hs.helloRetry) {
/* SSL3_SendAlert() will uncache the SID. */
desc = illegal_parameter;
errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
@@ -6393,8 +6405,9 @@ ssl3_HandleServerHello(sslSocket *ss, PRUint8 *b, PRUint32 length)
/* Finally, now all the version-related checks have passed. */
ss->ssl3.hs.preliminaryInfo |= ssl_preinfo_version;
/* Update the write cipher spec to match the version. But not after
- * HelloRetryRequest, because cwSpec might be a 0-RTT cipher spec. */
- if (!ss->firstHsDone && !ss->ssl3.hs.helloRetry) {
+ * HelloRetryRequest, because cwSpec might be a 0-RTT cipher spec,
+ * in which case this is a no-op. */
+ if (!ss->firstHsDone && !isHelloRetry) {
ssl_GetSpecWriteLock(ss);
ssl_SetSpecVersions(ss, ss->ssl3.cwSpec);
ssl_ReleaseSpecWriteLock(ss);
@@ -6729,6 +6742,10 @@ ssl_HandleDHServerKeyExchange(sslSocket *ss, PRUint8 *b, PRUint32 length)
errCode = SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY;
goto alert_loser;
}
+ if (dh_p_bits > SSL_MAX_DH_KEY_BITS) {
+ errCode = SSL_ERROR_DH_KEY_TOO_LONG;
+ goto alert_loser;
+ }
rv = ssl3_ConsumeHandshakeVariable(ss, &dh_g, 2, &b, &length);
if (rv != SECSuccess) {
goto loser; /* malformed. */
@@ -6938,8 +6955,10 @@ ssl3_ParseCertificateRequestCAs(sslSocket *ss, PRUint8 **b, PRUint32 *length,
goto alert_loser; /* malformed */
remaining -= 2;
+ if (SECITEM_MakeItem(ca_list->arena, &node->name, *b, len) != SECSuccess) {
+ goto no_mem;
+ }
node->name.len = len;
- node->name.data = *b;
*b += len;
*length -= len;
remaining -= len;
@@ -6967,7 +6986,6 @@ ssl3_ParseCertificateRequestCAs(sslSocket *ss, PRUint8 **b, PRUint32 *length,
return SECSuccess;
no_mem:
- PORT_SetError(SEC_ERROR_NO_MEMORY);
return SECFailure;
alert_loser:
@@ -7332,10 +7350,6 @@ ssl3_SendClientSecondRound(sslSocket *ss)
* certificate to an attacker that does not have a valid cert for the
* domain we are connecting to.
*
- * XXX: We should do the same for the NPN extension, but for that we
- * need an option to give the application the ability to leak the NPN
- * information to get better performance.
- *
* During the initial handshake on a connection, we never send/receive
* application data until we have authenticated the server's certificate;
* i.e. we have fully authenticated the handshake before using the cipher
@@ -7409,14 +7423,6 @@ ssl3_SendClientSecondRound(sslSocket *ss)
ss->enoughFirstHsDone = PR_TRUE;
if (!ss->firstHsDone) {
- /* XXX: If the server's certificate hasn't been authenticated by this
- * point, then we may be leaking this NPN message to an attacker.
- */
- rv = ssl3_SendNextProto(ss);
- if (rv != SECSuccess) {
- goto loser; /* err code was set. */
- }
-
if (ss->opt.enableFalseStart) {
if (!ss->ssl3.hs.authCertificatePending) {
/* When we fix bug 589047, we will need to know whether we are
@@ -8879,12 +8885,10 @@ ssl_ConstructServerHello(sslSocket *ss, PRBool helloRetry,
SSL3ProtocolVersion version;
sslSessionID *sid = ss->sec.ci.sid;
- if (IS_DTLS(ss) && ss->version < SSL_LIBRARY_VERSION_TLS_1_3) {
- version = dtls_TLSVersionToDTLSVersion(ss->version);
- } else {
- version = PR_MIN(ss->version, SSL_LIBRARY_VERSION_TLS_1_2);
+ version = PR_MIN(ss->version, SSL_LIBRARY_VERSION_TLS_1_2);
+ if (IS_DTLS(ss)) {
+ version = dtls_TLSVersionToDTLSVersion(version);
}
-
rv = sslBuffer_AppendNumber(messageBuf, version, 2);
if (rv != SECSuccess) {
return SECFailure;
@@ -11404,6 +11408,10 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, PRUint8 *b, PRUint32 length,
/* Increment the expected sequence number */
ss->ssl3.hs.recvMessageSeq++;
}
+
+ /* Taint the message so that it's easier to detect UAFs. */
+ PORT_Memset(b, 'N', length);
+
return rv;
}
@@ -11738,7 +11746,7 @@ ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, unsigned int macSize)
}
for (i = 0; i < toCheck; i++) {
- unsigned int t = paddingLength - i;
+ t = paddingLength - i;
/* If i <= paddingLength then the MSB of t is zero and mask is
* 0xff. Otherwise, mask is 0. */
unsigned char mask = DUPLICATE_MSB_TO_ALL(~t);
@@ -11878,6 +11886,7 @@ ssl3_UnprotectRecord(sslSocket *ss,
unsigned int good;
unsigned int ivLen = 0;
SSL3ContentType rType;
+ SSL3ProtocolVersion rVersion;
unsigned int minLength;
unsigned int originalLen = 0;
PRUint8 headerBuf[13];
@@ -11950,7 +11959,9 @@ ssl3_UnprotectRecord(sslSocket *ss,
return SECFailure;
}
- rType = cText->type;
+ rType = (SSL3ContentType)cText->hdr[0];
+ rVersion = ((SSL3ProtocolVersion)cText->hdr[1] << 8) |
+ (SSL3ProtocolVersion)cText->hdr[2];
if (cipher_def->type == type_aead) {
/* XXX For many AEAD ciphers, the plaintext is shorter than the
* ciphertext by a fixed byte count, but it is not true in general.
@@ -11960,8 +11971,8 @@ ssl3_UnprotectRecord(sslSocket *ss,
cText->buf->len - cipher_def->explicit_nonce_size -
cipher_def->tag_size;
rv = ssl3_BuildRecordPseudoHeader(
- spec->epoch, IS_DTLS(ss) ? cText->seq_num : spec->seqNum,
- rType, isTLS, cText->version, IS_DTLS(ss), decryptedLen, &header);
+ spec->epoch, cText->seqNum,
+ rType, isTLS, rVersion, IS_DTLS(ss), decryptedLen, &header);
PORT_Assert(rv == SECSuccess);
rv = spec->aead(&spec->keyMaterial,
PR_TRUE, /* do decrypt */
@@ -12008,8 +12019,8 @@ ssl3_UnprotectRecord(sslSocket *ss,
/* compute the MAC */
rv = ssl3_BuildRecordPseudoHeader(
- spec->epoch, IS_DTLS(ss) ? cText->seq_num : spec->seqNum,
- rType, isTLS, cText->version, IS_DTLS(ss),
+ spec->epoch, cText->seqNum,
+ rType, isTLS, rVersion, IS_DTLS(ss),
plaintext->len - spec->macDef->mac_size, &header);
PORT_Assert(rv == SECSuccess);
if (cipher_def->type == type_block) {
@@ -12059,13 +12070,19 @@ ssl3_UnprotectRecord(sslSocket *ss,
return SECSuccess;
}
-static SECStatus
+SECStatus
ssl3_HandleNonApplicationData(sslSocket *ss, SSL3ContentType rType,
DTLSEpoch epoch, sslSequenceNumber seqNum,
sslBuffer *databuf)
{
SECStatus rv;
+ /* check for Token Presence */
+ if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {
+ PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
+ return SECFailure;
+ }
+
ssl_GetSSL3HandshakeLock(ss);
/* All the functions called in this switch MUST set error code if
@@ -12111,15 +12128,16 @@ ssl3_HandleNonApplicationData(sslSocket *ss, SSL3ContentType rType,
* Returns NULL if no appropriate cipher spec is found.
*/
static ssl3CipherSpec *
-ssl3_GetCipherSpec(sslSocket *ss, sslSequenceNumber seq)
+ssl3_GetCipherSpec(sslSocket *ss, SSL3Ciphertext *cText)
{
ssl3CipherSpec *crSpec = ss->ssl3.crSpec;
ssl3CipherSpec *newSpec = NULL;
- DTLSEpoch epoch = seq >> 48;
+ DTLSEpoch epoch;
if (!IS_DTLS(ss)) {
return crSpec;
}
+ epoch = dtls_ReadEpoch(crSpec, cText->hdr);
if (crSpec->epoch == epoch) {
return crSpec;
}
@@ -12136,6 +12154,11 @@ ssl3_GetCipherSpec(sslSocket *ss, sslSequenceNumber seq)
return NULL;
}
+/* MAX_EXPANSION is the amount by which a record might plausibly be expanded
+ * when protected. It's the worst case estimate, so the sum of block cipher
+ * padding (up to 256 octets) and HMAC (48 octets for SHA-384). */
+#define MAX_EXPANSION (256 + 48)
+
/* if cText is non-null, then decipher and check the MAC of the
* SSL record from cText->buf (typically gs->inbuf)
* into databuf (typically gs->buf), and any previous contents of databuf
@@ -12159,16 +12182,16 @@ ssl3_GetCipherSpec(sslSocket *ss, sslSequenceNumber seq)
* Application Data records.
*/
SECStatus
-ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
+ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText)
{
SECStatus rv;
PRBool isTLS;
DTLSEpoch epoch;
- sslSequenceNumber seqNum = 0;
ssl3CipherSpec *spec = NULL;
+ PRUint16 recordSizeLimit;
PRBool outOfOrderSpec = PR_FALSE;
SSL3ContentType rType;
- sslBuffer *plaintext;
+ sslBuffer *plaintext = &ss->gs.buf;
SSL3AlertDescription alert = internal_error;
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
@@ -12178,27 +12201,23 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
return SECFailure;
}
- /* cText is NULL when we're called from ssl3_RestartHandshakeAfterXXX().
- * This implies that databuf holds a previously deciphered SSL Handshake
- * message.
- */
- if (cText == NULL) {
- SSL_DBG(("%d: SSL3[%d]: HandleRecord, resuming handshake",
- SSL_GETPID(), ss->fd));
- /* Note that this doesn't pass the epoch and sequence number of the
- * record through, which DTLS 1.3 depends on. DTLS doesn't support
- * asynchronous certificate validation, so that should be OK. */
- PORT_Assert(!IS_DTLS(ss));
- return ssl3_HandleNonApplicationData(ss, content_handshake,
- 0, 0, databuf);
+ /* Clear out the buffer in case this exits early. Any data then won't be
+ * processed twice. */
+ plaintext->len = 0;
+
+ /* We're waiting for another ClientHello, which will appear unencrypted.
+ * Use the content type to tell whether this should be discarded. */
+ if (ss->ssl3.hs.zeroRttIgnore == ssl_0rtt_ignore_hrr &&
+ cText->hdr[0] == content_application_data) {
+ PORT_Assert(ss->ssl3.hs.ws == wait_client_hello);
+ return SECSuccess;
}
ssl_GetSpecReadLock(ss); /******************************************/
- spec = ssl3_GetCipherSpec(ss, cText->seq_num);
+ spec = ssl3_GetCipherSpec(ss, cText);
if (!spec) {
PORT_Assert(IS_DTLS(ss));
ssl_ReleaseSpecReadLock(ss); /*****************************/
- databuf->len = 0; /* Needed to ensure data not left around */
return SECSuccess;
}
if (spec != ss->ssl3.crSpec) {
@@ -12209,66 +12228,68 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
}
isTLS = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0);
if (IS_DTLS(ss)) {
- if (!dtls_IsRelevant(ss, spec, cText, &seqNum)) {
+ if (!dtls_IsRelevant(ss, spec, cText, &cText->seqNum)) {
ssl_ReleaseSpecReadLock(ss); /*****************************/
- databuf->len = 0; /* Needed to ensure data not left around */
-
return SECSuccess;
}
} else {
- seqNum = spec->seqNum + 1;
+ cText->seqNum = spec->nextSeqNum;
}
- if (seqNum >= spec->cipherDef->max_records) {
+ if (cText->seqNum >= spec->cipherDef->max_records) {
ssl_ReleaseSpecReadLock(ss); /*****************************/
SSL_TRC(3, ("%d: SSL[%d]: read sequence number at limit 0x%0llx",
- SSL_GETPID(), ss->fd, seqNum));
+ SSL_GETPID(), ss->fd, cText->seqNum));
PORT_SetError(SSL_ERROR_TOO_MANY_RECORDS);
return SECFailure;
}
- plaintext = databuf;
- plaintext->len = 0; /* filled in by Unprotect call below. */
-
- /* We're waiting for another ClientHello, which will appear unencrypted.
- * Use the content type to tell whether this is should be discarded.
- *
- * XXX If we decide to remove the content type from encrypted records, this
- * will become much more difficult to manage. */
- if (ss->ssl3.hs.zeroRttIgnore == ssl_0rtt_ignore_hrr &&
- cText->type == content_application_data) {
+ recordSizeLimit = spec->recordSizeLimit;
+ if (cText->buf->len > recordSizeLimit + MAX_EXPANSION) {
ssl_ReleaseSpecReadLock(ss); /*****************************/
- PORT_Assert(ss->ssl3.hs.ws == wait_client_hello);
- databuf->len = 0;
- return SECSuccess;
+ SSL3_SendAlert(ss, alert_fatal, record_overflow);
+ PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
+ return SECFailure;
}
- if (plaintext->space < MAX_FRAGMENT_LENGTH) {
- rv = sslBuffer_Grow(plaintext, MAX_FRAGMENT_LENGTH + 2048);
+ if (plaintext->space < recordSizeLimit + MAX_EXPANSION) {
+ rv = sslBuffer_Grow(plaintext, recordSizeLimit + MAX_EXPANSION);
if (rv != SECSuccess) {
ssl_ReleaseSpecReadLock(ss); /*************************/
SSL_DBG(("%d: SSL3[%d]: HandleRecord, tried to get %d bytes",
- SSL_GETPID(), ss->fd, MAX_FRAGMENT_LENGTH + 2048));
+ SSL_GETPID(), ss->fd, recordSizeLimit + MAX_EXPANSION));
/* sslBuffer_Grow has set a memory error code. */
/* Perhaps we should send an alert. (but we have no memory!) */
return SECFailure;
}
}
+ /* Most record types aside from protected TLS 1.3 records carry the content
+ * type in the first octet. TLS 1.3 will override this value later. */
+ rType = cText->hdr[0];
+ /* Encrypted application data records could arrive before the handshake
+ * completes in DTLS 1.3. These can look like valid TLS 1.2 application_data
+ * records in epoch 0, which is never valid. Pretend they didn't decrypt. */
+ if (spec->epoch == 0 && rType == content_application_data) {
+ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA);
+ alert = unexpected_message;
+ rv = SECFailure;
+ } else {
#ifdef UNSAFE_FUZZER_MODE
- rv = Null_Cipher(NULL, plaintext->buf, (int *)&plaintext->len,
- plaintext->space, cText->buf->buf, cText->buf->len);
+ rv = Null_Cipher(NULL, plaintext->buf, (int *)&plaintext->len,
+ plaintext->space, cText->buf->buf, cText->buf->len);
#else
- /* IMPORTANT: Unprotect functions MUST NOT send alerts
- * because we still hold the spec read lock. Instead, if they
- * return SECFailure, they set *alert to the alert to be sent. */
- if (spec->version < SSL_LIBRARY_VERSION_TLS_1_3 ||
- spec->cipherDef->calg == ssl_calg_null) {
- /* Unencrypted TLS 1.3 records use the pre-TLS 1.3 format. */
- rv = ssl3_UnprotectRecord(ss, spec, cText, plaintext, &alert);
- } else {
- rv = tls13_UnprotectRecord(ss, spec, cText, plaintext, &alert);
- }
+ /* IMPORTANT: Unprotect functions MUST NOT send alerts
+ * because we still hold the spec read lock. Instead, if they
+ * return SECFailure, they set *alert to the alert to be sent. */
+ if (spec->version < SSL_LIBRARY_VERSION_TLS_1_3 ||
+ spec->epoch == 0) {
+ rv = ssl3_UnprotectRecord(ss, spec, cText, plaintext, &alert);
+ } else {
+ rv = tls13_UnprotectRecord(ss, spec, cText, plaintext, &rType,
+ &alert);
+ }
#endif
+ }
if (rv != SECSuccess) {
ssl_ReleaseSpecReadLock(ss); /***************************/
@@ -12276,39 +12297,45 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
SSL_DBG(("%d: SSL3[%d]: decryption failed", SSL_GETPID(), ss->fd));
/* Ensure that we don't process this data again. */
- databuf->len = 0;
+ plaintext->len = 0;
- /* Ignore a CCS if the alternative handshake is negotiated. Note that
- * this will fail if the server fails to negotiate the alternative
- * handshake type in a 0-RTT session that is resumed from a session that
- * did negotiate it. We don't care about that corner case right now. */
+ /* Ignore a CCS if compatibility mode is negotiated. Note that this
+ * will fail if the server fails to negotiate compatibility mode in a
+ * 0-RTT session that is resumed from a session that did negotiate it.
+ * We don't care about that corner case right now. */
if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
- cText->type == content_change_cipher_spec &&
+ cText->hdr[0] == content_change_cipher_spec &&
ss->ssl3.hs.ws != idle_handshake &&
cText->buf->len == 1 &&
cText->buf->buf[0] == change_cipher_spec_choice) {
/* Ignore the CCS. */
return SECSuccess;
}
+
if (IS_DTLS(ss) ||
(ss->sec.isServer &&
ss->ssl3.hs.zeroRttIgnore == ssl_0rtt_ignore_trial)) {
- /* Silently drop the packet */
+ /* Silently drop the packet unless we sent a fatal alert. */
+ if (ss->ssl3.fatalAlertSent) {
+ return SECFailure;
+ }
return SECSuccess;
- } else {
- int errCode = PORT_GetError();
- SSL3_SendAlert(ss, alert_fatal, alert);
- /* Reset the error code in case SSL3_SendAlert called
- * PORT_SetError(). */
- PORT_SetError(errCode);
- return SECFailure;
}
+
+ int errCode = PORT_GetError();
+ SSL3_SendAlert(ss, alert_fatal, alert);
+ /* Reset the error code in case SSL3_SendAlert called
+ * PORT_SetError(). */
+ PORT_SetError(errCode);
+ return SECFailure;
}
/* SECSuccess */
- spec->seqNum = PR_MAX(spec->seqNum, seqNum);
if (IS_DTLS(ss)) {
- dtls_RecordSetRecvd(&spec->recvdRecords, seqNum);
+ dtls_RecordSetRecvd(&spec->recvdRecords, cText->seqNum);
+ spec->nextSeqNum = PR_MAX(spec->nextSeqNum, cText->seqNum + 1);
+ } else {
+ ++spec->nextSeqNum;
}
epoch = spec->epoch;
@@ -12317,19 +12344,18 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
/*
* The decrypted data is now in plaintext.
*/
- rType = cText->type; /* This must go after decryption because TLS 1.3
- * has encrypted content types. */
/* IMPORTANT: We are in DTLS 1.3 mode and we have processed something
* from the wrong epoch. Divert to a divert processing function to make
* sure we don't accidentally use the data unsafely. */
if (outOfOrderSpec) {
PORT_Assert(IS_DTLS(ss) && ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
- return dtls13_HandleOutOfEpochRecord(ss, spec, rType, databuf);
+ return dtls13_HandleOutOfEpochRecord(ss, spec, rType, plaintext);
}
/* Check the length of the plaintext. */
- if (isTLS && databuf->len > MAX_FRAGMENT_LENGTH) {
+ if (isTLS && plaintext->len > recordSizeLimit) {
+ plaintext->len = 0;
SSL3_SendAlert(ss, alert_fatal, record_overflow);
PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
return SECFailure;
@@ -12344,14 +12370,16 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
ss->sec.isServer &&
ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
- return tls13_HandleEarlyApplicationData(ss, databuf);
+ return tls13_HandleEarlyApplicationData(ss, plaintext);
}
+ plaintext->len = 0;
(void)SSL3_SendAlert(ss, alert_fatal, unexpected_message);
PORT_SetError(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA);
return SECFailure;
}
- return ssl3_HandleNonApplicationData(ss, rType, epoch, seqNum, databuf);
+ return ssl3_HandleNonApplicationData(ss, rType, epoch, cText->seqNum,
+ plaintext);
}
/*
diff --git a/security/nss/lib/ssl/ssl3ecc.c b/security/nss/lib/ssl/ssl3ecc.c
index 913a14f637..f8b9a94000 100644
--- a/security/nss/lib/ssl/ssl3ecc.c
+++ b/security/nss/lib/ssl/ssl3ecc.c
@@ -548,12 +548,14 @@ ssl3_HandleECDHServerKeyExchange(sslSocket *ss, PRUint8 *b, PRUint32 length)
if (ss->ssl3.prSpec->version == SSL_LIBRARY_VERSION_TLS_1_2) {
rv = ssl_ConsumeSignatureScheme(ss, &b, &length, &sigScheme);
if (rv != SECSuccess) {
- goto loser; /* malformed or unsupported. */
+ errCode = PORT_GetError();
+ goto alert_loser; /* malformed or unsupported. */
}
rv = ssl_CheckSignatureSchemeConsistency(ss, sigScheme,
ss->sec.peerCert);
if (rv != SECSuccess) {
- goto loser;
+ errCode = PORT_GetError();
+ goto alert_loser;
}
hashAlg = ssl_SignatureSchemeToHashType(sigScheme);
} else {
diff --git a/security/nss/lib/ssl/ssl3ext.c b/security/nss/lib/ssl/ssl3ext.c
index 5a50779989..9b6c719f88 100644
--- a/security/nss/lib/ssl/ssl3ext.c
+++ b/security/nss/lib/ssl/ssl3ext.c
@@ -39,7 +39,6 @@ static const ssl3ExtensionHandler clientHelloHandlers[] = {
{ ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn },
{ ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
- { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
{ ssl_app_layer_protocol_xtn, &ssl3_ServerHandleAppProtoXtn },
{ ssl_use_srtp_xtn, &ssl3_ServerHandleUseSRTPXtn },
{ ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn },
@@ -51,6 +50,7 @@ static const ssl3ExtensionHandler clientHelloHandlers[] = {
{ ssl_tls13_early_data_xtn, &tls13_ServerHandleEarlyDataXtn },
{ ssl_tls13_psk_key_exchange_modes_xtn, &tls13_ServerHandlePskModesXtn },
{ ssl_tls13_cookie_xtn, &tls13_ServerHandleCookieXtn },
+ { ssl_record_size_limit_xtn, &ssl_HandleRecordSizeLimitXtn },
{ 0, NULL }
};
@@ -61,7 +61,6 @@ static const ssl3ExtensionHandler serverHelloHandlersTLS[] = {
/* TODO: add a handler for ssl_ec_point_formats_xtn */
{ ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
- { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
{ ssl_app_layer_protocol_xtn, &ssl3_ClientHandleAppProtoXtn },
{ ssl_use_srtp_xtn, &ssl3_ClientHandleUseSRTPXtn },
{ ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn },
@@ -70,6 +69,7 @@ static const ssl3ExtensionHandler serverHelloHandlersTLS[] = {
{ ssl_tls13_key_share_xtn, &tls13_ClientHandleKeyShareXtn },
{ ssl_tls13_pre_shared_key_xtn, &tls13_ClientHandlePreSharedKeyXtn },
{ ssl_tls13_early_data_xtn, &tls13_ClientHandleEarlyDataXtn },
+ { ssl_record_size_limit_xtn, &ssl_HandleRecordSizeLimitXtn },
{ 0, NULL }
};
@@ -122,7 +122,6 @@ static const sslExtensionBuilder clientHelloSendersTLS[] =
{ ssl_supported_groups_xtn, &ssl_SendSupportedGroupsXtn },
{ ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
{ ssl_session_ticket_xtn, &ssl3_ClientSendSessionTicketXtn },
- { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn },
{ ssl_app_layer_protocol_xtn, &ssl3_ClientSendAppProtoXtn },
{ ssl_use_srtp_xtn, &ssl3_ClientSendUseSRTPXtn },
{ ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn },
@@ -137,6 +136,7 @@ static const sslExtensionBuilder clientHelloSendersTLS[] =
{ ssl_signature_algorithms_xtn, &ssl3_SendSigAlgsXtn },
{ ssl_tls13_cookie_xtn, &tls13_ClientSendHrrCookieXtn },
{ ssl_tls13_psk_key_exchange_modes_xtn, &tls13_ClientSendPskModesXtn },
+ { ssl_record_size_limit_xtn, &ssl_SendRecordSizeLimitXtn },
/* The pre_shared_key extension MUST be last. */
{ ssl_tls13_pre_shared_key_xtn, &tls13_ClientSendPreSharedKeyXtn },
{ 0, NULL }
@@ -183,7 +183,6 @@ static const struct {
{ ssl_tls13_psk_key_exchange_modes_xtn, ssl_ext_native_only },
{ ssl_tls13_ticket_early_data_info_xtn, ssl_ext_native_only },
{ ssl_tls13_certificate_authorities_xtn, ssl_ext_native },
- { ssl_next_proto_nego_xtn, ssl_ext_none },
{ ssl_renegotiation_info_xtn, ssl_ext_native }
};
@@ -681,7 +680,11 @@ ssl_CallCustomExtensionSenders(sslSocket *ss, sslBuffer *buf,
}
}
- sslBuffer_Append(buf, tail.buf, tail.len);
+ rv = sslBuffer_Append(buf, tail.buf, tail.len);
+ if (rv != SECSuccess) {
+ goto loser; /* Code already set. */
+ }
+
sslBuffer_Clear(&tail);
return SECSuccess;
diff --git a/security/nss/lib/ssl/ssl3ext.h b/security/nss/lib/ssl/ssl3ext.h
index d0f75a599a..6d77c7459e 100644
--- a/security/nss/lib/ssl/ssl3ext.h
+++ b/security/nss/lib/ssl/ssl3ext.h
@@ -98,6 +98,9 @@ struct TLSExtensionDataStr {
/* The application token contains a value that was passed to the client via
* a session ticket, or the cookie in a HelloRetryRequest. */
SECItem applicationToken;
+
+ /* The record size limit set by the peer. Our value is kept in ss->opt. */
+ PRUint16 recordSizeLimit;
};
typedef struct TLSExtensionStr {
diff --git a/security/nss/lib/ssl/ssl3exthandle.c b/security/nss/lib/ssl/ssl3exthandle.c
index e6388945e1..d1f286dc3c 100644
--- a/security/nss/lib/ssl/ssl3exthandle.c
+++ b/security/nss/lib/ssl/ssl3exthandle.c
@@ -242,33 +242,11 @@ ssl_AlpnTagAllowed(const sslSocket *ss, const SECItem *tag)
return PR_FALSE;
}
-/* handle an incoming Next Protocol Negotiation extension. */
-SECStatus
-ssl3_ServerHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
- SECItem *data)
-{
- PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3);
-
- if (ss->firstHsDone || data->len != 0) {
- /* Clients MUST send an empty NPN extension, if any. */
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
- return SECFailure;
- }
-
- xtnData->negotiated[xtnData->numNegotiated++] = ssl_next_proto_nego_xtn;
-
- /* TODO: server side NPN support would require calling
- * ssl3_RegisterServerHelloExtensionSender here in order to echo the
- * extension back to the client. */
-
- return SECSuccess;
-}
-
-/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none
+/* ssl3_ValidateAppProtocol checks that the given block of data is valid: none
* of the lengths may be 0 and the sum of the lengths must equal the length of
* the block. */
SECStatus
-ssl3_ValidateNextProtoNego(const unsigned char *data, unsigned int length)
+ssl3_ValidateAppProtocol(const unsigned char *data, unsigned int length)
{
unsigned int offset = 0;
@@ -286,7 +264,7 @@ ssl3_ValidateNextProtoNego(const unsigned char *data, unsigned int length)
return SECSuccess;
}
-/* protocol selection handler for ALPN (server side) and NPN (client side) */
+/* Protocol selection handler for ALPN. */
static SECStatus
ssl3_SelectAppProtocol(const sslSocket *ss, TLSExtensionData *xtnData,
PRUint16 extension, SECItem *data)
@@ -295,7 +273,7 @@ ssl3_SelectAppProtocol(const sslSocket *ss, TLSExtensionData *xtnData,
unsigned char resultBuffer[255];
SECItem result = { siBuffer, resultBuffer, 0 };
- rv = ssl3_ValidateNextProtoNego(data->data, data->len);
+ rv = ssl3_ValidateAppProtocol(data->data, data->len);
if (rv != SECSuccess) {
ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
@@ -303,11 +281,13 @@ ssl3_SelectAppProtocol(const sslSocket *ss, TLSExtensionData *xtnData,
}
PORT_Assert(ss->nextProtoCallback);
- /* For ALPN, the cipher suite isn't selected yet. Note that extensions
+ /* The cipher suite isn't selected yet. Note that extensions
* sometimes affect what cipher suite is selected, e.g., for ECC. */
PORT_Assert((ss->ssl3.hs.preliminaryInfo &
ssl_preinfo_all & ~ssl_preinfo_cipher_suite) ==
(ssl_preinfo_all & ~ssl_preinfo_cipher_suite));
+ /* The callback has to make sure that either rv != SECSuccess or that result
+ * is not set if there is no common protocol. */
rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len,
result.data, &result.len, sizeof(resultBuffer));
if (rv != SECSuccess) {
@@ -320,21 +300,20 @@ ssl3_SelectAppProtocol(const sslSocket *ss, TLSExtensionData *xtnData,
* stack. */
if (result.len > sizeof(resultBuffer)) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- /* TODO: crash */
+ PORT_Assert(PR_FALSE);
return SECFailure;
}
SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE);
- if (extension == ssl_app_layer_protocol_xtn &&
- xtnData->nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) {
- /* The callback might say OK, but then it picks a default value - one
- * that was not listed. That's OK for NPN, but not ALPN. */
+ if (result.len < 1 || !result.data) {
+ /* Check that we actually got a result. */
ssl3_ExtSendAlert(ss, alert_fatal, no_application_protocol);
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL);
return SECFailure;
}
+ xtnData->nextProtoState = SSL_NEXT_PROTO_NEGOTIATED;
xtnData->negotiated[xtnData->numNegotiated++] = extension;
return SECITEM_CopyItem(NULL, &xtnData->nextProto, &result);
}
@@ -356,7 +335,7 @@ ssl3_ServerHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
return SECFailure;
}
- /* Unlike NPN, ALPN has extra redundant length information so that
+ /* ALPN has extra redundant length information so that
* the extension is the same in both ClientHello and ServerHello. */
rv = ssl3_ExtConsumeHandshakeNumber(ss, &count, 2, &data->data, &data->len);
if (rv != SECSuccess || count != data->len) {
@@ -389,39 +368,6 @@ ssl3_ServerHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
}
SECStatus
-ssl3_ClientHandleNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
- SECItem *data)
-{
- PORT_Assert(ss->version < SSL_LIBRARY_VERSION_TLS_1_3);
- PORT_Assert(!ss->firstHsDone);
-
- if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) {
- /* If the server negotiated ALPN then it has already told us what
- * protocol to use, so it doesn't make sense for us to try to negotiate
- * a different one by sending the NPN handshake message. However, if
- * we've negotiated NPN then we're required to send the NPN handshake
- * message. Thus, these two extensions cannot both be negotiated on the
- * same connection. */
- ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter);
- PORT_SetError(SSL_ERROR_BAD_SERVER);
- return SECFailure;
- }
-
- /* We should only get this call if we sent the extension, so
- * ss->nextProtoCallback needs to be non-NULL. However, it is possible
- * that an application erroneously cleared the callback between the time
- * we sent the ClientHello and now. */
- if (!ss->nextProtoCallback) {
- PORT_Assert(0);
- ssl3_ExtSendAlert(ss, alert_fatal, internal_error);
- PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK);
- return SECFailure;
- }
-
- return ssl3_SelectAppProtocol(ss, xtnData, ssl_next_proto_nego_xtn, data);
-}
-
-SECStatus
ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
SECItem *data)
{
@@ -475,19 +421,6 @@ ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
}
SECStatus
-ssl3_ClientSendNextProtoNegoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
- sslBuffer *buf, PRBool *added)
-{
- /* Renegotiations do not send this extension. */
- if (!ss->opt.enableNPN || !ss->nextProtoCallback || ss->firstHsDone) {
- return SECSuccess;
- }
-
- *added = PR_TRUE;
- return SECSuccess;
-}
-
-SECStatus
ssl3_ClientSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
sslBuffer *buf, PRBool *added)
{
@@ -499,35 +432,15 @@ ssl3_ClientSendAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
return SECSuccess;
}
- /* NPN requires that the client's fallback protocol is first in the
- * list. However, ALPN sends protocols in preference order. So move the
- * first protocol to the end of the list. */
-
if (len > 0) {
/* Each protocol string is prefixed with a single byte length. */
- unsigned int i;
-
rv = sslBuffer_AppendNumber(buf, len, 2);
if (rv != SECSuccess) {
return SECFailure;
}
-
- i = ss->opt.nextProtoNego.data[0] + 1;
- if (i <= len) {
- rv = sslBuffer_Append(buf, &ss->opt.nextProtoNego.data[i], len - i);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- rv = sslBuffer_Append(buf, ss->opt.nextProtoNego.data, i);
- if (rv != SECSuccess) {
- return SECFailure;
- }
- } else {
- /* This seems to be invalid data so we'll send as-is. */
- rv = sslBuffer_Append(buf, ss->opt.nextProtoNego.data, len);
- if (rv != SECSuccess) {
- return SECFailure;
- }
+ rv = sslBuffer_Append(buf, ss->opt.nextProtoNego.data, len);
+ if (rv != SECSuccess) {
+ return SECFailure;
}
}
@@ -1955,3 +1868,67 @@ ssl_HandleSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
return SECSuccess;
}
+
+SECStatus
+ssl_HandleRecordSizeLimitXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ SECItem *data)
+{
+ SECStatus rv;
+ PRUint32 limit;
+ PRUint32 maxLimit = (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3)
+ ? (MAX_FRAGMENT_LENGTH + 1)
+ : MAX_FRAGMENT_LENGTH;
+
+ rv = ssl3_ExtConsumeHandshakeNumber(ss, &limit, 2, &data->data, &data->len);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ if (data->len != 0 || limit < 64) {
+ ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
+ return SECFailure;
+ }
+
+ if (ss->sec.isServer) {
+ rv = ssl3_RegisterExtensionSender(ss, xtnData, ssl_record_size_limit_xtn,
+ &ssl_SendRecordSizeLimitXtn);
+ if (rv != SECSuccess) {
+ return SECFailure; /* error already set. */
+ }
+ } else if (limit > maxLimit) {
+ /* The client can sensibly check the maximum. */
+ ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_HANDSHAKE);
+ return SECFailure;
+ }
+
+ /* We can't enforce the maximum on a server. But we do need to ensure
+ * that we don't apply a limit that is too large. */
+ xtnData->recordSizeLimit = PR_MIN(maxLimit, limit);
+ xtnData->negotiated[xtnData->numNegotiated++] = ssl_record_size_limit_xtn;
+ return SECSuccess;
+}
+
+SECStatus
+ssl_SendRecordSizeLimitXtn(const sslSocket *ss, TLSExtensionData *xtnData,
+ sslBuffer *buf, PRBool *added)
+{
+ PRUint32 maxLimit;
+ if (ss->sec.isServer) {
+ maxLimit = (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3)
+ ? (MAX_FRAGMENT_LENGTH + 1)
+ : MAX_FRAGMENT_LENGTH;
+ } else {
+ maxLimit = (ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3)
+ ? (MAX_FRAGMENT_LENGTH + 1)
+ : MAX_FRAGMENT_LENGTH;
+ }
+ PRUint32 limit = PR_MIN(ss->opt.recordSizeLimit, maxLimit);
+ SECStatus rv = sslBuffer_AppendNumber(buf, limit, 2);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ *added = PR_TRUE;
+ return SECSuccess;
+}
diff --git a/security/nss/lib/ssl/ssl3exthandle.h b/security/nss/lib/ssl/ssl3exthandle.h
index b84bd074c0..eaf7f0081c 100644
--- a/security/nss/lib/ssl/ssl3exthandle.h
+++ b/security/nss/lib/ssl/ssl3exthandle.h
@@ -119,4 +119,11 @@ SECStatus ssl_SendSupportedGroupsXtn(const sslSocket *ss,
SECStatus ssl3_SendSupportedPointFormatsXtn(const sslSocket *ss,
TLSExtensionData *xtnData,
sslBuffer *buf, PRBool *added);
+SECStatus ssl_HandleRecordSizeLimitXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ SECItem *data);
+SECStatus ssl_SendRecordSizeLimitXtn(const sslSocket *ss,
+ TLSExtensionData *xtnData,
+ sslBuffer *buf, PRBool *added);
+
#endif
diff --git a/security/nss/lib/ssl/ssl3gthr.c b/security/nss/lib/ssl/ssl3gthr.c
index 8b323bb054..5ea7cc249e 100644
--- a/security/nss/lib/ssl/ssl3gthr.c
+++ b/security/nss/lib/ssl/ssl3gthr.c
@@ -158,6 +158,7 @@ ssl3_GatherData(sslSocket *ss, sslGather *gs, int flags, ssl2Gather *ssl2gs)
* the length of the following encrypted data, and then
* read in the rest of the record into gs->inbuf. */
gs->remainder = (gs->hdr[3] << 8) | gs->hdr[4];
+ gs->hdrLen = SSL3_RECORD_HEADER_LENGTH;
} else {
/* Probably an SSLv2 record header. No need to handle any
* security escapes (gs->hdr[0] & 0x40) as we wouldn't get
@@ -264,8 +265,9 @@ static int
dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
{
int nb;
- int err;
- int rv = 1;
+ PRUint8 contentType;
+ unsigned int headerLen;
+ SECStatus rv;
SSL_TRC(30, ("dtls_GatherData"));
@@ -285,81 +287,97 @@ dtls_GatherData(sslSocket *ss, sslGather *gs, int flags)
** to 13 (the size of the record header).
*/
if (gs->dtlsPacket.space < MAX_FRAGMENT_LENGTH + 2048 + 13) {
- err = sslBuffer_Grow(&gs->dtlsPacket,
- MAX_FRAGMENT_LENGTH + 2048 + 13);
- if (err) { /* realloc has set error code to no mem. */
- return err;
+ rv = sslBuffer_Grow(&gs->dtlsPacket,
+ MAX_FRAGMENT_LENGTH + 2048 + 13);
+ if (rv != SECSuccess) {
+ return -1; /* Code already set. */
}
}
/* recv() needs to read a full datagram at a time */
nb = ssl_DefRecv(ss, gs->dtlsPacket.buf, gs->dtlsPacket.space, flags);
-
if (nb > 0) {
PRINT_BUF(60, (ss, "raw gather data:", gs->dtlsPacket.buf, nb));
} else if (nb == 0) {
/* EOF */
SSL_TRC(30, ("%d: SSL3[%d]: EOF", SSL_GETPID(), ss->fd));
- rv = 0;
- return rv;
+ return 0;
} else /* if (nb < 0) */ {
SSL_DBG(("%d: SSL3[%d]: recv error %d", SSL_GETPID(), ss->fd,
PR_GetError()));
- rv = SECFailure;
- return rv;
+ return -1;
}
gs->dtlsPacket.len = nb;
}
+ contentType = gs->dtlsPacket.buf[gs->dtlsPacketOffset];
+ if (dtls_IsLongHeader(ss->version, contentType)) {
+ headerLen = 13;
+ } else if (contentType == content_application_data) {
+ headerLen = 7;
+ } else if ((contentType & 0xe0) == 0x20) {
+ headerLen = 2;
+ } else {
+ SSL_DBG(("%d: SSL3[%d]: invalid first octet (%d) for DTLS",
+ SSL_GETPID(), ss->fd, contentType));
+ PORT_SetError(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE);
+ gs->dtlsPacketOffset = 0;
+ gs->dtlsPacket.len = 0;
+ return -1;
+ }
+
/* At this point we should have >=1 complete records lined up in
* dtlsPacket. Read off the header.
*/
- if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < 13) {
+ if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < headerLen) {
SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet "
"too short to contain header",
SSL_GETPID(), ss->fd));
- PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
+ PORT_SetError(PR_WOULD_BLOCK_ERROR);
gs->dtlsPacketOffset = 0;
gs->dtlsPacket.len = 0;
- rv = SECFailure;
- return rv;
+ return -1;
}
- memcpy(gs->hdr, gs->dtlsPacket.buf + gs->dtlsPacketOffset, 13);
- gs->dtlsPacketOffset += 13;
+ memcpy(gs->hdr, SSL_BUFFER_BASE(&gs->dtlsPacket) + gs->dtlsPacketOffset,
+ headerLen);
+ gs->hdrLen = headerLen;
+ gs->dtlsPacketOffset += headerLen;
/* Have received SSL3 record header in gs->hdr. */
- gs->remainder = (gs->hdr[11] << 8) | gs->hdr[12];
+ if (headerLen == 13) {
+ gs->remainder = (gs->hdr[11] << 8) | gs->hdr[12];
+ } else if (headerLen == 7) {
+ gs->remainder = (gs->hdr[5] << 8) | gs->hdr[6];
+ } else {
+ PORT_Assert(headerLen == 2);
+ gs->remainder = gs->dtlsPacket.len - gs->dtlsPacketOffset;
+ }
if ((gs->dtlsPacket.len - gs->dtlsPacketOffset) < gs->remainder) {
SSL_DBG(("%d: SSL3[%d]: rest of DTLS packet too short "
"to contain rest of body",
SSL_GETPID(), ss->fd));
- PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
+ PORT_SetError(PR_WOULD_BLOCK_ERROR);
gs->dtlsPacketOffset = 0;
gs->dtlsPacket.len = 0;
- rv = SECFailure;
- return rv;
+ return -1;
}
/* OK, we have at least one complete packet, copy into inbuf */
- if (gs->remainder > gs->inbuf.space) {
- err = sslBuffer_Grow(&gs->inbuf, gs->remainder);
- if (err) { /* realloc has set error code to no mem. */
- return err;
- }
+ gs->inbuf.len = 0;
+ rv = sslBuffer_Append(&gs->inbuf,
+ SSL_BUFFER_BASE(&gs->dtlsPacket) + gs->dtlsPacketOffset,
+ gs->remainder);
+ if (rv != SECSuccess) {
+ return -1; /* code already set. */
}
-
- SSL_TRC(20, ("%d: SSL3[%d]: dtls gathered record type=%d len=%d",
- SSL_GETPID(), ss->fd, gs->hdr[0], gs->inbuf.len));
-
- memcpy(gs->inbuf.buf, gs->dtlsPacket.buf + gs->dtlsPacketOffset,
- gs->remainder);
- gs->inbuf.len = gs->remainder;
gs->offset = gs->remainder;
gs->dtlsPacketOffset += gs->remainder;
gs->state = GS_INIT;
+ SSL_TRC(20, ("%d: SSL3[%d]: dtls gathered record type=%d len=%d",
+ SSL_GETPID(), ss->fd, contentType, gs->inbuf.len));
return 1;
}
@@ -442,7 +460,11 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
* We need to process it now before we overwrite it with the next
* handshake record.
*/
- rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
+ SSL_DBG(("%d: SSL3[%d]: resuming handshake",
+ SSL_GETPID(), ss->fd));
+ PORT_Assert(!IS_DTLS(ss));
+ rv = ssl3_HandleNonApplicationData(ss, content_handshake,
+ 0, 0, &ss->gs.buf);
} else {
/* State for SSLv2 client hello support. */
ssl2Gather ssl2gs = { PR_FALSE, 0 };
@@ -495,20 +517,14 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
* If it's application data, ss->gs.buf will not be empty upon return.
* If it's a change cipher spec, alert, or handshake message,
* ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess.
+ *
+ * cText only needs to be valid for this next function call, so
+ * it can borrow gs.hdr.
*/
- cText.type = (SSL3ContentType)ss->gs.hdr[0];
- cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];
-
- if (IS_DTLS(ss)) {
- sslSequenceNumber seq_num;
-
- /* DTLS sequence number */
- PORT_Memcpy(&seq_num, &ss->gs.hdr[3], sizeof(seq_num));
- cText.seq_num = PR_ntohll(seq_num);
- }
-
+ cText.hdr = ss->gs.hdr;
+ cText.hdrLen = ss->gs.hdrLen;
cText.buf = &ss->gs.inbuf;
- rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
+ rv = ssl3_HandleRecord(ss, &cText);
}
}
if (rv < 0) {
@@ -520,7 +536,6 @@ ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
* completing any renegotiation handshake we may be doing.
*/
PORT_Assert(ss->firstHsDone);
- PORT_Assert(cText.type == content_application_data);
break;
}
diff --git a/security/nss/lib/ssl/ssl3prot.h b/security/nss/lib/ssl/ssl3prot.h
index d1f46db971..8e6cf27456 100644
--- a/security/nss/lib/ssl/ssl3prot.h
+++ b/security/nss/lib/ssl/ssl3prot.h
@@ -16,7 +16,7 @@ typedef PRUint16 SSL3ProtocolVersion;
/* The TLS 1.3 draft version. Used to avoid negotiating
* between incompatible pre-standard TLS 1.3 drafts.
* TODO(ekr@rtfm.com): Remove when TLS 1.3 is published. */
-#define TLS_1_3_DRAFT_VERSION 23
+#define TLS_1_3_DRAFT_VERSION 28
typedef PRUint16 ssl3CipherSuite;
/* The cipher suites are defined in sslproto.h */
diff --git a/security/nss/lib/ssl/sslcert.c b/security/nss/lib/ssl/sslcert.c
index 6cd02e4025..1c3ddb0e75 100644
--- a/security/nss/lib/ssl/sslcert.c
+++ b/security/nss/lib/ssl/sslcert.c
@@ -256,7 +256,8 @@ ssl_PopulateKeyPair(sslServerCert *sc, sslKeyPair *keyPair)
/* Get the size of the cert's public key, and remember it. */
sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->pubKey);
- if (sc->serverKeyBits == 0) {
+ if (sc->serverKeyBits == 0 ||
+ (keyType == rsaKey && sc->serverKeyBits > SSL_MAX_RSA_KEY_BITS)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
diff --git a/security/nss/lib/ssl/sslerr.h b/security/nss/lib/ssl/sslerr.h
index b94d0cc62e..518a2b8875 100644
--- a/security/nss/lib/ssl/sslerr.h
+++ b/security/nss/lib/ssl/sslerr.h
@@ -262,6 +262,8 @@ typedef enum {
SSL_ERROR_TOO_MANY_KEY_UPDATES = (SSL_ERROR_BASE + 171),
SSL_ERROR_HANDSHAKE_FAILED = (SSL_ERROR_BASE + 172),
SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR = (SSL_ERROR_BASE + 173),
+ SSL_ERROR_RX_MALFORMED_DTLS_ACK = (SSL_ERROR_BASE + 174),
+ SSL_ERROR_DH_KEY_TOO_LONG = (SSL_ERROR_BASE + 175),
SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
} SSLErrorCodes;
#endif /* NO_SECURITY_ERROR_ENUM */
diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h
index 10d0333d9e..a2209e90a1 100644
--- a/security/nss/lib/ssl/sslimpl.h
+++ b/security/nss/lib/ssl/sslimpl.h
@@ -121,6 +121,10 @@ typedef enum { SSLAppOpRead = 0,
/* default number of entries in namedGroupPreferences */
#define SSL_NAMED_GROUP_COUNT 31
+/* The maximum DH and RSA bit-length supported. */
+#define SSL_MAX_DH_KEY_BITS 8192
+#define SSL_MAX_RSA_KEY_BITS 8192
+
/* Types and names of elliptic curves used in TLS */
typedef enum {
ec_type_explicitPrime = 1, /* not supported */
@@ -232,6 +236,7 @@ typedef struct sslOptionsStr {
/* If SSL_SetNextProtoNego has been called, then this contains the
* list of supported protocols. */
SECItem nextProtoNego;
+ PRUint16 recordSizeLimit;
PRUint32 maxEarlyDataSize;
unsigned int useSecurity : 1;
@@ -251,7 +256,6 @@ typedef struct sslOptionsStr {
unsigned int enableFalseStart : 1;
unsigned int cbcRandomIV : 1;
unsigned int enableOCSPStapling : 1;
- unsigned int enableNPN : 1;
unsigned int enableALPN : 1;
unsigned int reuseServerECDHEKey : 1;
unsigned int enableFallbackSCSV : 1;
@@ -261,6 +265,7 @@ typedef struct sslOptionsStr {
unsigned int requireDHENamedGroups : 1;
unsigned int enable0RttData : 1;
unsigned int enableTls13CompatMode : 1;
+ unsigned int enableDtlsShortHeader : 1;
} sslOptions;
typedef enum { sslHandshakingUndetermined = 0,
@@ -325,9 +330,11 @@ struct sslGatherStr {
** than into buf or inbuf, while in the GS_HEADER state.
** The portion of the SSL record header put here always comes off the wire
** as plaintext, never ciphertext.
- ** For SSL3/TLS, the plaintext portion is 5 bytes long. For DTLS it is 13.
+ ** For SSL3/TLS, the plaintext portion is 5 bytes long. For DTLS it
+ ** varies based on version and header type.
*/
unsigned char hdr[13];
+ unsigned int hdrLen;
/* Buffer for DTLS data read off the wire as a single datagram */
sslBuffer dtlsPacket;
@@ -440,7 +447,7 @@ struct sslSessionIDStr {
*/
SECItem signedCertTimestamps;
- /* The NPN/ALPN value negotiated in the original connection.
+ /* The ALPN value negotiated in the original connection.
* Used for TLS 1.3. */
SECItem alpnSelection;
@@ -780,9 +787,13 @@ struct ssl3StateStr {
#define IS_DTLS(ss) (ss->protocolVariant == ssl_variant_datagram)
typedef struct {
- SSL3ContentType type;
- SSL3ProtocolVersion version;
- sslSequenceNumber seq_num; /* DTLS only */
+ /* |seqNum| eventually contains the reconstructed sequence number. */
+ sslSequenceNumber seqNum;
+ /* The header of the cipherText. */
+ const PRUint8 *hdr;
+ unsigned int hdrLen;
+
+ /* |buf| is the payload of the ciphertext. */
sslBuffer *buf;
} SSL3Ciphertext;
@@ -805,7 +816,7 @@ struct ssl3DHParamsStr {
};
typedef struct SSLWrappedSymWrappingKeyStr {
- PRUint8 wrappedSymmetricWrappingkey[512];
+ PRUint8 wrappedSymmetricWrappingkey[SSL_MAX_RSA_KEY_BITS / 8];
CK_MECHANISM_TYPE symWrapMechanism;
/* unwrapped symmetric wrapping key uses this mechanism */
CK_MECHANISM_TYPE asymWrapMechanism;
@@ -1375,8 +1386,11 @@ SECStatus ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type);
/*
* input into the SSL3 machinery from the actualy network reading code
*/
-SECStatus ssl3_HandleRecord(
- sslSocket *ss, SSL3Ciphertext *cipher, sslBuffer *out);
+SECStatus ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cipher);
+SECStatus ssl3_HandleNonApplicationData(sslSocket *ss, SSL3ContentType rType,
+ DTLSEpoch epoch,
+ sslSequenceNumber seqNum,
+ sslBuffer *databuf);
SECStatus ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, unsigned int macSize);
int ssl3_GatherAppDataRecord(sslSocket *ss, int flags);
@@ -1537,8 +1551,8 @@ SECStatus ssl_GetSelfEncryptKeys(sslSocket *ss, unsigned char *keyName,
PK11SymKey **encKey, PK11SymKey **macKey);
void ssl_ResetSelfEncryptKeys();
-extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char *data,
- unsigned int length);
+extern SECStatus ssl3_ValidateAppProtocol(const unsigned char *data,
+ unsigned int length);
/* Construct a new NSPR socket for the app to use */
extern PRFileDesc *ssl_NewPRSocket(sslSocket *ss, PRFileDesc *fd);
@@ -1636,6 +1650,9 @@ SSLHashType ssl_SignatureSchemeToHashType(SSLSignatureScheme scheme);
KeyType ssl_SignatureSchemeToKeyType(SSLSignatureScheme scheme);
SECStatus ssl3_SetupCipherSuite(sslSocket *ss, PRBool initHashes);
+SECStatus ssl_InsertRecordHeader(const sslSocket *ss, ssl3CipherSpec *cwSpec,
+ SSL3ContentType contentType, sslBuffer *wrBuf,
+ PRBool *needsLength);
/* Pull in DTLS functions */
#include "dtlscon.h"
diff --git a/security/nss/lib/ssl/sslsecur.c b/security/nss/lib/ssl/sslsecur.c
index f09ec067ce..a1d3892145 100644
--- a/security/nss/lib/ssl/sslsecur.c
+++ b/security/nss/lib/ssl/sslsecur.c
@@ -791,7 +791,7 @@ tls13_CheckKeyUpdate(sslSocket *ss, CipherSpecDirection dir)
spec = ss->ssl3.cwSpec;
margin = spec->cipherDef->max_records / 4;
}
- seqNum = spec->seqNum;
+ seqNum = spec->nextSeqNum;
keyUpdate = seqNum > spec->cipherDef->max_records - margin;
ssl_ReleaseSpecReadLock(ss);
if (!keyUpdate) {
@@ -922,21 +922,30 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
*/
if (!ss->firstHsDone) {
PRBool allowEarlySend = PR_FALSE;
+ PRBool firstClientWrite = PR_FALSE;
ssl_Get1stHandshakeLock(ss);
- if (ss->opt.enableFalseStart ||
- (ss->opt.enable0RttData && !ss->sec.isServer)) {
+ /* The client can sometimes send before the handshake is fully
+ * complete. In TLS 1.2: false start; in TLS 1.3: 0-RTT. */
+ if (!ss->sec.isServer &&
+ (ss->opt.enableFalseStart || ss->opt.enable0RttData)) {
ssl_GetSSL3HandshakeLock(ss);
- /* The client can sometimes send before the handshake is fully
- * complete. In TLS 1.2: false start; in TLS 1.3: 0-RTT. */
zeroRtt = ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted;
allowEarlySend = ss->ssl3.hs.canFalseStart || zeroRtt;
+ firstClientWrite = ss->ssl3.hs.ws == idle_handshake;
ssl_ReleaseSSL3HandshakeLock(ss);
}
if (!allowEarlySend && ss->handshake) {
rv = ssl_Do1stHandshake(ss);
}
+ if (firstClientWrite) {
+ /* Wait until after sending ClientHello and double-check 0-RTT. */
+ ssl_GetSSL3HandshakeLock(ss);
+ zeroRtt = ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
+ ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted;
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ }
ssl_Release1stHandshakeLock(ss);
}
diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c
index e08d5e2326..33595ffae9 100644
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -55,6 +55,7 @@ static const sslSocketOps ssl_secure_ops = { /* SSL. */
static sslOptions ssl_defaults = {
.nextProtoNego = { siBuffer, NULL, 0 },
.maxEarlyDataSize = 1 << 16,
+ .recordSizeLimit = MAX_FRAGMENT_LENGTH + 1,
.useSecurity = PR_TRUE,
.useSocks = PR_FALSE,
.requestCertificate = PR_FALSE,
@@ -72,7 +73,6 @@ static sslOptions ssl_defaults = {
.enableFalseStart = PR_FALSE,
.cbcRandomIV = PR_TRUE,
.enableOCSPStapling = PR_FALSE,
- .enableNPN = PR_FALSE,
.enableALPN = PR_TRUE,
.reuseServerECDHEKey = PR_TRUE,
.enableFallbackSCSV = PR_FALSE,
@@ -81,7 +81,8 @@ static sslOptions ssl_defaults = {
.enableSignedCertTimestamps = PR_FALSE,
.requireDHENamedGroups = PR_FALSE,
.enable0RttData = PR_FALSE,
- .enableTls13CompatMode = PR_FALSE
+ .enableTls13CompatMode = PR_FALSE,
+ .enableDtlsShortHeader = PR_FALSE
};
/*
@@ -803,10 +804,23 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRIntn val)
ss->opt.enable0RttData = val;
break;
+ case SSL_RECORD_SIZE_LIMIT:
+ if (val < 64 || val > (MAX_FRAGMENT_LENGTH + 1)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ } else {
+ ss->opt.recordSizeLimit = val;
+ }
+ break;
+
case SSL_ENABLE_TLS13_COMPAT_MODE:
ss->opt.enableTls13CompatMode = val;
break;
+ case SSL_ENABLE_DTLS_SHORT_HEADER:
+ ss->opt.enableDtlsShortHeader = val;
+ break;
+
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
@@ -914,7 +928,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRIntn *pVal)
val = ss->opt.enableOCSPStapling;
break;
case SSL_ENABLE_NPN:
- val = ss->opt.enableNPN;
+ val = PR_FALSE;
break;
case SSL_ENABLE_ALPN:
val = ss->opt.enableALPN;
@@ -940,9 +954,15 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRIntn *pVal)
case SSL_ENABLE_0RTT_DATA:
val = ss->opt.enable0RttData;
break;
+ case SSL_RECORD_SIZE_LIMIT:
+ val = ss->opt.recordSizeLimit;
+ break;
case SSL_ENABLE_TLS13_COMPAT_MODE:
val = ss->opt.enableTls13CompatMode;
break;
+ case SSL_ENABLE_DTLS_SHORT_HEADER:
+ val = ss->opt.enableDtlsShortHeader;
+ break;
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
@@ -1037,7 +1057,7 @@ SSL_OptionGetDefault(PRInt32 which, PRIntn *pVal)
val = ssl_defaults.enableOCSPStapling;
break;
case SSL_ENABLE_NPN:
- val = ssl_defaults.enableNPN;
+ val = PR_FALSE;
break;
case SSL_ENABLE_ALPN:
val = ssl_defaults.enableALPN;
@@ -1060,9 +1080,15 @@ SSL_OptionGetDefault(PRInt32 which, PRIntn *pVal)
case SSL_ENABLE_0RTT_DATA:
val = ssl_defaults.enable0RttData;
break;
+ case SSL_RECORD_SIZE_LIMIT:
+ val = ssl_defaults.recordSizeLimit;
+ break;
case SSL_ENABLE_TLS13_COMPAT_MODE:
val = ssl_defaults.enableTls13CompatMode;
break;
+ case SSL_ENABLE_DTLS_SHORT_HEADER:
+ val = ssl_defaults.enableDtlsShortHeader;
+ break;
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
rv = SECFailure;
@@ -1242,10 +1268,22 @@ SSL_OptionSetDefault(PRInt32 which, PRIntn val)
ssl_defaults.enable0RttData = val;
break;
+ case SSL_RECORD_SIZE_LIMIT:
+ if (val < 64 || val > (MAX_FRAGMENT_LENGTH + 1)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ ssl_defaults.recordSizeLimit = val;
+ break;
+
case SSL_ENABLE_TLS13_COMPAT_MODE:
ssl_defaults.enableTls13CompatMode = val;
break;
+ case SSL_ENABLE_DTLS_SHORT_HEADER:
+ ssl_defaults.enableDtlsShortHeader = val;
+ break;
+
default:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@@ -1895,10 +1933,7 @@ DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd)
}
/* SSL_SetNextProtoCallback is used to select an application protocol
- * for ALPN and NPN. For ALPN, this runs on the server; for NPN it
- * runs on the client. */
-/* Note: The ALPN version doesn't allow for the use of a default, setting a
- * status of SSL_NEXT_PROTO_NO_OVERLAP is treated as a failure. */
+ * for ALPN. */
SECStatus
SSL_SetNextProtoCallback(PRFileDesc *fd, SSLNextProtoCallback callback,
void *arg)
@@ -1919,7 +1954,7 @@ SSL_SetNextProtoCallback(PRFileDesc *fd, SSLNextProtoCallback callback,
return SECSuccess;
}
-/* ssl_NextProtoNegoCallback is set as an ALPN/NPN callback when
+/* ssl_NextProtoNegoCallback is set as an ALPN callback when
* SSL_SetNextProtoNego is used.
*/
static SECStatus
@@ -1929,7 +1964,6 @@ ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd,
unsigned int protoMaxLen)
{
unsigned int i, j;
- const unsigned char *result;
sslSocket *ss = ssl_FindSocket(fd);
if (!ss) {
@@ -1937,37 +1971,29 @@ ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd,
SSL_GETPID(), fd));
return SECFailure;
}
+ PORT_Assert(protoMaxLen <= 255);
+ if (protoMaxLen > 255) {
+ PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+ return SECFailure;
+ }
- /* For each protocol in server preference, see if we support it. */
- for (i = 0; i < protos_len;) {
- for (j = 0; j < ss->opt.nextProtoNego.len;) {
+ /* For each protocol in client preference, see if we support it. */
+ for (j = 0; j < ss->opt.nextProtoNego.len;) {
+ for (i = 0; i < protos_len;) {
if (protos[i] == ss->opt.nextProtoNego.data[j] &&
PORT_Memcmp(&protos[i + 1], &ss->opt.nextProtoNego.data[j + 1],
protos[i]) == 0) {
/* We found a match. */
- ss->xtnData.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED;
- result = &protos[i];
- goto found;
+ const unsigned char *result = &protos[i];
+ memcpy(protoOut, result + 1, result[0]);
+ *protoOutLen = result[0];
+ return SECSuccess;
}
- j += 1 + (unsigned int)ss->opt.nextProtoNego.data[j];
+ i += 1 + (unsigned int)protos[i];
}
- i += 1 + (unsigned int)protos[i];
+ j += 1 + (unsigned int)ss->opt.nextProtoNego.data[j];
}
- /* The other side supports the extension, and either doesn't have any
- * protocols configured, or none of its options match ours. In this case we
- * request our favoured protocol. */
- /* This will be treated as a failure for ALPN. */
- ss->xtnData.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP;
- result = ss->opt.nextProtoNego.data;
-
-found:
- if (protoMaxLen < result[0]) {
- PORT_SetError(SEC_ERROR_OUTPUT_LEN);
- return SECFailure;
- }
- memcpy(protoOut, result + 1, result[0]);
- *protoOutLen = result[0];
return SECSuccess;
}
@@ -1976,8 +2002,6 @@ SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data,
unsigned int length)
{
sslSocket *ss;
- SECStatus rv;
- SECItem dataItem = { siBuffer, (unsigned char *)data, length };
ss = ssl_FindSocket(fd);
if (!ss) {
@@ -1986,17 +2010,22 @@ SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data,
return SECFailure;
}
- if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess)
+ if (ssl3_ValidateAppProtocol(data, length) != SECSuccess) {
return SECFailure;
+ }
+ /* NPN required that the client's fallback protocol is first in the
+ * list. However, ALPN sends protocols in preference order. So move the
+ * first protocol to the end of the list. */
ssl_GetSSL3HandshakeLock(ss);
SECITEM_FreeItem(&ss->opt.nextProtoNego, PR_FALSE);
- rv = SECITEM_CopyItem(NULL, &ss->opt.nextProtoNego, &dataItem);
+ SECITEM_AllocItem(NULL, &ss->opt.nextProtoNego, length);
+ size_t firstLen = data[0] + 1;
+ /* firstLen <= length is ensured by ssl3_ValidateAppProtocol. */
+ PORT_Memcpy(ss->opt.nextProtoNego.data + (length - firstLen), data, firstLen);
+ PORT_Memcpy(ss->opt.nextProtoNego.data, data + firstLen, length - firstLen);
ssl_ReleaseSSL3HandshakeLock(ss);
- if (rv != SECSuccess)
- return rv;
-
return SSL_SetNextProtoCallback(fd, ssl_NextProtoNegoCallback, NULL);
}
@@ -3034,26 +3063,27 @@ ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags)
} else { /* handshaking as server */
new_flags |= PR_POLL_READ;
}
- } else
+ } else if (ss->lastWriteBlocked) {
/* First handshake is in progress */
- if (ss->lastWriteBlocked) {
if (new_flags & PR_POLL_READ) {
/* The caller is waiting for data to be received,
** but the initial handshake is blocked on write, or the
** client's first handshake record has not been written.
** The code should select on write, not read.
*/
- new_flags ^= PR_POLL_READ; /* don't select on read. */
+ new_flags &= ~PR_POLL_READ; /* don't select on read. */
new_flags |= PR_POLL_WRITE; /* do select on write. */
}
} else if (new_flags & PR_POLL_WRITE) {
/* The caller is trying to write, but the handshake is
** blocked waiting for data to read, and the first
** handshake has been sent. So do NOT to poll on write
- ** unless we did false start.
+ ** unless we did false start or we are doing 0-RTT.
*/
- if (!ss->ssl3.hs.canFalseStart) {
- new_flags ^= PR_POLL_WRITE; /* don't select on write. */
+ if (!(ss->ssl3.hs.canFalseStart ||
+ ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
+ ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted)) {
+ new_flags &= ~PR_POLL_WRITE; /* don't select on write. */
}
new_flags |= PR_POLL_READ; /* do select on read. */
}
@@ -3093,6 +3123,9 @@ ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags)
}
}
+ SSL_TRC(20, ("%d: SSL[%d]: ssl_Poll flags %x -> %x",
+ SSL_GETPID(), fd, how_flags, new_flags));
+
if (new_flags && (fd->lower->methods->poll != NULL)) {
PRInt16 lower_out_flags = 0;
PRInt16 lower_new_flags;
diff --git a/security/nss/lib/ssl/sslspec.c b/security/nss/lib/ssl/sslspec.c
index 26c3eb5462..7833eeab69 100644
--- a/security/nss/lib/ssl/sslspec.c
+++ b/security/nss/lib/ssl/sslspec.c
@@ -143,6 +143,7 @@ ssl_CreateCipherSpec(sslSocket *ss, CipherSpecDirection direction)
spec->refCt = 1;
spec->version = ss->version;
spec->direction = direction;
+ spec->recordSizeLimit = MAX_FRAGMENT_LENGTH;
SSL_TRC(10, ("%d: SSL[%d]: new %s spec %d ct=%d",
SSL_GETPID(), ss->fd, SPEC_DIR(spec), spec,
spec->refCt));
diff --git a/security/nss/lib/ssl/sslspec.h b/security/nss/lib/ssl/sslspec.h
index 729ac1006f..b256017553 100644
--- a/security/nss/lib/ssl/sslspec.h
+++ b/security/nss/lib/ssl/sslspec.h
@@ -162,12 +162,18 @@ struct ssl3CipherSpecStr {
DTLSEpoch epoch;
const char *phase;
- sslSequenceNumber seqNum;
+
+ /* The next sequence number to be sent or received. */
+ sslSequenceNumber nextSeqNum;
DTLSRecvdRecords recvdRecords;
/* The number of 0-RTT bytes that can be sent or received in TLS 1.3. This
* will be zero for everything but 0-RTT. */
PRUint32 earlyDataRemaining;
+ /* The maximum plaintext length. This differs from the configured or
+ * negotiated value for TLS 1.3; it is reduced by one to account for the
+ * content type octet. */
+ PRUint16 recordSizeLimit;
};
typedef void (*sslCipherSpecChangedFunc)(void *arg,
diff --git a/security/nss/lib/ssl/sslt.h b/security/nss/lib/ssl/sslt.h
index e2b80fb436..bb1bec7a3d 100644
--- a/security/nss/lib/ssl/sslt.h
+++ b/security/nss/lib/ssl/sslt.h
@@ -432,6 +432,7 @@ typedef enum {
ssl_signed_cert_timestamp_xtn = 18,
ssl_padding_xtn = 21,
ssl_extended_master_secret_xtn = 23,
+ ssl_record_size_limit_xtn = 28,
ssl_session_ticket_xtn = 35,
/* 40 was used in draft versions of TLS 1.3; it is now reserved. */
ssl_tls13_pre_shared_key_xtn = 41,
@@ -454,7 +455,7 @@ typedef enum {
/* SSL_MAX_EXTENSIONS includes the maximum number of extensions that are
* supported for any single message type. That is, a ClientHello; ServerHello
* and TLS 1.3 NewSessionTicket and HelloRetryRequest extensions have fewer. */
-#define SSL_MAX_EXTENSIONS 20
+#define SSL_MAX_EXTENSIONS 21
/* Deprecated */
typedef enum {
diff --git a/security/nss/lib/ssl/tls13con.c b/security/nss/lib/ssl/tls13con.c
index c06acc83a9..4d9170fb01 100644
--- a/security/nss/lib/ssl/tls13con.c
+++ b/security/nss/lib/ssl/tls13con.c
@@ -792,7 +792,7 @@ tls13_HandleKeyUpdate(sslSocket *ss, PRUint8 *b, unsigned int length)
/* Only send an update if we have sent with the current spec. This
* prevents us from being forced to crank forward pointlessly. */
ssl_GetSpecReadLock(ss);
- sendUpdate = ss->ssl3.cwSpec->seqNum > 0;
+ sendUpdate = ss->ssl3.cwSpec->nextSeqNum > 0;
ssl_ReleaseSpecReadLock(ss);
} else {
sendUpdate = PR_TRUE;
@@ -1620,7 +1620,7 @@ tls13_HandleClientHelloPart2(sslSocket *ss,
ssl_GetSpecWriteLock(ss);
/* Increase the write sequence number. The read sequence number
* will be reset after this to early data or handshake. */
- ss->ssl3.cwSpec->seqNum = 1;
+ ss->ssl3.cwSpec->nextSeqNum = 1;
ssl_ReleaseSpecWriteLock(ss);
}
@@ -2007,7 +2007,7 @@ tls13_SendHelloRetryRequest(sslSocket *ss,
/* We depend on this being exactly one record and one message. */
PORT_Assert(!IS_DTLS(ss) || (ss->ssl3.hs.sendMessageSeq == 1 &&
- ss->ssl3.cwSpec->seqNum == 1));
+ ss->ssl3.cwSpec->nextSeqNum == 1));
ssl_ReleaseXmitBufLock(ss);
ss->ssl3.hs.helloRetry = PR_TRUE;
@@ -2209,6 +2209,8 @@ tls13_HandleHelloRetryRequest(sslSocket *ss, const PRUint8 *savedMsg,
} else {
PORT_Assert(ss->ssl3.hs.zeroRttState == ssl_0rtt_none);
}
+ /* Set the spec version, because we want to send CH now with 0303 */
+ tls13_SetSpecRecordVersion(ss, ss->ssl3.cwSpec);
/* Extensions must contain more than just supported_versions. This will
* ensure that a HelloRetryRequest isn't a no-op: we must have at least two
@@ -2248,6 +2250,7 @@ tls13_HandleHelloRetryRequest(sslSocket *ss, const PRUint8 *savedMsg,
goto loser;
}
}
+
rv = ssl3_SendClientHello(ss, client_hello_retry);
if (rv != SECSuccess) {
goto loser;
@@ -3251,6 +3254,17 @@ tls13_SetupPendingCipherSpec(sslSocket *ss, ssl3CipherSpec *spec)
}
tls13_SetSpecRecordVersion(ss, spec);
+
+ /* The record size limit is reduced by one so that the remainder of the
+ * record handling code can use the same checks for all versions. */
+ if (ssl3_ExtensionNegotiated(ss, ssl_record_size_limit_xtn)) {
+ spec->recordSizeLimit = ((spec->direction == CipherSpecRead)
+ ? ss->opt.recordSizeLimit
+ : ss->xtnData.recordSizeLimit) -
+ 1;
+ } else {
+ spec->recordSizeLimit = MAX_FRAGMENT_LENGTH;
+ }
return SECSuccess;
}
@@ -3316,7 +3330,7 @@ tls13_SetCipherSpec(sslSocket *ss, PRUint16 epoch,
return SECFailure;
}
spec->epoch = epoch;
- spec->seqNum = 0;
+ spec->nextSeqNum = 0;
if (IS_DTLS(ss)) {
dtls_InitRecvdRecords(&spec->recvdRecords);
}
@@ -3536,14 +3550,15 @@ tls13_AESGCM(ssl3KeyMaterial *keys,
CK_GCM_PARAMS gcmParams;
unsigned char nonce[12];
+ PORT_Assert(additionalDataLen > 8);
memset(&gcmParams, 0, sizeof(gcmParams));
gcmParams.pIv = nonce;
gcmParams.ulIvLen = sizeof(nonce);
- gcmParams.pAAD = NULL;
- gcmParams.ulAADLen = 0;
+ gcmParams.pAAD = (PRUint8 *)(additionalData + 8);
+ gcmParams.ulAADLen = additionalDataLen - 8;
gcmParams.ulTagBits = 128; /* GCM measures tag length in bits. */
- tls13_WriteNonce(keys, additionalData, additionalDataLen,
+ tls13_WriteNonce(keys, additionalData, 8,
nonce, sizeof(nonce));
return tls13_AEAD(keys, doDecrypt, out, outlen, maxout, in, inlen,
CKM_AES_GCM,
@@ -3560,14 +3575,15 @@ tls13_ChaCha20Poly1305(ssl3KeyMaterial *keys, PRBool doDecrypt,
CK_NSS_AEAD_PARAMS aeadParams;
unsigned char nonce[12];
+ PORT_Assert(additionalDataLen > 8);
memset(&aeadParams, 0, sizeof(aeadParams));
aeadParams.pNonce = nonce;
aeadParams.ulNonceLen = sizeof(nonce);
- aeadParams.pAAD = NULL; /* No AAD in TLS 1.3. */
- aeadParams.ulAADLen = 0;
+ aeadParams.pAAD = (PRUint8 *)(additionalData + 8);
+ aeadParams.ulAADLen = additionalDataLen - 8;
aeadParams.ulTagLen = 16; /* The Poly1305 tag is 16 octets. */
- tls13_WriteNonce(keys, additionalData, additionalDataLen,
+ tls13_WriteNonce(keys, additionalData, 8,
nonce, sizeof(nonce));
return tls13_AEAD(keys, doDecrypt, out, outlen, maxout, in, inlen,
CKM_NSS_CHACHA20_POLY1305,
@@ -3579,7 +3595,7 @@ tls13_HandleEncryptedExtensions(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
SECStatus rv;
PRUint32 innerLength;
- SECItem oldNpn = { siBuffer, NULL, 0 };
+ SECItem oldAlpn = { siBuffer, NULL, 0 };
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
@@ -3603,11 +3619,11 @@ tls13_HandleEncryptedExtensions(sslSocket *ss, PRUint8 *b, PRUint32 length)
return SECFailure;
}
- /* If we are doing 0-RTT, then we already have an NPN value. Stash
+ /* If we are doing 0-RTT, then we already have an ALPN value. Stash
* it for comparison. */
if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent &&
ss->xtnData.nextProtoState == SSL_NEXT_PROTO_EARLY_VALUE) {
- oldNpn = ss->xtnData.nextProto;
+ oldAlpn = ss->xtnData.nextProto;
ss->xtnData.nextProto.data = NULL;
ss->xtnData.nextProtoState = SSL_NEXT_PROTO_NO_SUPPORT;
}
@@ -3627,8 +3643,8 @@ tls13_HandleEncryptedExtensions(sslSocket *ss, PRUint8 *b, PRUint32 length)
ss->ssl3.hs.zeroRttState = ssl_0rtt_accepted;
/* Check that the server negotiated the same ALPN (if any). */
- if (SECITEM_CompareItem(&oldNpn, &ss->xtnData.nextProto)) {
- SECITEM_FreeItem(&oldNpn, PR_FALSE);
+ if (SECITEM_CompareItem(&oldAlpn, &ss->xtnData.nextProto)) {
+ SECITEM_FreeItem(&oldAlpn, PR_FALSE);
FATAL_ERROR(ss, SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID,
illegal_parameter);
return SECFailure;
@@ -3650,7 +3666,7 @@ tls13_HandleEncryptedExtensions(sslSocket *ss, PRUint8 *b, PRUint32 length)
ss->ssl3.hs.zeroRttState == ssl_0rtt_ignored));
}
- SECITEM_FreeItem(&oldNpn, PR_FALSE);
+ SECITEM_FreeItem(&oldAlpn, PR_FALSE);
if (ss->ssl3.hs.kea_def->authKeyType == ssl_auth_psk) {
TLS13_SET_HS_STATE(ss, wait_finished);
} else {
@@ -3815,13 +3831,14 @@ tls13_HandleCertificateVerify(sslSocket *ss, PRUint8 *b, PRUint32 length)
rv = ssl_ConsumeSignatureScheme(ss, &b, &length, &sigScheme);
if (rv != SECSuccess) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_CERT_VERIFY);
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERT_VERIFY, illegal_parameter);
return SECFailure;
}
rv = ssl_CheckSignatureSchemeConsistency(ss, sigScheme, ss->sec.peerCert);
if (rv != SECSuccess) {
/* Error set already */
+ FATAL_ERROR(ss, PORT_GetError(), illegal_parameter);
return SECFailure;
}
hashAlg = ssl_SignatureSchemeToHashType(sigScheme);
@@ -4740,7 +4757,8 @@ static const struct {
{ ssl_tls13_cookie_xtn, _M2(client_hello, hello_retry_request) },
{ ssl_tls13_certificate_authorities_xtn, _M1(certificate_request) },
{ ssl_tls13_supported_versions_xtn, _M3(client_hello, server_hello,
- hello_retry_request) }
+ hello_retry_request) },
+ { ssl_record_size_limit_xtn, _M2(client_hello, encrypted_extensions) }
};
tls13ExtensionStatus
@@ -4780,19 +4798,20 @@ tls13_ExtensionStatus(PRUint16 extension, SSLHandshakeType message)
#undef _M2
#undef _M3
-/* TLS 1.3 doesn't actually have additional data but the aead function
- * signature overloads additional data to carry the record sequence
- * number and that's what we put here. The TLS 1.3 AEAD functions
- * just use this input as the sequence number and not as additional
- * data. */
+/* We cheat a bit on additional data because the AEAD interface
+ * which doesn't have room for the record number. The AAD we
+ * format is serialized record number followed by the true AD
+ * (i.e., the record header) plus the serialized record number. */
static SECStatus
-tls13_FormatAdditionalData(sslSocket *ss, PRUint8 *aad, unsigned int length,
- DTLSEpoch epoch, sslSequenceNumber seqNum)
+tls13_FormatAdditionalData(
+ sslSocket *ss,
+ const PRUint8 *header, unsigned int headerLen,
+ DTLSEpoch epoch, sslSequenceNumber seqNum,
+ PRUint8 *aad, unsigned int *aadLength, unsigned int maxLength)
{
SECStatus rv;
- sslBuffer buf = SSL_BUFFER_FIXED(aad, length);
+ sslBuffer buf = SSL_BUFFER_FIXED(aad, maxLength);
- PORT_Assert(length == 8);
if (IS_DTLS(ss)) {
rv = sslBuffer_AppendNumber(&buf, epoch, 2);
if (rv != SECSuccess) {
@@ -4803,6 +4822,14 @@ tls13_FormatAdditionalData(sslSocket *ss, PRUint8 *aad, unsigned int length,
if (rv != SECSuccess) {
return SECFailure;
}
+
+ rv = sslBuffer_Append(&buf, header, headerLen);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+
+ *aadLength = buf.len;
+
return SECSuccess;
}
@@ -4843,43 +4870,68 @@ tls13_ProtectRecord(sslSocket *ss,
PORT_Assert(cwSpec->direction == CipherSpecWrite);
SSL_TRC(3, ("%d: TLS13[%d]: spec=%d epoch=%d (%s) protect 0x%0llx len=%u",
SSL_GETPID(), ss->fd, cwSpec, cwSpec->epoch, cwSpec->phase,
- cwSpec->seqNum, contentLen));
+ cwSpec->nextSeqNum, contentLen));
- if (contentLen + 1 + tagLen > wrBuf->space) {
+ if (contentLen + 1 + tagLen > SSL_BUFFER_SPACE(wrBuf)) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
/* Copy the data into the wrBuf. We're going to encrypt in-place
* in the AEAD branch anyway */
- PORT_Memcpy(wrBuf->buf, pIn, contentLen);
+ PORT_Memcpy(SSL_BUFFER_NEXT(wrBuf), pIn, contentLen);
if (cipher_def->calg == ssl_calg_null) {
/* Shortcut for plaintext */
- wrBuf->len = contentLen;
+ rv = sslBuffer_Skip(wrBuf, contentLen, NULL);
+ PORT_Assert(rv == SECSuccess);
} else {
- PRUint8 aad[8];
+ PRUint8 hdr[13];
+ sslBuffer buf = SSL_BUFFER_FIXED(hdr, sizeof(hdr));
+ PRBool needsLength;
+ PRUint8 aad[21];
+ unsigned int aadLen;
+ int len;
+
PORT_Assert(cipher_def->type == type_aead);
/* Add the content type at the end. */
- wrBuf->buf[contentLen] = type;
+ *(SSL_BUFFER_NEXT(wrBuf) + contentLen) = type;
- rv = tls13_FormatAdditionalData(ss, aad, sizeof(aad), cwSpec->epoch,
- cwSpec->seqNum);
+ /* Create the header (ugly that we have to do it twice). */
+ rv = ssl_InsertRecordHeader(ss, cwSpec, content_application_data,
+ &buf, &needsLength);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ if (needsLength) {
+ rv = sslBuffer_AppendNumber(&buf, contentLen + 1 +
+ cwSpec->cipherDef->tag_size,
+ 2);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ }
+ rv = tls13_FormatAdditionalData(ss, SSL_BUFFER_BASE(&buf), SSL_BUFFER_LEN(&buf),
+ cwSpec->epoch, cwSpec->nextSeqNum,
+ aad, &aadLen, sizeof(aad));
if (rv != SECSuccess) {
return SECFailure;
}
rv = cwSpec->aead(&cwSpec->keyMaterial,
- PR_FALSE, /* do encrypt */
- wrBuf->buf, /* output */
- (int *)&wrBuf->len, /* out len */
- wrBuf->space, /* max out */
- wrBuf->buf, contentLen + 1, /* input */
- aad, sizeof(aad));
+ PR_FALSE, /* do encrypt */
+ SSL_BUFFER_NEXT(wrBuf), /* output */
+ &len, /* out len */
+ SSL_BUFFER_SPACE(wrBuf), /* max out */
+ SSL_BUFFER_NEXT(wrBuf), /* input */
+ contentLen + 1, /* input len */
+ aad, aadLen);
if (rv != SECSuccess) {
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
return SECFailure;
}
+ rv = sslBuffer_Skip(wrBuf, len, NULL);
+ PORT_Assert(rv == SECSuccess);
}
return SECSuccess;
@@ -4897,25 +4949,22 @@ tls13_ProtectRecord(sslSocket *ss,
SECStatus
tls13_UnprotectRecord(sslSocket *ss,
ssl3CipherSpec *spec,
- SSL3Ciphertext *cText, sslBuffer *plaintext,
+ SSL3Ciphertext *cText,
+ sslBuffer *plaintext,
+ SSL3ContentType *innerType,
SSL3AlertDescription *alert)
{
const ssl3BulkCipherDef *cipher_def = spec->cipherDef;
- sslSequenceNumber seqNum;
- PRUint8 aad[8];
+ PRUint8 aad[21];
+ unsigned int aadLen;
SECStatus rv;
*alert = bad_record_mac; /* Default alert for most issues. */
PORT_Assert(spec->direction == CipherSpecRead);
- if (IS_DTLS(ss)) {
- seqNum = cText->seq_num & RECORD_SEQ_MASK;
- } else {
- seqNum = spec->seqNum;
- }
SSL_TRC(3, ("%d: TLS13[%d]: spec=%d epoch=%d (%s) unprotect 0x%0llx len=%u",
- SSL_GETPID(), ss->fd, spec, spec->epoch, spec->phase, seqNum,
- cText->buf->len));
+ SSL_GETPID(), ss->fd, spec, spec->epoch, spec->phase,
+ cText->seqNum, cText->buf->len));
/* We can perform this test in variable time because the record's total
* length and the ciphersuite are both public knowledge. */
@@ -4927,28 +4976,38 @@ tls13_UnprotectRecord(sslSocket *ss,
return SECFailure;
}
- /* Verify that the content type is right, even though we overwrite it. */
- if (cText->type != content_application_data) {
+ /* Verify that the content type is right, even though we overwrite it.
+ * Also allow the DTLS short header in TLS 1.3. */
+ if (!(cText->hdr[0] == content_application_data ||
+ (IS_DTLS(ss) &&
+ ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
+ (cText->hdr[0] & 0xe0) == 0x20))) {
SSL_TRC(3,
- ("%d: TLS13[%d]: record has invalid exterior content type=%d",
- SSL_GETPID(), ss->fd, cText->type));
+ ("%d: TLS13[%d]: record has invalid exterior type=%2.2x",
+ SSL_GETPID(), ss->fd, cText->hdr[0]));
/* Do we need a better error here? */
PORT_SetError(SSL_ERROR_BAD_MAC_READ);
return SECFailure;
}
- /* Check the version number in the record. */
- if (cText->version != spec->recordVersion) {
- /* Do we need a better error here? */
- SSL_TRC(3,
- ("%d: TLS13[%d]: record has bogus version",
- SSL_GETPID(), ss->fd));
- return SECFailure;
+ /* Check the version number in the record. Stream only. */
+ if (!IS_DTLS(ss)) {
+ SSL3ProtocolVersion version =
+ ((SSL3ProtocolVersion)cText->hdr[1] << 8) |
+ (SSL3ProtocolVersion)cText->hdr[2];
+ if (version != spec->recordVersion) {
+ /* Do we need a better error here? */
+ SSL_TRC(3, ("%d: TLS13[%d]: record has bogus version",
+ SSL_GETPID(), ss->fd));
+ return SECFailure;
+ }
}
/* Decrypt */
PORT_Assert(cipher_def->type == type_aead);
- rv = tls13_FormatAdditionalData(ss, aad, sizeof(aad), spec->epoch, seqNum);
+ rv = tls13_FormatAdditionalData(ss, cText->hdr, cText->hdrLen,
+ spec->epoch, cText->seqNum,
+ aad, &aadLen, sizeof(aad));
if (rv != SECSuccess) {
return SECFailure;
}
@@ -4959,7 +5018,7 @@ tls13_UnprotectRecord(sslSocket *ss,
plaintext->space, /* maxout */
cText->buf->buf, /* in */
cText->buf->len, /* inlen */
- aad, sizeof(aad));
+ aad, aadLen);
if (rv != SECSuccess) {
SSL_TRC(3,
("%d: TLS13[%d]: record has bogus MAC",
@@ -4968,6 +5027,16 @@ tls13_UnprotectRecord(sslSocket *ss,
return SECFailure;
}
+ /* There is a similar test in ssl3_HandleRecord, but this test is needed to
+ * account for padding. It's safe to do this here (including the alert),
+ * because it only confirms that the record exceeded the size limit, which
+ * is apparent from the size of the ciphertext. */
+ if (plaintext->len > spec->recordSizeLimit + 1) {
+ SSL3_SendAlert(ss, alert_fatal, record_overflow);
+ PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
+ return SECFailure;
+ }
+
/* The record is right-padded with 0s, followed by the true
* content type, so read from the right until we receive a
* nonzero byte. */
@@ -4977,9 +5046,7 @@ tls13_UnprotectRecord(sslSocket *ss,
/* Bogus padding. */
if (plaintext->len < 1) {
- SSL_TRC(3,
- ("%d: TLS13[%d]: empty record",
- SSL_GETPID(), ss->fd, cText->type));
+ SSL_TRC(3, ("%d: TLS13[%d]: empty record", SSL_GETPID(), ss->fd));
/* It's safe to report this specifically because it happened
* after the MAC has been verified. */
PORT_SetError(SSL_ERROR_BAD_BLOCK_PADDING);
@@ -4987,12 +5054,12 @@ tls13_UnprotectRecord(sslSocket *ss,
}
/* Record the type. */
- cText->type = plaintext->buf[plaintext->len - 1];
+ *innerType = (SSL3ContentType)plaintext->buf[plaintext->len - 1];
--plaintext->len;
/* Check that we haven't received too much 0-RTT data. */
if (spec->epoch == TrafficKeyEarlyApplicationData &&
- cText->type == content_application_data) {
+ *innerType == content_application_data) {
if (plaintext->len > spec->earlyDataRemaining) {
*alert = unexpected_message;
PORT_SetError(SSL_ERROR_TOO_MUCH_EARLY_DATA);
@@ -5002,9 +5069,8 @@ tls13_UnprotectRecord(sslSocket *ss,
}
SSL_TRC(10,
- ("%d: TLS13[%d]: %s received record of length=%d type=%d",
- SSL_GETPID(), ss->fd, SSL_ROLE(ss),
- plaintext->len, cText->type));
+ ("%d: TLS13[%d]: %s received record of length=%d, type=%d",
+ SSL_GETPID(), ss->fd, SSL_ROLE(ss), plaintext->len, *innerType));
return SECSuccess;
}
@@ -5227,6 +5293,58 @@ tls13_EncodeDraftVersion(SSL3ProtocolVersion version)
return (PRUint16)version;
}
+SECStatus
+tls13_ClientReadSupportedVersion(sslSocket *ss)
+{
+ PRUint32 temp;
+ SSL3ProtocolVersion v;
+ TLSExtension *versionExtension;
+ SECItem it;
+ SECStatus rv;
+
+ /* Update the version based on the extension, as necessary. */
+ versionExtension = ssl3_FindExtension(ss, ssl_tls13_supported_versions_xtn);
+ if (!versionExtension) {
+ return SECSuccess;
+ }
+
+ /* Struct copy so we don't damage the extension. */
+ it = versionExtension->data;
+
+ rv = ssl3_ConsumeHandshakeNumber(ss, &temp, 2, &it.data, &it.len);
+ if (rv != SECSuccess) {
+ return SECFailure;
+ }
+ if (it.len) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_SERVER_HELLO, illegal_parameter);
+ return SECFailure;
+ }
+ v = (SSL3ProtocolVersion)temp;
+
+ /* You cannot negotiate < TLS 1.3 with supported_versions. */
+ if (v < SSL_LIBRARY_VERSION_TLS_1_3) {
+ FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_SERVER_HELLO, illegal_parameter);
+ return SECFailure;
+ }
+
+#ifdef TLS_1_3_DRAFT_VERSION
+ if (temp == SSL_LIBRARY_VERSION_TLS_1_3) {
+ FATAL_ERROR(ss, SSL_ERROR_UNSUPPORTED_VERSION, protocol_version);
+ return SECFailure;
+ }
+ if (temp == tls13_EncodeDraftVersion(SSL_LIBRARY_VERSION_TLS_1_3)) {
+ v = SSL_LIBRARY_VERSION_TLS_1_3;
+ } else {
+ v = (SSL3ProtocolVersion)temp;
+ }
+#else
+ v = (SSL3ProtocolVersion)temp;
+#endif
+
+ ss->version = v;
+ return SECSuccess;
+}
+
/* Pick the highest version we support that is also advertised. */
SECStatus
tls13_NegotiateVersion(sslSocket *ss, const TLSExtension *supportedVersions)
diff --git a/security/nss/lib/ssl/tls13con.h b/security/nss/lib/ssl/tls13con.h
index 1aaffb651d..f35b20023d 100644
--- a/security/nss/lib/ssl/tls13con.h
+++ b/security/nss/lib/ssl/tls13con.h
@@ -28,6 +28,7 @@ typedef enum {
SECStatus tls13_UnprotectRecord(
sslSocket *ss, ssl3CipherSpec *spec,
SSL3Ciphertext *cText, sslBuffer *plaintext,
+ SSL3ContentType *innerType,
SSL3AlertDescription *alert);
#if defined(WIN32)
@@ -101,6 +102,7 @@ PRInt32 tls13_Read0RttData(sslSocket *ss, void *buf, PRInt32 len);
SECStatus tls13_HandleEarlyApplicationData(sslSocket *ss, sslBuffer *origBuf);
PRBool tls13_ClientAllow0Rtt(const sslSocket *ss, const sslSessionID *sid);
PRUint16 tls13_EncodeDraftVersion(SSL3ProtocolVersion version);
+SECStatus tls13_ClientReadSupportedVersion(sslSocket *ss);
SECStatus tls13_NegotiateVersion(sslSocket *ss,
const TLSExtension *supported_versions);
diff --git a/security/nss/lib/ssl/tls13exthandle.c b/security/nss/lib/ssl/tls13exthandle.c
index 899f238276..1ab8a8e597 100644
--- a/security/nss/lib/ssl/tls13exthandle.c
+++ b/security/nss/lib/ssl/tls13exthandle.c
@@ -860,12 +860,12 @@ tls13_ServerHandleCookieXtn(const sslSocket *ss, TLSExtensionData *xtnData,
}
if (xtnData->cookie.len == 0) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
return SECFailure;
}
if (data->len) {
- PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
+ PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
return SECFailure;
}
diff --git a/security/nss/lib/util/nssutil.def b/security/nss/lib/util/nssutil.def
index 936455f6e7..26e438ba6a 100644
--- a/security/nss/lib/util/nssutil.def
+++ b/security/nss/lib/util/nssutil.def
@@ -322,4 +322,9 @@ _NSSUTIL_UTF8ToWide;-
_NSSUTIL_Access;-
;- local:
;- *;
-;-};
+;+NSSUTIL_3.38 { # NSS Utilities 3.38 release
+;+ global:
+SECITEM_MakeItem;
+;+ local:
+;+ *;
+;+};
diff --git a/security/nss/lib/util/nssutil.h b/security/nss/lib/util/nssutil.h
index b65d4a0c9f..2749abaa16 100644
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -19,10 +19,10 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
*/
-#define NSSUTIL_VERSION "3.36.4"
+#define NSSUTIL_VERSION "3.38"
#define NSSUTIL_VMAJOR 3
-#define NSSUTIL_VMINOR 36
-#define NSSUTIL_VPATCH 4
+#define NSSUTIL_VMINOR 38
+#define NSSUTIL_VPATCH 0
#define NSSUTIL_VBUILD 0
#define NSSUTIL_BETA PR_FALSE
diff --git a/security/nss/lib/util/pkcs11t.h b/security/nss/lib/util/pkcs11t.h
index c945f314e2..01ff8a5725 100644
--- a/security/nss/lib/util/pkcs11t.h
+++ b/security/nss/lib/util/pkcs11t.h
@@ -466,6 +466,8 @@ typedef CK_ULONG CK_ATTRIBUTE_TYPE;
#define CKA_EXPONENT_1 0x00000126
#define CKA_EXPONENT_2 0x00000127
#define CKA_COEFFICIENT 0x00000128
+/* CKA_PUBLIC_KEY_INFO is new for v2.40 */
+#define CKA_PUBLIC_KEY_INFO 0x00000129
#define CKA_PRIME 0x00000130
#define CKA_SUBPRIME 0x00000131
#define CKA_BASE 0x00000132
diff --git a/security/nss/lib/util/secasn1d.c b/security/nss/lib/util/secasn1d.c
index ccd97481d6..ed237ed72c 100644
--- a/security/nss/lib/util/secasn1d.c
+++ b/security/nss/lib/util/secasn1d.c
@@ -2987,7 +2987,9 @@ SEC_ASN1DecoderFinish(SEC_ASN1DecoderContext *cx)
* XXX anything else that needs to be finished?
*/
- PORT_FreeArena(cx->our_pool, PR_TRUE);
+ if (cx) {
+ PORT_FreeArena(cx->our_pool, PR_TRUE);
+ }
return rv;
}
diff --git a/security/nss/lib/util/secitem.c b/security/nss/lib/util/secitem.c
index 22c5b1f6e6..1e505a9af1 100644
--- a/security/nss/lib/util/secitem.c
+++ b/security/nss/lib/util/secitem.c
@@ -76,6 +76,15 @@ loser:
}
SECStatus
+SECITEM_MakeItem(PLArenaPool *arena, SECItem *dest, unsigned char *data,
+ unsigned int len)
+{
+ SECItem it = { siBuffer, data, len };
+
+ return SECITEM_CopyItem(arena, dest, &it);
+}
+
+SECStatus
SECITEM_ReallocItem(PLArenaPool *arena, SECItem *item, unsigned int oldlen,
unsigned int newlen)
{
diff --git a/security/nss/lib/util/secitem.h b/security/nss/lib/util/secitem.h
index 5b9d0e1748..4fb1239382 100644
--- a/security/nss/lib/util/secitem.h
+++ b/security/nss/lib/util/secitem.h
@@ -35,6 +35,14 @@ SEC_BEGIN_PROTOS
extern SECItem *SECITEM_AllocItem(PLArenaPool *arena, SECItem *item,
unsigned int len);
+/* Allocate and make an item with the requested contents.
+ *
+ * We seem to have mostly given up on SECItemType, so the result is
+ * always siBuffer.
+ */
+extern SECStatus SECITEM_MakeItem(PLArenaPool *arena, SECItem *dest,
+ unsigned char *data, unsigned int len);
+
/*
** This is a legacy function containing bugs. It doesn't update item->len,
** and it has other issues as described in bug 298649 and bug 298938.
diff --git a/security/nss/nss-tool/enc/enctool.cc b/security/nss/nss-tool/enc/enctool.cc
index b3c0d1dbe6..e37e4593a7 100644
--- a/security/nss/nss-tool/enc/enctool.cc
+++ b/security/nss/nss-tool/enc/enctool.cc
@@ -271,7 +271,6 @@ bool EncTool::DoCipher(std::string file_name, std::string out_file,
if (file_name.empty()) {
std::vector<uint8_t> data = ReadInputData("");
std::vector<uint8_t> out(data.size() + 16);
- SECStatus rv;
if (encrypt) {
rv = PK11_Encrypt(symKey.get(), cipher_mech_, params.get(), out.data(),
&outLen, data.size() + 16, data.data(), data.size());
diff --git a/security/nss/tests/all.sh b/security/nss/tests/all.sh
index 3a02debef2..f8a777fb3b 100755
--- a/security/nss/tests/all.sh
+++ b/security/nss/tests/all.sh
@@ -309,7 +309,7 @@ TESTS=${NSS_TESTS:-$tests}
ALL_TESTS=${TESTS}
-nss_ssl_tests="crl iopr policy"
+nss_ssl_tests="crl iopr policy normal_normal"
if [ $NO_INIT_SUPPORT -eq 0 ]; then
nss_ssl_tests="$nss_ssl_tests fips_normal normal_fips"
fi
diff --git a/security/nss/tests/bogo/bogo.sh b/security/nss/tests/bogo/bogo.sh
index d1a93bf9b7..4fccb845b4 100755
--- a/security/nss/tests/bogo/bogo.sh
+++ b/security/nss/tests/bogo/bogo.sh
@@ -25,7 +25,7 @@ bogo_init()
BORING=${BORING:=boringssl}
if [ ! -d "$BORING" ]; then
git clone -q https://boringssl.googlesource.com/boringssl "$BORING"
- git -C "$BORING" checkout -q a513e86c1ebb1383930c9e504bdabcc302a85f30
+ git -C "$BORING" checkout -q ec55dc15d3a39e5f1a58bfd79148729f38f6acb4
fi
SCRIPTNAME="bogo.sh"
@@ -39,11 +39,12 @@ bogo_cleanup()
. common/cleanup.sh
}
-cd "$(dirname "$0")"
-SOURCE_DIR="$PWD"/../..
+cd ../
+cwd=$(cd $(dirname $0); pwd -P)
+SOURCE_DIR="$cwd"/..
bogo_init
(cd "$BORING"/ssl/test/runner;
- GOPATH="$PWD" go test -pipe -shim-path "${BINDIR}"/nss_bogo_shim \
+ GOPATH="$cwd" go test -pipe -shim-path "${BINDIR}"/nss_bogo_shim \
-loose-errors -allow-unimplemented \
-shim-config "${SOURCE_DIR}/gtests/nss_bogo_shim/config.json") \
2>bogo.errors | tee bogo.log
diff --git a/security/nss/tests/cert/cert.sh b/security/nss/tests/cert/cert.sh
index d1a9148a97..34006efd19 100755
--- a/security/nss/tests/cert/cert.sh
+++ b/security/nss/tests/cert/cert.sh
@@ -1060,6 +1060,25 @@ cert_extended_ssl()
# -d "${PROFILEDIR}" -i "${CLIENT_CADIR}/clientCA-ecmixed.ca.cert" \
# 2>&1
+ # Check that a repeated import with a different nickname doesn't change the
+ # nickname of the existing cert (bug 1458518).
+ # We want to search for the results using grep, to avoid subset matches,
+ # we'll use one of the longer nicknames for testing.
+ # (Because "grep -w hostname" matches "grep -w hostname-dsamixed")
+ MYDBPASS="-d ${PROFILEDIR} -f ${R_PWFILE}"
+ TESTNAME="Ensure there's exactly one match for ${CERTNAME}-dsamixed"
+ cert_check_nickname_exists "$MYDBPASS" "${CERTNAME}-dsamixed" 0 1 "${TESTNAME}"
+
+ CU_ACTION="Repeated import of $CERTNAME's mixed DSA Cert with different nickname"
+ certu -A -n "${CERTNAME}-repeated-dsamixed" -t "u,u,u" -d "${PROFILEDIR}" \
+ -f "${R_PWFILE}" -i "${CERTNAME}-dsamixed.cert" 2>&1
+
+ TESTNAME="Ensure there's still exactly one match for ${CERTNAME}-dsamixed"
+ cert_check_nickname_exists "$MYDBPASS" "${CERTNAME}-dsamixed" 0 1 "${TESTNAME}"
+
+ TESTNAME="Ensure there's zero matches for ${CERTNAME}-repeated-dsamixed"
+ cert_check_nickname_exists "$MYDBPASS" "${CERTNAME}-repeated-dsamixed" 0 0 "${TESTNAME}"
+
echo "Importing all the server's own CA chain into the servers DB"
for CA in `find ${SERVER_CADIR} -name "?*.ca.cert"` ;
do
@@ -1532,6 +1551,37 @@ cert_make_with_param()
return 0
}
+cert_check_nickname_exists()
+{
+ MYDIRPASS="$1"
+ MYCERTNAME="$2"
+ EXPECT="$3"
+ EXPECTCOUNT="$4"
+ MYTESTNAME="$5"
+
+ echo certutil ${MYDIRPASS} -L
+ ${BINDIR}/certutil ${MYDIRPASS} -L
+
+ RET=$?
+ if [ "${RET}" -ne "${EXPECT}" ]; then
+ CERTFAILED=1
+ html_failed "${MYTESTNAME} - list"
+ cert_log "ERROR: ${MYTESTNAME} - list"
+ return 1
+ fi
+
+ LISTCOUNT=`${BINDIR}/certutil ${MYDIRPASS} -L | grep -wc ${MYCERTNAME}`
+ if [ "${LISTCOUNT}" -ne "${EXPECTCOUNT}" ]; then
+ CERTFAILED=1
+ html_failed "${MYTESTNAME} - list and count"
+ cert_log "ERROR: ${MYTESTNAME} - list and count failed"
+ return 1
+ fi
+
+ html_passed "${MYTESTNAME}"
+ return 0
+}
+
cert_list_and_count_dns()
{
DIRPASS="$1"
@@ -2425,6 +2475,31 @@ EOF
RETEXPECTED=0
}
+cert_test_orphan_key_reuse()
+{
+ CU_ACTION="Create orphan key in serverdir"
+ certu -G -f "${R_PWFILE}" -z ${R_NOISE_FILE} -d ${PROFILEDIR}
+ # Let's get the key ID of the first orphan key.
+ # The output of certutil -K (list keys) isn't well formatted.
+ # The initial <key-number> part may or may not contain white space, which
+ # makes the use of awk to filter the column unreliable.
+ # To fix that, we remove the initial <number> field using sed, then select the
+ # column that contains the key ID.
+ ORPHAN=`${BINDIR}/certutil -d ${PROFILEDIR} -K -f ${R_PWFILE} | \
+ sed 's/^<.*>//g' | grep -w orphan | head -1 | awk '{print $2}'`
+ CU_ACTION="Create cert request for orphan key"
+ certu -R -f "${R_PWFILE}" -k ${ORPHAN} -s "CN=orphan" -d ${PROFILEDIR} \
+ -o ${SERVERDIR}/orphan.req
+ # Ensure that creating the request really works by listing it, and check
+ # if listing was successful.
+ ${BINDIR}/pp -t certificate-request -i ${SERVERDIR}/orphan.req
+ RET=$?
+ if [ "$RET" -ne 0 ]; then
+ html_failed "Listing cert request for orphan key ($RET)"
+ cert_log "ERROR: Listing cert request for orphan key failed $RET"
+ fi
+}
+
############################## cert_cleanup ############################
# local shell function to finish this script (no exit since it might be
# sourced)
@@ -2444,6 +2519,7 @@ cert_all_CA
cert_test_implicit_db_init
cert_extended_ssl
cert_ssl
+cert_test_orphan_key_reuse
cert_smime_client
IS_FIPS_DISABLED=`certutil --build-flags |grep -cw NSS_FIPS_DISABLED`
if [ $IS_FIPS_DISABLED -ne 0 ]; then
diff --git a/security/nss/tests/common/init.sh b/security/nss/tests/common/init.sh
index 933551e834..6aa22af8d8 100644
--- a/security/nss/tests/common/init.sh
+++ b/security/nss/tests/common/init.sh
@@ -543,8 +543,8 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
D_DISTRUST="Distrust.$version"
D_RSAPSS="RSAPSS.$version"
- # we need relative pathnames of these files abd directories, since our
- # tools can't handle the unix style absolut pathnames on cygnus
+ # we need relative pathnames of these files and directories, since our
+ # tools can't handle the unix style absolute pathnames on cygnus
R_CADIR=../CA
R_SERVERDIR=../server
@@ -565,6 +565,7 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
R_NOLOGINDIR=../nologin
R_SSLGTESTDIR=../ssl_gtests
R_GTESTDIR=../gtests
+ R_RSAPSSDIR=../rsapss
#
# profiles are either paths or domains depending on the setting of
@@ -581,6 +582,7 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
P_R_EXT_SERVERDIR=${R_EXT_SERVERDIR}
P_R_EXT_CLIENTDIR=${R_EXT_CLIENTDIR}
P_R_IMPLICIT_INIT_DIR=${R_IMPLICIT_INIT_DIR}
+ P_R_RSAPSSDIR=${R_RSAPSSDIR}
if [ -n "${MULTIACCESS_DBM}" ]; then
P_R_CADIR="multiaccess:${D_CA}"
P_R_ALICEDIR="multiaccess:${D_ALICE}"
@@ -593,6 +595,7 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
P_R_EXT_SERVERDIR="multiaccess:${D_EXT_SERVER}"
P_R_EXT_CLIENTDIR="multiaccess:${D_EXT_CLIENT}"
P_R_IMPLICIT_INIT_DIR="multiaccess:${D_IMPLICIT_INIT}"
+ P_R_RSAPSSDIR="multiaccess:${D_RSAPSS}"
fi
R_PWFILE=../tests.pw
diff --git a/security/nss/tests/interop/interop.sh b/security/nss/tests/interop/interop.sh
index 97c82e0ca0..50c8bb3c18 100644
--- a/security/nss/tests/interop/interop.sh
+++ b/security/nss/tests/interop/interop.sh
@@ -25,7 +25,7 @@ interop_init()
INTEROP=${INTEROP:=tls_interop}
if [ ! -d "$INTEROP" ]; then
git clone -q https://github.com/ttaubert/tls-interop "$INTEROP"
- git -C "$INTEROP" checkout -q 07930b791827c1bdb6f4c19ca0aa63850fd59e22
+ git -C "$INTEROP" checkout -q d07b28ac32b390dea1c9bcca5c56716247d23e5e
fi
INTEROP=$(cd "$INTEROP";pwd -P)
diff --git a/security/nss/tests/ssl/ssl.sh b/security/nss/tests/ssl/ssl.sh
index de867a4bda..9a63bd9971 100755
--- a/security/nss/tests/ssl/ssl.sh
+++ b/security/nss/tests/ssl/ssl.sh
@@ -283,34 +283,30 @@ ssl_cov()
echo "${testname}" | grep "EXPORT" > /dev/null
EXP=$?
- if [ "$ectype" = "ECC" ] ; then
- echo "$SCRIPTNAME: skipping $testname (ECC only)"
- else
- echo "$SCRIPTNAME: running $testname ----------------------------"
- VMAX="ssl3"
- if [ "$testmax" = "TLS10" ]; then
- VMAX="tls1.0"
- fi
- if [ "$testmax" = "TLS11" ]; then
- VMAX="tls1.1"
- fi
- if [ "$testmax" = "TLS12" ]; then
- VMAX="tls1.2"
- fi
-
- echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\"
- echo " -f -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE}"
-
- rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
- ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} -f \
- -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE} \
- >${TMP}/$HOST.tmp.$$ 2>&1
- ret=$?
- cat ${TMP}/$HOST.tmp.$$
- rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
- html_msg $ret 0 "${testname}" \
- "produced a returncode of $ret, expected is 0"
+ echo "$SCRIPTNAME: running $testname ----------------------------"
+ VMAX="ssl3"
+ if [ "$testmax" = "TLS10" ]; then
+ VMAX="tls1.0"
+ fi
+ if [ "$testmax" = "TLS11" ]; then
+ VMAX="tls1.1"
fi
+ if [ "$testmax" = "TLS12" ]; then
+ VMAX="tls1.2"
+ fi
+
+ echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\"
+ echo " -f -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE}"
+
+ rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
+ ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} -f \
+ -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE} \
+ >${TMP}/$HOST.tmp.$$ 2>&1
+ ret=$?
+ cat ${TMP}/$HOST.tmp.$$
+ rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
+ html_msg $ret 0 "${testname}" \
+ "produced a returncode of $ret, expected is 0"
done
kill_selfserv
@@ -335,8 +331,6 @@ ssl_auth()
echo "$SCRIPTNAME: skipping $testname (non-FIPS only)"
elif [ "$ectype" = "SNI" -a "$NORM_EXT" = "Extended Test" ] ; then
echo "$SCRIPTNAME: skipping $testname for $NORM_EXT"
- elif [ "$ectype" = "ECC" ] ; then
- echo "$SCRIPTNAME: skipping $testname (ECC only)"
else
cparam=`echo $cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" `
if [ "$ectype" = "SNI" ]; then
@@ -550,8 +544,6 @@ ssl_stress()
if [ "$ectype" = "SNI" -a "$NORM_EXT" = "Extended Test" ] ; then
echo "$SCRIPTNAME: skipping $testname for $NORM_EXT"
- elif [ "$ectype" = "ECC" ] ; then
- echo "$SCRIPTNAME: skipping $testname (ECC only)"
elif [ "${CLIENT_MODE}" = "fips" -a "${CAUTH}" -ne 0 ] ; then
echo "$SCRIPTNAME: skipping $testname (non-FIPS only)"
elif [ "${NOLOGIN}" -eq 0 ] && \
@@ -615,9 +607,7 @@ ssl_crl_ssl()
ignore_blank_lines ${SSLAUTH} | \
while read ectype value sparam cparam testname
do
- if [ "$ectype" = "ECC" ] ; then
- echo "$SCRIPTNAME: skipping $testname (ECC only)"
- elif [ "$ectype" = "SNI" ]; then
+ if [ "$ectype" = "SNI" ]; then
continue
else
servarg=`echo $sparam | awk '{r=split($0,a,"-r") - 1;print r;}'`
@@ -729,43 +719,39 @@ ssl_policy()
do
VMIN="ssl3"
- if [ "$ectype" = "ECC" ] ; then
- echo "$SCRIPTNAME: skipping $testname (ECC only)"
- else
- echo "$SCRIPTNAME: running $testname ----------------------------"
- VMAX="ssl3"
- if [ "$testmax" = "TLS10" ]; then
- VMAX="tls1.0"
- fi
- if [ "$testmax" = "TLS11" ]; then
- VMAX="tls1.1"
- fi
- if [ "$testmax" = "TLS12" ]; then
- VMAX="tls1.2"
- fi
+ echo "$SCRIPTNAME: running $testname ----------------------------"
+ VMAX="ssl3"
+ if [ "$testmax" = "TLS10" ]; then
+ VMAX="tls1.0"
+ fi
+ if [ "$testmax" = "TLS11" ]; then
+ VMAX="tls1.1"
+ fi
+ if [ "$testmax" = "TLS12" ]; then
+ VMAX="tls1.2"
+ fi
- # load the policy
- policy=`echo ${policy} | sed -e 's;_; ;g'`
- setup_policy "$policy" ${P_R_CLIENTDIR}
+ # load the policy
+ policy=`echo ${policy} | sed -e 's;_; ;g'`
+ setup_policy "$policy" ${P_R_CLIENTDIR}
- echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\"
- echo " -f -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE}"
+ echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} \\"
+ echo " -f -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE}"
- rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
- ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} -f \
- -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE} \
- >${TMP}/$HOST.tmp.$$ 2>&1
- ret=$?
- cat ${TMP}/$HOST.tmp.$$
- rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
+ rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
+ ${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -c ${param} -V ${VMIN}:${VMAX} ${CLIENT_OPTIONS} -f \
+ -d ${P_R_CLIENTDIR} $verbose -w nss < ${REQUEST_FILE} \
+ >${TMP}/$HOST.tmp.$$ 2>&1
+ ret=$?
+ cat ${TMP}/$HOST.tmp.$$
+ rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
- #workaround for bug #402058
- [ $ret -ne 0 ] && ret=1
- [ ${value} -ne 0 ] && value=1
+ #workaround for bug #402058
+ [ $ret -ne 0 ] && ret=1
+ [ ${value} -ne 0 ] && value=1
- html_msg $ret ${value} "${testname}" \
- "produced a returncode of $ret, expected is ${value}"
- fi
+ html_msg $ret ${value} "${testname}" \
+ "produced a returncode of $ret, expected is ${value}"
done
cp ${P_R_CLIENTDIR}/pkcs11.txt.sav ${P_R_CLIENTDIR}/pkcs11.txt
@@ -1004,9 +990,7 @@ ssl_crl_cache()
while read ectype value sparam cparam testname
do
[ "$ectype" = "" ] && continue
- if [ "$ectype" = "ECC" ] ; then
- echo "$SCRIPTNAME: skipping $testname (ECC only)"
- elif [ "$ectype" = "SNI" ]; then
+ if [ "$ectype" = "SNI" ]; then
continue
else
servarg=`echo $sparam | awk '{r=split($0,a,"-r") - 1;print r;}'`
diff --git a/security/nss/tests/ssl_gtests/ssl_gtests.sh b/security/nss/tests/ssl_gtests/ssl_gtests.sh
index fd678bf594..eef77f16f3 100755
--- a/security/nss/tests/ssl_gtests/ssl_gtests.sh
+++ b/security/nss/tests/ssl_gtests/ssl_gtests.sh
@@ -47,6 +47,7 @@ make_cert() {
dsa) type_args='-g 1024' ;;
rsa) type_args='-g 1024' ;;
rsa2048) type_args='-g 2048';type=rsa ;;
+ rsa8192) type_args='-g 8192';type=rsa ;;
rsapss) type_args='-g 1024 --pss';type=rsa ;;
p256) type_args='-q nistp256';type=ec ;;
p384) type_args='-q secp384r1';type=ec ;;
@@ -83,6 +84,7 @@ ssl_gtest_certs() {
make_cert client rsa sign
make_cert rsa rsa sign kex
make_cert rsa2048 rsa2048 sign kex
+ make_cert rsa8192 rsa8192 sign kex
make_cert rsa_sign rsa sign
make_cert rsa_pss rsapss sign
make_cert rsa_decrypt rsa kex
diff --git a/security/nss/tests/tools/TestRSAPSS.p12 b/security/nss/tests/tools/TestRSAPSS.p12
new file mode 100644
index 0000000000..91473891c8
--- /dev/null
+++ b/security/nss/tests/tools/TestRSAPSS.p12
Binary files differ
diff --git a/security/nss/tests/tools/tools.sh b/security/nss/tests/tools/tools.sh
index 11be23e051..7cf1ef73f8 100644
--- a/security/nss/tests/tools/tools.sh
+++ b/security/nss/tests/tools/tools.sh
@@ -105,6 +105,7 @@ tools_init()
mkdir -p ${TOOLSDIR}/data
cp ${QADIR}/tools/TestOldCA.p12 ${TOOLSDIR}/data
cp ${QADIR}/tools/TestOldAES128CA.p12 ${TOOLSDIR}/data
+ cp ${QADIR}/tools/TestRSAPSS.p12 ${TOOLSDIR}/data
cd ${TOOLSDIR}
}
@@ -436,6 +437,23 @@ tools_p12_import_old_files()
check_tmpfile
}
+tools_p12_import_rsa_pss_private_key()
+{
+ echo "$SCRIPTNAME: Importing RSA-PSS private key from PKCS#12 file --------------"
+ ${BINDIR}/pk12util -i ${TOOLSDIR}/data/TestRSAPSS.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '' 2>&1
+ ret=$?
+ html_msg $ret 0 "Importing RSA-PSS private key from PKCS#12 file"
+ check_tmpfile
+
+ # Check if RSA-PSS identifier is included in the key listing
+ ${BINDIR}/certutil -d ${P_R_COPYDIR} -K -f ${R_PWFILE} | grep '^<[0-9 ]*> *rsaPss'
+ ret=$?
+ html_msg $ret 0 "Listing RSA-PSS private key imported from PKCS#12 file"
+ check_tmpfile
+
+ return $ret
+}
+
############################## tools_p12 ###############################
# local shell function to test basic functionality of pk12util
########################################################################
@@ -448,6 +466,9 @@ tools_p12()
tools_p12_export_with_none_ciphers
tools_p12_export_with_invalid_ciphers
tools_p12_import_old_files
+ if [ "${TEST_MODE}" = "SHARED_DB" ] ; then
+ tools_p12_import_rsa_pss_private_key
+ fi
}
############################## tools_sign ##############################